必须手动配置Monolog并添加request通道监听器才能记录生产环境访问路径,因APP_DEBUG=0时框架内核层已禁用debug日志源,仅调高level无效;需注册kernel.request事件监听器,写入轻量request.log,并验证channel声明、handler绑定及服务注册三要素。

生产环境默认不记录访问路径日志,必须手动启用
Symfony 2 默认在 prod 环境下关闭所有 debug 级别日志,包括路由匹配、控制器调用等访问路径痕迹——var/logs/prod.log 里几乎只有 error/warning,看不到“谁在什么时候访问了哪个 URL”。这不是 bug,是性能与安全的默认取舍。
要看到访问路径(如 GET /api/users、POST /login),得主动配置 Monolog 记录请求生命周期事件。但注意:不能直接开 level: debug,否则 event 和 doctrine 日志会瞬间撑爆磁盘。
- 确认
APP_ENV=prod且APP_DEBUG=0(这是前提,否则不是真 prod 行为) - 编辑
config/packages/prod/monolog.yaml,确保已声明mainhandler 并显式包含request通道:channels: ["!event", "!doctrine", "request"] - 在
config/packages/monolog.yaml根级追加channels: ["request"],否则request通道不会被容器识别 - 添加一个轻量 handler 专收 request 日志,避免污染主日志:
request_logger: type: rotating_file path: "%kernel.logs_dir%/request.log" level: info channels: ["request"]
如何让 Symfony 2 记录每次 HTTP 请求的路径和方法
仅靠 Monolog 配置还不够——request 通道本身不自动产生日志,需要事件监听器或中间件触发。Symfony 2 没有现代版本的 KernelEvents::REQUEST,得靠 kernel.request 事件手动埋点。
最简可行方案:写一个服务监听 kernel.request,只记路径和 method,不记 body 或 headers,避免敏感信息泄露:
- 创建监听器类
src/EventListener/RequestLoggerListener.php,注入LoggerInterface并限定 channel:monolog.logger.request - 在
services.yml中注册并绑定事件:services: app.request_logger_listener: class: App\EventListener\RequestLoggerListener arguments: ['@monolog.logger.request'] tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } - 在
onKernelRequest()方法里写:$logger->info('{method} {uri}', ['method' => $request->getMethod(), 'uri' => $request->getRequestUri()]); - 确保该服务只在
prod环境加载(加env: prod条件,或放在config/services_prod.yml)
为什么 prod 环境开了 debug 日志反而看不到访问路径
很多人试过把 level: debug 直接塞进 prod/monolog.yaml,结果 prod.log 还是空的——因为 Symfony 2 的 debug 日志严重依赖 debug 模式开关,而 APP_DEBUG=0 时,框架会跳过大部分 debug 级别的内部日志(比如 Router、ControllerResolver 的 trace),连 monolog 都收不到这些消息。
换句话说:APP_DEBUG=0 不只是关掉错误页面,它从内核层就掐断了 debug 日志源。强行改 level 只影响“能收到的日志怎么处理”,不影响“哪些日志会被生成”。
-
APP_DEBUG=1在 prod 环境是危险操作:暴露堆栈、参数、服务列表,还可能引发性能抖动 - 想看路由匹配过程?用
php bin/console router:match /path手动测,比开 debug 更安全 - 真正要监控线上访问路径,应优先走 Nginx/Apache access log,再用 Logstash + ELK 聚合,而不是依赖 PHP 层日志
检查 request 日志是否生效的三个硬指标
配完别急着上线,先验证三点,否则白忙活:
- 运行
php bin/console debug:event-dispatcher kernel.request,确认你的监听器在 list 里且 priority ≥ 0 - 执行一次真实请求(
curl -I https://yoursite.com/health),立刻查var/logs/request.log是否新增一行:INFO [2026-08-13 12:05:22] request.INFO: GET /health [] [] - 检查
monolog.logger.request服务是否存在:php bin/console debug:container monolog.logger.request,无结果说明 channel 声明或 handler 绑定漏了
request 日志最容易卡在 channel 声明和 handler 绑定的大小写一致性上——channels: ["request"] 和 channels: [request] 效果完全不同,YAML 解析器会静默失败。


















