Tambah Pelacakan Manual
Geser, catat, dan lacak¶
Berikut adalah contoh sederhana menggunakan 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)
Jika Anda menjalankan ini, itu harus mencetak sesuatu seperti ini:
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
URL proyek pembukaan harus menampilkan yang berikut ini dalam tampilan Langsung:
Kotak biru dengan 1+ menunjukkan bahwa bentang berisi 1 anak langsung. Klik kotak untuk memperluas bentang untuk menampilkan anak-anaknya:
Harap dicatat:
-
Setiap bentang atau log yang dibuat dalam blok
with logfire.span(...):akan menjadi anak dari rentang itu. Ini memungkinkan Anda untuk mengatur kayu gelondongan Anda dengan baik di pohon terstruktur. Anda juga dapat melihat hubungan orang tua-anak ini dalam log konsol berbasis indent. -
Rentang memiliki waktu mulai dan waktu akhir, dan karena itu durasi. Rentang ini membutuhkan waktu 3 detik untuk menyelesaikannya.
-
Untuk log, waktu mulai dan akhir sama, sehingga tidak memiliki durasi. Namun, Anda masih dapat melihat di UI bahwa log dibuat 1 detik setelah rentang dimulai dan 2 detik sebelum rentang berakhir.
Jika Anda mengklik tautan "Jelajahi" di bilah navigasi atas, Anda dapat menulis SQL untuk menjelajah lebih lanjut, misalnya:
Perhatian:
-
Spanduk dan log disimpan bersama dalam tabel
记录yang sama. -
Log
的parent_span_idadalah rentangspan_id. -
Keduanya memiliki
trace_idyang sama. Anda dapat mengkliknya untuk membuka tab baru di tampilan "langsung," yang telah disaring ke_trace_itu.
_trace_adalah pohon bentang / batang kayu yang memiliki akar yang sama. Setiap kali bentang / batang kayu baru dibuat tanpa bentang aktif, jejak baru dibuat. Jika itu adalah bentang, setiap keturunan dari bentang itu akan menjadi bagian dari jejak yang sama. Untuk mengatur log dengan baik ke dalam jejak, yang terbaik adalah membuat rentang di tingkat atas untuk mewakili operasi lanjutan, seperti memproses permintaan server web.
atribut¶
Bentang dan log dapat ditambahkan dengan data terstruktur, seperti:
logfire.info ('Halo', nama = 'Dunia')
Jika Anda mengklik log "Halo" di Live View, Anda akan melihat yang berikut di panel detail di sebelah kanan:
Data ini disimpan dalam format JSON di kolom 属性 tabel 记录. Misalnya, Anda dapat menggunakan attributes->>'name' = 'world' dalam filter SQL di bagian atas tampilan langsung untuk hanya menampilkan log ini. Ini digunakan sebagai klausa WHERE dari kueri SQL pada tabel 记录.
Baik bentang maupun log dapat memiliki sifat yang mengandung nilai arbitrer yang secara cerdas diserialisasikan ke JSON sesuai kebutuhan. Anda dapat menyampaikan argumen kata kunci apa pun untuk mengatur properti selama tidak dimulai dengan garis bawah (_).
Namespace ini dicadangkan untuk parameter kata kunci tambahan dengan makna spesifik logfire.
Terkadang berguna untuk melampirkan properti ke ruang lingkup setelah dibuat tetapi sebelum selesai. Anda dapat melakukannya dengan memanggil metode span.set_attribute:
with logfire.span('Calculating...') as span:
result = 1 + 2
span.set_attribute('result', result)
Nama pesan dan rentang¶
Jika Anda menjalankan kode ini:
import logfire
logfire.configure()
for name in ['Alice', 'Bob', 'Carol']:
logfire.info('Hello {name}', name=name)
Di sini Anda dapat melihat:
-
Argumen pertama,
“Hello {name}”, menjadi nilai kolomspan_name. Anda dapat menggunakannya untuk menemukan semua catatan dari kode yang sama, meskipun pesannya berbeda, misalnya menggunakanspan_name = 'Hello {name}'filter SQL. -
Nama span juga digunakan sebagai template bergaya
str.formatyang diformat dengan properti untuk menghasilkan kolom消息. Pesan ditampilkan di log konsol dan dalam tampilan langsung.
Anda juga dapat mengatur span.message setelah rentang dimulai tetapi sebelum rentang selesai, misalnya:
with logfire.span('Calculating...') as span:
result = 1 + 2
span.message = f'Calculated: {result}'
Anda dapat menggunakan 消息 untuk menyaring catatan terkait, seperti “Hello%”之类的消息, tetapi menyaring kolom span_name lebih efisien karena diindeks. Sekali lagi, menggunakan span_name = 'Hello {name}' 和 attributes->>'name' = 'Alice' lebih baik daripada menggunakan message = 'Hello Alice'.
Agar dapat menyaring catatan terkait secara efektif,_kardinalitas_dari nama rentang harus rendah, yang berarti mereka tidak boleh terlalu bervariasi. Misalnya, ini akan buruk:
name = get_username()
logfire.info('Hello ' + name, name=name)
Karena sekarang kolom span_name akan memiliki nilai yang berbeda untuk setiap nama pengguna. Tapi tidak apa-apa:
Karena kolom span_name sekarang hanya memiliki dua nilai ('Goodbye {name}' dan 'Hello {name}'), penyaringan span_name = 'Hello {name}' lebih mudah dan lebih efisien daripada penyaringan span_name = '{word} {name}' 和 attributes->>'word' = 'Hello'.
Jika Anda ingin nama rentang berbeda dari templat pesan, Anda dapat menggunakan parameter _span_name, misalnya:
word = 'Goodbye' if leaving else 'Hello'
logfire.info(word + ' {name}', name=name)
Ini mengatur span_name ke “Hello” dan 消息 ke “Hello world”。 Perhatikan bahwa parameter _span_name dimulai dengan garis bawah untuk membedakannya dari properti.
logfire.info('Hello {name}', name='world', _span_name='Hello')
senar-f¶
Sebagai gantinya:
logfire.info('Hello {name}', name=name)
Jauh lebih nyaman menggunakan S-String untuk menghindari pengulangan NAME tiga kali:
logfire.info(f'Hello {name}')
Berlawanan dengan bagian sebelumnya, ini ada di Python 3.11 +_efek_Bagus, karena Logfire akan menggunakan sihir khusus untuk span_name Setel ke “Hello {name}” Dan akan name Properti diatur ke name Nilai variabel, sehingga setara dengan cuplikan kode sebelumnya. Inilah yang perlu Anda ketahui:
-
Fitur ini diaktifkan secara default pada Python 3.11 +. Anda dapat menonaktifkannya menggunakan [
logfire.configure(inspect_arguments=False)][logfire.configure(inspect_arguments)]. Anda juga dapat mengaktifkannya dalam Python 3.9 dan 3.10, tetapi kemungkinan besar tidak berfungsi dengan baik. -
Dalam keadaan normal, parameter pemeriksaan harus selalu valid. Penting untuk dicatat bahwa kode sumber harus tersedia, jadi, misalnya, menyebarkan hanya file
.pycyang akan menyebabkannya gagal. -
Jika memeriksa parameter gagal, Anda akan menerima peringatan, dan parameter s-string akan digunakan sebagai template pemformatan. Ini berarti Anda akan mendapatkan nama rentang kardinalitas yang tinggi, seperti
“Hello Alice”, dan tidak ada atribut名称, tetapi informasinya tidak akan sepenuhnya hilang. -
Jika memeriksa parameter diaktifkan, parameter akan diperiksa apakah string f digunakan atau tidak. Jadi jika Anda menulis
logfire.info('Hello {name}', name=name)dan memeriksa parameter gagal, Anda masih akan mendapatkan peringatan. -
Nilai dalam s-string kembali dievaluasi dan diformat oleh Logfire. Ini berarti bahwa jika
get_username()(atau konversi string dari apa pun yang dikembalikan) mahal atau memiliki efek samping, Anda harus menghindari penggunaan kode sepertilogfire.info(f'Hello {get_username()}'). -
Argumen pertama harus menjadi string f yang sebenarnya.
logfire.info(f'Hello {name}')akan bekerja, tetapimessage = f'Hello {name}'; logfire.info(message)tidak, dan juga tidak akanlogfire.info('Hello ' + name). -
Parameter pemeriksaan di-cache sehingga pemeriksaan berulang dari string f yang sama memiliki kinerja minimal di atas kepala. Namun, mengurai file sumber besar menimbulkan overhead yang signifikan saat memeriksa parameter untuk pertama kalinya. Either way, menghindari overhead ini memerlukan menonaktifkan parameter pemeriksaan sepenuhnya, tidak hanya menghindari senar f.
abnormal¶
logfire.span Manajer konteks akan secara otomatis mencatat pengecualian apa pun yang menyebabkannya keluar, seperti:
import logfire
logfire.configure()
with logfire.span('This is a span'):
raise ValueError('This is an error')
Jika Anda mengklik Spans di Live View, akan ada tab "Exception Traceback" di panel kanan:
Pengecualian yang ditangkap tetapi tidak dibaca ulang tidak akan dicatat, misalnya:
with logfire.span('This is a span'):
try:
raise ValueError('This is an acceptable error not worth recording')
except ValueError:
pass
Jika Anda ingin mencatat pengecualian yang ditangani, gunakan span.record_exception Metode:
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)
Atau, jika Anda hanya ingin mencatat pengecualian tanpa membuat bentang untuk kasus normal, Anda dapat menggunakan logfire.exception :
try:
raise ValueError('This is an error')
except ValueError:
logfire.exception('Something went wrong')
logfire.exception(...) setara dengan logfire.error(..., _exc_info=True)。. Jika Anda ingin mencatat tracebacks tingkat non-error, Anda juga dapat menggunakan _exc_info dengan metode logging lainnya. Jika objek pengecualian bukan yang sedang diproses, Anda dapat mengatur _exc_info sebagai objek pengecualian. Jangan lupa garis bawah di depan!
Rentang fungsional yang nyaman dengan @logfire.instrument¶
Biasanya, Anda ingin membungkus seluruh fungsi dalam rentang. Alih-alih melakukan ini:
def my_function(x, y):
with logfire.span('my_function', x=x, y=y):
...
Anda dapat menggunakan dekorator @logfire.instrument :
Secara default, ini menambahkan parameter fungsi sebagai properti ke bentang. Untuk menonaktifkan fitur ini (misalnya, jika parameter adalah objek besar yang tidak layak untuk dikumpulkan), gunakan instrument(extract_args=False)。
Nama rentang default mirip dengan Calling module_name.my_function Anda dapat memberikan nama rentang alternatif sebagai argumen pertama untuk instrument Bahkan dapat diformat sebagai argumen untuk template, seperti:
@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
Perhatian
- '@ Logfire.instrumental' Dekorator harus diterapkan terlebih dahulu, yaitu, di bawah dekorator lainnya.
- Kode sumber suatu fungsi harus dapat diakses.
tingkat log¶
Metode untuk membuat berbagai tingkat log adalah sebagai berikut:
logfire.tracelogfire.debuglogfire.infologfire.notice(日志火灾通知)logfire.warnlogfire.errorlogfire.fatal
Secara default, log 跟踪 dan 调试 disembunyikan. Anda dapat mengubah pengaturan ini dengan mengklik menu drop-down "Default Level" di Live View:
Anda juga dapat menggunakan logfire.configure untuk mengatur level minimum untuk konsol logging, seperti:
import logfire
logfire.configure(console=logfire.ConsoleOptions(min_log_level='debug'))
Untuk mencatat pesan dengan tingkat variabel, Anda dapat menggunakan logfire.log, mis.logfire.log('info', 'This is an info log') setara dengan logfire.info('This is an info log')。
Secara default, bentang adalah level 信息. Anda dapat mengubah parameter ini dengan parameter _level, misalnya 使用 logfire.span('This is a debug span', _level='debug'):. Anda juga dapat mengubah level dengan span.set_level setelah rentang dimulai tetapi sebelum rentang selesai. LogfireSpan. set _ level], misalnya:
with logfire.span('Doing a thing') as span:
success = do_thing()
if not success:
span.set_level('error')
Dalam tampilan "real-time,"Rentang diwarnai sesuai dengan peringkat tertinggi dan keturunannyaMisalnya, kode berikut:
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')
Ini akan muncul seperti ini:
Di sini, tingkat bentang itu sendiri masih diatur ke informasi 默认, tetapi warnanya merah, bukan biru karena mengandung log kesalahan.
Jika bentang berakhir dengan pengecualian yang tidak tertangani, tingkat log bentang juga diatur ke 错误 selain mencatat jejak belakang seperti yang dijelaskan di atas. Ini tidak terjadi ketika menggunakan metode span.record_exception . Metode LogfireSpan.record _ exception].
Dalam database, level log disimpan sebagai angka dalam kolom 级别. Nilai-nilai ini didasarkan pada OpenTelemetry, mis.info adalah 9. Anda dapat menggunakan fungsi SQL level_num untuk mengubah nama level menjadi angka, mis.级别 > level_num('info') akan mencari semua catatan "pengecualian."
Anda juga dapat menggunakan fungsi level_name SQL untuk mengonversi angka ke nama, seperti SELECT level_name(level)、... untuk melihat level yang dapat dibaca manusia dalam tampilan "Jelajahi." Perhatikan bahwa kolom level diindeks, jadi penyaringan untuk level = level_num('error') valid, tetapi penyaringan untuk level_name(level) = 'error' tidak.
本文总阅读量次







