Rails 日志实战:配置、请求标记与 Lograge 结构化输出

Rails 日志中文实战:Rails.logger 与 config.log_level、ActiveSupport::TaggedLogging 请求标记、log_tags 注入 request_id、Lograge 单行 JSON 请求日志、生产环境日志配置清单,以及观测云 DataKit 采集与告警落地方案。

最佳实践
Rails 日志实战:配置、请求标记与 Lograge 结构化输出技术指南封面

Rails 自带完整的日志体系:Rails.logger、按环境的配置文件、请求级标记。但默认的 Rails 请求日志是多行纯文本——开发友好,生产灾难。本文讲解 Rails 日志的配置要点、log_tags 请求关联、Lograge 结构化改造,以及观测云平台落地方案。

核心要点速览

  • Rails.logger 开箱即用:默认写到 log/<environment>.log,级别由 config.log_level 控制。
  • 默认请求日志不适合生产:一次请求几十行多行日志,解析与聚合都困难,Lograge 把它压缩成一行结构化日志。
  • log_tags + TaggedLogging:给日志自动打上 request_id 等标记,是请求级排障的基础。
  • 生产落地:JSON 输出 stdout,观测云 DataKit 采集,监控器告警,APM trace_id 关联。

Rails 日志的默认行为

Rails 应用里随处可用 Rails.logger

Rails.logger.info("订单创建成功 order_id=#{order.id}")
Rails.logger.error("支付回调验签失败")

默认行为:

  • 输出到 log/production.log(随环境变化);
  • 级别由环境配置控制:开发 debug,生产传统上是 info(新版本 Rails 默认从 RAILS_LOG_LEVEL 环境变量读取);
  • 每次 HTTP 请求会产生一大坨多行日志:Started、Processing、SQL、Rendered、Completed……

在控制器里还可以用 loggerActionController 已注入)。自定义子系统日志建议 ActiveSupport::Logger.new 或直接用 Rails.logger.tagged 派生。

调整级别与输出目的地

# config/environments/production.rb
config.log_level = :info

# 输出到 stdout(容器部署推荐)
config.logger = ActiveSupport::Logger.new($stdout)

临时排障不想重启?Rails 控制台里 Rails.logger.level = :debug 即时生效(仅当前进程)。

用 log_tags 给每个请求打标记

config.log_tags = [:request_id, :remote_ip]

之后该请求生命周期内的所有日志都会带上 [7f3a9c...] [10.0.0.8] 前缀。配合 grep request_id 或在观测云中按字段过滤,即可还原单次请求的全部日志。

类内使用:logger.tagged("OrderService") { logger.info("...") } 手动追加标记。

Lograge:把请求日志压缩成一行

默认 Rails 请求日志又长又散。Lograge 把一次请求的所有信息汇总为单行结构化日志

# Gemfile
gem "lograge"

# config/environments/production.rb
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Json.new
config.lograge.custom_options = lambda do |event|
  { user_id: event.payload[:current_user_id] }
end

输出从几十行变成一行 JSON:

{"method":"GET","path":"/api/orders","format":"json","controller":"Api::OrdersController","action":"index","status":200,"duration":45.2,"view":12.3,"db":8.9,"timestamp":"2026-08-25T14:42:10.123+08:00","user_id":42}

method、path、status、duration、db/view 耗时一应俱全——访问日志、慢请求分析、5xx 告警全部建立在这一行之上。custom_options 里按需注入业务字段(用户 ID、租户 ID)。

生产配置清单

一份稳妥的 production.rb 日志配置:

config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
config.logger = ActiveSupport::Logger.new($stdout)   # 容器:stdout
config.log_tags = [:request_id]
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Json.new
# 业务 logger 用 JSON formatter(见 Ruby 篇自定义 formatter)

要点:stdout 输出(十二要素)、JSON 格式、request_id 标记、级别走环境变量。文件轮转交给容器运行时或系统 logrotate,Rails 自身不用管。

观测云落地:Rails 日志采集与分析

  1. 应用侧:stdout + JSON(Lograge 管请求日志,业务日志自定义 JSON formatter)。
  2. DataKit 采集:容器 stdout 自动采集;主机部署在 conf.d/log/logging.conf 配置 logfiles 指向 log/production.logsource: rails-appservice 标识服务。JSON 自动解析。
  3. Pipeline 标准化:Lograge 的 status(HTTP 状态码)与业务日志的级别统一映射为观测云标准 status 字段(5xx/error → error),timestamp 解析为 time
  4. 检索分析:日志查看器按 statuscontrolleraction 过滤;图表模式统计各接口耗时与错误率;聚类分析发现新增错误模式。
  5. 告警:监控器对"5xx 请求 5 分钟超阈值""duration P99 超 2s"等规则告警,通知对象发钉钉/企业微信/飞书。
  6. 链路关联:接入观测云 APM Ruby 探针后,trace_id 自动出现在日志与链路中,双向跳转定位慢请求。
  7. 成本控制:请求日志量大走低频索引,错误日志走标准索引长保留,历史数据归档对象存储。

常见问题(FAQ)

Rails 7/8 默认日志有什么变化?

新版本 Rails 生产环境默认 RAILS_LOG_LEVEL 环境变量控制级别(默认 info),并鼓励 stdout 输出(RAILS_LOG_TO_STDOUT)。容器化部署下无需再手动覆盖 config.logger。

开发环境也想用 Lograge 吗?

不建议。开发环境默认的多行详细日志(含 SQL、渲染细节)正是排障所需;Lograge 是给生产环境的机器可读格式。按环境开关即可。

Sidekiq 等后台任务的日志怎么统一?

Sidekiq 自带 logger,可设置 Sidekiq.logger = Rails.logger 统一出口;任务日志建议 tagged(job_id) 标记,平台侧按 job_id 过滤还原任务执行过程。

日志里出现敏感参数怎么办?

Rails 的 config.filter_parameters(如 :password, :token)会在参数日志中打码;Lograge 的 custom_options 也要注意别注入敏感字段。平台侧再启用观测云敏感数据扫描做第二道防线。

系列阅读


获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台