Logi wersja de luxe

Jestem leniem. Jestem leniem i nie cierpię marnowania swojego czasu na nudne i powtarzalne czynności. Podczas pracy z railsami zawsze bardzo mnie denerwowała ilość czasu potrzebna na znalezienie niezbędnej mi informacji w logach aplikacji. Mam na myśli oczywiście głównie prace w trybie development – kiedy do logów zagląda się bardzo często. Postanowiłem coś z tym zrobić...

Chciałbym aby informacje zrzucane do logów:

  1. zawierały informacje o miejscu z którego nastąpił zapis do logów – dzięki czemu prosto jest znaleźć fragmentu kodu z którego dany zapis został wygenerowany,
  2. dały się analizować za pomocą narzędzia wygodniejszego niż tail i grep – wiadomo obie te komendy to potęga – ale korzystanie z nich to nie jest dla mnie szczyt wygody,
  3. format logów był bardziej zbliżony do standardowych logów np. z apache’a czy log4j

log4r

Podczas pracy z Javą od niemal zawsze korzystam z biblioteki log4j. Myślę, że specjalnie przedstawiać tej biblioteki nie ma potrzeby, nawet komuś kto nie miał do czynienia z Javą, powstały bowiem już analogiczne rozwiązania dla innych popularnych języków programowania (jeżeli jednak się mylę krótka instrukcja znajduje się tutaj). Ruby także ma swój wersję biblioteki czyli - log4r, naturalnym więc wydaje się skorzystanie z już istniejących drzwi. Po zainstalowniu log4r (gem install log4r), konfiguracja aplikacji polega na dodaniu do pliku conf/environment.yml:

RUBY:
  1. # --- logger
  2. config.logger = Log4r::Logger.new('logger')
  3. # Chcemy dolaczac do logow informacje o miejscu wywolania
  4. config.logger.trace = true
  5. # Priorytet zapisywanych informacji - tu zapisywane jest wszystko
  6. config.logger.level = Log4r::DEBUG
  7.  
  8. # Co się dzieje z informacjami kierowanymi do loga - tu zapis do pliku
  9. config.logger.add(Log4r::FileOutputter.new(:logger,
  10.     :filename => File.join(RAILS_ROOT, 'log', "#{RAILS_ENV}.log"),
  11.     :trunc => false,
  12.     :formatter => Log4r::PatternFormatter.new(:pattern => "%d %-5l %c (#{config.logger.trace ? '%t': ':'}) - %M")
  13. ))

W tym miejscu mam już logi które zawierają znacznie więcej informacji i to w bardziej standardowym formacie. Nadal jednak ich przeszukiwanie podczas pracy nad aplikacją jest zadaniem zbyt żmudnym jak dla mnie :)

Chainsaw

Wraz z biblioteką log4j od dłuższego czasu rozwijany jest program który stanowi rodzaj przeglądarki do logów. Początkowo był dołączany do samej biblioteki, ale od pewnego czasu istnieje jako osoby projekt – Chainsaw 2. Oto krótka lista jego możliwości:

  • odbierania zdarzeń zdalnych,
  • wyróżnianie kolorem poszczególnych priorytetów zgłoszonych zdarzeń,
  • filtrowanie zdarzeń za pomocą filtrów treści tworzonych ad hoc,
  • filtrowanie zdarzeń według kategorii.

Cechy przedstawione powyżej pozwalają na dużo sprawniejsze wyłuskanie potrzebnej informacji z logów. Jak uruchomić Chainsaw ? Najprościej jako Java Web Start (ale na stronie jest również wersja binarna do uruchomienia w zwykły sposób). Uruchominy program trzeba skonfigurować - najprościej chyba w taki sposób (taka konfiguracja potrzebna jest tylko raz):

  1. pobierz ten plik konfiguracyjny i umieść gdzieś na dysku,
  2. wybierz z menu View opcję Application-wide Preferences
  3. w zakładce General w polu o nazwie 'Automatic Configuration URL' wpisz scieżkę do pobranego pliku konfiguracyjnego np: file:///D:/workspace/rails/chainsaw-config.xml

Uff, mamy więc już uruchomiony i skonfigurowany program do anlizy logów, pozostaje więc tylko...

Połączenie Chainsaw z log4r

Połączenie to realizuje chainsaw_outputter.rb (ściągnij ten plik i wrzuć go np. do katalogu lib/). Pozostaje jeszcze konfiguracja, na początku pliku conf/environment.yml dodaj linię:

CODE:
  1. require File.join(File.dirname(__FILE__),
  2.       '../lib/chainsaw_outputter')

a w pliku conf/environments/development.yml dodaj:

CODE:
  1. config.logger.add(Log4r::ChainsawOutputter.new(:logger))

W ten sposób połączenie z Chainsaw będzie tylko realizowane w trybie development. Po restarcie aplikacji Chainsaw powinien zacząć odbierać komunikaty z aplikacji i pokazywać je w zakładce o nazwie 'rails-app'. Warto jeszcze wyłączyć kolorowanie logów (ActiveRecord::Base.colorize_logging = false) - kody dla konsoli troche przeszkadzają w czytaniu logów.

Wyjaśnię jeszcze jedną sztuczkę jaką robi ChainsawOutputter. Pomysł na hierarchiczne kategorie jest chyba najbardziej przydatnym konceptem w całej rodzinie bibliotek log4x, niestety w przypadku railsów nie bardzo można wprost z niego skorzystać. Aby jednak nie tracić tej funkcjonalności ChainsawOutputter tworzy sztuczne kategorie ze ścieżki i nazwy skryptu. W ten sposób powstają kategorie np.: app/helper/auth_helper_rb czy lib/action_controller/cookies_rb – prawda że przydatne ? Acha żeby ta konwersja działała musi być ustawione config.logger.trace = true (tak jak w przykładowej konfiguracji powyżej)

Dla pewności podaję jeszcze raz kolejność działań:
1. uruchomienie chainsaw (+ konfiguracja jeżeli nie jest już skonfigurowany)
2. start aplikacji railsowej
Jeżeli kolejność będzie inna, albo Chainsaw nie będzie uruchomiony wcale – zauważysz znaczne spowolnienie w działaniu aplikacji – po prostu przy każdym dostępie logów będzie podejmowana próba połączenia z Chainsaw. Wystarczy jednak tylko jego uruchomienie i wszystko wraca do normy – nie ma wówczas potrzeby restartowania aplikacji.

Zakończenie

Niestety nie ma róży bez ognia, dodatkowe informacje jakie pojawiają się w logach (trace), ich formatowanie i wysyłanie przez socketa do Chainsaw to dodatkowa praca jaka musi zostać wykonana kosztem drobnego spadku wydajności railsowej aplikacji. Całe więc rozwiązanie jest przydatne tylko w trakcie developerki. Wersja produkcyjna aplikacji raczej powinna korzystać ze starego sposobu logowania informacji, a z pewnością powinna być pozbawiona komunikacji z Chainsaw.

TODO

W wolnej chwili postaram się z outputtera zrobić plugin do railsów co z pewnościa uprości instalację i korzystanie.

[ ]
Spodobało się? Podziel się z innymi: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Wykop
  • Gwar
  • Digg
  • Technorati

1 komentarz »

  1. scott said,

    październik 24, 2007 @ 06:43

    Chainsaw can also process regular text log files using LogFilePatternReceiver (see chainsaw-config.xml)

RSS feed for comments on this post · Adres TrackBack

Dodaj komentarz