ThinkPHP6可通过Monolog自定义Handler实现远程日志推送,推荐GelfHandler直连Graylog,并需注入trace_id、host、env等上下文字段,禁用文件日志,启用异步容错机制。

ThinkPHP6 本身不内置远程日志推送能力,但底层使用 Monolog 作为日志引擎,支持通过自定义 Handler 将日志发往远程服务。关键在于替换默认的 file 驱动为网络型日志通道,并确保上下文携带可追踪字段。
选用兼容 PSR-3 的远程日志处理器
Monolog 提供多种网络传输 Handler,按场景推荐:
- SyslogHandler:适合已有 rsyslog 基础设施的团队。日志先写入本地 syslog,再由 rsyslog 转发至 Graylog、Papertrail 或自建 UDP/TCP 日志服务器
-
GelfHandler(需
graylog2/gelf-php):直连 Graylog,发送结构化 GELF 日志,自动包含host、level_name、timestamp,可手动追加trace_id、app_name等字段 -
StreamHandler + TCP/UDP:用
tcp://graylog.example.com:12201或udp://...直连,轻量但需自行处理序列化与重试 - 自定义 HTTP Handler:向自建 API(如 FastAPI 写的日志接收端)POST JSON,建议启用 Basic Auth、gzip 压缩、500ms 超时及失败缓存降级
配置自定义日志通道(以 GelfHandler 为例)
在 config/log.php 中新增通道配置:
'gelf' => [
'type' => 'monolog',
'level' => 'info',
'handler' => \Monolog\Handler\GelfHandler::class,
'constructor' => [
new \Gelf\Publisher(new \Gelf\Transport\UdpTransport('graylog.example.com', 12201)),
],
'processors' => [
// 自动注入 trace_id、host、env 等
\Monolog\Processor\IntrospectionProcessor::class,
\Monolog\Processor\MemoryUsageProcessor::class,
],
],
然后将默认通道切换过去:'default' => 'gelf'
同时注释或删除 'file' 驱动配置,防止误用。
立即学习“PHP免费学习笔记(深入)”;
注入分布式关键上下文字段
每条日志必须带标识,否则多节点日志无法关联。推荐在全局中间件中生成并绑定:
-
trace_id:用
bin2hex(random_bytes(8))生成,存入 Request 对象或容器,再通过Log::info('msg', ['trace_id' => $id])显式传入 -
host / server_id:从
gethostname()或env('SERVER_ID')获取,避免用 IP(可能变化) -
app_env & app_version:从
.env读取APP_ENV和自定义APP_VERSION,便于区分环境和灰度版本
禁用文件日志 + 启用异步容错机制
生产环境应彻底关闭本地文件写入:
- 确认
config/log.php中无'file'驱动残留,且'default'不指向它 - HTTP 上报务必设
'timeout' => 0.5,并实现失败后写入临时 buffer 文件(如/tmp/log_buffer.json),配合后台脚本定时重发 - 禁止在控制器或模型中直接调用
error_log()或file_put_contents(),所有日志统一走Log::channel('gelf')门面



















