logging 模块应用模板
模板一
模板代码(log_util.py)
import os
import logging
import logging.config
# 日志文件不存在,创建
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:
simple_format = '[%(asctime)s][%(levelname)s][%(filename)s:%(lineno)d]>>>: %(message)s'
standard_format = '%(levelname)s [%(asctime)s][%(pathname)s:%(lineno)d][%(process)d][%(processName)s][%(thread)d][%(threadName)s]>>>: %(message)s'
# log文件的全路径
logfile_dir = os.path.dirname(os.path.abspath(__file__)) # logs文件的目录
logfile_path = os.path.join(logfile_dir, 'logs', 'log.log')
logging_dic = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': simple_format,
'datefmt': '%H:%M:%S'
},
'standard': {
'format': standard_format,
'datefmt': '%Y-%m-%d %H:%M:%S'
}
},
# 日志的执行者
'handlers': {
# 打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
# 打印到文件的日志,收集info及以上的日志
'file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024 * 1024 * 20, # 日志大小 5M
'backupCount': 1,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
}
},
# 日志的生产者
'loggers': {
# logging.getLogger(__name__)拿到的logger配置,
# 空的指定对象,在不指定的情况下,默认使用该对象中的handlers
'basic': {
'handlers': ['file', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'INFO', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
'propagate': False, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
}
},
}
# 调用日志对象
@classmethod
def load_logger(cls, logger_name='basic'): # 传入一个日志的类型,名称为loggers中的,如果没有默认'basic'
logging.config.dictConfig(cls.logging_dic) # 导入上面定义的logging配置
logger = logging.getLogger(logger_name) # 生成一个log实例变量对应日志配置中的%(name)s
return logger # 返回一个日志对象,可以直接调用
模板二
模板三
日志处理程序
- 可用的处理程序类
StreamHandler 实例将消息发送到流(类似于对象的文件)。 FileHandler 实例将消息发送到磁盘文件。 BaseRotatingHandler 是在某一点旋转日志文件的处理程序的基类。它并不打算直接实例化。相反,使用 RotatingFileHandler 或 TimedRotatingFileHandler . RotatingFileHandler 实例向磁盘文件发送消息,支持最大日志文件大小和日志文件旋转。 TimedRotatingFileHandler 实例将消息发送到磁盘文件,以特定的时间间隔旋转日志文件。 SocketHandler 实例将消息发送到TCP/IP套接字。自3.4以来,还支持Unix域套接字。 DatagramHandler 实例将消息发送到UDP套接字。自3.4以来,还支持Unix域套接字。 SMTPHandler 实例将消息发送到指定的电子邮件地址。 SysLogHandler 实例将消息发送到一个UNIX系统日志守护进程,可能在远程计算机上。 NTEventLogHandler 实例将消息发送到Windows NT/2000/XP事件日志。 MemoryHandler 实例将消息发送到内存中的缓冲区,只要满足特定条件,缓冲区就会被刷新。 HTTPHandler 实例使用以下任一方法向HTTP服务器发送消息 GET 或 POST 语义学。 WatchedFileHandler 实例监视它们正在登录的文件。如果文件发生更改,将关闭该文件并使用文件名重新打开。此处理程序仅在类Unix系统上有用;Windows不支持所使用的底层机制。 QueueHandler 实例将消息发送到队列,例如 queue 或 multiprocessing 模块。 NullHandler 实例不处理错误消息。它们由希望使用日志记录的库开发人员使用,但希望避免出现“找不到日志记录器XXX的处理程序”消息,如果库用户未配置日志记录,则可以显示该消息。见 为库配置日志记录 更多信息。
日志输出格式表
- Formatter 格式器
变量 | 格式 | 变量描述 |
---|---|---|
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 ]
参考文献
- 基础教程
- 高级教程
- logging --- python的日志记录工具
- logging.config ---日志配置
- logging.handlers ---日志处理程序
- 日志秘诀 日志秘诀