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 ningún 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.Usar Rack :: CommonLogger en Sinatra
Respuesta
Rack::CommonLogger
no proporcionará un registrador a su aplicación principal, solo registrará la solicitud como lo haría Apache.
Comprobar el código en solitario: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
Todos Rack
aplicaciones tienen la llamada al método que consiguen que está invoca con la petición HTTP env, si marca el método llamado 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 estado [encabezado, cuerpo] triple y luego invoca un método de registro privado con esos parámetros , devolviendo el mismo triple que tu a pp regresó en primer lugar.
El método logger
dice así:
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 se puede ver, el método log
simplemente agarra algo de información de la solicitud env, e ingresa en un registrador que se especifica en la llamada al constructor, si hay se ningún caso registrador luego se va a la rack.errors
registrador (parece que hay uno por defecto)
la forma de usarlo (en su config.ru
):
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
Si usted quiere tener un registrador común en toda su aplicación, se puede crear un simple middleware registrador:
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 su config.ru
:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
Espero que esto ayude.
que siguieron lo que he encontrado en este blog posterior - un extracto 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
a continuación, utilizar puts
o print
. Funcionó para mí
que funciona, pero que realmente me gustaría averiguar cómo utilizar rack :: CommonLogger para enviar mensajes formateados con marcas de tiempo. –
En su 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
pruebo su solución, y funciona. Me pregunto por qué tiene que estar en config.ru? – Chamnap
un archivo cosas que no estoy al 100% allí, ¿te importaría comentar sobre qué/por qué algunas de las líneas están ahí, por favor? –
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
reapertura STDOUT y redirigir a un archivo no es una buena idea si el uso del pasajero. Causa en mi caso que el Pasajero no comienza. Lee https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection para este problema.
Esta sería la manera correcta en su lugar:
logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger
- 1. Sinatra + Rack :: Test + Rspec2 - ¿Cómo usar sesiones?
- 2. Rack :: Session :: Grupo con Sinatra
- 3. Usando Rack :: Session :: Pool with Sinatra
- 4. Configuración de Sinatra y Rack Protection
- 5. ¿Iniciar sesión en Sinatra?
- 6. Sinatra aplicación usando OmniAuth obtiene rack :: :: Protección SessionHijacking en IE9
- 7. Transmisión de datos desde la aplicación Sinatra/Rack
- 8. Rack :: Session: error de cookies con Sinatra, Thin, Rails y Rack :: Cascade
- 9. Rack/Sinatra LoadError: no se puede cargar dicho archivo
- 10. Cómo POSTAR datos en Rack :: Test
- 11. Cómo probar los encabezados con rspec y prueba en rack en Sinatra
- 12. ¿A dónde se conecta RACK?
- 13. Error de carga rack/test
- 14. Rack Session Cookie y Sinatra: configuración y acceso a los datos
- 15. Qué es un esquema de autenticación muy simple para Sinatra/Rack
- 16. ¿Cuál es la forma más rápida de un verdadero sinatra (ruby/rack) after_filter?
- 17. ¿Cómo usar las cookies en un middleware Rack?
- 18. ¿Cómo medir el uso de memoria de una aplicación Rack o Sinatra?
- 19. Cuándo usar node.js vs sinatra vs rails?
- 20. La aplicación Passenger Rack 'no puede inferir basepath'
- 21. ¿Cuál es la diferencia entre Rack y Passenger?
- 22. Ejecutando Sinatra en el puerto 80
- 23. Sinatra + Bundler?
- 24. Evitar las declaraciones de dependencia de Bundler redundantes para Rack
- 25. Problemas con Sinatra y Ruby 1.9.2 en Shotgun
- 26. ¿Cómo config.ru correctamente en la aplicación modular de Sinatra?
- 27. Sinatra vs. Rails
- 28. Recarga Sinatra aplicación en cada petición en Windows
- 29. ¿Cómo usar params con barras diagonales con Sinatra?
- 30. Múltiples aplicaciones de Sinatra con montaje en bastidor
¿No debería la primera línea de MyLoggerMiddleware # call (env) ser: env ['rack.errors'] = @logger ? –
Además, no quiero registrar todas las solicitudes, solo advertencias y mensajes de error. Pero me gustaría que sea configurable para que pueda establecer el nivel de registro, como en "depuración", "información", "advertencias", "errores", ... BTW - Mi aplicación no es un rieles aplicación No hay archivo config.ru. Es una aplicación simple de Sinatra. Tenía la esperanza de utilizar un estándar existente, pero no puedo entender qué es eso. ¿Tal vez tengo que tomar el CommonLogger que me mostró y dirigirlo solo? –
'config.ru' es un archivo de configuración para Rack, no para Rails. Tanto Sinatra como Rails están basados en Rack, por lo que puedes usar 'config.ru' en las aplicaciones de Sinatra también. – jafrog