Python регистратор не выводится в файл - PullRequest
0 голосов
/ 08 марта 2020

Возможно, что-то не так с моим файлом logging.ini. Мой код python работает для другого файла, но не для этого.

Python Запустите этот main.py

# main.py
import logging
from logging.config import fileConfig

import my_module

# load the logging configuration
fileConfig('logging.ini')

my_module.foo()
bar = my_module.Bar()
bar.bar()

Другой файл с настроенными методами

# my_module.py
import logging

def foo():
    logger = logging.getLogger(__name__)
    logger.info('Hi, foo')

class Bar(object):
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def bar(self):
        self.logger.info('Hi, bar')
        self.logger.debug('Testing')

Я попробовал этот logging.ini файл, и он работает правильно

keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

Затем я хотел бы сохранить некоторые журналы в файл и распечатать некоторые на консоли, поэтому здесь я попробовал другой logging.ini файл

[loggers]
keys=root,sLogger

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=consoleFormatter,fileFormatter


[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_sLogger]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=sLogger
propagate=0


[handler_consoleHandler]
class=StreamHandler
level=WARNING
formatter=consoleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=fileFormatter
args=('display_info.log','w')


[formatter_consoleFormatter]
format=%(levelname)s - %(message)s
datefmt=

[formatter_fileFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

Это было выполнено так

python main.py

На этот раз программа работает нормально, без ошибок. Но нет логина display_info.log. Может кто-нибудь помочь мне в этой проблеме? Спасибо!

1 Ответ

1 голос
/ 08 марта 2020

Это потому, что вы пытаетесь получить регистратор через __name__, который не "__main__", а "my_module". У вас нет ключа для этого, так что регистратор не настроен. Измените ваш getLogger, чтобы он вызывал правильное имя, sLogger, и он выбирает правильное:

import logging

def foo():
    # here
    logger = logging.getLogger("sLogger")
    logger.info('Hi, foo')

class Bar(object):
    def __init__(self, logger=None):
        # or here
        self.logger = logger or logging.getLogger("sLogger")

    def bar(self):
        self.logger.info('Hi, bar')
        self.logger.debug('Testing')

. Вызывает регистратор по названию, которое вы ему дали (key, на которое он указывает в INI-файл). И теперь ваш display_info.log файл должен выглядеть следующим образом:

# display_info.log

2020-03-07 22:14:45,351 - sLogger - INFO - Hi, foo
2020-03-07 22:14:45,351 - sLogger - INFO - Hi, bar
2020-03-07 22:14:45,351 - sLogger - DEBUG - Testing

Причина в том, что каждому регистратору присваивается имя, поэтому, когда вы вызываете logging.getLogger(<some_name>), этот регистратор буквально называется именем, которое вы ему дали. Затем, когда вы вызываете этот логгер из других модулей, он уже доступен.

Атрибут __name__ - это не имя регистратора, а имя сценария, который вы запускаете. Когда вы звоните python somescript.py, somescript.__name__ - это __main__, потому что это основной вызываемый модуль. Но при импорте __name__ - это имя модуля, потому что он не выполняется. Таким образом, в действительности все происходило следующим образом:

import logging

''' these two are created when you load the .ini file '''
# this is aliased as root
main_logger = logging.getLogger("__main__")
~ some logging configuration ~

# the other logger you configured
sLogger = logging.getLogger("sLogger")
~ some logging configuration ~
''' and are in global scope in the main script '''

# and the logger you were getting by mistake
logger = logging.getLogger("my_module")


# when you really meant to do this
# which is the same thing as sLogger
logger = logging.getLogger("sLogger")

В качестве альтернативы, если вы хотите сохранить синтаксис __name__ и иметь логгеры для модуля c, то вы просто добавляете имена Модули в качестве квалификационных имен:

# logging.ini
~ snip ~

[logger_sLogger]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=my_module
propagate=0

~ rest of file ~

И вы можете сохранить logging.getLogger(__name__) вызов:

# my_module.py
import logging

def foo():
    logger = logging.getLogger(__name__)
    logger.info('Hi, foo')

class Bar(object):
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def bar(self):
        self.logger.info('Hi, bar')
        self.logger.debug('Testing')
...