You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kubernetes集群中实现Symfony应用向Graylog发送日志

解决Symfony应用日志转发到Graylog的问题

你的环境是Kubernetes集群,运行着PHP、Nginx、MySQL、Redis等Docker容器,Graylog 3负责采集所有容器的stdout和stderr日志。但PHP容器内的Symfony应用使用Monolog默认将日志写入容器内部文件,Graylog无法读取这些文件,现在需要把Symfony的所有日志(错误、警告、通知、信息等)都发送到Graylog。

先梳理你已经尝试过的方案及问题:

  • 配置Monolog输出到控制台:修改/config/packages/prod/monolog.yaml添加console和syslog_handler,但日志未输出到stdout;
  • 使用error_log():可输出到控制台,但无法利用Monolog的日志捕获能力,还会导致Nginx与PHP容器重复输出日志,产生冗余;
  • 链接日志文件到stdout:执行ln -sf /dev/stdout /var/www/docroot/var/log/my-log-file.log时出现文件无法打开的错误,且操作繁琐;
  • 通过Graylog API发送日志:是理想方案,但希望有更简便的实现方式。

接下来给出两个可行的解决方案:

方案1:修复Monolog Console Handler配置,输出到stdout

之前的配置可能存在优先级或参数错误,正确的生产环境Monolog配置应确保Console Handler正确指向stdout,并覆盖默认的文件写入逻辑。

修改config/packages/prod/monolog.yaml:

monolog:
    handlers:
        main:
            type: console
            process_psr_3_messages: true
            channels: ["!event"]
            level: debug # 设置为debug即可覆盖所有日志级别
            formatter: monolog.formatter.json # 可选,用JSON格式方便Graylog解析结构化日志
        # 注释或删除原有的file handler,避免重复写入文件
        # file:
        #     type: stream
        #     path: "%kernel.logs_dir%/%kernel.environment%.log"
        #     level: debug

注意事项:

  • 确保Symfony运行在prod环境(通过容器环境变量APP_ENV=prod设置),否则会加载其他环境的配置;
  • 检查Docker容器启动命令是否未重定向stdout/stderr;
  • 开启process_psr_3_messages确保所有符合PSR-3标准的日志都能被处理;
  • JSON格式的日志能让Graylog更方便地解析日志中的上下文数据。

方案2:使用Monolog的Gelf Handler直接发送到Graylog(推荐)

Graylog原生支持GELF(Graylog扩展日志格式)协议,通过Monolog的Gelf Handler可以直接将日志发送到Graylog的GELF输入端口,比API更简便,还能完整保留Monolog的日志上下文信息。

步骤1:安装依赖

在PHP容器内执行以下命令:

composer require monolog/monolog graylog2/gelf-php

步骤2:配置Monolog的Gelf Handler

修改config/packages/prod/monolog.yaml:

monolog:
    handlers:
        graylog:
            type: gelf
            publisher:
                hostname: "%env(GRAYLOG_HOST)%" # 替换为你的Graylog服务地址,比如Kubernetes内部服务名graylog-service.default.svc.cluster.local
                port: 12201 # Graylog默认的GELF UDP输入端口
            level: debug
            formatter: monolog.formatter.gelf_message
            # 可选:添加自定义上下文字段,方便Graylog筛选
            context:
                app_name: "symfony-app"
                pod_name: "%env(HOSTNAME)%" # Kubernetes容器的HOSTNAME即为Pod名称
        # 可选保留console handler,同时输出到stdout和Graylog
        main:
            type: console
            level: debug

步骤3:在Graylog中配置GELF输入

登录Graylog后台,创建一个GELF UDP输入(也可选择TCP,需与配置一致),端口设置为12201,绑定到合适的网络接口即可。

该方案优势:

  • 直接将日志发送到Graylog,无需依赖容器stdout采集,避免与Nginx日志混淆;
  • 完整保留Monolog的结构化日志数据(上下文、额外字段、日志级别等);
  • 配置简单,无需修改容器启动命令或文件链接。

为什么之前的Console Handler未生效?

大概率是以下原因:

  • 配置优先级问题:如果同时存在file handler和console handler,file handler可能先捕获了日志,导致console无输出;
  • 环境配置覆盖:检查config/packages/monolog.yaml等全局配置是否覆盖了prod环境的配置;
  • 日志级别设置过高:比如设置为error时,info、notice级别的日志不会被输出。

内容的提问来源于stack exchange,提问作者Zeth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:40:38