Регистрация журнала Python только из script
Я использую модуль протоколирования Python в простой script моей со следующей настройкой на данный момент.
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger(__name__)
Моя проблема в том, что это также захватывает сторонние модули, такие как запросы и выходные данные() из них. Есть ли способ подавить эти сообщения или сообщить модулю регистрации только для регистрации сообщений из моего собственного script?
Ответы
Ответ 1
Использование названных журналов в ваших модулях:
import logging
logger = logging.getLogger(__name__)
logger.info("my info")
logger.error("my error")
вы можете установить уровень журнала для всех других регистраторов на ошибку и для отладки ваших регистраторов:
import logging
logging.basicConfig(level=logging.ERROR)
logging.getLogger(my_module.__name__).setLevel(logging.DEBUG)
Ответ 2
Вышеприведенный ответ не совсем правильный - он просто установит планку выше для сообщений из других модулей, которые будут показаны.
Очень быстрый подход заключается в использовании этого фрагмента кода:
import logging.config
logging.config.dictConfig({
'version': 1,
'disable_existing_loggers': True,
})
Вы должны установить это после импорта всех модулей - он отключит все регистраторы, которые были созданы до этого момента. Это будет работать большую часть времени, но некоторые модули создают свой журнал, когда вы делаете экземпляр класса, например (что произойдет позже в вашем коде).
Когда вы настраиваете регистраторы в соответствии с основным руководством по python, они говорят вам использовать logging.basicConfig(...)
. Это проблема, так как это приведет к тому, что обработчик (ака, где будет маршрутизироваться журнал) будет logging.lastResort
, который является stderr, начиная с Python 3.2 для всех регистраторов во всем мире. Это означает, что теперь вы включили полную регистрацию для всех модулей.
Таким образом, лучший подход заключается в создании другого регистратора только для ваших модулей и придания ему некоторых обработчиков вместо использования basicConfig()
.
Есть два способа сделать это:
1) Вся функция:
import logging
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
formatter = logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s",
datefmt="%Y-%m-%d - %H:%M:%S")
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
fh = logging.FileHandler("mylog.log", "w")
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(ch)
log.addHandler(fh)
Это даст вам регистратор log
, который затем можно использовать как log.error("Error found")
. Он будет записывать в новый файл с именем mylog.log и также будет записывать так sys.stdout. Вы можете изменить это, как вам нравится, конечно.
2) Используя dict:
import logging
import logging.config
DEFAULT_LOGGING = {
'version': 1,
'formatters': {
'standard': {
'format': '%(asctime)s %(levelname)s: %(message)s',
'datefmt': '%Y-%m-%d - %H:%M:%S' },
},
'handlers': {
'console': {'class': 'logging.StreamHandler',
'formatter': "standard",
'level': 'DEBUG',
'stream': sys.stdout},
'file': {'class': 'logging.FileHandler',
'formatter': "standard",
'level': 'DEBUG',
'filename': 'live_detector.log','mode': 'w'}
},
'loggers': {
__name__: {'level': 'INFO',
'handlers': ['console', 'file'],
'propagate': False },
}
}
logging.config.dictConfig(DEFAULT_LOGGING)
log = logging.getLogger(__name__)
Это даст тот же результат, что и выше, немного дольше, но, возможно, легче читать. Это также автоматически установит 'disable_existing_loggers': True
. Если вы этого не хотите, вы должны добавить его и установить для него значение False.