ruby - Ruby - 为不同的目标设置不同的日志级别
问题描述
想知道如何为不同的目标设置不同的日志级别。下面是我的代码,它向和Ruby
写入一行。Console
File
# https://stackoverflow.com/a/6407200
class MultiIO
def initialize(*targets)
@targets = targets
end
def write(*args)
@targets.each do |t|
t.write(*args)
end
end
def close
@targets.each(&:close)
end
end
module Logging
def self.logger(logname, programname, debug = false)
log_file = File.open(logname, "a")
log_file.sync = true
zlogger = Logger.new MultiIO.new(log_file, STDOUT)
zlogger.level = Logger::INFO
zlogger.progname = programname
zlogger.formatter = proc do |serverity, datetime, progname, msg|
"#{datetime.strftime('%Y-%m-%d %I:%M:%S %p %:::z %Z')} - #{serverity} - [#{progname}] | #{msg}\n"
end
zlogger
end
end
如果找到特殊的环境变量,我可以将级别设置为调试,
$logger.level = Logger::DEBUG if ENV['enable_debug_logs'] == 'true'
但是,不确定如何始终将Debug
行写入日志文件并且只Info
将行写入控制台。
有人知道吗?任何帮助是极大的赞赏!
解决方案
由于日志级别是logger的属性,而不是 的属性IO
,因此在我看来,您真正需要做的是定义 aMultiLogger
而不是 a MultiIO
。类似于以下内容:
class MultiLogger
attr_reader :default_level, :default_progname, :default_formatter
def initialize(**args)
@default_level = args[:default_level]
@default_progname = args[:default_progname]
@default_formatter = args[:default_formatter]
@loggers = []
Array(args[:loggers]).each { |logger| add_logger(logger) }
end
def add_logger(logger)
logger.level = default_level if default_level
logger.progname = default_progname if default_progname
logger.formatter = default_formatter if default_formatter
@loggers << logger
end
def close
@loggers.map(&:close)
end
Logger::Severity.constants.each do |level|
define_method(level.downcase) do |*args|
@loggers.each { |logger| logger.send(__method__, args) }
end
# These methods are a bit weird in the context of a "multi-logger" with varying levels,
# since they are now returning an `Array`; never a falsey value.
# You may want to define them differently, e.g. `@loggers.all? {...}`, or use a non-predicate method name here.
define_method("#{level.downcase}?".to_sym) do
@loggers.map(&__method__)
end
end
end
# Usage:
log_file = File.open(logname, "a")
log_file.sync = true
file_logger = Logger.new(log_file)
console_logger = Logger.new(STDOUT)
console_logger.level = Logger::INFO
multi_logger = MultiLogger.new(
default_progname: programname,
default_formatter: proc do |severity, datetime, progname, msg|
"#{datetime.strftime('%Y-%m-%d %I:%M:%S %p %:::z %Z')} - #{severity} - [#{progname}] | #{msg}\n"
end,
loggers: [file_logger, console_logger]
)
推荐阅读
- python - 为三个项目生成固定值以在而不是 randrange 之间随机播放
- bash - 如何将默认 python 解释器设置为 Anaconda2 路径,而不是 WSL 中的 usr/bin/ 默认值
- python - 如何通过python填充文本区域并选择选项(选择标签)并点击提交(输入标签)?
- jquery - 如何阻止点击事件创建多个元素?
- javascript - 如何在反应中使用leader-line(一个外部javascript库)?
- php - PHP - 对象数组
- mysql - 对多连接表求和
- javascript - ES2015 + flow:自引用(循环?)枚举
- java - 在 API 响应中自定义 JSON 属性
- c# - 是否可以在 Outlook 中将附件作为 URL 发送