Я хотів би використовувати 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']['']є більш логічним. Дивіться також обговорення тут