example ruby logging sinatra rack error-logging

ruby grape example



Utilice Rack:: CommonLogger en Sinatra (5)

Tengo un pequeño servidor web que escribí con Sinatra. Quiero poder registrar mensajes en un archivo de registro. He leído http://www.sinatrarb.com/api/index.html y www.sinatrarb.com/intro.html, y veo que Rack tiene algo llamado Rack :: CommonLogger, pero no puedo encontrar cualquier ejemplo de cómo se puede acceder y usar para registrar mensajes. Mi aplicación es simple, así que la escribí como una DSL de nivel superior, pero puedo pasar a una subclasificación de SinatraBase si eso es parte de lo que se requiere.


En tu 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


Seguí lo que encontré en esta blog - fragmento a continuación

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

luego usa puts o print . Funcionó para mí



Rack::CommonLogger no proporcionará un registrador a su aplicación principal, solo registrará la solicitud como haría Apache.

Verifique el código usted mismo: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb

Todas las aplicaciones de Rack tienen el método de llamada invocado get con HTTP Request env, si comprueba el método de llamada de este middleware, esto es lo que sucede:

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

El @app en este caso es la aplicación principal, el middleware solo está registrando el momento en que comenzó la solicitud, luego clasifica su middleware obteniendo el triple [estado, encabezado, cuerpo] y luego invoca un método de registro privado con esos parámetros, devolver el mismo triple que su aplicación devuelta en primer lugar.

El método de logger es como:

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

Como puede ver, el método de log simplemente toma algo de la información del env de la solicitud, y se registra en un registrador que se especifica en la llamada del constructor, si no hay una instancia del registrador, entonces va al registrador rack.errors (parece que hay es uno por defecto)

La forma de usarlo (en tu config.ru ):

logger = Logger.new(''log/app.log'') use Rack::CommonLogger, logger run YourApp

Si desea tener un registrador común en toda su aplicación, puede crear un middleware de registrador simple:

class MyLoggerMiddleware def initialize(app, logger) @app, @logger = app, logger end def call(env) env[''mylogger''] = @logger @app.call(env) end end

Para usarlo, en tu config.ru :

logger = Logger.new(''log/app.log'') use Rack::CommonLogger, logger use MyLoggerMiddleware, logger run MyApp

Espero que esto ayude.


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