1.logging模块简介
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志输出格式等
2.logging库日志级别
级别 | 级别数值 | 使用时机 | DEBUG | 10 | 详细信息,常用于调试 | INFO | 20 | 程序正常运行过程中产生的一些信息 | WARNING | 30 | 警告用户,虽然程序还在正常工作,但有可能发生错误 | ERROR | 40 | 由于更严重的问题,程序已不能执行一些功能了 | CRITICAL | 50 | 严重错误,程序已不能继续运行 |
默认的日志级别是waring
3.logging模块简单使用
logging模块向控制台输出
# -*- coding: UTF-8 -*-
import logging
# 默认的日志输出级别为warning
# 使用basicConfig()来指定日志输出级别
logging.basicConfig(level=logging.DEBUG)
logging.debug("This is debug info")
logging.info("This is info info")
logging.warning("This is warning info")
logging.error("This is error info")
logging.critical("This is critical info")
控制台输出: DEBUG:root:This is debug info INFO:root:This is info info WARNING:root:This is warning info ERROR:root:This is error info CRITICAL:root:This is critical info
Process finished with exit code 0
logging模块输出日志到文件中
# 日志输出到文件,默认是追加,filemode="a";通过设置filemode="w",日志输出先清除文件原有内容再写入
logging.basicConfig(filename="log.txt", level=logging.DEBUG)
logging.basicConfig(filename="log1.txt", filemode="w", level=logging.DEBUG)
logging.debug("This is debug info")
logging.info("This is info info")
logging.warning("This is warning info")
logging.error("This is error info")
logging.critical("This is critical info")
logging模块输出日志,设置输出格式和一些其他信息
logging.basicConfig(format="%(asctime)s %(levelname)s %(filename)s %(lineno)s %(message)s", level=logging.DEBUG)
logging.debug("This is debug info")
logging.info("This is info info")
logging.warning("This is warning info")
logging.error("This is error info")
logging.critical("This is critical info")
#设置时间格式
logging.basicConfig(format="%(asctime)s %(levelname)s %(filename)s %(lineno)s %(message)s",
datefmt="%Y-%m-%d %H-%M-%S", level=logging.DEBUG)
logging.debug("This is debug info")
logging.info("This is info info")
logging.warning("This is warning info")
logging.error("This is error info")
logging.critical("This is critical info")
控制台输出
2021-08-12 23:56:04,650 DEBUG testlogging.py 16 This is debug info 2021-08-12 23:56:04,650 INFO testlogging.py 17 This is info info 2021-08-12 23:56:04,650 WARNING testlogging.py 18 This is warning info 2021-08-12 23:56:04,650 ERROR testlogging.py 19 This is error info 2021-08-12 23:56:04,650 CRITICAL testlogging.py 20 This is critical info
2021-08-12 23-58-26 DEBUG testlogging.py 17 This is debug info 2021-08-12 23-58-26 INFO testlogging.py 18 This is info info 2021-08-12 23-58-26 WARNING testlogging.py 19 This is warning info 2021-08-12 23-58-26 ERROR testlogging.py 20 This is error info 2021-08-12 23-58-26 CRITICAL testlogging.py 21 This is critical info
4.logging的高级应用
logging模块采用了模块化设计,主要包含四种组件:
Logger:?记录器,提供应用程序代码能直接使用的接口;
Handler:?处理器,将记录器产生的日志发送到目的地;
Filter:?过滤器,提供更好的粒度控制,决定哪些日志会被输出;
Formatter:?格式化器,设置日志内容的组成结构和消息字段;
创建一个logger,接着可以创建多个Handler,设置Handler的日志等级,可以创建Formatter来渲染Handler(设置日志输出的格式),将多个Handler添加到logger里,程序调用logger的函数输出日志。可以理解为创建一只笔,为这只笔绑定输出载体(可以一对多),可以是控制台,可以是文件等等,通过格式化器,对笔输出的内容进行格式化处理。
Logger记录器?
1.提供应用程序的调用接口
logger = logging.getLogger(__name__)?
logger是单例的
2.决定日志记录的级别
logger.setLevel()
3.将日志内容传递到相关联的handlers中
logger.addHandler()和logger.removeHandler()
Handler处理器
将日志分发到不同的目的地。可以是文件、标准输出(sys.stdout,sys.stderr)、邮件、或者通过socke、http等协议发送到任何地方。
StreamHandler
标准输出stdout(如显示器)分发器。
创建方法:sh = logging.StreamHandler()
FileHandler
将日志保存到磁盘文件的处理器
创建方法:fh = logging.FileHandler()
所有handler都可以使用setFormatter(): 设置当前handler对象使用的消息格式
支持日志回滚的两个FileHandler处理器
RotatingFileHandler
回滚时刻是当日志文件的大小达到一定值。当日志文件的大小达到指定值的时候,RotatingFileHandler 会将日志文件重命名存档,然后打开一个新的日志文件。
代码示例:
# -*- coding: UTF-8 -*-
import logging.handlers
# 记录器
logger = logging.getLogger("app")
# 处理器
ro_handler = logging.handlers.RotatingFileHandler(filename="app.log", maxBytes=200, backupCount=3)
# 格式化处理器
formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s :%(lineno)s %(message)s")
# 给处理器设置格式
ro_handler.setFormatter(formatter)
# 记录器绑定处理器
logger.addHandler(ro_handler)
logger.error("This is a error message")
logger.critical("This is a critical message")
TimeRotatingFileHandler
当某个时刻到来时执行回滚,同RotatingFileHandler 一样,当回滚时机来临时,TimedRotatingFileHandler 会将日志文件重命名存档,然后打开一个新的日志文件。
time_ro = logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0)
注:
日志回滚的意思为:比如日志文件是chat.log,当chat.log达到指定的大小之后,RotatingFileHandler自动把文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。最后重新创建 chat.log,继续输出日志信息。【这样保证了chat.log里面是最新的日志】
Formatter格式
Formatter对象用来最终设置日志信息的顺序、结构和内容
其构造方法中,datefmt参数默认是%Y-%m-%d %H-%M-%S样式的
属性 | 格式 | 描述 |
---|
asctime | %(asctime)s | 日志产生的时间,默认是%Y-%m-%d %H-%M-%S,%毫秒 | filename | %(filename)s | 生成日志的py文件名 | funcName | %(funcName)s | 调用日志的函数名 | levelname | %(levelname)s | 日志级别 | levelno | %(levelno)s | 日志级别对应的数值 | lineno | %(lineno)s | 调用日志的代码行号 | module | %(module)s | 生成日志的模块 | message | %(message)s | 具体的日志信息 | name | %(name)s | 日志调用者 | pathname | %(pathname)s | 生成日志的文件的完整路径 | created | %(created)s | time.time()生成的日志创建时间戳 | msecs | %(msecs)s | 日志生成时间的毫秒部分 | process | %(process)s | 生成日志的进程ID(如果可用) | processName | %(processName)s | 进程名(如果可用) | thread | %(thread)s | 生成日志的线程ID(如果可用) | threadName | %(threadName)s | 线程名(如果可用) |
5.logging高级应用代码示例
Demo1:
# 记录器
logger = logging.getLogger()
print(logger)
print(type(logger))
?控制台输出:
<RootLogger root (WARNING)> <class 'logging.RootLogger'>
名字为root的RootLogger,日志默认等级WARNING
Demo2:
logger = logging.getLogger()
# 设置日志级别
logger.setLevel(logging.DEBUG)
print(logger)
print(type(logger))
控制台输出:
<RootLogger root (DEBUG)> <class 'logging.RootLogger'>
Demo3:
# 设置logger的名字
logger = logging.getLogger("applog")
logger.setLevel(logging.DEBUG)
print(logger)
print(type(logger))
控制台输出:
<Logger applog (DEBUG)> <class 'logging.Logger'>
名字为applog的Logger,日志等级DEBUG?
Demo4:
记录器,处理器,格式化处理器,过滤器
# 记录器
logger = logging.getLogger("cn.applog")
# 记录器设置日志级别优先级 > 处理器设置日志级别,日志会根据记录器日志级别先进行一层过滤,然后根据处理器日志级别过滤
logger.setLevel(logging.DEBUG)
# 处理器Handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 没有给handler指定日志级别,将使用logger的级别
file_handler = logging.FileHandler(filename="log.txt")
# 格式化处理器Formatter
formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s :%(lineno)s %(message)s")
# 给处理器设置格式
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 记录器设置处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 定义过滤器,用来过滤记录器和处理器
# flt = logging.Filter("cn")
# 关联过滤器
# 过滤器存在层级关系
# logger.addFilter(logging.Filter("cn"))
# file_handler.addFilter(logging.Filter("sn"))
# 使用记录器打印日志
logger.debug("This is debug info")
logger.info("This is info info")
logger.warning("This is warning info")
logger.error("This is error info")
logger.critical("This is critical info")
控制台输出:
2021-08-13 19:44:45,501 INFO testlogging1.py :35 This is info info 2021-08-13 19:44:45,501 WARNING testlogging1.py :36 This is warning info 2021-08-13 19:44:45,501 ERROR testlogging1.py :37 This is error info 2021-08-13 19:44:45,501 CRITICAL testlogging1.py :38 This is critical info
(注:过滤器后面学习详述)
Demo5:
配置文件的方式来处理日志
# -*- coding: UTF-8 -*-
import logging.config
# 配置文件的方式来处理日志
# 载入配置文件的信息
# logging模块的config文件的fileConfig
logging.config.fileConfig("logging.conf")
root_logger = logging.getLogger()
root_logger.debug("This is debug info")
app_logger = logging.getLogger("applog")
app_logger.debug("This is debug info")
控制台输出:
2021-08-13 20:52:13 DEBUG testlogging2.py :10 This is debug info 2021-08-13 20:52:13 DEBUG testlogging2.py :13 This is debug info
配置文件:logging.conf
[loggers]
keys=root,applog
[handlers]
keys=fileHandler,consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[logger_applog]
level=DEBUG
handlers=fileHandler,consoleHandler
qualname=applog
propagate=0
[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter
[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
args=("app.log", "midnight", 1, 0)
level=DEBUG
formatter=simpleFormatter
[formatter_simpleFormatter]
format=%(asctime)s %(levelname)s %(filename)s :%(lineno)s %(message)s
datefmt=%Y-%m-%d %H:%M:%S
# 约定俗成,root必写
# qualname别名
# propagate继承关系,比较多使用0(以后用到再详述)
# 配置文件里面不要用中文,代码会报gbk错误
其他:
1.使用logger.exception(message),记录器输出栈信息
# 记录器输出栈信息
try:
int("abc")
except Exception as e:
# app_logger.error(e)
app_logger.exception(e)
控制台输出:
2021-08-13 20:57:23 ERROR testlogging2.py :19 invalid literal for int() with base 10: 'abc' Traceback (most recent call last): ? File "E:/PycharmProjects/IVSPlat/test/testlogging2.py", line 16, in <module> ? ? int("abc") ValueError: invalid literal for int() with base 10: 'abc'
2.可以用字典配置来处理日志
logging.config.dictConfig({})
后续进行学习
|