Файл журнала python не работает при использовании logging.basicConfig
У меня есть следующие строки кода, которые инициализируют ведение журнала.
Я прокомментирую один из них и оставлю другое.
Проблема, с которой я сталкиваюсь, заключается в том, что она предназначена для входа в файл, не регистрирующий файл. Вместо этого он записывается в консоль.
Пожалуйста, помогите.
Для входа в консоль:
logging.basicConfig(level=logging.INFO,
format='%(asctime)s [%(levelname)s] (%(threadName)-10s) %(message)s',)
для регистрации файлов
logging.basicConfig(filename='server-soap.1.log',level=logging.INFO,
format='%(asctime)s [%(levelname)s] (%(threadName)-10s) %(message)s')
Ответы
Ответ 1
Я выяснил, в чем проблема.
Это было в упорядочении импорта и определении журнала.
Эффект плохого упорядочения заключался в том, что библиотеки, которые я импортировал, прежде чем определять журнал, используя logging.basicConfig()
, определили ведение журнала. Поэтому это имело приоритет для журнала, который я пытался определить позже, используя logging.basicConfig()
Ниже, как мне нужно было его заказать:
import logging
## for file logging
logging.basicConfig(filename='server-soap.1.log',
level=logging.INFO,
format='%(asctime)s %(levelname)s %(threadName)-10s %(message)s',)
from pysimplesoap.server import SoapDispatcher, SOAPHandler
from BaseHTTPServer import HTTPServer
import time,random,datetime,pytz,sys,threading
from datetime import timedelta
#DB
import psycopg2, psycopg2.extras
from psycopg2.pool import ThreadedConnectionPool
#ESB Call
from suds import WebFault
from suds.client import Client
Но ошибочный порядок, который я изначально имел, заключался в следующем:
from pysimplesoap.server import SoapDispatcher, SOAPHandler
from BaseHTTPServer import HTTPServer
import logging
import time,random,datetime,pytz,sys,threading
from datetime import timedelta
#DB
import psycopg2, psycopg2.extras
from psycopg2.pool import ThreadedConnectionPool
#ESB Call
from suds import WebFault
from suds.client import Client
## for file logging
logging.basicConfig(filename='server-soap.1.log',
level=logging.INFO,
format='%(asctime)s %(levelname)s %(threadName)-10s %(message)s',)
Ответ 2
Из исходного кода регистрации я нашел потоки:
This function does nothing if the root logger already has handlers
configured. It is a convenience method intended for use by simple scripts
to do one-shot configuration of the logging package.
Итак, если какой-то модуль, который мы импортируем, вызвал метод basicConfig()
перед нами, наш вызов ничего не сделает.
Решение, которое я нашел, может работать, состоит в том, что вы можете перезагрузить ведение журнала перед собственным вызовом basicConfig()
, таким как
def init_logger(*, fn=None):
# !!! here
from imp import reload # python 2.x don't need to import reload, use it directly
reload(logging)
logging_params = {
'level': logging.INFO,
'format': '%(asctime)s__[%(levelname)s, %(module)s.%(funcName)s](%(name)s)__[L%(lineno)d] %(message)s',
}
if fn is not None:
logging_params['filename'] = fn
logging.basicConfig(**logging_params)
logging.error('init basic configure of logging success')
Ответ 3
Другое решение, которое сработало для меня, состоит в том, чтобы вместо того, чтобы отследить, какой модуль мог импортировать logging
или даже вызвать basicConfig
до меня, это просто снова вызвать setLevel
после basicConfig
.
import os
import logging
RUNTIME_DEBUG_LEVEL = os.environ.get('RUNTIME_DEBUG_LEVEL').upper()
LOGGING_KWARGS = {
'level': getattr(logging, RUNTIME_DEBUG_LEVEL)
}
logging.basicConfig(**LOGGING_KWARGS)
logging.setLevel(getattr(logging, RUNTIME_DEBUG_LEVEL))
Вроде сырая, кажется хакерская, исправила мою проблему, стоит поделиться.
Ответ 4
Если basicConfig()
не работает:
logger = logging.getLogger('Spam Logger')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)
# 'application' code
logger.debug('debug Spam message')
logging.debug('debug Spam message')
logger.info('info Ham message')
logger.warning('warn Eggs message')
logger.error('error Spam and Ham message')
logger.critical('critical Ham and Eggs message')
что дает мне следующий вывод:
2019-06-20 11:33:48,967 - Spam Logger - DEBUG - debug Spam message
2019-06-20 11:33:48,968 - Spam Logger - INFO - info Ham message
2019-06-20 11:33:48,968 - Spam Logger - WARNING - warn Eggs message
2019-06-20 11:33:48,968 - Spam Logger - ERROR - error Spam and Ham message
2019-06-20 11:33:48,968 - Spam Logger - CRITICAL - critical Ham and Eggs message
Для справки, Python Logging Cookbook заслуживает внимания.