Saya ingin memiliki loglevel TRACE (5) untuk aplikasi saya, karena menurut saya itu tidak debug()
cukup. Selain log(5, msg)
itu bukan yang saya inginkan. Bagaimana cara menambahkan loglevel khusus ke logger Python?
Saya punya mylogger.py
dengan konten berikut:
import logging
@property
def log(obj):
myLogger = logging.getLogger(obj.__class__.__name__)
return myLogger
Dalam kode saya, saya menggunakannya dengan cara berikut:
class ExampleClass(object):
from mylogger import log
def __init__(self):
'''The constructor with the logger'''
self.log.debug("Init runs")
Sekarang saya ingin menelepon self.log.trace("foo bar")
Terima kasih sebelumnya atas bantuan Anda.
Sunting (8 Des 2016): Saya mengubah jawaban yang diterima menjadi pfa yang, IMHO, solusi luar biasa berdasarkan proposal yang sangat bagus dari Eric S.
sumber
logging.DEBUG_LEVEL_NUM = 9
sehingga Anda dapat mengakses tingkat debug di mana pun Anda mengimpor logger dalam kode Anda?DEBUG_LEVEL_NUM = 9
Anda harus mendefinisikanlogging.DEBUG_LEVEL_NUM = 9
. Dengan cara ini Anda akan dapat menggunakanlog_instance.setLevel(logging.DEBUG_LEVEL_NUM)
cara yang sama seperti Anda menggunakan pengetahuan yang benarlogging.DEBUG
ataulogging.INFO
logging.DEBUGV = DEBUG_LEVELV_NUM
danlogging.__all__ += ['DEBUGV']
Yang kedua tidak terlalu penting tetapi yang pertama diperlukan jika Anda memiliki kode yang secara dinamis menyesuaikan tingkat pencatatan dan Anda ingin dapat melakukan sesuatu sepertiif verbose: logger.setLevel(logging.DEBUGV)
`Saya mengambil jawaban "hindari melihat lambda" dan harus memodifikasi di mana log_at_my_log_level ditambahkan. Saya juga melihat masalah yang dilakukan Paul, "Menurut saya ini tidak berhasil. Apakah Anda tidak perlu logger sebagai argumen pertama di log_at_my_log_level?" Ini berhasil untuk saya
sumber
__init__.py
dan berbahagialah: DTypeError: not all arguments converted during string formatting
tetapi berfungsi dengan baik dengan *. (Python 3.4.3). Apakah ini masalah versi python, atau sesuatu yang saya lewatkan?AttributeError: module 'logging' has no attribute 'debugv'
Menggabungkan semua jawaban yang ada dengan sekumpulan pengalaman penggunaan, saya pikir saya telah membuat daftar semua hal yang perlu dilakukan untuk memastikan penggunaan level baru yang sepenuhnya mulus. Langkah-langkah di bawah ini mengasumsikan bahwa Anda menambahkan level baru
TRACE
dengan nilailogging.DEBUG - 5 == 5
:logging.addLevelName(logging.DEBUG - 5, 'TRACE')
perlu dipanggil untuk mendapatkan level baru yang terdaftar secara internal sehingga bisa direferensikan dengan nama.logging
dirinya sendiri untuk konsistensi:logging.TRACE = logging.DEBUG - 5
.trace
perlu ditambahkan kelogging
modul. Ini harus bersikap sepertidebug
,info
, dlltrace
perlu ditambahkan ke kelas logger yang saat ini dikonfigurasi. Karena ini tidak dijamin 100%logging.Logger
, gunakanlogging.getLoggerClass()
saja.Semua langkah diilustrasikan dalam metode di bawah ini:
sumber
Oldest
, dan Anda akan menghargai bahwa ini adalah jawaban terbaik dari semuanya!args
dalamlogForLevel
implementasi disengaja / dibutuhkan?Pertanyaan ini agak lama, tetapi saya hanya membahas topik yang sama dan menemukan cara yang mirip dengan yang telah disebutkan yang tampak sedikit lebih bersih bagi saya. Ini telah diuji pada 3.4, jadi saya tidak yakin apakah metode yang digunakan ada di versi yang lebih lama:
sumber
get
dansetLoggerClass
tepatnya lakukan dan mengapa mereka dibutuhkan?TRACE
level ke pustaka logging default. +1Siapa yang memulai praktik buruk menggunakan metode internal (
self._log
) dan mengapa setiap jawaban didasarkan pada itu ?! Solusi pythonic akan digunakanself.log
sehingga Anda tidak perlu mengacaukan hal-hal internal apa pun:sumber
Saya merasa lebih mudah untuk membuat atribut baru untuk objek logger yang melewati fungsi log (). Saya pikir modul logger menyediakan addLevelName () dan log () karena alasan ini. Jadi tidak diperlukan subclass atau metode baru.
sekarang
harus bekerja seperti yang diharapkan.
sumber
_log
, bukanlog
.Meskipun kami sudah memiliki banyak jawaban yang benar, berikut ini menurut saya lebih pythonic:
Jika Anda ingin menggunakan
mypy
kode Anda, disarankan untuk menambahkan# type: ignore
untuk menyembunyikan peringatan dari menambahkan atribut.sumber
logging.trace = partial(logging.log, logging.TRACE) # type: ignore
?Saya pikir Anda harus membuat subclass
Logger
kelas dan menambahkan metodetrace
yang pada dasarnya memanggilLogger.log
dengan level yang lebih rendah dariDEBUG
. Saya belum mencoba ini tetapi ini yang ditunjukkan oleh dokumen .sumber
logging.getLogger
untuk mengembalikan subclass Anda, bukan kelas bawaan.setLoggerClass(MyClass)
dan kemudian menelepongetLogger()
seperti biasa ...Kiat untuk membuat logger ubahsuaian:
_log
, gunakanlog
(Anda tidak perlu memeriksaisEnabledFor
)getLogger
, jadi Anda perlu mengatur kelas melaluisetLoggerClass
__init__
untuk logger, kelas jika Anda tidak menyimpan apapunSaat memanggil logger ini gunakan
setLoggerClass(MyLogger)
untuk menjadikan ini logger default darigetLogger
Anda akan perlu
setFormatter
,setHandler
dansetLevel(TRACE)
padahandler
dan padalog
dirinya sendiri untuk benar-benar se jejak ini tingkat rendahsumber
Ini berhasil untuk saya:
Masalah lambda / funcName telah diperbaiki dengan logger._log seperti yang ditunjukkan @marqueed. Saya pikir menggunakan lambda terlihat sedikit lebih bersih, tetapi kekurangannya adalah tidak dapat mengambil argumen kata kunci. Aku sendiri belum pernah menggunakannya, jadi bukan masalah besar.
sumber
Dalam pengalaman saya, ini adalah solusi lengkap dari masalah op ... untuk menghindari melihat "lambda" sebagai fungsi di mana pesan tersebut dipancarkan, masuk lebih dalam:
Saya belum pernah mencoba bekerja dengan kelas logger mandiri, tapi menurut saya ide dasarnya sama (gunakan _log).
sumber
logger
sebagai argumen pertamalog_at_my_log_level
?Penambahan contoh Mad Physicists untuk mendapatkan nama file dan nomor baris yang benar:
sumber
Berdasarkan jawaban yang disematkan, saya menulis sedikit metode yang secara otomatis membuat tingkat logging baru
config mungkin seperti itu:
sumber
Sebagai alternatif untuk menambahkan metode tambahan ke kelas Logger, saya akan merekomendasikan menggunakan
Logger.log(level, msg)
metode tersebut.sumber
Saya bingung; dengan python 3.5, setidaknya, ini berfungsi:
keluaran:
sumber
logger.trace('hi')
yang saya yakini sebagai tujuan utamaJika ada yang menginginkan cara otomatis untuk menambahkan level logging baru ke modul logging (atau salinannya) secara dinamis, saya telah membuat fungsi ini, memperluas jawaban @ pfa:
sumber
setattr
...