beego默认日志不支持结构化json输出,需升级至v2.1+并配置log.setformat("json")、setoutput(os.stdout),或自定义logs.logger实现;配合filebeat启用json.keys_under_root等参数直连es,跳过logstash以提升性能。

Beego 应用默认输出日志到本地文件或 stdout,直接对接 ELK 需要结构化、带上下文字段(如 app_name、level、trace_id)的 JSON 日志,否则 Logstash 解析困难、Kibana 查询低效。原生 beego.BeeLogger 不支持自动 JSON 输出,必须改造或替换日志后端。
Beego 日志如何输出结构化 JSON 格式
Beego 1.x/2.x 默认使用 logs 模块,但其 SetLogger 接口只接受 logs.Logger 实现,不兼容第三方结构化日志库(如 zerolog 或 logrus)。可行路径是:自己实现一个符合 logs.Logger 接口的 JSON 封装器,或改用 Beego 2.1+ 的 log 模块(基于 go.uber.org/zap)并桥接输出。
- 推荐方案:升级到 Beego v2.1+,启用
log模块,并通过log.SetOutput将日志重定向到os.Stdout,再由 Filebeat 捕获 - 关键配置项:
log.SetLevel(log.LevelDebug)、log.SetOutput(os.Stdout)、log.SetFormat("json")(需确认版本是否支持;若不支持,需自定义Encoder) - 注意:Beego 的
log.Info等方法默认不带trace_id,需在 middleware 中注入上下文,并用log.With显式携带,例如log.With("trace_id", ctx.Value("trace_id")).Info("request handled")
Filebeat 配置要点:匹配 Beego JSON 日志格式
Filebeat 必须识别 Beego 输出的 JSON 行,否则会当作纯文本切分,丢失字段。核心是启用 json.keys_under_root: true 并关闭默认的行首时间解析(Beego JSON 已含 time 字段)。
-
filebeat.inputs.type: filestream(替代已弃用的log类型) -
filebeat.inputs.json.add_error_key: true,便于排查解析失败 -
filebeat.inputs.json.message_key: "msg",让 Kibana 的message字段显示可读内容 - 避免使用
multiline,Beego JSON 日志每行一条,开启 multiline 反而导致合并错误 - 示例片段:
filebeat.inputs: - type: filestream paths: ["/var/log/myapp/*.log"] json.keys_under_root: true json.overwrite_keys: true json.add_error_key: true json.message_key: "msg"
Logstash 过滤器要不要?什么情况下可以跳过
如果 Beego 日志已完整输出标准 JSON(含 time、level、app_name、trace_id),且字段命名规范(如 level 值为 "info" 而非 "INFO"),Logstash 可完全省略,Filebeat 直连 Elasticsearch。这是当前生产环境主流做法,减少单点故障与延迟。
- 必须保留 Logstash 的场景:需要动态脱敏(如过滤
password字段)、跨服务字段补全(如从 HTTP header 提取user_id)、或做复杂条件路由(不同app_name写入不同 ES 索引) - 若保留 Logstash,
filter段只需 minimal 处理:用date插件将time字段转为@timestamp,用mutate重命名或小写level - 注意:Logstash 7.14+ 默认禁用
pipeline.workers并行,高吞吐下需显式调大,否则成为瓶颈
Kibana Space 权限与索引生命周期(ILM)配置易忽略点
Beego 服务多、部署频繁,若所有日志写入同一索引(如 beego-logs),会导致单索引过大、查询变慢、无法按服务隔离权限。必须结合 ILM + Space 实现自动滚动与访问控制。
- 索引模板中
index_patterns应设为"beego-*",配合 Filebeat 的output.elasticsearch.index使用日期变量,如beego-%{+yyyy.MM.dd} - ILM 策略里
rollover条件优先用max_size: "50gb"而非max_age,避免日志量波动导致碎片过多 - Kibana Space 命名建议按团队或服务域(如
backend-space),而非按环境(prod),因同一 Space 可配多个索引模式,更灵活 - Beego 日志中缺失
host.name或service.name字段时,Kibana Discover 无法按服务聚合——务必在 Filebeatprocessors中注入:processors: - add_host_metadata: ~ - add_fields: target: '' fields: service.name: 'my-beego-app'
最常被跳过的一步是 Filebeat 的 add_fields 注入和 ILM 的 max_size 设置。没有它们,日志看似能进 Kibana,但查一周前的数据极慢,跨服务筛选基本不可用。











