Hyperf默认不记录完整SQL,需在db.php中启用log_sql=>true并设置PDO::ATTR_EMULATE_PREPARES=>true;若仍截断,还需调整Monolog LineFormatter的max_length参数,并注意生产环境敏感信息泄露风险。

Hyperf 日志里 SQL 被截断,不是日志配置问题,而是 DB 组件默认关了完整 SQL 记录
Hyperf 的 db 组件默认不记录完整 SQL(尤其是带大量参数的 INSERT/UPDATE),即使你把 logger 级别调成 debug,也只会看到类似 INSERT INTO users VALUES (?, ?, ?) 这种占位符形式。这不是 Monolog 截断,是 DB 层压根没把绑定参数拼进去。
开启 PDOStatement::getAttribute(PDO::ATTR_DRIVER_NAME) 后才能触发完整 SQL 日志
Hyperf 底层用的是 Swoole 协程 PDO 封装,SQL 日志是否“展开参数”,取决于 DbLogger 是否调用了 getSQL() 方法——而该方法只在启用 log_sql 且驱动支持时才生效。常见误区是以为改 logger.php 就够,其实必须先打开 DB 配置开关:
-
config/autoload/db.php中确保'options' => [PDO::ATTR_EMULATE_PREPARES => true]已设置(否则部分驱动如 MySQLi 不返回完整 SQL) - 在
'logger'子项中显式启用:'log_sql' => true(默认为false) - 若使用 MySQL,建议同时加
PDO::MYSQL_ATTR_DIRECT_QUERY => false,避免绕过预处理导致日志丢失参数
日志仍被截断?检查 formatter 的 max_length 和 monolog 默认限制
即使 DB 层吐出了完整 SQL,Monolog 的 LineFormatter 默认会把 message 字段截到 10000 字符(约 10KB)。你在 config/autoload/logger.php 里看到的 'formatter' 配置,如果没显式传 max_length,就走 Monolog 内置默认值:
- 找到
'formatter' => ['class' => LineFormatter::class, 'constructor' => [...]] - 在
constructor数组第 5 个位置(索引 4)传null,表示不限长;或传一个足够大的整数,比如50000 - 注意:设太大可能撑爆内存或让日志文件难以查看,建议按实际最长 SQL 长度 + 20% 浮动设置
生产环境慎用 full SQL 日志,尤其含敏感字段时
开启 log_sql => true 后,所有参数(包括密码、token、手机号)都会明文写入日志文件。这不是 bug,是设计行为。如果你只是想排查慢查询或语法错误,更安全的做法是:
- 临时开启,查完立刻关掉
- 配合
level控制,比如只在app_env === 'dev'时启用 - 用
DB::listen()回调做条件过滤,例如只记录执行时间 > 100ms 的 SQL:if ($event->time > 100) { \Hyperf\Logger\LoggerFactory::get('slowsql')->info($event->sql, $event->bindings); }
协程环境下,DB::listen() 是比改全局配置更轻量、更可控的日志介入点,且能直接拿到已解析的 $event->sql 和 $event->bindings,无需担心 formatter 截断。


















