需三处联动:1. 配置 lineformatter 启用堆栈(constructor 第四、五参数设为 true);2. 在异常处理器中手动注入 request_id、correlation_id 等上下文;3. 调用 logger->error 时传入含异常类名、错误码、文件行号及业务字段的结构化 context 数组。

要让 Hyperf 日志组件输出**完整报错信息(含堆栈、上下文、协程 ID、请求 ID)**,不能只靠默认配置。关键在于三处联动:日志 Formatter 启用堆栈、异常处理器注入上下文、业务日志调用时传结构化 context。
启用 LineFormatter 的堆栈追踪
在 config/autoload/logger.php 中,为需要记录错误详情的 channel(如 'error' 或 'default')配置 LineFormatter,并显式开启堆栈支持:
- constructor 第四个参数设为 true(
include_stacktraces) - 第五个参数也设为 true(
allow_inline_line_breaks,避免堆栈被截断成一行) - 示例片段:
'formatter' => [ 'class' => \Monolog\Formatter\LineFormatter::class, 'constructor' => [ null, 'Y-m-d H:i:s', true, true, true ] ]
在异常处理器中注入请求上下文
Hyperf 默认不自动把 request_id、correlation_id 写入日志。需在自定义异常处理器(如 App\Exception\Handler\AppExceptionHandler)的 handle() 方法里手动补充:
- 从容器或请求对象中取
$request->getAttribute('request_id') - 用
\Hyperf\Context\Context::get('correlation_id')获取协程级唯一标识 - 调用
$this->logger->error($throwable->getMessage(), [...上下文数组...]),而非仅->error($msg)
结构化记录异常本身
不要只记 $e->getMessage()。完整错误日志应包含:
- 异常类名:
get_class($throwable) - 错误码:
$throwable->getCode() - 文件与行号:
$throwable->getFile() . ':' . $throwable->getLine() - 完整堆栈:
$throwable->getTraceAsString()(已在 LineFormatter 中启用,无需重复拼) - 业务上下文字段(如 order_id、user_id)必须作为 context 数组键值对传入,不能拼进 message 字符串











