官方文档说明:https://docs.python.org/zh-cn/3/howto/logging.html
级别从低到高
级别 | 何时使用 |
---|---|
DEBUG | 细节信息,仅当诊断问题时使用。 |
INFO | 确认程序按预期运行。 |
WARNING | 表明有已经或者即将发生的意外(例如:磁盘空间不足)。程序仍然按照预期进行。 |
ERROR | 由于严重的问题,程序的某些功能已经不能正常执行。 |
CRITICAL | 严重的错误,表明程序已经不能继续执行。 |
函数 | 说明 |
---|---|
logging.debug(msg,*args,**kwargs) | 创建一条严重级别为DEBUG的日志记录 |
logging.info(msg,*args,**kwargs) | 创建一条严重级别为INFO的日志记录 |
logging.warning(msg,*args,**kwargs) | 创建一条严重级别为WARNING的日志记录 |
logging.error(msg,*args,**kwargs) | 创建一条严重级别为ERROR的日志记录 |
logging.critical(msg,*args,**kwargs) | 创建一条严重级别为CRITICAL的日志记录 |
logging.log(level,*args,**kwargs) | 创建一条严重级别为Level的日志记录 |
logging.basicConfig(**kwargs) | 对 root logger进行一次性配置 |
注:logging默认日志级别是warning。根据定义的级别,打印当前级别及以上级别的日志,比如:定义的是warning的话,则会打印warning及其以上级别的日志,即warning、error、critical级别。
basicConfig 一定要定义在代码最前面,因为basiConfig只执行一次,并且没有累加的效果。如果设置再后面,只对basicConfig之后的代码生效,之前的无效。
示例:
import logging
#logging默认设置的界别是warning
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything
logging.error('This a Error.')
"""
打印结果:
WARNING:root:Watch out!
ERROR:root:This a Error.
"""
#只打印了warning和warning以上的error级别的日志。
import logging
#把日志级别设置成INFO级别。
logging.basicConfig(level=logging.INFO)
#日志设置成哪个级别,就会打印哪个级别及其以上级别的日志。
logging.debug('This is a Debug.')
logging.warning('Watch out!')
logging.info('I told you so')
logging.error('This a Error.')
"""
打印结果:
WARNING:root:Watch out!
INFO:root:I told you so
ERROR:root:This a Error.
"""
#打印了INFO及以上级别的日志,Debug没有被打印。
使用logging.basicConfig()
中的filename
参数来确定日志文件的名称和日志保存的位置。
import logging
#filename参数确认日志名称和保存位置
logging.basicConfig(filename="example.log",level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
"""
example.log文件中记录的结果:
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
ERROR:root:And non-ASCII stuff, too, like \xd8resund and Malm\xf6
"""
使用logging.basicConfig()
函数中的format
参数来确定日志信息的格式,datefmt
参数来确定日期的格式。
import logging
logging.basicConfig(filename="example.log",format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö')
"""
example.log文件中记录的结果:
09/09/2022 10:58:58 AM This message should go to the log file
09/09/2022 10:58:58 AM So should this
09/09/2022 10:58:58 AM And this, too
09/09/2022 10:58:58 AM And non-ASCII stuff, too, like \xd8resund and Malm\xf6
"""
format='%(asctime)s %(message)s'
:%(asctime)s
:表示人类易读的LogRecord生成时间。 默认形式为 ‘2003-07-08 16:49:45,896’ (逗号之后的数字为时间的毫秒部分)。
%(message)s
:记入日志的消息.
LogRecord属性格式化详细说明:https://docs.python.org/zh-cn/3/library/logging.html#logrecord-attributes
datefmt='%m/%d/%Y %I:%M:%S %p'
%m/%d/%Y %I:%M:%S %p
:时间格式化显示为:月/日/年 小时(12小时制的小时):分钟:秒
时间格式化详细说明: https://docs.python.org/zh-cn/3/library/time.html#time.strftime
日志内容中打印级别,文件名和行号
import logging
#在format参数中将日志打印格式丰富,添加了日志界别,代码文件名和代码行号
logging.basicConfig(filename="example.log",format='%(asctime)s [%(levelname)s]: %(message)s (%(filename)s:%(lineno)s)', datefmt='%m/%d/%Y %I:%M:%S %p',level=logging.DEBUG)
logging.debug('This message should go to the log file.')
logging.info('So should this.')
logging.warning('And this, too.')
logging.error('And non-ASCII stuff, too, like Øresund and Malmö.')
"""
example.log文件中记录的结果:
09/09/2022 11:16:13 AM [DEBUG]: This message should go to the log file. (demo.py:3)
09/09/2022 11:16:13 AM [INFO]: So should this. (demo.py:4)
09/09/2022 11:16:13 AM [WARNING]: And this, too. (demo.py:5)
09/09/2022 11:16:13 AM [ERROR]: And non-ASCII stuff, too, like \xd8resund and Malm\xf6. (demo.py:6)
"""
组件 | 说明 |
---|---|
loggers(记录器) | 提供应用程序代码直接使用的接口 |
handlers(处理器) | 用于将日志记录发送到指定的目的位置 |
filters(过滤器) | 提供更细粒度的日志过滤功能,用于决定哪些日志记录将会被输出(其他日志记录将会被忽略) |
formatters(格式器) | 用于控制日志信息的最终输出格式 |
示例1:将日志信息输出至终端
import logging
# 创建一个记录器
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# 创建一个处理器,将消息输出到终端中
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 创建格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 把格式器放到处理器
ch.setFormatter(formatter)
# 把处理器放到记录器中
logger.addHandler(ch)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
"""
终端打印内容:
2022-09-09 11:43:00,388 - simple_example - DEBUG - debug message
2022-09-09 11:43:00,388 - simple_example - INFO - info message
2022-09-09 11:43:00,388 - simple_example - WARNING - warn message
2022-09-09 11:43:00,388 - simple_example - ERROR - error message
2022-09-09 11:43:00,389 - simple_example - CRITICAL - critical message
"""
示例2:将日志输出至文件
import logging
# 创建一个记录器
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# 创建一个处理器,将消息输出到文件中
ch = logging.FileHandler(filename='logger_demo.log',encoding='UTF-8')
ch.setLevel(logging.DEBUG)
# 创建格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 把格式器放到处理器
ch.setFormatter(formatter)
# 把处理器放到记录器中
logger.addHandler(ch)
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
"""
终端中未输出内容,输出到文件中。
文件中输出内容:
2022-09-09 11:45:44,390 - simple_example - DEBUG - debug message
2022-09-09 11:45:44,390 - simple_example - INFO - info message
2022-09-09 11:45:44,390 - simple_example - WARNING - warn message
2022-09-09 11:45:44,391 - simple_example - ERROR - error message
2022-09-09 11:45:44,391 - simple_example - CRITICAL - critical message
"""
示例3:将日志输出到文件中和终端中
一个记录器可以同时有多个处理器。
import logging
# 创建一个记录器
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# 创建一个处理器,将消息输出到文件中
ch = logging.FileHandler(filename='logger_demo.log',encoding='UTF-8')
ch.setLevel(logging.DEBUG)
# 创建一个处理器,将消息输出到终端
ch1 = logging.StreamHandler()
ch1.setLevel(logging.DEBUG)
# 创建格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 把格式器放到处理器
ch.setFormatter(formatter)
ch1.setFormatter(formatter)
# 把处理器放到记录器中
logger.addHandler(ch)
logger.addHandler(ch1)
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
"""
文件和终端都有日志输出。
"""
封装日志公共模块后,更加方便代码开发与调用。
import logging
import os
#定义一个记录器
def get_logger():
# 定义了记录器
logger = logging.getLogger(os.path.basename(__file__))
logger.setLevel(logging.DEBUG)
# 定义了一个处理器
ch = logging.FileHandler(filename='mylog.log', encoding="utf-8")
ch.setLevel(logging.DEBUG)
# 定义了一个格式器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 将格式器加入处理器中
ch.setFormatter(formatter)
# 将处理器加入记录器中
logger.addHandler(ch)
return logger
#封装一个info级别方法
def log_info(message):
logger.info(message)
#声明一个get_logger对象
logger=get_logger()
#使用封装的方法输入info级别日志
log_info('info message')
logger.debug('debug message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
"""
日志文件中输出内容:
2022-09-09 13:57:33,066 - demo.py - INFO - info message
2022-09-09 13:57:33,067 - demo.py - DEBUG - debug message
2022-09-09 13:57:33,067 - demo.py - WARNING - warn message
2022-09-09 13:57:33,068 - demo.py - ERROR - error message
2022-09-09 13:57:33,069 - demo.py - CRITICAL - critical message
"""
示例:
注意:Windows系统下,conf文件中不能包含中文字符,否者会报错。
[loggers] # loggers 对象列表。root必须要有,他是一个根节点的值。
keys=root,main
[handlers] # handlers 对象列表
keys=consoleHandlers,fileHandlers
[formatters] # formatters 对象列表
keys=fmt
[logger_root]
level=DEBUG
handlers=consoleHandlers,fileHandlers
[logger_main] # main logger
level = DEBUG
handlers = fileHandlers
qualname=main #定义logger需要的名称,一般和前面一致
propagate=0
[handler_consoleHandlers] # consoleHandlers 指定控制器的输出方向、级别、输出格式、参数
class = StreamHandler
level = DEBUG
formatter = fmt
args = (sys.stdout,)
[handler_fileHandlers] # 循环日志文件
class = logging.handlers.RotatingFileHandler
level = DEBUG
formatter = fmt
args = ('./logs/test.log', 'a', 10000, 3, 'UTF-8') # 以文件大小来分割,每隔 1000 Byte 划分一个日志文件,备份文件为 3 个
[formatter_fmt] # fmt 格式
format=%(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
datefmt=
import logging.config
logging.config.fileConfig('logging.conf')
logger=logging.getLogger("main")
logger.debug("这是一个debug的问题")
"""
logs/test.log内容:
2022-09-09 14:15:09,100 [DEBUG] 这是一个debug的问题 (demo.py:5)
"""