Ответ 1
На самом деле в Python это выглядит очень похоже. Есть разные способы сделать это. Я обычно создаю класс logger, который очень прост:
import os
import logging
import settings # alternativly from whereever import settings
class Logger(object):
def __init__(self, name):
name = name.replace('.log','')
logger = logging.getLogger('log_namespace.%s' % name) # log_namespace can be replaced with your namespace
logger.setLevel(logging.DEBUG)
if not logger.handlers:
file_name = os.path.join(settings.LOGGING_DIR, '%s.log' % name) # usually I keep the LOGGING_DIR defined in some global settings file
handler = logging.FileHandler(file_name)
formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s %(message)s')
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
self._logger = logger
def get(self):
return self._logger
Затем, если я хочу что-то записать в класс или модуль, я просто импортирую регистратор и создаю экземпляр. Передача имени класса создаст один файл для каждого класса. Регистратор может затем записывать сообщения в свой файл с помощью отладки, информации, ошибок и т. Д.:
from module_where_logger_is_defined import Logger
class MyCustomClass(object):
def __init__(self):
self.logger = Logger(self.__class__.__name__).get() # accessing the "private" variables for each class
def do_something():
...
self.logger.info('Hello')
def raise_error():
...
self.logger.error('some error message')
Обновленный ответ
За эти годы я немного изменил то, как я использую логи Python. Основываясь на передовой практике, я настраиваю ведение журнала всего приложения один раз в любом модуле, который загружается сначала во время запуска приложения, а затем использую отдельные средства ведения журнала в каждом файле. Пример:
# app.py (runs when application starts)
import logging
import os.path
def main():
logging_config = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default_handler': {
'class': 'logging.handlers.FileHandler',
'level': 'DEBUG',
'formatter': 'standard',
'filename': os.path.join('logs', 'application.log'),
'encoding': 'utf8'
},
},
'loggers': {
'': {
'handlers': ['default_handler'],
'level': 'DEBUG',
'propagate': False
}
}
}
logging.config.dictConfig(logging_config)
# start application ...
if __name__ == '__main__':
main()
# submodule.py (any application module used later in the application)
import logging
# define top level module logger
logger = logging.getLogger(__name__)
def do_something():
# application code ...
logger.info('Something happended')
# more code ...
try:
# something which might break
except SomeError:
logger.exception('Something broke')
# handle exception
# more code ...
Выше приведен рекомендуемый способ сделать это. Каждый модуль определяет свой собственный регистратор и может легко определить на основе атрибута __name__
какое сообщение было зарегистрировано в каком модуле, когда вы просматриваете журналы. Это удаляет шаблон из моего исходного ответа и вместо этого использует модуль logging.config
из стандартной библиотеки Python.