很多的小伙伴在平时写代码的时候,基本上使用的都是使用print()函数来进行一些日志的打印,使用print()来进行一些代码的调试,在较小的程序中这样做是可以的。但是在实际的工程项目中,我们需要保存程序运行的日志,以排查程序在某一个时候崩溃的具体原因,以便及时定位Bug进行抢救,而在Python中,logging就可以十分灵活的帮助我们记录程序运行的过程的中的一些信息。
第一个示例:
import logging
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
会发现debug,info不会输出,这是因为logging模块提供的日志记录函数所使用的日志器设置的日志级别是WARNING,因此只有WARNING级别的日志记录以及大于它的ERROR和CRITICAL级别的日志记录被输出了,而小于它的DEBUG和INFO级别的日志记录被丢弃了。
解决方法:
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
在logging.basicConfig
设置参数level
的显示级别为dubug。
这里用到了函数logging.basicConfig
,下面具体介绍一下该函数使用:
logging.basicConfig(filename=”config.levellog”,filemode=”w”,format=”%(asctime)s-%(name)s-%(levelname)s-%(message)s”,level=logging.INFO)。
filename:指定日志输出目标文件的文件名,指定该设置项后日志信心就不会被输出到控制台了
filemode:如果指定 filename,则以此模式打开文件(‘r’、‘w’、‘a’)。默认为“a”。
format:指定输出的个数和内容
datefmt 指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效
level:设置日志等级。默认是logging.warning
其中format使用如下:
字段/属性名称 | 使用格式 | 描述 |
---|---|---|
asctime | %(asctime)s | 日志事件发生的时间–人类可读时间,如:2022-07-26 17:22:31,655 |
created | %(created)f | 日志事件发生的时间–时间戳,就是当时调用time.time()函数返回的值 |
relativeCreated | %(relativeCreated)d | 日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的) |
msecs | %(msecs)d | 日志事件发生事件的毫秒部分 |
levelname | %(levelname)s | 该日志记录的文字形式的日志级别(‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’) |
levelno | %(levelno)s | 该日志记录的数字形式的日志级别(10, 20, 30, 40, 50) |
name | %(name)s | 所使用的日志器名称,默认是’root’,因为默认使用的是 rootLogger |
message | %(message)s | 日志记录的文本内容,通过 msg % args计算得到的 |
pathname | %(pathname)s | 调用日志记录函数的源码文件的全路径 |
filename | %(filename)s | pathname的文件名部分,包含文件后缀 |
module | %(module)s | filename的名称部分,不包含后缀 |
lineno | %(lineno)d | 调用日志记录函数的源代码所在的行号 |
funcName | %(funcName)s | 调用日志记录函数的函数名 |
process | %(process)d | 进程ID |
processName | %(processName)s | 进程名称 |
thread | %(thread)d | 线程ID |
threadName | %(thread)s | 线程名称 |
举个栗子:
import logging
FORMAT = "%(asctime)s - %(levelname)s - %(message)s - %(msecs)d ms "
logging.basicConfig(level=logging.DEBUG, format=FORMAT)
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
import logging
FORMAT = "%(asctime)s - %(levelname)s - %(message)s - %(msecs)d ms "
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt='%a %d %b %Y %H:%M:%S', )
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
保存到文件内:
import logging
FORMAT = "%(asctime)s - %(levelname)s - %(message)s - %(msecs)d ms "
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt='%a %d %b %Y %H:%M:%S', filename='my.log',
filemode='w')
logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
会生成一个文件:
文件内容如下:
上面的例子中日志输出都是英文内容,发现不了将日志输出到文件中会有中文乱码的问题,解决中文乱码,需要将文件编码设置为 “utf-8”:
FORMAT = "%(asctime)s - %(levelname)s - %(message)s - %(msecs)d ms "
handlers = [logging.FileHandler("test.log", encoding="utf-8")]
logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt='%a %d %b %Y %H:%M:%S', handlers=handlers)