我可以禁用ruby logger的日志头吗?

时间:2010-11-04 11:51:03

标签: ruby header logging

我目前遇到了一个问题。

您可能知道,ruby记录器在每个新创建的日志文件的顶部添加了一个日志标头。

"# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]

我正在记录CSV文件以便稍后在仓库中导入它们,通常我只是跳过带标题的第一行。看起来记录器中存在一个错误,因为有时日志记录标题会出现在日志文件的中间。

所以我决定简单地把那个标题留下来。令我惊讶的是,我没有发现在创建记录器时可以传递的任何争论。我想到了这样的事情:

Logger.new "info.log", :skip_header => true

但它不存在。我搜索了ruby核心源代码,令人惊讶的是,确实没有任何东西可以阻止记录器添加日志头:

def create_logfile(filename)
  logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT))
  logdev.sync = true
  add_log_header(logdev)
  logdev
end

def add_log_header(file)
  file.write(
    "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName]
)
end

有没有人知道我能做什么,以防止日志标题?我在这里使用Ruby 1.8.7 302和Rails 2.3.5。简单地忽略仓库方面的注释是不可能的,因为我无法控制那里的代码,如果记录行出现问题,那么忽略它似乎有风险。

是否有人知道允许此操作的记录器?你认为在文件中使用和写明文是个好主意吗?

提前致谢, 托米

3 个答案:

答案 0 :(得分:8)

理想情况下,Logger实例上的方法add_log_header应该被覆盖,但是由于在初始化时调用了add_log_header,所以当你开始使用它时已经太晚了。 好吧,你可以在Class上覆盖add_log_header方法。

class Logger::LogDevice
  def add_log_header(file)
  end
end

log1 = Logger.new('info1.log')

但是如果您的应用在此之后需要更多的Logger实例,它们的行为将相同:无标题。为了防止这种情况:

# dismantle the header and save it under another name
class Logger::LogDevice
  alias orig_add_log_header add_log_header

  def add_log_header(file)
  end
end

# Quick,create an instance 
log1 = Logger.new('test_log1file.log')

# restore the old method:
class Logger::LogDevice  
  alias add_log_header orig_add_log_header 
end

答案 1 :(得分:5)

这是一个涉及子类化Logger的解决方案。我们必须偷偷摸摸initializesuper,以防止它过早创建标准Logger::LogDevice

class HeadlessLogger < Logger
  def initialize(logdev, shift_age = 0, shift_size = 1048576)
    super(nil) # this prevents it from initializing a LogDevice
    if logdev
      @logdev = HeadlessLogger::LogDevice.new(logdev, shift_age: shift_age, shift_size: shift_size)
    end
  end

  class LogDevice < ::Logger::LogDevice
    def add_log_header(file) ; end
  end
end

答案 2 :(得分:4)

作为修补记录器类的替代方法,只需不要让它通过触摸它来创建日志文件:

FileUtils.touch logfile_path
Logger.new logfile_path

在普通的Ruby中,你需要明显地从stdlib require 'fileutils'

编辑:如果你使用内置的logrotation,或者文件被删除,这将不起作用,因为没有on-rotate挂钩,然后它会再次写入标题。