Manuelles Tracing hinzufügen
Spanne , Tagebuch und Tracking¶
Hier ist ein Beispiel für die Verwendung von Logfire :
import time
import logfire
logfire.configure()
with logfire.span('This is a span'):
time.sleep(1)
logfire.info('This is an info log')
time.sleep(2)
Wenn Sie dies ausführen , sollte es etwas ähnliches drucken :
Logfire project URL: https://logfire.pydantic.dev/my_username/my_project_name
21:02:55.078 This is a span
21:02:56.084 This is an info log
Projekt-URLs öffnen sollten in der Live-Ansicht wie folgt angezeigt werden :
Ein blaues Feld mit 1+ zeigt an , dass die Spanne 1 direktes Unterelement enthält , indem Sie auf das Feld klicken , um die Spanne zu erweitern , um die Unterelemente anzuzeigen :
Bitte beachten :
-
Jeder Bereich oder jedes Protokoll , das in einem
with logfire.span(...):-Block erstellt wird , ist ein Unterelement dieses Bereichs , wodurch Sie das Protokoll in einem strukturierten Baum gut organisieren können . -
Die Spanne hat eine Anfangszeit und eine Endzeit und hat daher eine Dauer Diese Spanne dauert 3 Sekunden , um abzuschließen .
-
Bei Protokollen sind die Start - und Endzeiten gleich , so dass sie keine Dauer haben Sie können jedoch immer noch auf der Benutzeroberfläche sehen , dass das Protokoll 1 Sekunde nach dem Start der Spanne und 2 Sekunden vor dem Ende der Spanne erstellt wird .
Wenn Sie in der oberen Navigationsleiste auf den Link Erkunden klicken , können Sie SQL schreiben , um es weiter zu untersuchen , z . B . :
Beachtung :
-
Die Spannweite und das Logbuch werden in derselben
记录-Tabelle gespeichert . -
Das Logbuch
的parent_span_idist die Spanne vonspan_id. -
Beide haben das gleiche.
trace_idSie können darauf klicken, um eine neue Registerkarte in der Live-Ansicht zu öffnen, auf die gefiltert wurde.nachverfolgen。
_verfolgen._Ist Freigabe desselben Spanne/Protokollbaums Ein neues Tracking wird erstellt, wenn ohne Aktivitätsspannung eine neue Spanne/ein neues Log erstellt wird Wenn es sich um eine Spanne handelt, sind alle Nachkommen dieser Spanne Teil derselben Ablaufverfolgung Um das Protokoll gut in die Ablaufverfolgung zu organisieren, ist es am besten, eine Spanne auf oberster Ebene zu erstellen, um erweiterte Aktionen wie die Verarbeitung von Webserveranforderungen darzustellen.
Eigenschaften .¶
Spannweiten und Protokolle können mit strukturierten Daten angefügt werden , z . B . :
logfire.info(„ Hallo " , name = „ Welt ")
Wenn Sie in der Live-Ansicht auf das Protokoll „ Hello " klicken , sollten Sie im Detailbereich auf der rechten Seite Folgendes sehen :
Diese Daten werden in den 属性-Spalten der 记录-Tabelle im JSON-Format gespeichert Beispielsweise können Sie attributes->>'name' = 'world' im SQL-Filter oben in der Live-Ansicht verwenden , um nur dieses Protokoll anzuzeigen Dies wird als WHERE-Klausel für SQL-Abfragen in 记录-Tabellen verwendet .
Sowohl span als auch logs können Attribute mit beliebigen Werten haben , die intelligent zu JSON serialisiert werden , wenn Sie möchten Sie können beliebige Schlüsselwortparameter übergeben , um Eigenschaften zu setzen , solange sie nicht mit einem Unterstrich (_) beginnen Dieser Namespace ist für andere Schlüsselwortparameter mit logfire-spezifischer Bedeutung reserviert .
Manchmal ist es nützlich, ein Attribut an den Bereich anzuhängen, nachdem der Bereich erstellt wurde, aber bevor der Bereich abgeschlossen ist, können Sie dies tun, indem Sie die span.set_attribute-Methode aufrufen:
with logfire.span('Calculating...') as span:
result = 1 + 2
span.set_attribute('result', result)
Nachrichten und Name des Bereiches¶
Falls dieser Code ausgeführt wird:
import logfire
logfire.configure()
for name in ['Alice', 'Bob', 'Carol']:
logfire.info('Hello {name}', name=name)
Hier könnt ihr es sehen:
-
Das erste Argument,
“Hello {name}”, wird zum Wert derspan_name-Spalte, mit der Sie alle Datensätze aus dem gleichen Code finden können, auch wenn die Nachrichten unterschiedlich sind, z. B. mit dem SQL-Filterspan_name = 'Hello {name}'. -
Der span-Name wird auch als Vorlage im
str.format-Stil verwendet, die mit einem Attribut formatiert ist, um eine消息-Spalte zu erzeugen, bei der die Nachricht im Konsolenprotokoll und in der Live-Ansicht angezeigt wird.
Sie können span.message auch nach dem Start der Spanne, aber vor dem Ende der Spanne festlegen, zum Beispiel:
with logfire.span('Calculating...') as span:
result = 1 + 2
span.message = f'Calculated: {result}'
Sie können 消息 verwenden, um verwandte Datensätze wie “Hello%”之类的消息 zu filtern, aber es ist effizienter,span_name-Spalten zu filtern, da sie indiziert wurden Auch hier ist es besser,span_name = 'Hello {name}' 和 attributes->>'name' = 'Alice' als message = 'Hello Alice' zu verwenden.
Um die relevanten Datensätze effektiv überprüfen zu können, Spannweite Name_Basis ist_Sollte niedriger sein, was bedeutet, dass sie nicht viel ändern sollten, zum Beispiel, und das wäre schlecht:
name = get_username()
logfire.info('Hello ' + name, name=name)
Denn jetzt wird die span_name-Spalte einen anderen Wert für jeden Benutzernamen haben, aber das ist in Ordnung:
Da die span_name-Spalte jetzt nur zwei Werte hat ('Goodbye {name}' und 'Hello {name}'), ist es einfacher und effizienter,span_name = 'Hello {name}' zu filtern als span_name = '{word} {name}' 和 attributes->>'word' = 'Hello'.
Wenn Sie möchten, dass der span Name von der Nachrichtenvorlage abweicht, können Sie den _span_name-Parameter verwenden, z. B.:
word = 'Goodbye' if leaving else 'Hello'
logfire.info(word + ' {name}', name=name)
Dies wird span_name eingerichtet für “Hello”, wird 消息 eingerichtet für “Hello world”。 Bitte beachten Sie,_span_name Parameter beginnen mit einem Unterstrich, um sie von den Eigenschaften zu unterscheiden.
logfire.info('Hello {name}', name='world', _span_name='Hello')
F Strings-Strings sind¶
Ersetzt werden soll dies:
logfire.info('Hello {name}', name=name)
Es ist viel bequemer, F-String zu verwenden, um zu vermeiden, dass NAME dreimal wiederholt wird:
logfire.info(f'Hello {name}')
Im Gegensatz zum vorherigen Abschnitt wirkt sich dies auf_in Python 3.11 + aus_ist gut, da Logfire einen speziellen Zauber verwendet, um span_name auf “Hello {name}” zu setzen und die name-Eigenschaft auf den Wert der name-Variable zu setzen, so dass es mit dem vorherigen Snippet äquivalent ist, was Sie wissen müssen:
-
Diese Funktion ist in Python 3.11 + standardmäßig aktiviert. [
logfire.configure(inspect_arguments=False)][logfire.configure(inspect_arguments)] Sie können es auch in Python 3.9 und 3.10 aktivieren, aber es ist wahrscheinlicher, dass es nicht richtig funktioniert. -
Unter normalen Umständen sollten Prüfparameter immer gültig sein Es ist wichtig zu beachten, dass der Quellcode verfügbar sein muss, so dass zum Beispiel nur das Bereitstellen einer
.pyc-Datei zum Fehlschlagen führen wird. -
Wenn die Überprüfung der Parameter fehlschlägt, erhalten Sie eine Warnung und der f-string-Parameter wird als Formatvorlage verwendet, was bedeutet, dass Sie Namen mit hoher Basis erhalten, wie
“Hello Alice”, und es gibt kein名称-Attribut, aber die Informationen gehen nicht vollständig verloren. -
Wenn der Prüfparameter aktiviert ist, werden die Parameter überprüft, unabhängig davon, ob Sie eine f-Zeichenfolge verwenden oder nicht Wenn Sie also
logfire.info('Hello {name}', name=name)schreiben und die Überprüfung der Parameter fehlschlägt, erhalten Sie immer noch eine Warnung. -
Der Wert in f-strings wird von Logfire erneut berechnet und formatiert.
get_username()(oder String-Konvertierung von allem, was es zurückgibt) ist teuer oder hat Nebenwirkungen, und Sie sollten vermeiden, mit ähnlichenlogfire.info(f'Hello {get_username()}')den Code. -
Das erste Argument muss die tatsächliche f-Zeichenfolge sein
logfire.info(f'Hello {name}')wird funktionieren, abermessage = f'Hello {name}'; logfire.info(message)wird es nicht tun, nochlogfire.info('Hello ' + name)wird es funktionieren. -
Prüfparameter werden zwischengespeichert, damit der Leistungsaufwand für die wiederholte Überprüfung derselben f-Zeichenfolge minimal ist, aber das Parsen großer Quelldateien erzeugt einen nicht zu vernachlässigenden Overhead, wenn die Parameter zuerst überprüft werden müssen In jedem Fall muss der Prüfparameter vollständig deaktiviert werden, nicht nur um f-Zeichenfolgen zu vermeiden.
Ungewöhnlich.¶
logfire.span Der Kontext-Manager protokolliert automatisch alle Ausnahmen, die zu seiner Beendigung geführt haben, wie z. B.:
import logfire
logfire.configure()
with logfire.span('This is a span'):
raise ValueError('This is an error')
Wenn Sie in der Live-Ansicht auf die Spanne klicken, befindet sich im rechten Bereich eine Registerkarte "Außergewöhnliches Backtracking":
Ausnahmen, die erfasst, aber nicht erneut ausgelöst werden, werden nicht protokolliert, wie zum Beispiel:
with logfire.span('This is a span'):
try:
raise ValueError('This is an acceptable error not worth recording')
except ValueError:
pass
Um eine behandelte Ausnahme zu protokollieren, verwenden Sie span.record_exception Methoden:
with logfire.span('This is a span') as span:
try:
raise ValueError('Catch this error, but record it')
except ValueError as e:
span.record_exception(e)
Oder wenn Sie nur Ausnahmen aufzeichnen möchten und keine Spanne für die normale Situation erstellen, können Sie logfire.exception:
try:
raise ValueError('This is an error')
except ValueError:
logfire.exception('Something went wrong')
logfire.exception(...) Gleichwertigkeit mit logfire.error(..., _exc_info=True)。 Wenn Sie ein nicht fehlerhaftes Backtracking in einem Protokoll aufzeichnen möchten, können Sie _exc_info Wird in Verbindung mit anderen Protokollierungsmethoden verwendet, können Sie die Ausnahme verwenden, wenn es sich nicht um das Objekt handelt, mit dem Sie arbeiten._exc_info Auf dieses ungewöhnliche Objekt setzen Vergessen Sie nicht den führenden Unterstrich!
Komfortable Funktionsspannung durch @logfire.instrument¶
Im Allgemeinen möchten Sie die gesamte Funktion in einen Bereich packen, anstatt dies zu tun:
def my_function(x, y):
with logfire.span('my_function', x=x, y=y):
...
Sie können @logfire.instrument Dekorer verwenden:
Standardmäßig werden dadurch Funktionsparameter als Eigenschaften zu span hinzugefügt Um diese Funktion zu deaktivieren (z. B. wenn ein Parameter ein großes Objekt ist, das es nicht wert ist, gesammelt zu werden), verwenden Sie span. instrument(extract_args=False)。
Der Standardspan ist ähnlich wie Calling module_name.my_function Sie können den alternativen Span als ersten Parameter an instrument übergeben, der sogar als Vorlage für die Parameterformatierung dienen kann, z. B.:
@logfire.instrument('Applying my_function to {x=} and {y=}')
def my_function(x, y):
...
my_function(3, 4)
# Logs: Applying my_function to x=3 and y=4
!!! Achtung!
- ['@ logfire. instrument '][logfire.Logfire.instrument] Dekoratoren müssen zuerst angewendet werden, d.h. unter jedem anderen Ornament.
- Der Quellcode einer Funktion muss zugänglich sein.
Tagebuch Level¶
Die Methoden zum Erstellen von Protokollen verschiedener Ebenen sind wie folgt:
logfire.tracelogfire.debuglogfire.infologfire.notice(日志火灾通知)logfire.warnlogfire.errorlogfire.fatal
Standardmäßig sind die 跟踪-und 调试-Protokolle ausgeblendet Sie können diese Einstellung ändern, indem Sie in der Live-Ansicht auf das Dropdown-Menü "Standardstufe" klicken:
Sie können es noch verwenden. logfire.configure Legen Sie die Mindeststufe für die Konsolenprotokollierung fest, z. B.:
import logfire
logfire.configure(console=logfire.ConsoleOptions(min_log_level='debug'))
Um Nachrichten mit Variablenebene zu protokollieren, können Sie logfire.log verwenden, z. B.logfire.log('info', 'This is an info log') ist äquivalent zu logfire.info('This is an info log')。
In diesem Fall ist die Spanne der Rang.信息 Sie können verwenden. _level Parameter ändern, z.B.使用 logfire.span('This is a debug span', _level='debug'): Sie können es auch nach dem Beginn der Spanne verwenden, aber bevor Sie die Spanne beenden. span.set_level Ändern Sie die Ebene LogfireSpan. set_level], zum Beispiel:
with logfire.span('Doing a thing') as span:
success = do_thing()
if not success:
span.set_level('error')
In der Live-Ansicht wird die-Spanne nach ihrer höchsten Ebene und ihren Nachkommen gefärbtzum Beispiel mit dem folgenden Code:
import logfire
logfire.configure()
with logfire.span('Outer span'):
with logfire.span('Inner span'):
logfire.info('This is an info message')
logfire.error('This is an error message')
Es wird wie folgt gezeigt:
Hier sind die Stufen der Spanne selbst immer noch auf 默认-Informationen festgelegt, aber sie werden rot statt blau gestrichen, da sie Fehlerprotokolle enthalten.
Wenn die Spanne mit einer unbehandelten Ausnahme endet, wird zusätzlich zu der oben beschriebenen Protokollrückverfolgung auch die Protokollstufe der Spanne auf 错误 Verwendung. span.record_exception Dies ist bei der LogfireSpan. record_exception Methode nicht der Fall.
In der Datenbank werden die Protokollebenen in numerischer Form gespeichert 级别 Diese Werte in der Spalte basieren auf OpenTelemetry. info für 9 Sie können verwenden. level_num SQL-Funktionen konvertieren einen Stufennamen in eine Zahl, z. B.级别 > level_num('info') Alle "ungewöhnlichen" Datensätze werden gefunden, und Sie können sie auch verwenden. level_name SQL-Funktionen, die Zahlen in Namen umwandeln, z. B. SELECT level_name(level)、... Um die für Menschen lesbare Ebene in der Explorationsansicht anzuzeigen, beachten Sie, dass level Die Indizierung ist also richtig. level = level_num('error') Die Prüfung ist wirksam, aber ja. level_name(level) = 'error' Das Auswahlverfahren ist unwirksam.
本文总阅读量次







