我有一个Logger实例:
require 'logger'
logger = Logger.new( 'foo.log', 'weekly' )
Run Code Online (Sandbox Code Playgroud)
我想将运行时错误(stderr输出)重定向到日志中.我发现这个论坛帖子有以下建议:
new_fd = logger.get_logger_file_descriptor
$stderr.reopen new_fd
Run Code Online (Sandbox Code Playgroud)
但是,Logger没有实例方法get_logger_file_descriptor
,也无法找到任何公开的方法来获取对日志设备或文件的访问权限.
如何让所有$ stderr输出进入日志?
mat*_*att 17
如果您自己创建记录器,则可以先创建File
对象,然后使用它创建记录器并将其分配给$stderr
:
log_file = File.new('foo.log', 'a')
logger = Logger.new(log_file, 'weekly')
$stderr = log_file #usually no need to use reopen
Run Code Online (Sandbox Code Playgroud)
请注意,这将导致日志输出混合了的输出$stderr
,如果你输入的日志文件,期待它在一定的格式(这将与您的解决方案发生太大),这可能会导致问题.
如果您没有底层文件但只是logger
从其他地方接收,那就有点棘手了.所需要的是一个IO
类似的对象,可以将其分配给$stderr
并将写入其中的任何内容传递给记录器.IO
遗憾的是,Ruby中的类与底层的i/o系统(文件描述符等)密切相关,并且没有可用于创建输入和输出流的通用接口.(StringIO
是值得注意的例外).
然而,大多数(如果不是全部)输出方法IO
最终会通过#write
,所以通过覆盖这一种方法,您可以接近您所追求的内容:
class IOToLog < IO
def initialize(logger)
@logger = logger
end
def write(string)
#assume anything written to stderr is an error
@logger.error(message)
end
end
logger = get_logger_from_somewhere
$stderr = IOToLog.new(logger)
Run Code Online (Sandbox Code Playgroud)
现在写入的任何内容$stderr
最终都会转到日志文件中.然而格式化将有点奇怪.任何时候任何写入方法#write
都会在日志文件中调用新条目.例如,#puts
使用数组调用将调用数组#write
的每个条目,并在每个条目之间再次使用换行符,从而产生2n - 1个日志条目,其中n - 1将为空.
您可以使重写#write
方法更复杂,可能使用内部缓冲区,并且只在您认为有完整消息时才调用记录器.或者,您可以覆盖各个方法以自行写入记录器.如果你这样做,那么这个IOToLog
课不一定要继承IO
.
您最好的解决方案将取决于您希望标准错误输出显示在日志文件中,程序如何使用$stderr
以及您希望从中实现方法的工作量IO
.
归档时间: |
|
查看次数: |
5593 次 |
最近记录: |