Путаница Python Logger - PullRequest
       25

Путаница Python Logger

1 голос
/ 24 марта 2019

Я пытаюсь понять регистрацию Python, и у меня есть это:

Main.py :

import logging
from Foo import Foo

logging.basicConfig(level=logging.DEBUG)

fh_formatter = logging.Formatter('[%(asctime)s : %(levelname)s : %(name)s] : %(message)s')
file_handler = logging.FileHandler('logger.log', mode='w')
file_handler.setFormatter(fh_formatter)
file_handler.setLevel(logging.DEBUG)

sh_formatter = logging.Formatter('%(message)s')
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(sh_formatter)
stream_handler.setLevel(logging.DEBUG)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)

logger.info('Running main')
Foo().print_foo()

Foo.py

import logging
from Bar import Bar

logger = logging.getLogger(__name__)

class Foo():

    def print_foo(self):
        Bar().print_bar()
        logger.info('Inside Foo.foo')

Bar.py:

import logging

logger = logging.getLogger(__name__)

class Bar():

    def print_bar(self):
        logger.info('Inside Bar.bar')

Когда я бегукод, на консоли я вижу этот вывод :

Running main
INFO:__main__:Running main
INFO:Bar:Inside Bar.bar
INFO:Foo:Inside Foo.foo

Но когда я проверяю logger.log, я вижу только одну строку

[2019-03-23 18:46:01,276 : INFO : __main__] : Running main

Какя могу сделать так, чтобы я видел все линии в обоих местах?Нужно ли устанавливать обработчик файла и обработчик потока для каждого регистратора в каждом файле?Если у меня есть проект Python, и я хочу иметь один файл журнала вместе с выводом на консоль, каков правильный способ сделать это?

1 Ответ

1 голос
/ 24 марта 2019

Проблема в этой строке в Foo и Bar:

logger = logging.getLogger(__name__)

Обратите внимание, что вы сбрасываете обработчик журналирования только в Main.py с именем регистратора __name__, которое разрешено до "__main__", как вы можете видеть в выходных данных. Когда вы получаете регистратор от Foo.py, ваше имя регистратора будет "Foo", и, следовательно, все, что вы установили на "__main__", не будет применено.

Что вы хотите сделать: Измените часть __name__. Например, ваше приложение называется fubar, тогда вы делаете это в Main.py:

logger = logging.getLogger("fubar")

и в Foo.py, как подмодуль в приложении, сделайте это:

logger = logging.getLogger("fubar.Foo")

Или вы можете даже использовать то же имя, если хотите. Таким образом, обработчик, назначенный на более высоком уровне, перейдет на подуровни.

...