Hyperf MySQL协程日志需绑定协程ID和请求路径以精准归属,应隔离至专用sql.log文件,仅记录超100ms慢查询,并确保logger实例与formatter协程安全。

Hyperf MySQL协程日志不是简单开启开关就能看到,关键是要让每条 SQL 日志能准确归属到当前协程和请求,避免并发混杂、无法定位问题。
让 SQL 日志带上协程 ID 和请求标识
默认日志不带协程上下文,多请求同时执行时 SQL 会挤在一起,根本分不清哪条属于哪个请求。必须强制注入 cid(协程 UID)和 request_id(或路径)。
- 监听 StatementExecuted 事件,在回调中获取
\Swoole\Coroutine::getuid() - 从上下文中提取请求路径:
\Hyperf\Context\Context::get(\Hyperf\HttpMessage\Server\RequestInterface::class)?->getUri()?->getPath() - 用
logger()->info()输出结构化日志,字段包含cid、time、sql、path
单独隔离 SQL 日志到专用文件
把 SQL 日志从主日志里拆出来,方便排查慢查、分析执行频次,也避免干扰业务日志。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 在
config/autoload/logger.php中新增一个名为'sql'的 logger 配置 - 指定 handler 为
RotatingFileHandler,路径设为runtime/logs/sql.log - 在监听器中调用
$loggerFactory->get('sql', 'sql')获取专属 logger 实例
只记录慢查询,减少日志噪音
全量打印所有 SQL 容易撑爆磁盘,建议按耗时阈值过滤,比如只记超过 100ms 的语句。
- 监听 QueryExecuted 事件(注意不是 StatementExecuted),它含完整耗时
$event->time - 判断
round($event->time * 1000) > 100,满足才写入日志 - 可结合
MAX_EXECUTION_TIME提前中断长 SQL,防止日志还没打完就超时
验证日志是否真的协程安全
如果日志内容错乱、时间戳跳变、或者某些请求完全没日志,大概率是 logger 实例被跨协程复用或 formatter 不支持协程。
- 确认未启用
useLocking(Monolog 默认关闭,但自定义 handler 时可能误开) - 检查 formatter 是否用了
LineFormatter或JsonFormatter,二者均协程安全 - 避免在日志 context 中传入不可序列化的对象(如 PDO 实例),会导致写入失败静默丢弃


















