10

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

4

2 回答 2

10

文档给出了一些有关范围的示例,但您可以logger在块中定义的方法中看到帮助helper程序,因为帮助程序块具有应用程序范围。在 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 开始)还带有一个用于 logging 的助手这里是一个用于记录到 STDOUT 的方法和一个您可能会发现有用的文件。

于 2013-01-22T17:14:47.187 回答
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
于 2015-06-09T23:24:14.310 回答