【问题标题】:Properly using Log4r in Ruby Application在 Ruby 应用程序中正确使用 Log4r
【发布时间】:2010-03-18 19:42:50
【问题描述】:

我确实遗漏了一些明显的东西,但是在我的 Ruby 应用程序中一般使用 Log4r 时遇到了问题。我可以毫无问题地登录,但是我设置它的方式似乎很笨重。我基本上将完整路径传递给文件名以登录我的应用程序中的每个类。被调用的 ruby​​ 脚本从 ARGV 中的一个参数中提取日志文件,然后在我在 ruby​​ 中调用的每个类中传递并设置该日志文件。在每个类中,我使用 patternFormatter 将类/文件名插入到日志语句中。

有没有更好的方法来完成这项工作?感觉无论我怎么想,都需要在我的 ruby​​ 应用程序中向每个类传递一些东西。我可以改为在 yaml 配置文件中设置日志文件,但是我也会将配置文件传递给每个类。

有什么建议吗?如果这没有意义,我可以尝试发布一些更具体的代码示例以进一步解释我的意思。

谢谢!

【问题讨论】:

    标签: ruby logging log4r


    【解决方案1】:

    我是log4r的维护者,

    对于单个脚本(不同的 .rb 文件),您可以通过几种不同的方式来处理此问题(我知道很合适),首先,请注意我在此处介绍的功能在 >= 1.1.4 中可用。

    一种方法是为每个脚本设置不同的 PatternFormatter 字符串(如果您创建 yaml 或 xml 配置文件,则可以基于每个类名指定不同的模式)。

    另一种方法是在 PatternFormatter 中使用 GDC、NDC 或 MDC 之一。

    GDC 将设置一个“全局诊断上下文”,也就是说,它是一个可从所有运行脚本的线程获得的值。您可以通过将 %g 放入模式中并通过 GDC.set(String) 设置值来使用它以获取更多详细信息,请参阅:http://log4r.rubyforge.org/manual.html

    NDC 和 MDC 分别是嵌套和映射诊断上下文。这些模式是使用 %x 和 %X{Symbol|Object},并通过 NDC.set(String) 和 MDC.put(Symbol|Object, Object) 设置它们

    另一种方法是使用模式 %t,它会打印出调用位置的文件名和行号。

    这些方法之间的权衡是它们在 CPU 资源使用方面的成本越来越高。我倾向于首先将 GDC 用于您要求的那种事情。

    【讨论】:

    • 你能举个例子吗? (您提供的链接已失效)
    【解决方案2】:

    嗯,您为什么不在脚本开头实例化Log4r::Logger 类并传递实例?您甚至不必到处传递它,您可以随时从Logger 类中通过名称获取它:

    运行.rb:

    require 'log4r'
    require 'class_a'
    
    logger = Log4r::Logger.new('test')
    logger.outputters << Log4r::Outputter.stdout
    logger.outputters << Log4r::FileOutputter.new('logtest', :filename =>  'logtest.log')
    logger.info('started script')
    a = A.new
    a.do_something
    logger.info('finishing')
    

    class_a.rb:

    class A
      def do_something
        logger = Log4r::Logger['test']
        logger.info('in do_something')
        puts 'hi!'
      end
    end
    

    当您运行 run.rb 时,您会得到:

    $ ruby run.rb 
     INFO test: started script
     INFO test: in do_something
    hi!
     INFO test: finishing
    

    还有一个名为 logtest.log 的日志文件在磁盘上。

    【讨论】:

    • 我似乎无法做到这一点。在另一个 .rb 文件中调用 Logger['mylog'] 返回 nil。
    • 我如何告诉 Logger 注销到哪个文件?
    • 看看上面更新的例子。当您说“另一个 .rb 文件”时,您是什么意思?
    • 如果您有许多连接的 ruby​​ 脚本不在同一个实例中运行(例如一个脚本在外部调用另一个脚本,或者一个批处理顺序运行 10 个脚本),那么您需要在每个脚本分开。如果您正在讨论通过“require”包含的其他脚本,那么您可能需要在需要这些外部文件之前创建 Log4r 实例,如果它们在第一次通过文件期间记录(而不是仅在以后使用它们时)。
    • 尤里卡!您上面的代码示例使 Mladen 非常清楚。现在我只需要弄清楚如何更改日志标记或显示在每行开头的任何名称,以显示 ruby​​ 类或文件名。但是,现在我走上了正确的轨道。谢谢!
    猜你喜欢
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2021-04-14
    • 2017-06-17
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多