Python'da kaynak dosya adı ve satır numarası nasıl kaydedilir?


123

Python standart günlükleme sistemini dekore etmek / genişletmek mümkün mü, böylece bir günlükleme yöntemi çağrıldığında dosya ve çağrıldığı satır numarasını veya belki de onu çağıran yöntemi de günlüğe kaydeder?

Yanıtlar:


228

Elbette, günlük belgelerinde biçimlendiricileri kontrol edin . Özellikle lineno ve yol adı değişkenleri.

% (yol adı) s Günlük çağrısının yapıldığı kaynak dosyanın tam yol adı (varsa).

% (dosya adı) s yol adının dosya adı kısmı.

% (modül) s Modülü (dosya adının ad kısmı).

% (funcName) s Günlük çağrısını içeren işlevin adı.

% (lineno) d Günlük çağrısının yayınlandığı kaynak hat numarası (varsa).

Şuna benzer bir şeye benziyor:

formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')

1
Ve evet, değişkenlerdeki büyük / küçük harf karışıklığı dikkate alınmalıdır.
Tom Pohl

1
Aksi takdirde "çok kötü uygulanmış deve vakası" olarak anılır.
Jon Spencer

81

Üstüne üstlük Seb'in çok yararlı cevap , burada makul bir formatı ile logger kullanımını gösteren kullanışlı bir kod parçacığı geçerli:

#!/usr/bin/env python
import logging

logging.basicConfig(format='%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG)

logger = logging.getLogger(__name__)
logger.debug("This is a debug log")
logger.info("This is an info log")
logger.critical("This is critical")
logger.error("An error occurred")

Bu çıktıyı üretir:

2017-06-06:17:07:02,158 DEBUG    [log.py:11] This is a debug log
2017-06-06:17:07:02,158 INFO     [log.py:12] This is an info log
2017-06-06:17:07:02,158 CRITICAL [log.py:13] This is critical
2017-06-06:17:07:02,158 ERROR    [log.py:14] An error occurred

5
Daha fazla ayrıntı için bunu kullanın: formatter = logging.Formatter ('% (asctime) s,% (levelname) -8s [% (dosya adı) s:% (module) s:% (funcName) s:% (lineno) d] % (message) s ')
Girish Gupta

günlüğe kaydetme mesajlarının yazdırılıp yazdırılmamasına bakmaksızın kodun üstündeki tek bir yerde değişiklik yapmanın bir yolu var mı? Programın tam olarak ne yaptığını görmek için çok sayıda baskı içeren iki mod istiyorum; ve biri, yeterince kararlı olduğunda, hiçbir çıktının gösterilmediği durumlarda.
Marie. S.

3
Marie.P @. yorumlarda farklı sorular sormayın. Cevap yine de seviyeleri kaydetmektir.
bugmenot123

4

Yukarıdakileri, standart çıkışa hata ayıklama günlüğü gönderecek şekilde geliştirmek için:

import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
formatter = logging.Formatter(FORMAT)
ch.setFormatter(formatter)
root.addHandler(ch)

logging.debug("I am sent to standard out.")

Yukarıdakileri adlı bir dosyaya koymak debug_logging_example.pyçıktıyı üretir:

[debug_logging_example.py:14 -             <module>() ] I am sent to standard out.

Ardından, yorum oturumunu kapatmayı kapatmak istiyorsanız root.setLevel(logging.DEBUG).

Tek dosyalar için (örneğin, sınıf atamaları), print()ifadeleri kullanmaktan çok bunu yapmanın çok daha iyi bir yolunu buldum . Göndermeden önce hata ayıklama çıktısını tek bir yerde kapatmanıza izin verdiği yer.


1

PyCharm veya Eclipse pydev kullanan geliştiriciler için aşağıdakiler, konsol günlük çıktısındaki günlük ifadesinin kaynağına bir bağlantı oluşturacaktır:

import logging, sys, os
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(message)s | \'%(name)s:%(lineno)s\'')
log = logging.getLogger(os.path.basename(__file__))


log.debug("hello logging linked to source")

Daha uzun tartışma ve geçmiş için Eclipse konsolundaki Pydev kaynak dosyası köprülerine bakın .


0
# your imports above ...


logging.basicConfig(
    format='%(asctime)s,%(msecs)d %(levelname)-8s [%(pathname)s:%(lineno)d in 
    function %(funcName)s] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.DEBUG
)

logger = logging.getLogger(__name__)

# your classes and methods below ...
# An naive Sample of usage:
try:
    logger.info('Sample of info log')
    # your code here
except Exception as e:
    logger.error(e)

Diğer yanıtlardan farklı olarak, bu dosya tam yolunu ve bir hata oluşmuş olabilecek işlev adını günlüğe kaydedecektir. Birden fazla modül içeren bir projeniz ve bu modüllerde dağıtılmış aynı ada sahip birkaç dosyanız varsa bu yararlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.