Ruby 中如何同时把日志输出到文件和控制台?

Ruby 同时输出到文件和控制台:创建两个 Logger 实例分别输出,或封装一个多路 Logger 类统一调用。本文给出两种实现方案。

最佳实践
Ruby 中如何同时把日志输出到文件和控制台?封面

Ruby 的 Logger 类只接受一个 IO 目标。同时输出到文件和控制台的两种方案:一、创建两个 Logger 实例分别调用;二、封装一个多路 Logger 类,一次调用同时写多个目标。

方法一:两个 Logger 实例

require 'logger'

file_logger = Logger.new('application.log', 'daily')
file_logger.level = Logger::INFO
file_logger.formatter = proc do |severity, datetime, progname, msg|
  "#{datetime.strftime('%Y-%m-%d %H:%M:%S')} [#{severity}] #{msg}\n"
end

console_logger = Logger.new(STDOUT)
console_logger.level = Logger::DEBUG

file_logger.info("写入文件")
console_logger.info("输出到控制台")

缺点:每次要打两条,代码冗余。

方法二:封装多路 Logger(推荐)

require 'logger'

class MultiLogger
  def initialize(*loggers)
    @loggers = loggers
  end

  %i[debug info warn error fatal].each do |level|
    define_method(level) do |msg|
      @loggers.each { |l| l.send(level, msg) }
    end
  end
end

file_logger = Logger.new('application.log', 'daily')
console_logger = Logger.new(STDOUT)

logger = MultiLogger.new(file_logger, console_logger)
logger.info("同时写入文件和控制台")

调用一次 logger.info,两个目标都会收到。

观测云对照

生产环境建议统一输出到 stdout,由观测云 DataKit 采集容器/进程的标准输出日志,不需要应用管理日志文件和轮转。

常见问题(FAQ)

Q:Rails 项目怎么做?
A:Rails 的 config.logger 只接受一个 Logger。可以用 ActiveSupport::BroadcastLogger(Rails 7.1+)或第三方 gem(如 semantic_logger)支持多路输出。

Q:文件轮转怎么配?
A:Logger.new('app.log', 'daily') 按天轮转,或 Logger.new('app.log', 10, 100.megabytes) 按大小轮转。

Q:两个 Logger 的格式可以不同吗?
A:可以。文件用 JSON 格式便于机器解析,控制台用彩色/简洁格式便于人眼阅读。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台