共计 3731 个字符,预计需要花费 10 分钟才能阅读完成。
python & django logging 小结
[TOC]
python
基本
一次配置, 多处生效
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
>>>12/12/2010 11:46:36 AM is when this event was logged.
高级
- log_record
filters 会用到, 一个和 log 信息有关的对象
- loggers
接口, 被应用层 (我们开发者) 调用的
- handlers
写文件的, 挂在 logger 上
- filters
过滤文本的, 可以给 logger 用, 也可以给 handler 用
- formatters
定义 log 的格式, 给 handler 用
formatter
- fmt
message 的格式
- datefmt
时间格式
-
style
分隔符
- %(asctime)s – %(levelname)s – %(message)s
- &(asctime)s – &(levelname)s – &(message)s
例子
my_formater = logging.Formatter(fmt='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', style='%')
详细参数
源码里面有, 也可以看文档
filter
- 返回 True 或者 False
- False 将会被过滤
- 可以是一个类, 也可以是函数.
- 建议用类的形式, 因为带 name, 将来想 remove filter 更方便
-
Filter 类长这样
class Filter(object): def __init__(self, name=''): self.name = name self.nlen = len(name) def filter(self, record): return True
-
函数
def my_filter(record): return False
handler
- logging 模块提供了很多 handler.
-
logging.StreamHandler(sys.stdout)
和logging.RotatingFileHandler
常见 handler.addFilter()
handler.setFormatter()
my_handler.setLevel()
logger
- 定义 logger
logger = logging.getLogger('666')
- set level
logger.setLevel(logging.DEBUG)
- logger.addFilter()
- logger.addHandler()
- logger.info(‘message’)
例子
import logging
logger = logging.getLogger('spam_application')
logger.setLevel(logging.DEBUG)
my_handler = logging.StreamHandler()
my_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
my_handler.setFormatter(formatter)
logger.addHandler(my_handler)
logger.info('creating an instance of auxiliary_module.Auxiliary')
>>> 2019-07-03 16:02:30,952 - spam_application - INFO - creating an instance of auxiliary_module.Auxiliary
my_filter = lambda record: True
my_handler.addFilter(my_filter)
logger.info('creating an instance of auxiliary_module.Auxiliary')
>>> 2019-07-03 16:03:06,858 - spam_application - INFO - creating an instance of auxiliary_module.Auxiliary
my_filter = lambda record: False
my_handler.addFilter(my_filter)
logger.info('creating an instance of auxiliary_module.Auxiliary')
配置日志记录
三种方式
- 像上面用方法配置
-
dict
LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'standard': {'format': '[%(asctime)s][%(filename)s] - %(funcName)s[line:%(lineno)d] - [%(levelname)s]: %(message)s' }, }, 'filters': { }, 'handlers': { 'security_log': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(cf['log']['path'], 'security_log.log'), 'maxBytes': 1024 * 1024 * 10, 'backupCount': 10, 'formatter': 'standard', }, 'event_log': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(cf['log']['path'], 'event_log.log'), 'maxBytes': 1024 * 1024 * 10, 'backupCount': 10, 'formatter': 'standard', }, 'console': { 'level': 'ERROR', 'class': 'logging.StreamHandler', 'formatter': 'standard' }, }, 'loggers': { 'eventLog': {'handlers': ['event_log', 'console'], 'level': 'DEBUG', 'propagate': False }, 'security': {'handlers': ['security_log', 'console', 'security_db'], 'level': 'DEBUG', 'propagate': False }, 'system': {'handlers': ['system_log', 'console', 'system_db'], 'level': 'DEBUG', 'propagate': False }, } }
- file
略
django
django 默认使用 dict 方式.
logging_settings == settings.LOGGING
logging_config == logging.config.dictConfig
def configure_logging(logging_config, logging_settings):
if logging_config:
# First find the logging configuration function ...
logging_config_func = import_string(logging_config)
logging.config.dictConfig(DEFAULT_LOGGING)
# ... then invoke it with the logging settings
if logging_settings:
logging_config_func(logging_settings)
例子
理想情况下, 如果在 settings 中配置了 LOGGING, 直接使用即可.
# import the logging library
import logging
# Get an instance of a logger
logger = logging.getLogger(__name__)
def my_view(request, arg1, arg):
...
if bad_mojo:
# Log an error message
logger.error('Something went wrong!')
最佳实践
-
disable_existing_loggers
== Falsedjango 本身是有一个 logging 配置的, 这里有一个标志位去决定是否需要取消掉.
- 灵活运用
propagate
和logging.getLogger(__name__)
通过
.
找父亲.‘a.b’ 是‘a.b.c’的父亲.‘a.b’是 logger name
正文完