python根据日期和大小自动切割

最近在项目中需要用到python日志存储问题,之前一直使用的内部基于logging模块封装的,所以不用考虑日志存储问题,但是在新项目中只能直接使用logging来做日志打印和存储,所以学习了下日志的配置。

日志的基本配置

1
2
3
4
5
6
7
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger()

logger.info("logging info")
logger.debug("logging debug")
logger.warning("logging warning")

输出如下:

2020-03-18 16:05:39,095 - root - INFO - logging info
2020-03-18 16:05:39,095 - root - WARNING - logging warning

从输出中可以看到打印了特定格式的日志,并且logger.debug("logging debug") 并未打印,下面将介绍日志的输出格式和日志级别对输出的控制。

日志输出格式

%(levelno)s:打印日志级别的数值
%(levelname)s:打印日志级别的名称
%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(lineno)d:打印日志的当前行号
%(asctime)s:打印日志的时间
%(thread)d:打印线程ID
%(threadName)s:打印线程名称
%(process)d:打印进程ID
%(message)s:打印日志信息

可以在日志logging.basicConfig中配置日志格式,也可以在对应的handler实例中设置,如果是logging.basicConfig中配置,则只需将对应格式传入format参数即可,但是若在handler中设置,则需要先初始化成logging.Formatter类。

日志级别

日志类会根据设置的日志级别来控制输出,日志优先级为NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL,只能设置比设置的日志级别更高级别的日志,比如当前设置的级别是INFO,则不会输出DEBUGNOTSET级别的日志

根据大小切割

1
2
3
4
5
6
7
8
9
10
11
import logging
from logging.handlers import RotatingFileHandler
LOG_FILE_PATH = "test/test.log"
date_fmt = '%d-%b-%Y %H:%M:%S'
def_format = "%(asctime)s[%(levelname)s] %(filename)s %(message)s"
logger_format = logging.Formatter(def_format, date_fmt)
logger = logging.getLogger("test")
logger.setLevel(logging.INFO) # 如果在addhandler前不执行这一步,则不会打印日志
ro_handler = RotatingFileHandler(LOG_FILE_PATH, maxBytes=2048, backupCount=3, encoding="utf-8")
ro_handler.setFormatter(logger_format)
logger.addHandler(ro_handler)

RotatingFileHandler类介绍

1
2
from logging.handlers import RotatingFileHandler
ro_handler = RotatingFileHandler(filename="test/test.log", mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False)

filename 指定日志文件
mode 日志写入文件的模式,默认为a也即追加模式
maxBytes 单个日志文件最大容量,单位为字节,也即1024 为1M
backupCount 日志备份数,当前日志量等于maxBytes时,日志会自动切分成filename.1到filename.backupCount
encoding 日志编码格式,建议设置成utf-8,否则写入中文时会报warning
delay 是否需要开启缓存,默认不缓存,若开启缓存,则日志会先写入缓存,等缓存区满后再写入文件中

根据时间切割

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
LOG_FILE_PATH = "test.log"
date_fmt = '%d-%b-%Y %H:%M:%S'
def_format = "%(asctime)s[%(levelname)s] %(filename)s %(message)s"
logger_format = logging.Formatter(def_format, date_fmt)
logger = logging.getLogger("test")
logger.setLevel(logging.INFO) # 如果在addhandler前不执行这一步,则不会打印日志
time_handler = TimedRotatingFileHandler(LOG_FILE_PATH, when='D', interval=1, backupCount=2, encoding="utf-8", delay=False, utc=True, atTime=False)
time_handler.setFormatter(logger_format)
logger.addHandler(time_handler)
logger.debug("这是一个debug信息")
logger.info("这是一个info信息")
logger.error("这是一个error信息")

TimedRotatingFileHandler类

1
2
from logging.handlers import TimedRotatingFileHandler
ro_handler = TimedRotatingFileHandler(filename="test/test.log", when='D', interval=1, backupCount=2, encoding="utf-8", delay=False, utc=True, atTime=False)

when s 秒; m 分钟; h 小时; d 天 设置后会按照指定的方式进行切割,比如设置为s,则美妙会生成一个文件
interval 指等待多少个when后执行创建
utc 是否启用utc时区

以上

投食