Użyj Rack:: CommonLogger in Sinatra
Mam mały serwer WWW, który napisałem z Sinatrą. Chcę móc rejestrować Wiadomości do pliku dziennika. Przeczytałem http://www.sinatrarb.com/api/index.html oraz www.sinatrarb.com/intro.html i widzę, że Rack ma coś o nazwie Rack:: CommonLogger, ale nie mogę znaleźć żadnych przykładów, jak można go uzyskać i użyć do logowania wiadomości. Moja aplikacja jest prosta, więc napisałem ją jako najwyższego poziomu DSL, ale mogę przełączyć się na podkategorię z SinatraBase, jeśli to część tego, co jest wymagane.
5 answers
Rack::CommonLogger
nie dostarczy rejestratora do głównej aplikacji, po prostu zarejestruje żądanie, tak jak zrobiłby to Apache.
Sprawdź sam kod: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
Wszystkie Rack
aplikacje mają metodę wywołania, która jest wywoływana z żądaniem HTTP env, jeśli zaznaczysz metodę wywołania tego middleware, dzieje się tak:
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
w tym przypadku jest to główna aplikacja, middleware jest tylko rejestrowanie czasu żądanie zaczęło się od, a następnie klasuje oprogramowanie pośredniczące, otrzymując potrójne [status, header, body], a następnie wywołuje prywatną metodę dziennika z tymi parametrami, zwracając to samo potrójne, co Twoja aplikacja.
Metoda logger
wygląda następująco:
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
Jak widać, metoda log
po prostu pobiera pewne informacje z żądania env i loguje się do loggera, który jest określony w wywołaniu konstruktora, jeśli nie ma instancji loggera, to przechodzi do rack.errors
logger (it wygląda na to, że domyślnie istnieje jeden)
Sposób użycia (w Twoim config.ru
):
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
Jeśli chcesz mieć wspólny logger w całej swojej aplikacji, możesz utworzyć proste oprogramowanie pośrednie loggera:]}
class MyLoggerMiddleware
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
env['mylogger'] = @logger
@app.call(env)
end
end
Aby go użyć, na Twoim config.ru
:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 19:34:22
W Twoim 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-17 00:02:28
Śledziłem to, co znalazłem na tym blogu Post-fragment poniżej
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
Następnie użyj puts
lub print
. U mnie zadziałało.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-10 19:32:01
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-14 15:10:21
Ponowne otwarcie STDOUT i przekierowanie go do pliku nie jest dobrym pomysłem, jeśli używasz pasażera. Powoduje to w moim przypadku, że pasażer nie uruchamia się. Czytaj https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection{[3]za ten problem.
To byłaby właściwa droga zamiast:
logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-25 08:18:50