Я хотів би використовувати dictConfig , але документація трохи абстрактна. Де я можу знайти конкретний, копіювальний + прикладний приклад словника, який використовується dictConfig
?
Я хотів би використовувати dictConfig , але документація трохи абстрактна. Де я можу знайти конкретний, копіювальний + прикладний приклад словника, який використовується dictConfig
?
Відповіді:
Як тут?
LOGGING_CONFIG = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default': {
'level': 'INFO',
'formatter': 'standard',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout', # Default is stderr
},
},
'loggers': {
'': { # root logger
'handlers': ['default'],
'level': 'WARNING',
'propagate': False
},
'my.packg': {
'handlers': ['default'],
'level': 'INFO',
'propagate': False
},
'__main__': { # if __name__ == '__main__'
'handlers': ['default'],
'level': 'DEBUG',
'propagate': False
},
}
}
Використання:
# Run once at startup:
logging.config.dictConfig(LOGGING_CONFIG)
# Include in each module:
log = logging.getLogger(__name__)
log.debug("Logging is configured.")
Якщо ви бачите занадто багато журналів із сторонніх пакетів, не забудьте запустити цю конфігурацію logging.config.dictConfig(LOGGING_CONFIG)
до того, як сторонні пакети будуть імпортовані.
Довідка: https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema
'disable_existing_loggers': False
як тоді ви, можливо, не налаштовуєте його цілою тканиною, але, можливо, повторно використовуєте щось, що вже є. Якщо ви встановите це, True
я, здається, не отримую жодного результату.
format
з formatters
?
Прийнята відповідь приємна! Але що робити, якщо можна почати з чогось менш складного? Модуль ведення журналів - це дуже потужна річ, а документація - трохи непосильна, особливо для початківців. Але для початку вам не потрібно налаштовувати формати та обробники. Ви можете додати його, коли з’ясуєте, що хочете.
Наприклад:
import logging.config
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'loggers': {
'': {
'level': 'INFO',
},
'another.module': {
'level': 'DEBUG',
},
}
}
logging.config.dictConfig(DEFAULT_LOGGING)
logging.info('Hello, log')
logging.info('Hello, log')
змусив мене натиснути речі. Плутанина в документації полягає в тому, що з dictConfig нам більше не потрібно виконувати getLogger
жодну з цих дій.
'': { 'level': 'INFO'...
і чому він не працює без нього (наприклад, при зміні порожнього значення на дійсне значення, наприкладstandard
getLogger()
якщо потрібно кілька реєстраторів з різними іменами. Кожен з цих реєстраторів успадковує конфігурацію від кореневого реєстратора.
getLogger
завжди необов’язковий. При використанні logging.info()
методу використовується кореневий реєстратор, тоді як у getLogger()
вас можуть бути різні реєстратори, з різними іменами та рівнями.
Приклад із обробкою потоків, обробкою файлів, обертовим обробником файлів та обробкою SMTP
from logging.config import dictConfig
LOGGING_CONFIG = {
'version': 1,
'loggers': {
'': { # root logger
'level': 'NOTSET',
'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler', 'critical_mail_handler'],
},
'my.package': {
'level': 'WARNING',
'propagate': False,
'handlers': ['info_rotating_file_handler', 'error_file_handler' ],
},
},
'handlers': {
'debug_console_handler': {
'level': 'DEBUG',
'formatter': 'info',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
},
'info_rotating_file_handler': {
'level': 'INFO',
'formatter': 'info',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'info.log',
'mode': 'a',
'maxBytes': 1048576,
'backupCount': 10
},
'error_file_handler': {
'level': 'WARNING',
'formatter': 'error',
'class': 'logging.FileHandler',
'filename': 'error.log',
'mode': 'a',
},
'critical_mail_handler': {
'level': 'CRITICAL',
'formatter': 'error',
'class': 'logging.handlers.SMTPHandler',
'mailhost' : 'localhost',
'fromaddr': 'monitoring@domain.com',
'toaddrs': ['dev@domain.com', 'qa@domain.com'],
'subject': 'Critical error with application name'
}
},
'formatters': {
'info': {
'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
},
'error': {
'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
},
},
}
dictConfig(LOGGING_CONFIG)
Нижче я знайшов конфігурацію за замовчуванням Django v1.11.15 , сподіваюся, що це допоможе
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'formatters': {
'django.server': {
'()': 'django.utils.log.ServerFormatter',
'format': '[%(server_time)s] %(message)s',
}
},
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
},
'django.server': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'django.server',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
},
'django.server': {
'handlers': ['django.server'],
'level': 'INFO',
'propagate': False,
},
}
}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import logging.handlers
from logging.config import dictConfig
logger = logging.getLogger(__name__)
DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': False,
}
def configure_logging(logfile_path):
"""
Initialize logging defaults for Project.
:param logfile_path: logfile used to the logfile
:type logfile_path: string
This function does:
- Assign INFO and DEBUG level to logger file handler and console handler
"""
dictConfig(DEFAULT_LOGGING)
default_formatter = logging.Formatter(
"[%(asctime)s] [%(levelname)s] [%(name)s] [%(funcName)s():%(lineno)s] [PID:%(process)d TID:%(thread)d] %(message)s",
"%d/%m/%Y %H:%M:%S")
file_handler = logging.handlers.RotatingFileHandler(logfile_path, maxBytes=10485760,backupCount=300, encoding='utf-8')
file_handler.setLevel(logging.INFO)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(default_formatter)
console_handler.setFormatter(default_formatter)
logging.root.setLevel(logging.DEBUG)
logging.root.addHandler(file_handler)
logging.root.addHandler(console_handler)
[31/10/2015 22:00:33] [DEBUG] [yourmodulename] [yourfunction_name():9] [PID:61314 TID:140735248744448] this is logger infomation from hello module
root
реєстратора: на верхньому рівні словника. Це описано в документах , має перевагу над тим,['loggers']['']
коли обидва присутні, але, на мій погляд,['loggers']['']
є більш логічним. Дивіться також обговорення тут