puts vs logger w zadaniach rake'u railsów

108

W zadaniu rake, jeśli używam polecenia puts, widzę wynik na konsoli. Jednak nie zobaczę tego komunikatu w pliku dziennika, gdy aplikacja zostanie wdrożona w środowisku produkcyjnym.

Jeśli jednak powiem Rails.logger.info, to w trybie programistycznym nic nie widzę na konsoli. Muszę przejść do pliku dziennika i to załatwić.

Idealnie chciałbym użyć Rails.logger.info, aw trybie deweloperskim wewnątrz zadania rake, dane wyjściowe z loggera powinny być również wysłane do konsoli.

Czy jest na to sposób?

Nick Vanderbilt
źródło

Odpowiedzi:

57

Umieść to application.rblub w kodzie inicjującym zadanie rake

if defined?(Rails) && (Rails.env == 'development')
  Rails.logger = Logger.new(STDOUT)
end

To jest kod Rails 3. Zauważ, że spowoduje to zastąpienie logowania do development.log. Jeśli chcesz obu STDOUTi development.logbędziesz potrzebować funkcji opakowującej.

Jeśli chcesz to zachowanie tylko w konsoli Railsów, umieść ten sam blok kodu w swoim ~/.irbrc.

shmichael
źródło
26
Czy nie byłoby łatwiej po prostu umieścić plik Rails.logger = Logger.new(STDOUT)development.rb?
ghempton
Dla rails 2 umieść to w swoim config.logger = Logger.new(STDOUT)
pliku
38

Możesz utworzyć nowe zadanie prowizji, aby to zadziałało.

desc "switch logger to stdout"
task :to_stdout => [:environment] do
 Rails.logger = Logger.new(STDOUT)
end

W ten sposób, gdy wykonujesz zadanie rake, możesz najpierw dodać to_stdout, aby uzyskać komunikaty dziennika stdout lub nie dołączać go, aby wiadomości były wysyłane do domyślnego pliku dziennika

rake to_stdout some_task
Pete Brumm
źródło
11

Zadania rake są uruchamiane przez użytkownika w wierszu poleceń. Wszystko, co chcą wiedzieć od razu ("przetworzone 5 wierszy"), powinno być wyprowadzane na terminal z poleceniem puts.

Wszystko, co należy zachować dla potomności („wysłano e-mail z ostrzeżeniem na adres [email protected]”), należy przesłać na adres Rails.logger.

Jonathan Julian
źródło
17
Uruchamianie zadań rake w cronie nie jest niczym niezwykłym.
Johannes Gorset
2
Prawdziwe. Jeśli chcesz, aby komunikaty dziennika były wysyłane do Ciebie e-mailem po zakończeniu zadania crona, wypluj je na $ stdout lub $ stderr.
Jonathan Julian
10

Powiedziałbym, że używanie Rails.logger.infojest właściwą drogą.

Nie będziesz mógł go zobaczyć w konsoli serwera, ponieważ nie będzie działał przez serwer. Po prostu otwórz nową konsolę i tail -fplik dziennika, załatwi sprawę.

Wielu użytkowników jest świadomych polecenia UNIX® „tail”, którego można użyć do wyświetlenia kilku ostatnich wierszy dużego pliku. Może to być przydatne do przeglądania plików dziennika itp.

Jeszcze bardziej przydatny w niektórych sytuacjach jest parametr „-f” polecenia „tail”. Powoduje to, że tail podąża za wyjściem pliku. Początkowo odpowiedź będzie taka sama, jak w przypadku samego „ogona” - zostanie wyświetlonych kilka ostatnich wierszy pliku. Jednak polecenie nie wraca do monitu i zamiast tego kontynuuje „śledzenie” pliku. Gdy do pliku zostaną dodane dodatkowe linie, zostaną one wyświetlone na terminalu. Jest to bardzo przydatne do oglądania plików dziennika lub innych plików, które mogą być dołączane z czasem. Wpisz „ogon człowieka”, aby uzyskać więcej informacji na temat tego i innych opcji ogona.

( przez )

marcgg
źródło
Ale nie jest to zbyt wygodne podczas pracy na komputerze lokalnym, ponieważ nie widzisz wyniku w tym samym oknie, w którym wywołałeś zadanie. Zwłaszcza jeśli nie masz dużego ekranu, aby zmieścić wiele okien obok siebie.
Tomas Markauskas,
10
Jeszcze lepiej jest użyć tailf"Jest podobny do tail -f, ale nie uzyskuje dostępu do pliku, gdy nie rośnie" (ze strony podręcznika). Jest też krótszy
MBO
@tomas dlaczego nie zminimalizować konsoli dziennika serwera i mieć tylko jedną konsolę z uruchomionym tail-f? W każdym razie nie jest to prawdziwy problem ... Używam jak 8 konsol śledzenia tego, co dzieje się w mojej aplikacji, wystarczy przełączyć się między kartami, gdy pracujesz na część konkretnego systemu nic wielkiego imho
marcgg
@mbo nice :) halas, wygląda na to, że nie jest dostępne na moim komputerze (mac os @ leopard)
marcgg
1
@marcgg: Nie mam "konsoli serwera" (używam pasażera), ale pytanie dotyczy zadań rake i jeśli uruchamiasz zadanie z jednego okna terminala, nie widzisz nic z loggera w tym oknie. Musisz mieć inne okno z development.log, aby zobaczyć dane wyjściowe. Idealnie byłoby jakoś dodać stdout jako kolejny strumień wyjściowy do Rails.logger, ale nie usunąć oryginalnego.
Tomas Markauskas,
9

Kod

W przypadku Rails 4 i nowszych możesz użyć transmisji Loggera .

Jeśli chcesz uzyskać zarówno STDOUT, jak i rejestrowanie plików dla zadań rake w trybie programistycznym, możesz dodać ten kod do config/environments/development.rb:

  if File.basename($0) == 'rake'
    # http://stackoverflow.com/questions/2246141/puts-vs-logger-in-rails-rake-tasks
    log_file     = Rails.root.join("log", "#{Rails.env}.log")
    Rails.logger = ActiveSupport::Logger.new(log_file)
    Rails.logger.extend(ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT)))
  end

Test

Oto małe zadanie Rake, aby przetestować powyższy kod:

# lib/tasks/stdout_and_log.rake
namespace :stdout_and_log do
  desc "Test if Rails.logger outputs to STDOUT and log file"
  task :test => :environment do
    puts "HELLO FROM PUTS"
    Rails.logger.info "HELLO FROM LOGGER"
  end
end

Działające rake stdout_and_log:testwyjścia

HELLO FROM PUTS
HELLO FROM LOGGER

podczas

HELLO FROM LOGGER

został dodany do log/development.log.

Działające rake stdout_and_log:test RAILS_ENV=productionwyjścia

HELLO FROM PUTS

podczas

HELLO FROM LOGGER

został dodany do log/production.log.

Eric Duminil
źródło
W Railsach 5 ta basename($0) == 'rake'sztuczka już nie działa, ponieważ railssamo polecenie działa rake. Chciałbym znaleźć dla niego dobry zamiennik, który wykracza poza zakres zadania, które powoduje skonfigurowanie broadcast. (Przynajmniej ta część nadal działa dobrze.)
Brent Royal-Gordon
@ BrentRoyal-Gordon Nie ma potrzeby stosowania tego warunku w rozwoju, możesz po prostu dodać kod do Rakefilekatalogu głównego swojego projektu
Mauricio Pasquier Juan
4

Co powiesz na stworzenie pomocnika aplikacji, który wykrywa, które środowisko jest uruchomione i robi właściwe rzeczy?

def output_debug(info)
   if RAILS_ENV == "development"
      puts info
   else
      logger.info info
   end
end

Następnie wywołaj output_debug zamiast puts lub logger.info

naven87
źródło
5
Myślę, że to nie jest dobry pomysł. Rejestrator Railsów ma być konfigurowalny, ale zamiast używać tej konfiguracji, po prostu układasz tutaj więcej warstw na wierzchu.
Sijmen Mulder
Tak, to nie jest dobry pomysł, ponieważ ta sama kontrola będzie wykonywana za każdym razem , gdy chcesz coś zarejestrować.
furiabhavesh
3

W Railsach 2.X, aby przekierować rejestrator do STDOUT w modelach:

ActiveRecord::Base.logger = Logger.new(STDOUT)

Aby przekierować loggera w kontrolerach:

ActionController::Base.logger = Logger.new(STDOUT)
Tania R.
źródło
Znalazłem również ten artykuł, bardzo przydatny sepcot.com/blog/2009/08/rails-logging-to-stdout
Tania R
2

Wykonaj zadanie w tle za pomocą „&” i otwórz skrypt / konsolę lub cokolwiek innego. W ten sposób możesz uruchomić wiele poleceń w tym samym oknie.

tail -f log/development.log &
script/console
Loading development environment (Rails 2.3.5)
>> Product.all
2011-03-10 11:56:00 18062 DEBUG  Product Load (6.0ms)  SELECT * FROM "products"
[<Product.1>,<Product.2>]

note Uwaga Może szybko stać się niechlujna, gdy jest dużo danych wyjściowych logowania.

Tom Maeckelberghe
źródło