Rails: Protokollierung des gesamten Stack-Trace einer Ausnahme

110

Ich habe versucht, den richtigen Weg zum Protokollieren eines Stack-Trace zu finden. Ich bin auf diesen Link gestoßen, der besagt, dass logger.error $!, $!. Backtrace der richtige Weg ist, aber das funktioniert bei mir nicht. Log_error funktioniert. Gemäß der Dokumentation sehe ich nicht, wie das Übergeben eines zweiten Arguments an die Fehlermethode sowieso funktionieren würde, da der von Rails verwendete Ruby-Logger nur ein einziges Argument akzeptiert.

Seltsamerweise (oder vielleicht auch nicht) wird das zweite Argument ohne Beschwerden von Dolmetschern akzeptiert. Alles, was ich weitergebe, wird jedoch ignoriert.

Kann mir jemand erklären, was mir fehlt? Gibt es einen Einblick, wofür das zweite Argument des Fehlers ist und was es isst?

Moiz Raja
quelle

Antworten:

204

Wenn Sie sich die Quelle für die BufferedLogger-Klasse in ActiveSupport ansehen, werden Sie feststellen, dass das zweite Argument "Progname" ist. Dies wird nur verwendet, wenn das erste Argument Null ist und Sie ihm entweder keinen Block gegeben haben oder der Block einen nicht wahren Wert zurückgibt.

Im Wesentlichen können Sie den zweiten Parameter nicht verwenden, um zusätzliches Material auszugeben.

Was Sie tun möchten, ist etwas ähnlicheres:

begin
  raise
rescue => e
  logger.error e.message
  logger.error e.backtrace.join("\n")
end

Abhängig davon, wie Sie Ihre Protokollierung eingerichtet haben, ist es möglicherweise besser, jede Zeile des Backtraces zu durchlaufen und separat zu drucken, da bestimmte Protokollierer keine Zeilenumbrüche ausgeben. In diesem Fall würden Sie Folgendes tun:

begin
  raise
rescue => e
  logger.error e.message
  e.backtrace.each { |line| logger.error line }
end
dunkelflüssig
quelle
5
Ich würde mich mit "\ r \ n" anmelden, um die plattformübergreifende Kompatibilität aufrechtzuerhalten.
James Watkins
10
Würden Sie nicht $/stattdessen plattformübergreifend kompatibel sein? Lassen Sie Ruby sich darum kümmern, da dies \r\nnur für einige wenige Plattformen spezifisch ist.
VGoff
12
Möglicherweise wird Ihre Nachricht aufgeteilt und ist nicht lesbar, da ein mehrmaliger Aufruf des Loggers nicht threadsicher ist. Während der Logger selbst threadsicher ist. Normalerweise füge ich meine Nachricht in einer Zeichenfolge hinzu und protokolliere sie dann.
Morozov
Zu der Zeit schien Logger keine Zeilenumbrüche in Protokolleinträgen zu unterstützen, daher die Aufteilung, aber ja, Sie haben völlig Recht und sollten sich der Einschränkungen dieses Ansatzes bewusst sein
darkliquid
+1 @JackWatson absolut seltsame Antwort, weil es nicht threadsicher ist. Es ist wichtig, weil wir hier über Web-Apps sprechen
EvAlex
16

Das ist die Antwort.

begin
  raise
rescue => e
  logger.error ([e.message]+e.backtrace).join($/)
end
Kuboon
quelle
9
weniger Interpunktion:Rails.logger.error [e.message, *e.backtrace].join($/)
Artm