setzt vs Logger in Schienen Rechenaufgaben

108

Wenn ich in einer Rechenaufgabe den Befehl put verwende, wird die Ausgabe auf der Konsole angezeigt. Diese Meldung wird jedoch nicht in der Protokolldatei angezeigt, wenn die App in der Produktion bereitgestellt wird.

Wenn ich jedoch Rails.logger.info sage, sehe ich im Entwicklungsmodus nichts auf der Konsole. Ich muss zur Protokolldatei gehen und das verfolgen.

Ich möchte idealerweise Rails.logger.info verwenden und im Entwicklungsmodus innerhalb der Rake-Task sollte die Ausgabe von Logger auch an die Konsole gesendet werden.

Gibt es einen Weg, dies zu erreichen?

Nick Vanderbilt
quelle

Antworten:

57

Fügen Sie dies in application.rboder in eine Rake-Task ein, um den Code zu initialisieren

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

Dies ist Rails 3-Code. Beachten Sie, dass dadurch die Protokollierung überschrieben wird development.log. Wenn Sie beides möchten STDOUTund development.logeine Wrapper-Funktion benötigen.

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

shmichael
quelle
26
Wäre es nicht einfacher, einfach Rails.logger = Logger.new(STDOUT)in development.rb zu setzen?
Ghempton
Für Schienen 2 setzen Sie dies in Ihre Entwicklung.rb:config.logger = Logger.new(STDOUT)
jsarma
38

Sie können eine neue Rechenaufgabe erstellen, damit dies funktioniert.

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

Auf diese Weise können Sie beim Ausführen Ihrer Rake-Task zuerst to_stdout hinzufügen, um stdout-Protokollnachrichten abzurufen, oder es nicht einschließen, damit Nachrichten an die Standardprotokolldatei gesendet werden

rake to_stdout some_task
Pete Brumm
quelle
11

Rake-Tasks werden von einem Benutzer über eine Befehlszeile ausgeführt. Alles, was sie sofort wissen müssen ("5 Zeilen verarbeitet"), sollte auf dem Terminal mit ausgegeben werden puts.

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

Jonathan Julian
quelle
17
Es ist nicht ungewöhnlich, Rechenaufgaben mit cron auszuführen.
Johannes Gorset
2
Wahr. Wenn Sie möchten, dass die Protokollnachrichten nach Abschluss des Cron-Jobs per E-Mail an Sie gesendet werden, geben Sie sie an $ stdout oder $ stderr aus.
Jonathan Julian
10

Ich würde sagen, dass die Verwendung Rails.logger.infoder richtige Weg ist.

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

Vielen Benutzern ist der UNIX®-Befehl 'tail' bekannt, mit dem die letzten Zeilen einer großen Datei angezeigt werden können. Dies kann nützlich sein, um Protokolldateien usw. anzuzeigen.

In einigen Situationen ist der Parameter '-f' für den Befehl 'tail' sogar noch nützlicher. Dies bewirkt, dass tail der Ausgabe der Datei folgt. Anfänglich ist die Antwort dieselbe wie für 'tail' für sich allein - die letzten Zeilen der Datei werden angezeigt. Der Befehl kehrt jedoch nicht zur Eingabeaufforderung zurück und folgt stattdessen weiterhin der Datei. Wenn der Datei zusätzliche Zeilen hinzugefügt werden, werden diese auf dem Terminal angezeigt. Dies ist sehr nützlich, um Protokolldateien oder andere Dateien anzusehen, die im Laufe der Zeit angehängt werden können. Geben Sie 'man tail' ein, um weitere Informationen zu dieser und anderen Schwanzoptionen zu erhalten.

( via )

marcgg
quelle
Bei der Arbeit am lokalen Computer ist dies jedoch nicht sehr komfortabel, da die Ausgabe nicht in demselben Fenster angezeigt wird, in dem Sie die Aufgabe aufgerufen haben. Vor allem, wenn Sie keinen großen Bildschirm haben, auf den mehrere Fenster nebeneinander passen.
Tomas Markauskas
10
Noch besser ist es, tailf"Es ist ähnlich wie tail -f, greift aber nicht auf die Datei zu, wenn sie nicht wächst" (von der Manpage). Es ist auch kürzer
MBO
@tomas Warum nicht die Server-Protokollkonsole minimieren und nur die eine Konsole mit dem Tail-F ausführen? Sowieso ist es kein wirkliches Problem ... ich wie 8 - Konsolen Tracing leite was in meiner app geht, wechseln Sie einfach zwischen den Tabs , wenn Sie auf einem bestimmten Teil des Systems keine große Sache imho arbeiten
marcgg
@mbo schön :) halas es sieht nicht so aus, als wäre es auf meinem Computer verfügbar (mac os @ leopard)
marcgg
1
@marcgg: Ich habe keine "Serverkonsole" (ich verwende Passagier), aber die Frage bezieht sich auf Rake-Aufgaben. Wenn Sie eine Aufgabe von einem Terminalfenster aus ausführen, wird in diesem Fenster nichts vom Logger angezeigt. Sie müssen ein anderes Fenster mit der Datei development.log haben, um die Ausgabe zu sehen. Idealerweise würde ich rails.logger irgendwie als weiteren Ausgabestream hinzufügen, aber den ursprünglichen nicht entfernen.
Tomas Markauskas
9

Code

Für Rails 4 und höher können Sie Logger Broadcast verwenden .

Wenn Sie sowohl STDOUT als auch Dateiprotokollierung für Rake-Aufgaben im Entwicklungsmodus erhalten möchten, können Sie diesen Code hinzufügen in 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

Prüfung

Hier ist eine kleine Rake-Aufgabe, um den obigen Code zu testen:

# 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

Laufende rake stdout_and_log:testAusgaben

HELLO FROM PUTS
HELLO FROM LOGGER

während

HELLO FROM LOGGER

wurde hinzugefügt log/development.log.

Laufende rake stdout_and_log:test RAILS_ENV=productionAusgaben

HELLO FROM PUTS

während

HELLO FROM LOGGER

wurde hinzugefügt log/production.log.

Eric Duminil
quelle
In Rails 5 basename($0) == 'rake'funktioniert der Trick nicht mehr, da der railsBefehl selbst ausgeführt wird rake. Ich würde gerne einen guten Ersatz dafür finden, abhängig von einer Aufgabe, die das einrichtet broadcast. (Zumindest dieser Teil funktioniert immer noch gut.)
Brent Royal-Gordon
@ BrentRoyal-Gordon Es gibt keine Notwendigkeit für diese Bedingung in der Entwicklung, Sie können einfach den Code Rakefilean der Wurzel Ihres Projekts hinzufügen
Mauricio Pasquier Juan
4

Wie wäre es mit einem Anwendungshelfer, der erkennt, welche Umgebung ausgeführt wird und das Richtige tut?

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

Rufen Sie dann output_debug anstelle von put oder logger.info auf

naven87
quelle
5
Ich halte das nicht für eine gute Idee. Der Rails-Logger soll konfigurierbar sein, aber anstatt diese Konfigurierbarkeit zu verwenden, stapeln Sie hier einfach mehr Ebenen darüber.
Sijmen Mulder
Ja, das ist keine gute Idee, da jedes Mal , wenn Sie etwas protokollieren möchten, dieselbe Überprüfung durchgeführt wird .
Furiabhavesh
3

In Rails 2.X, um den Logger in Modellen auf STDOUT umzuleiten:

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

So leiten Sie den Logger in Controllern um:

ActionController::Base.logger = Logger.new(STDOUT)
Tania R.
quelle
Ich fand auch diesen Artikel, sehr nützlich sepcot.com/blog/2009/08/rails-logging-to-stdout
Tania R
2

Führen Sie einen Hintergrundjob mit '&' aus und öffnen Sie das Skript / die 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>]

Hinweis Kann schnell schlampig werden, wenn viel Protokoll ausgegeben wird.

Tom Maeckelberghe
quelle