hyperf日志需精准展示异常信息,核心是使上下文可识别、可定位、可追溯;应按异常类型动态记录,结构化注入元数据与业务标识,强化协程堆栈与请求隔离,并为异步队列异常单独归档。

Hyperf日志要精准展示关键程序异常信息,核心不是“过滤掉什么”,而是“让异常上下文可识别、可定位、可追溯”。默认日志容易淹没在海量输出中,尤其在协程高并发场景下,不加控制的日志会丢失请求链路、堆栈和业务标识。
按异常类型动态启用日志记录
Hyperf 的 OpenTracing 配置支持细粒度异常过滤,避免无意义的噪音干扰。关键在于区分“需告警的致命异常”和“可忽略的业务异常”:
- 在
config/autoload/opentracing.php中开启异常追踪:'exception' => true - 显式排除已知非故障类异常,例如 404 或表单验证失败:
'ignore_exceptions' => [ \Hyperf\HttpMessage\Exception\NotFoundException::class, \Hyperf\Validation\Exception\ValidationException::class ] - 保留真正需要排查的异常,如
RuntimeException、PDOException、自定义的BusinessLogicException等
结构化日志中强制注入异常上下文字段
仅用 $logger->error($e->getMessage()) 会导致关键信息丢失。必须将异常元数据作为 context 数组 显式传入:
- 包含标准字段:
['code' => $e->getCode(), 'file' => $e->getFile(), 'line' => $e->getLine()] - 补充业务标识:
['user_id' => context_get('user_id') ?? null, 'order_id' => $this->orderId ?? null] - 若使用 JSON 格式日志,这些字段会自动成为 JSON 的一级键,便于 ELK 或 Loki 做字段级检索
协程隔离日志 + 堆栈增强
协程环境下,堆栈易被截断、上下文易混淆。需两步加固:
- 启用完整堆栈:在
config/autoload/logger.php的LineFormatter配置中,将第四个参数设为true(include_stacktraces) - 绑定唯一请求标识:在中间件或控制器入口处写入
\Hyperf\Context\Context::set('request_id', $request->getAttribute('request_id')),再于日志 context 中读取并带上 - 避免使用
$_SERVER或全局变量——它们在协程间不安全,会导致日志错乱
异步队列任务异常单独归档
队列任务失败常静默消失,因其异常被全局 Handler 拦截或被 try-catch 吞掉。要确保关键异常进日志:
- Job 类的
handle()中禁止空 catch;必须重抛:catch (\Exception $e) { logger()->error('Job failed', ['job' => get_class($this), 'exception' => $e]); throw $e; } - 确认
config/autoload/exceptions.php中未对\Hyperf\AsyncQueue\Exception\JobException做无差别捕获,否则重试机制失效 - 建议为队列任务单独配置 channel(如
'queue_error'),把失败日志定向到独立文件或上报通道











