Як увімкнути ім'я вихідного файлу та номер рядка в Python


123

Чи можливо прикрасити / розширити стандартну систему журналу python, щоб при застосуванні методу ведення журналу він також записував файл та номер рядка, де він викликався, або, можливо, метод, який викликав його?

Відповіді:


227

Звичайно, перевіряйте формати в документах для реєстрації. Зокрема, змінні lineno та pathname.

% (ім'я шляху) s Повне ім'я вихідного файлу, куди було здійснено дзвінок реєстрації (якщо такий доступний).

% (ім'я файлу) s Частина імені файлу.

% (module) s Модуль (частина імені файлу).

% (funcName) s Назва функції, що містить виклик журналу.

% (lineno) d Номер вихідного рядка, куди був виданий дзвінок реєстрації (якщо він доступний).

Виглядає приблизно так:

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

1
І, так, потребує врахування верхнього / нижнього регістру у змінних.
Том Поль

1
Інакше називають "дуже погано реалізованою справою верблюдів".
Джон Спенсер

80

На додаток до дуже корисної відповіді Seb , ось зручний фрагмент коду, який демонструє використання реєстратора в розумному форматі:

#!/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")

Створює цей вихід:

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
Використовуйте це для отримання детальної інформації: formatter = logging.Formatter ('% (asctime) s,% (namename) -8s [% (filename) s:% (module) s:% (funcName) s:% (lineno) d] % (повідомлення) s ')
Гіріш Гупта

чи є спосіб змінити лише в одному місці вгорі коду, надруковано чи ні повідомлення журналу? Я хотів би два режими, один з великою кількістю відбитків, щоб побачити, що саме робить програма; і один, коли він досить стабільний, де не відображається вихід.
Марі. П.

3
@ Marie.P. не задавайте різних питань у коментарях. Хоча відповідь - це рівні реєстрації даних.
bugmenot123

4

Щоб розробити вищезазначене таким чином, що надсилає журнал налагодження до стандартного виходу:

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.")

Поміщення вищезазначеного у названий файл debug_logging_example.pyдає результат:

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

Тоді, якщо ви хочете вимкнути коментар із реєстрації, вимкніть root.setLevel(logging.DEBUG).

Для окремих файлів (наприклад, присвоєння класу) я вважав це набагато кращим способом зробити це на відміну від використання print()операторів. Там, де він дозволяє вимкнути вихід налагодження в одному місці перед тим, як надіслати його.


1

Для розробників, що використовують PyCharm або Eclipse pydev, наступне створить посилання на джерело оператора журналу у вихідному журналі консолі:

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")

Див. Гіперпосилання файлів вихідного файлу Pydev на консолі Eclipse для більш тривалої дискусії та історії.


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)

Відмінні від інших відповідей, він записує повний шлях файлу та ім'я функції, яка могла статися з помилкою. Це корисно, якщо у вас є проект з більш ніж одним модулем і декількома файлами з однаковим іменем, розподіленими в цих модулях.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.