【发布时间】:2015-06-10 07:24:14
【问题描述】:
似乎 Sinatra 的记录器仅在请求处理程序中可用(请参阅https://github.com/sinatra/sinatra#logging),但如果我想在其他地方使用记录器,例如在辅助方法或配置挂钩中怎么办?是否可以通过其他方式使用 Sinatra 记录器?
【问题讨论】:
似乎 Sinatra 的记录器仅在请求处理程序中可用(请参阅https://github.com/sinatra/sinatra#logging),但如果我想在其他地方使用记录器,例如在辅助方法或配置挂钩中怎么办?是否可以通过其他方式使用 Sinatra 记录器?
【问题讨论】:
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 logging 和 here is a recipe,用于记录到 STDOUT 和一个您可能会觉得有用的文件。
【讨论】:
self 附加到方法中,但我现在肯定走上了正确的轨道。
self,很好看!很高兴这是一个帮助。
接受的答案对我来说不太有效,所以我想出了以下内容:
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
【讨论】: