logging 模块应用模板
模板一
模板代码(log_util.py)
"""
#配置日志文件
"""
# 日志文件不存在,创建
if not os.path.isdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs')):
os.mkdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs'))
class Logger():
standard_format = '[%(asctime)s:%(levelname)s:task_id:%(name)s in %(filename)s:%(pathname)s:%(lineno)d]' \
'>>>:%(message)s'
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
error_format = '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
# log文件的全路径
logfile_dir = os.path.dirname(os.path.abspath(__file__)) # logs文件的目录
logfile_path = os.path.join(logfile_dir, 'logs', 'info.log')
error_logfile_path = os.path.join(logfile_dir, 'logs', 'error.log')
logging_dic = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
'error': {
'format': error_format
},
},
'filters': {},
# 日志的执行者
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024 * 1024 * 20, # 日志大小 5M
'backupCount': 15,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
# 只保存出现错误及以上的日志
'error': {
'level': 'ERROR',
'class': 'logging.FileHandler', # 保存到文件,没有分割文件的功能
'formatter': 'error',
'filename': error_logfile_path,
'encoding': 'utf-8',
},
},
# 日志的生产者
'loggers': {
# logging.getLogger(__name__)拿到的logger配置,
# 空的指定对象,在不指定的情况下,默认使用该对象中的handlers
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'INFO', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
'propagate': False, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
},
'error': {
'handlers': ['error', ],
'level': 'DEBUG',
'propagate': False,
},
},
}
#调用日志对象
@classmethod
def load_logger(cls,logger_name=None): #传入一个日志的类型,名称为loggers中的,如果没有默认''
logging.config.dictConfig(cls.logging_dic) # 导入上面定义的logging配置
logger = logging.getLogger(logger_name) # 生成一个log实例变量对应日志配置中的%(name)s
return logger #返回一个日志对象,可以直接调用
模板二
模板代码(log_util.py)
import os
import logging
import logging.config
USER_PATH = '' # 日志文件夹
BASIC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)))
if USER_PATH:
if not os.path.isdir(USER_PATH):
raise Exception('USER_PATH 目录不存在')
if not os.path.isdir(os.path.join(BASIC_PATH, 'logs')):
os.makedirs(os.path.join(BASIC_PATH, 'logs'))
PATH = os.path.join(BASIC_PATH, 'logs')
else:
if not os.path.isdir(os.path.join(USER_PATH, 'logs')):
os.makedirs(os.path.join(USER_PATH, 'logs'))
PATH = os.path.join(USER_PATH, 'logs')
class Logger:
simple = '[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d]>>>: %(message)s'
standard = '%(levelname)s [%(asctime)s][%(pathname)s:%(lineno)d][%(process)d][%(processName)s][%(thread)d][%(threadName)s]>>>: %(message)s'
default_log_path = '{}/{}'.format(PATH, 'log.log')
app_log_path = '{}/{}'.format(PATH, 'app.log')
config_dic = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': simple,
'datefmt': '%H:%M:%S'
},
'standard': {
'format': standard,
'datefmt': '%Y-%m-%d %H:%M:%S'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'default_file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'standard',
'filename': default_log_path,
'maxBytes': 1024 * 1024 * 20,
'backupCount': 1,
'encoding': 'utf-8',
},
'app_file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'standard',
'filename': app_log_path,
'maxBytes': 1024 * 1024 * 20,
'backupCount': 1,
'encoding': 'utf-8',
}
},
'loggers': {
'default': {
'handlers': ['console', 'default_file'],
'level': 'INFO',
'propagate': False,
},
'app': {
'handlers': ['console', 'app_file'],
'level': 'INFO',
'propagate': False,
}
},
}
@classmethod
def load_logger(cls, logger_name='default'):
logging.config.dictConfig(cls.config_dic)
return logging.getLogger(logger_name)
logger = Logger.load_logger()
logger_app = Logger.load_logger('app')
"""
配置 DIR_PATH 参数
from ... import logger,logger_app
logger.info('hello')
logger_app.info('hello app')
"""
模板三
日志处理程序
日志输出格式表
变量 |
格式 |
变量描述 |
asctime |
%(asctime)s |
将日志的时间构造成可读的形式,默认情况下是精确到毫秒,如 2018-10-13 23:24:57,832,可以额外指定 datefmt 参数来指定该变量的格式 |
name |
%(name)s |
日志对象的名称 |
filename |
%(filename)s |
不包含路径的文件名 |
pathname |
%(pathname)s |
包含路径的文件名 |
funcName |
%(funcName)s |
日志记录所在的函数名 |
levelname |
%(levelname)s |
日志的级别名称 |
message |
%(message)s |
具体的日志信息 |
lineno |
%(lineno)d |
日志记录所在的行号 |
pathname |
%(pathname)s |
完整路径 |
process |
%(process)d |
当前进程ID |
processName |
%(processName)s |
当前进程名称 |
thread |
%(thread)d |
当前线程ID |
threadName |
%(threadName)s |
当前线程名称 |
日志基础模式
-
基础模式构成代码
import logging
# 创建基础程序
logging.basicConfig(
filename='log.log',
filemode='w',
format='%(levelname)s--%(asctime)s -- %(message)s ',
datefmt='%m/%d/%Y %I:%M:%S %p',
style='%',
level=logging.DEBUG,
)
logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.exception('exception') # 仅从异常处理程序调用此方法。
# 创建高级日志记录器
# 格式化程序
formatter = logging.Formatter(fmt='%(levelname)s == %(asctime)s == %(message)s == %(filename)s == %(pathname)s',datefmt='%m/%d/%Y %I:%M:%S %p', style='%')
# 处理程序
stream_handler = logging.StreamHandler() # 标准系统输出
stream_handler.setLevel(logging.DEBUG)
stream_handler.setFormatter(formatter)
file_handler = logging.FileHandler('log.log', mode='a', encoding='utf-8', delay=False) # 文件输出
file_handler.setLevel(logging.DEBUG) # 设置输出等级
file_handler.setFormatter(formatter) # 设置输出格式
# 创建记录器
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG) # 设置日志过滤等级
logger.addHandler(stream_handler) # 添加流处理程序
logger.addHandler(file_handler) # 添加文件处理程序
logger.debug('DEBUG')
logger.info('INFO')
logger.warning('WARNING')
logger.error('ERROR')
logger.critical('CRITICAL')
logger.exception('EXCEPTION') # 仅从异常处理程序调用此方法。
-
控制台输出(高级)
ERROR [01/04/2023 10:57:07 AM]: msg=error -test.py
CRITICAL [01/04/2023 10:57:07 AM]: msg=critical -test.py
ERROR [01/04/2023 10:57:07 AM]: msg=exception -test.py
NoneType: None
-
文件输出(高级)
DEBUG [01/04/2023 10:57:07 AM]: msg=debug -test.py
INFO [01/04/2023 10:57:07 AM]: msg=info -test.py
WARNING [01/04/2023 10:57:07 AM]: msg=warning -test.py
ERROR [01/04/2023 10:57:07 AM]: msg=error -test.py
CRITICAL [01/04/2023 10:57:07 AM]: msg=critical -test.py
ERROR [01/04/2023 10:57:07 AM]: msg=exception -test.py
NoneType: None
日志特别说明
- 等级说明
- logger.setLevel(),对象可以设置等级 ,handler.setLevel()也可以设置等级
- logger 中设置的等级指的是,记录器传递给处理程序的日志等级,而hander 中的日志等级是,拿到记录器给的日志再根据等级判断哪些日志输出来。
- 记录器说明
- 一个记录器可以挂载 多个处理器,logger可以对应多个handler
- 日志记录程序说明
- 日志记录程序,可以多个记录器配置。
- 记录器是单例模式构成。
logging 日志对象加载配置
方式一: dict模式
查看代码
import logging
import logging.config
config = {
'version': 1,
'formatters': {
'simple': {
'format': '[%(asctime)s][%(name)s][%(levelname)s] - %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
'style': '%'
},
# 其他格式处理器
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'simple'
},
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'log.log',
'level': 'DEBUG',
'formatter': 'simple',
'maxBytes': 1024 * 1024,
'backupCount': 1,
},
# 其他处理程序
},
'loggers': {
'StreamLogger': {
'handlers': ['console'],
'level': 'DEBUG',
},
'FileLogger': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
# 其他记录器
}
}
logging.config.dictConfig(config)
logger = logging.getLogger("FileLogger")
logger.debug(' debug ')
logger.info('info ')
logger.warning(' warning ')
logger.error(' error ')
logger.critical('critical ')
方式二:yaml模式
查看代码
import logging
import logging.config
import yaml
with open('log.yaml', 'r') as f:
config = yaml.safe_load(f.read())
logging.config.dictConfig(config)
logger = logging.getLogger("simpleExample")
logger.debug(' debug ')
logger.info('info ')
logger.warning(' warning ')
logger.error(' error ')
logger.critical('123')
yaml 配置文件
查看代码
# 文件名为 log.yaml
version: 1
formatters:
simple:
format: '[%(asctime)s][%(name)s][%(levelname)s] - %(message)s'
datefmt: '%Y-%m-%d %H:%M:%S'
style: '%'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
file:
class: logging.handlers.RotatingFileHandler
filename: log.log
level: DEBUG
formatter: simple
maxBytes: 1048576
backupCount: 1
loggers:
simpleExample:
level: DEBUG
handlers: [ console,file ]
propagate: no
root:
level: DEBUG
handlers: [ console ]
参考文献