【问题标题】:How do I access Sinatra's Logger outside the Request Scope如何在请求范围之外访问 Sinatra 的记录器
【发布时间】:2015-06-10 07:24:14
【问题描述】:

似乎 Sinatra 的记录器仅在请求处理程序中可用(请参阅https://github.com/sinatra/sinatra#logging),但如果我想在其他地方使用记录器,例如在辅助方法或配置挂钩中怎么办?是否可以通过其他方式使用 Sinatra 记录器?

【问题讨论】:

    标签: ruby logging sinatra


    【解决方案1】:

    The docs 给出了一些有关范围的示例,但是您可以在 helper 块中定义的方法中看到 logger 帮助器,因为帮助器块具有应用程序范围。在 configure 中它不可用,但我倾向于在 rackup 文件中设置我自己的日志记录作为常量或类实例变量,然后它在 configure 中可用(以及其他任何地方)。仅以单个应用为例:

    require 'sinatra'
    require 'logger'
    
    configure do
      set :logging, nil
      logger = Logger.new STDOUT
      logger.level = Logger::INFO
      logger.datetime_format = '%a %d-%m-%Y %H%M '
      set :logger, logger
    end
    
    helpers do
      def check
        settings.logger.info "I'm inside a helper"
        # if you were using Sinatra's logger, you could just call
        # logger.info "I'm inside a helper"
        # and it would work, but only if you've not done the stuff above
        # in the configure block
      end
    end
    
    get "/" do
      check # this would work for the way above, or with the Sinatra logger
      "Hello, World!"
    end
    
    get "/another" do
      settings.logger.info "Using the settings helper this time" # this only works
      # when you've defined your own logger
      "Hello again"
    end
    

    一个作为类实例变量的例子作为一个更好的“全局”:

    class MyLogger
      def self.logger
        if @_logger.nil?
          @_logger = Logger.new STDOUT
          @_logger.level = Logger::INFO
          @_logger.datetime_format = '%a %d-%m-%Y %H%M '
        end
        @_logger
      end
    end
    

    然后在需要的地方使用:

    configure do
      set :logging, nil
      logger = MyLogger.logger
      set :logger, logger
    end
    

    或在课堂上:

    class AnotherClass
    
      def some_method
        MyLogger.logger.warn "I'm in some method"
      end
    

    Sinatra 还附带(自 1.3 起)a helper for logginghere is a recipe,用于记录到 STDOUT 和一个您可能会觉得有用的文件。

    【讨论】:

    • 我仍然无法登录其他课程。我的处理程序创建对象然后完成大部分工作,我想在这些类中登录。帮忙?
    • 太好了,谢谢!为了让它在不创建日志对象的情况下工作,我必须将 self 附加到方法中,但我现在肯定走​​上了正确的轨道。
    • @lyonsinbeta 哎呀,忘了self,很好看!很高兴这是一个帮助。
    【解决方案2】:

    接受的答案对我来说不太有效,所以我想出了以下内容:

    class AppLogger
      extend SingleForwardable
    
      def_delegators :logger, :info, :error, :warn, :level
    
      class << self
        def logger
          return @_logger if @_logger
    
          @_logger = Logger.new STDOUT
          @_logger.level = Logger::INFO
        end
    
        def suppress_logging
          logger.level = Logger::FATAL
        end
      end
    end
    

    suppress_logging 有助于保持规范安静。

    在应用初始化中:

    set :logging, AppLogger.logger
    

    来自请求:

    logger.info "Can't touch this."
    

    来自无权访问 logger 的类:

    AppLogger.info "You've got mail."
    

    还有,RSpec 模拟:

    let( :logger ){ double 'logger' }
    
    before do
      allow( AppLogger ).to receive( :logger ).and_return logger
      allow( logger ).to receive :error
    end
    
    specify 'logs error' do
      post '/raise/error'
    
      expect( logger ).to have_received( :error ).with 'An error has occured.'
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多