Ruby 中如何同时把日志输出到文件和控制台?
Ruby 同时输出到文件和控制台:创建两个 Logger 实例分别输出,或封装一个多路 Logger 类统一调用。本文给出两种实现方案。
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 格式便于机器解析,控制台用彩色/简洁格式便于人眼阅读。