2010-02-11 11 views
88

In einem Rake-Task, wenn ich Puts-Befehl verwenden, dann sehe ich die Ausgabe auf der Konsole. Diese Nachricht wird jedoch nicht in der Protokolldatei angezeigt, wenn die App in der Produktion bereitgestellt wird.puts vs Logger in Schienen rake Aufgaben

Wenn ich jedoch rails.logger.info sage dann im Entwicklungsmodus sehe ich nichts auf der Konsole. Ich muss zur Log-Datei gehen und das beenden.

Ich würde gerne Rails.logger.info verwenden und im Entwicklungsmodus innerhalb der Rake-Aufgabe sollte die Ausgabe von Logger auch an die Konsole gesendet werden.

Gibt es eine Möglichkeit, das zu erreichen?

+2

+1 Ich wollte nur die gleiche Frage stellen. –

Antwort

9

Ich würde sagen, dass mit Rails.logger.info ist der Weg zu gehen.

Sie können es nicht in der Serverkonsole anzeigen, da es nicht über den Server ausgeführt wird. Öffnen Sie einfach eine neue Konsole und tail -f die Protokolldatei, es wird den Trick tun.

Viele Anwender sind sich der UNIX® Befehl ‚Schwanz‘, die Display die letzten Zeilen einer großen Datei verwendet werden kann. Dies kann für die Anzeige Protokolldateien usw.

Noch nützlicher in einigen Situationen nützlich sein, sind die ‚f‘ Parameter auf den ‚Schwanz‘ Befehl. Dies bewirkt, dass der Ausgang der Datei " " folgt. Anfänglich ist die Antwort die gleiche wie für "Schwanz" allein - die letzten paar Zeilen der Datei werden angezeigt. Der Befehl gibt jedoch nicht an die Eingabeaufforderung zurück und setzt stattdessen fort, um der Datei zu folgen. Wenn der Datei zusätzliche Zeilen hinzugefügt werden, werden sie auf dem Terminal angezeigt. Dies ist sehr nützlich für die Überwachung von Log-Dateien, oder jede andere Datei, die im Laufe der Zeit angehängt werden kann. Geben Sie "Man Tail" für weitere Details zu diesem und anderen Schwanz Optionen.

(via)

+0

Es ist jedoch nicht sehr komfortabel, wenn Sie am lokalen Computer arbeiten, da Sie die Ausgabe nicht im selben Fenster sehen, in dem Sie die Aufgabe aufgerufen haben. Vor allem, wenn Sie nicht einen großen Bildschirm haben, um mehrere Fenster nebeneinander zu passen. –

+9

Noch besser ist es, 'tailf' zu verwenden. Es ist ähnlich wie tail -f, aber greift nicht auf die Datei zu, wenn sie nicht wächst" (von der Manpage). Es ist auch kürzer – MBO

+0

@tomas warum nicht minimiert die Server-Log-Konsole und nur die eine Konsole mit dem Schwanz-f läuft? Wie auch immer, es ist kein wirkliches Problem ... Ich laufe wie 8 Konsolen, was in meiner App abläuft, wechsle einfach zwischen den Tabs, wenn du an einem bestimmten Teil des Systems arbeitest keine große Sache imho – marcgg

10

Rake Aufgaben werden von einem Benutzer, auf einer Befehlszeile ausgeführt. Alles, was sie sofort wissen müssen ("verarbeitete 5 Zeilen"), sollte am Terminal mit puts ausgegeben werden.

Alles, was für die Nachwelt aufbewahrt werden muss ("Senden einer Warn-E-Mail an [email protected]") sollte an die Rails.logger gesendet werden.

+11

Es ist nicht ungewöhnlich, Rake-Aufgaben mit Cron auszuführen. –

+2

Wahr. Wenn Sie möchten, dass die Protokollnachrichten Ihnen per E-Mail gesendet werden, wenn der Cron-Job abgeschlossen ist, spucken Sie sie nach $ stdout oder $ stderr aus. –

3

Wie wäre es mit einem Anwendungshelfer, der erkennt, welche Umgebung läuft und das Richtige tut?

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

Dann rufen Sie anstelle von Puts output_debug oder Logger.INFO

+4

Ich denke nicht, dass dies eine gute Idee ist. Der Rails-Logger soll konfigurierbar sein, aber anstatt diese Konfigurierbarkeit zu verwenden, stapeln Sie hier einfach mehr Layer übereinander. –

+0

Ja, es ist keine gute Idee, da die gleiche Überprüfung * jedes Mal * durchgeführt wird, wenn Sie etwas protokollieren möchten. – furiabhavesh

46

dies in application.rb Setzen oder in einem Rake-Task-Code initialisieren

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

Dies ist Rails 3-Code. Beachten Sie, dass dies die Protokollierung auf development.log überschreibt.Wenn Sie sowohl STDOUT als auch development.log möchten, benötigen Sie eine Wrapper-Funktion.

Wenn Sie dieses Verhalten nur in der Rails-Konsole möchten, platzieren Sie den gleichen Codeblock in Ihrem ~/.irbrc.

+1

Wie mache ich das in Schienen 2? – Joelio

+23

Wäre es nicht einfacher, 'Rails.logger = Logger.new (STDOUT)' in development.rb zu setzen? – ghempton

+0

Für Schienen 2, setzen Sie dies in Ihre development.rb: 'config.logger = Logger.new (STDOUT)' – jsarma

1

Führen Sie einen Hintergrundjob mit '&' und öffnen Sie Skript/Konsole oder was auch immer .. Auf diese Weise können Sie mehrere Befehle im selben Fenster ausführen.

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 Kann schlampig schnell erhalten, wenn eine Menge von Log-Ausgabe gibt.

2

In Rails 2.X den Logger STDOUT in Modelle umzuleiten:

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

Um Logger in Controller umleiten:

ActionController::Base.logger = Logger.new(STDOUT) 
+0

Ich fand auch diesen Artikel, sehr nützlich http://www.sepcot.com/blog/2009/08/ rails-logging-to-stdout –

24

Sie könnten eine neue Rechen-Aufgabe erstellen diese Arbeit zu bekommen .

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

diese Weise, wenn Sie Ihre Rake Aufgabe ausführen Sie to_stdout erste hinzufügen können stdout Log-Meldungen zu erhalten oder nicht enthalten sie Nachrichten an die Standardprotokolldatei gesendet haben

rake to_stdout some_task 
+0

ausgezeichnete Idee! –

2

-Code

Für Rails 4 und neuer können Sie Logger broadcast verwenden.

Wenn Sie sowohl STDOUT und Dateiprotokollierung für Rake Aufgaben im Entwicklungsmodus erhalten möchten, können Sie diesen Code in config/environments/development.rb hinzufügen:

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

Hier ist eine kleine Rake Aufgabe, die oben zu testen Code:

# 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 

Lauf rake stdout_and_log:test Ausgänge

HELLO FROM PUTS 
HELLO FROM LOGGER 

während

HELLO FROM LOGGER 

wurde log/development.log hinzugefügt.

Lauf rake stdout_and_log:test RAILS_ENV=production Ausgänge

HELLO FROM PUTS 

während

HELLO FROM LOGGER 

hat log/production.log hinzugefügt.

+0

In Rails 5 funktioniert der 'basename ($ 0) == 'rake'-Trick nicht mehr, weil der' rails' Befehl selbst 'rake' ausführt. Ich würde gerne einen guten Ersatz dafür finden, der nicht von einer Aufgabe abhängt, die die "Übertragung" festlegt. (Dieser Teil funktioniert zumindest noch.) –