J'ai du mal à comprendre comment enregistrer des messages avec Sinatra. Je ne cherche pas à enregistrer les demandes, mais plutôt des messages personnalisés à certains points de mon application. Par exemple, lors de la récupération d'une URL, je voudrais enregistrer "Fetching #{url}"
.
Voici ce que j'aimerais:
logger.info("Fetching #{url}")
)Je suppose que cela peut facilement être fait dans config.ru
, Mais je ne suis pas sûr à 100% du paramètre que je veux activer, et si je dois créer manuellement un objet Logger
moi-même (et en outre, quelle classe de Logger
utiliser: Logger
, Rack::Logger
, ou Rack::CommonLogger
).
(Je sais qu'il y a des questions similaires sur StackOverflow, mais aucune ne semble répondre directement à ma question. Si vous pouvez me diriger vers une question existante, je la marquerai comme une copie).
Sinatra 1.3 sera livré avec un tel objet enregistreur, exactement utilisable comme ci-dessus. Vous pouvez utiliser Edge Sinatra comme décrit dans " The Bleeding Edge ". Ce ne sera pas si long avant la sortie de la 1.3, je suppose.
Pour l'utiliser avec Sinatra 1.2, faites quelque chose comme ceci:
require 'sinatra'
use Rack::Logger
helpers do
def logger
request.logger
end
end
Je me connecte personnellement à 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
Si vous utilisez quelque chose comme nicorn logging ou autre middleware qui correspond à IO streams, vous pouvez facilement configurer un enregistreur sur 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
cela vous permet d'intercepter des messages à la portée de l'application, plutôt que d'avoir simplement accès à l'enregistreur comme assistant de demande
Voici une autre solution:
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
Bien sûr, vous pouvez le faire sans ActiveSupport :: Concern en plaçant les blocs configure
et before
directement dans MySinatraApp, mais ce que j'aime dans cette approche, c'est qu'elle est très propre - toute la configuration de journalisation est totalement abstrait de la classe principale de l'application.
Il est également très facile de repérer où vous pouvez le changer. Par exemple, le SO a demandé de le faire se connecter à la console en cours de développement. Il est assez évident ici que tout ce que vous devez faire est un peu de logique si-alors dans le log_file
méthode.