Ho un piccolo server web che ho scritto con Sinatra. Voglio essere in grado di registrare i messaggi in un file di registro. Ho letto il numero http://www.sinatrarb.com/api/index.html e www.sinatrarb.com/intro.html e vedo che Rack ha qualcosa chiamato Rack :: CommonLogger, ma non riesco a trovare alcun esempio di come sia possibile accedere e utilizzare per registrare i messaggi. La mia app è semplice, quindi l'ho scritta come DSL di primo livello, ma posso passare a sottoclassi da SinatraBase se questo è parte di ciò che è richiesto.Usa Rack :: CommonLogger in Sinatra
risposta
Rack::CommonLogger
non fornirà un logger all'app principale, registrerà semplicemente la richiesta come farebbe Apache.
Controllare il codice da lei: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
Tutti Rack
applicazioni hanno la chiamata al metodo che vengono sta invocato con la richiesta HTTP env, se si seleziona la chiamata di metodo di questo middleware questo è ciò che accade:
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
Il @app
in questo caso è l'app principale, il middleware sta registrando solo il momento in cui è iniziata la richiesta, quindi classifica il middleware ottenendo il [stato, intestazione, corpo] triplo e quindi richiama un metodo di registro privato con tali parametri , restituendo la stessa tripla della tua a pp restituito in primo luogo.
Il metodo logger
va come:
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
Come si può dire, il metodo log
appena afferra alcune informazioni dalla richiesta env, e registra su un registratore che è specificato sulla chiamata al costruttore, se ci è alcuna istanza logger poi va al rack.errors
logger (sembra che ci sia uno per impostazione predefinita)
il modo di usarlo (in config.ru
):
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
Se si vuole avere un logger comune in tutta la vostra app, è possibile creare un semplice middleware logger:
class MyLoggerMiddleware
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
env['mylogger'] = @logger
@app.call(env)
end
end
Per usarlo, sul config.ru
:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
Spero che questo aiuti.
ho seguito quello che ho trovato su questo blog post - Tratto di sotto
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
quindi utilizzare puts
o print
. Ha funzionato per me.
che funziona, ma mi piacerebbe davvero scoprire come utilizzare Rack :: CommonLogger per inviare messaggi formattati con timestamp. –
Nel vostro 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
provo la tua soluzione, e funziona. mi chiedo perché deve essere in config.ru? – Chamnap
un file cose che non sono al 100% lì, ti dispiacerebbe commentare su cosa/perché alcune delle linee sono lì per favore? –
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
Riapertura STDOUT e orientarli verso un file non è una buona idea se si utilizza passeggeri. Provoca nel mio caso che il Passeggero non inizi. Leggi https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection per questo problema.
questo sarebbe il modo giusto, invece:
logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger
- 1. Rack :: Session :: Pool con Sinatra
- 2. Utilizzo di Rack :: Session :: Pool con Sinatra
- 3. Rack/Sinatra LoadError: impossibile caricare tale file
- 4. Sinatra + Rack :: Test + Rspec2 - Utilizzo delle sessioni?
- 5. Usa Foreman avviare Rack App trovano in diverse directory
- 6. Rack :: Sessione: errore nei cookie utilizzando Sinatra, Thin, Rails e Rack :: Cascade
- 7. Come misurare l'utilizzo della memoria di un'app Rack o Sinatra?
- 8. Come caricare i dati in Rack :: Test
- 9. sinatra config.ru: a cosa serve il blocco di configurazione?
- 10. Dove si collega RACK?
- 11. Errore carico rack/test
- 12. In Sinatra - qualcuno usa i dispositivi di prova? come è impostata la tua suite di test?
- 13. Come testare le intestazioni con rspec e test su rack in Sinatra
- 14. Sinatra applicazione utilizzando omniauth ottiene Rack :: Protezione :: dirottamento di sessione in IE9
- 15. Come specificare le opzioni Whitelist di origine in Sinatra utilizzando Rack/Protezione
- 16. App Passenger Rack 'non può inferire basepath'
- 17. stream in rack
- 18. Qual è il modo più veloce per un vero sinatra (ruby/rack) after_filter?
- 19. come forzare il rack: session + sinatra per leggere "rack.session" da params invece di cookies
- 20. Accesso intestazioni da Sinatra
- 21. Qual è la differenza tra Rack e Passenger?
- 22. Come scaricare una richiesta HTTP da Sinatra?
- 23. Rack rack. La variabile di input viene troncata?
- 24. Come far funzionare Sinatra su HTTPS/SSL?
- 25. Utilizzo di `Rack :: Session :: Pool` su` Rack :: Session :: Cookie`
- 26. cache rack rack - come svuotare manualmente tutta la cache
- 27. Problemi di debug dell'applicazione Sinatra in produzione
- 28. Quali sono gli scenari in cui si usa Sinatra o Merb?
- 29. Esecuzione di Sinatra sulla porta 80
- 30. Stubbing Sinatra aiutante in Cetriolo
La prima riga di MyLoggerMiddleware # call (env) non dovrebbe essere: env ['rack.errors'] = @logger ? –
Inoltre, non voglio registrare ogni richiesta, solo avvertimenti e messaggi di errore. Ma mi piacerebbe che fosse configurabile in modo da poter impostare il livello di registrazione, come in "debug", "informazioni", "avvisi", "errori", ... BTW - La mia app non è un Rails app. Non esiste un file config.ru. È una semplice app di Sinatra. Speravo di utilizzare uno standard esistente, ma non riesco a capire di cosa si tratta. Forse dovrò prendere il CommonLogger che mi hai mostrato e filarmelo da solo? –
'config.ru' è un file di configurazione per Rack, non per Rails. Sia Sinatra che Rails sono basati su rack, quindi puoi usare 'config.ru' anche nelle applicazioni Sinatra. – jafrog