2012-02-21 22 views
11

Potrzebuję unikalnego identyfikatora żądania dla mojego loggera, dzięki czemu mogę śledzić każde żądanie w pliku dziennika.Jak wygenerować unikalny identyfikator żądania w Railsach?

Do tej pory mam to

REQUEST_ID = Digest::MD5.hexdigest(Time.now.to_f.to_s + $PID.to_s) 

Problem polega na tym, że nie wiem gdzie umieścić ten. Próbowałem umieścić go wewnątrz mojego niestandardowego pliku rejestratora, poza klasą. Ale to musi być buforowane lub coś, ponieważ zawsze otrzymuję ten sam skrót.

Wszelkie pomysły?

Uwaga. Używam szyn 3 i pasażer autonomiczny

UPDATE:

Rails 3.2: tag UUID nie będzie działać. Zobacz, jak źle sformatowane są dzienniki:

[0909413851b79676cb06e0842d21c466] [127.0.0.1] 

Started HEAD "/" for 127.0.0.1 at Tue Feb 21 14:08:25 -0300 2012 
[0909413851b79676cb06e0842d21c466] [127.0.0.1] Processing by PagesController#home as HTML 
[0909413851b79676cb06e0842d21c466] [127.0.0.1] bla 
[0909413851b79676cb06e0842d21c466] [127.0.0.1] Rendered pages/home.html.erb within layouts/application (2.0ms) 

W produkcji będzie to bałagan. Zwróć uwagę na znaki nowej linii po pierwszym wierszu? Teraz wyobraź sobie, jak wyglądałyby logi na serwerze obsługującym wiele żądań na sekundę. Trudno będzie powiązać prośbę z URI

+0

HappyDeveloper, @SergioTulentsev przybity go! Usuwam odpowiedź; proszę, zaakceptuj jego. –

Odpowiedz

4

Jeśli chcesz wstawić UUID życzenie w wierszu dziennika Started GET "/" for 127.0.0.1 at Tue Feb 21 14:00:00 -0300 2012 można załatać lub podklasa Rails::Rack::Logger zmodyfikować metodę call_app:

def call_app(env) 
    request = ActionDispatch::Request.new(env) 
    path = request.filtered_path 
    Rails.logger.info "\n\nStarted #{request.request_method} \"#{path}\" for #{request.ip} at #{Time.now.to_default_s}" 
    @app.call(env) 
ensure 
    ActiveSupport::LogSubscriber.flush_all! 
end 

Obiekt żądania jest utworzony tuż przed instrukcją logowania , więc możesz zmienić instrukcję rejestrowania, aby dołączyć request.uuid.

+0

Począwszy od szyn 3.2 - można również przesłonić metodę "started_request_message" - https://github.com/rails/rails/commit/35a17502b6054ab6d6407c0af902a441e8ae8215 – robd

+0

Zobacz także http://stackoverflow.com/ pytania/7214166/full-urls-in-rails-logs – robd

34

Zespół Railsów załatwił to za Ciebie!

Rails 3.2 wprowadza metodę request.uuid, która zwraca unikalny identyfikator żądania, który wygląda następująco: ab939dfca5d57843ea4c695cab6f721d.

Zobacz release notes here.

Zobacz także, jak korzystać z tej nowej metody przy rejestrowaniu.

# config/environments/development.rb 
config.log_tags = [:uuid, :remote_ip] 


# log file 
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] 

Started GET "/" for 127.0.0.1 at 2012-01-27 21:52:58 +0000 
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Processing by ProductsController#index as HTML 
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Product Load (0.3ms) SELECT "products".* FROM "products" 
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Rendered products/index.html.erb within layouts/application (22.0ms) 
[ab939dfca5d57843ea4c695cab6f721d] [127.0.0.1] Completed 200 OK in 81ms (Views: 73.1ms | ActiveRecord: 0.3ms) 
[98eec5f8976586c1165b981797086b6a] [127.0.0.1] 
+0

Wow thanks. Czy istnieje więcej dokumentacji na ten temat? Jakie inne tagi mogę dodać? Dodaje też nieprzyjemne spacje, tak jak w opublikowanych logach (patrz spacje przed "Renderowane"). Czy wiesz, czy mogę uzyskać dostęp do uuid z zewnątrz, aby zrobić mój własny rejestrator? – HappyDeveloper

+0

@HappyDeveloper: tak, jest to metoda na obiekcie 'request'. Możesz więc uzyskać do niego dostęp w swoich kontrolerach, 'logger.debug request.uuid'. –

+0

Ale muszę uzyskać dostęp do identyfikatora żądania z mojego inicjalizatora, ponieważ dzienniki są uruchamiane przed kontrolerem. Dobrze? Co mogę zrobić?Nadal utknąłem z tym – HappyDeveloper

5

Kontynuacja odpowiedzi za pomocą log_tags, ponieważ: uuid jest wyjątkowy tylko w przypadku żądania, trudno jest go używać ze śledzeniem sesji.

Znalazłem log_tags, akceptuję Proc, i przekazuję obiekt żądania jako parametr. Tak, następujący kod będzie pieczęć wszystkich wpisu z session_id (zakładając że używasz ActiveRecord sklep sesji opartej)

config.log_tags = [ lambda {|req| "#{req.cookie_jar["_session_id"]}" }, :remote_ip, :uuid ] 
+0

Wow, to naprawiono mój problem z identyfikacją żądania heroku, dziękuję! –

Powiązane problemy