Entrando no Sinatra? - Ruby, log, sinatra, rack

Estou tendo problemas para descobrir como registrarmensagens com Sinatra. Eu não estou olhando para registrar solicitações, mas sim mensagens personalizadas em determinados pontos no meu aplicativo. Por exemplo, ao buscar uma URL eu gostaria de log "Fetching #{url}".

Aqui está o que eu gostaria:

  • A capacidade de especificar níveis de log (ex: logger.info("Fetching #{url}"))
  • Em ambientes de desenvolvimento e teste, as mensagens seriam gravadas no console.
  • Na produção, apenas escreva mensagens correspondentes ao nível de log atual.

Eu estou supondo que isso pode ser feito facilmente em config.ru, mas eu não estou 100% de certeza de qual configuração eu quero ativar, e se eu tenho que criar manualmente um Logger objeto eu mesmo (e além disso, qual classe de Logger usar: Logger, Rack::Loggerou Rack::CommonLogger).

(Eu sei que existem questões semelhantes no StackOverflow, mas nenhuma parece responder diretamente a minha pergunta. Se você pode me apontar para uma pergunta existente, eu vou marcar este como uma duplicata).

Respostas:

41 para resposta № 1

O Sinatra 1.3 será enviado com um objeto logger, exatamente utilizável como acima. Você pode usar a borda Sinatra como descrito em "A borda do sangramento". Não demorará tanto até que liberemos 1.3, eu acho.

Para usá-lo com o Sinatra 1.2, faça algo assim:

require "sinatra"
use Rack::Logger

helpers do
def logger
request.logger
end
end

16 para resposta № 2

Eu pessoalmente log in Sinatra via:

require "sinatra"
require "sequel"
require "logger"
class MyApp < Sinatra::Application
configure :production do
set :haml, { :ugly=>true }
set :clean_trace, true

Dir.mkdir("logs") unless File.exist?("logs")

$logger = Logger.new("logs/common.log","weekly")
$logger.level = Logger::WARN

# Spit stdout and stderr to a file during production
# in case something goes wrong
$stdout.reopen("logs/output.log", "w")
$stdout.sync = true
$stderr.reopen($stdout)
end

configure :development do
$logger = Logger.new(STDOUT)
end
end

# Log all DB commands that take more than 0.2s
DB = Sequel.postgres "mydb", user:"dbuser", password:"dbpass", host:"localhost"
DB << "SET CLIENT_ENCODING TO "UTF8";"
DB.loggers << $logger if $logger
DB.log_warn_duration = 0.2

3 para resposta № 3

Aqui está outra solução:

module MySinatraAppLogger
extend ActiveSupport::Concern

class << self
def logger_instance
@logger_instance ||= ::Logger.new(log_file).tap do |logger|
::Logger.class_eval { alias :write :"<<" }
logger.level = ::Logger::INFO
end
end

def log_file
@log_file ||= File.new("#{MySinatraApp.settings.root}/log/#{MySinatraApp.settings.environment}.log", "a+").tap do |log_file|
log_file.sync = true
end
end
end

included do
configure do
enable :logging
use Rack::CommonLogger, MySinatraAppLogger.logger_instance
end

before { env["rack.errors"] = MySinatraAppLogger.log_file }
end

def logger
MySinatraAppLogger.logger_instance
end
end

class MySinatraApp < Sinatra::Base
include MySinatraAppLogger
get "/" do
logger.info params.inspect
end
end

Claro, você pode fazê-lo sem o ActiveSupport :: Concern, colocando o configure e before bloqueia direto no MySinatraApp, mas o que eu gosto nessa abordagem é que ela é muito limpa - toda a configuração de registro é totalmente abstraída da classe principal do aplicativo.

Também é muito fácil identificar onde você pode mudaristo. Por exemplo, o SO perguntou sobre como fazer logar para consolar no desenvolvimento. É bastante óbvio aqui que tudo que você precisa fazer é um pouco se-então lógica no log_file método.


2 para resposta № 4

Se você estiver usando algo como unicórnio logging ou outro middleware que codifica fluxos de E / S, você pode facilmente configurar um logger para STDOUT ou STDERR

# unicorn.rb
stderr_path "#{app_root}/shared/log/unicorn.stderr.log"
stdout_path "#{app_root}/shared/log/unicorn.stdout.log"

# sinatra_app.rb
set :logger, Logger.new(STDOUT) # STDOUT & STDERR is captured by unicorn
logger.info("some info") # also accessible as App.settings.logger

isso permite que você intercepte mensagens no escopo do aplicativo, em vez de apenas ter acesso ao logger como auxiliar de solicitação


Cardápio