Utiliser Rack:: CommonLogger dans Sinatra
j'ai un petit serveur web que j'ai écrit avec Sinatra. Je veux pouvoir enregistrer des messages dans un fichier journal. J'ai lu http://www.sinatrarb.com/api/index.html et www.sinatrarb.com/intro.html et je vois que le Rack a quelque chose qui s'appelle Rack::CommonLogger, mais je ne peux pas trouver des exemples de la façon dont il peut être consulté et utilisé pour l'enregistrement des messages. Mon application est simple donc je l'ai écrit comme un DSL de haut niveau, mais je peux passer à la sous-classification de SinatraBase si cela fait partie de ce qui est requis.
5 réponses
Rack::CommonLogger
ne fournira pas d'enregistreur à votre application principale, il enregistrera simplement la requête comme Apache le ferait.
Vérifier le code par vous-même: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
Rack
les applis ont la méthode d'appel qui est invoquée avec la requête HTTP env, si vous vérifiez la méthode d'appel de cet middleware c'est ce qui se passe:
def call(env)
began_at = Time.now
status, header, body = @app.call(env)
header = Utils::HeaderHash.new(header)
log(env, status, header, began_at)
[status, header, body]
end
@app
dans ce cas est l'application principale, la middleware enregistre juste l'heure à laquelle la requête a commencé, puis Classe votre middleware en obtenant le triple [status, header, body], et puis invoquez une méthode de log privé avec ces paramètres, en retournant le même triple que votre application a retourné en premier lieu.
logger
méthode va comme ceci:
def log(env, status, header, began_at)
now = Time.now
length = extract_content_length(header)
logger = @logger || env['rack.errors']
logger.write FORMAT % [
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
env["REMOTE_USER"] || "-",
now.strftime("%d/%b/%Y %H:%M:%S"),
env["REQUEST_METHOD"],
env["PATH_INFO"],
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
env["HTTP_VERSION"],
status.to_s[0..3],
length,
now - began_at ]
end
Comme vous pouvez le dire, le log
la méthode saisit juste quelques informations de la requête env, et se connecte sur un logger qui est spécifié sur l'appel du constructeur, si il n'y a pas d'instance logger alors elle va à rack.errors
logger (il semble qu'il y en a un par défaut)
La manière de l'utiliser (dans votre config.ru
):
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
si vous voulez avoir un logger commun dans toute votre application, vous pouvez créer un middleware logger simple:
class MyLoggerMiddleware
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
env['mylogger'] = @logger
@app.call(env)
end
end
Pour l'utiliser, sur votre config.ru
:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
J'espère que cela vous aidera.
Dans votre config.ru
:
root = ::File.dirname(__FILE__)
logfile = ::File.join(root,'logs','requests.log')
require 'logger'
class ::Logger; alias_method :write, :<<; end
logger = ::Logger.new(logfile,'weekly')
use Rack::CommonLogger, logger
require ::File.join(root,'myapp')
run MySinatraApp.new # Subclassed from Sinatra::Application
j'ai suivi ce que j'ai trouvé sur ce blog post - extrait ci-dessous
require 'rubygems'
require 'sinatra'
disable :run
set :env, :production
set :raise_errors, true
set :views, File.dirname(__FILE__) + '/views'
set :public, File.dirname(__FILE__) + '/public'
set :app_file, __FILE__
log = File.new("log/sinatra.log", "a")
STDOUT.reopen(log)
STDERR.reopen(log)
require 'app'
run Sinatra.application
puis utilisez puts
ou print
. Il a travaillé pour moi.
class ErrorLogger
def initialize(file)
@file = ::File.new(file, "a+")
@file.sync = true
end
def puts(msg)
@file.puts
@file.write("-- ERROR -- #{Time.now.strftime("%d %b %Y %H:%M:%S %z")}: ")
@file.puts(msg)
end
end
class App < Sinatra::Base
if production?
error_logger = ErrorLogger.new('log/error.log')
before {
env["rack.errors"] = error_logger
}
end
...
end
rouvrir STDOUT et le rediriger vers un fichier n'est pas une bonne idée si vous utilisez Passenger. Il provoque dans mon cas, le Passager ne démarre pas. Lire https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection pour ce numéro.
Ce serait la bonne façon au lieu de:
logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger