如何在请求范围之外访问Sinatra的Logger

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

文档提供了有关范围的一些示例,但您可以在helper块中定义的方法中看到logger帮助程序,因为辅助程序块具有应用程序范围。 在配置中,它不可用,但我倾向于设置我自己的日志,无论如何,在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开始)带有日志记录的帮助程序 , 这里有一个记录到STDOUT的方法和一个你可能会觉得有用的文件。

接受的答案对我来说并不适用,所以我想出了以下内容:

 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对于保持规范安静很有用。

在app init中:

 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