参考
https://cloud.tencent.com/developer/article/1354396
http://cn.voidcc.com/question/p-bywlbukc-tp.html
需求
在Python中手动记录日志,并且日志以日期的方式输出到文件名
解决方法
两种方法
- logging原生
- TimedRotatingFileHandler
第一种方法:
日志配置文件:logging.conf.ini
[loggers]
keys = root,sampleLogger
[handlers]
keys = consoleHandler
[formatters]
keys = sampleFormatter
[logger_root]
level = DEBUG
handlers = consoleHandler
[logger_sampleLogger]
level = DEBUG
handlers = consoleHandler
qualname = sampleLogger
propagate = 0
[handler_consoleHandler]
class = StreamHandler
level = DEBUG
formatter = sampleFormatter
args = (sys.stdout,)
[formatter_sampleFormatter]
format = %(asctime)s - %(name)s - %(lineno)s - %(levelname)s - %(message)s
代码:
import logging
import logging.config
from datetime import datetime
# 定义日志存放路径
# LOG_PATH = "/data/zaspace/data/AutoRelease/log/"
LOG_PATH = "D:\\software\\laragon\\www\\test\\AutoRelease\\log\\"
def log_init():
"""
日志初始化
:return:
"""
# 加载日志配置文件
logging.config.fileConfig(fname='logging.conf.ini', disable_existing_loggers=False)
logger = logging.getLogger('mainLogger')
# 定义日志存放路径
log_path = LOG_PATH
# 日志文件名称 - 以日期为文件名
fh = logging.FileHandler(log_path + '{:%Y-%m-%d}.log'.format(datetime.now()))
# 设置日志格式 时间 - 名称 - 行数 - 严重程度 - 日志内容
formatter = logging.Formatter('%(asctime)s - %(name)s - %(lineno)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
return logger
# 日志初始化
main_logger = log_init()
# 记录日志
main_logger.info('这个是警告1')
main_logger.debug('这个是调试1')
main_logger.error('这个是错误1')
运行后:
控制台会显示:
Connected to pydev debugger (build 191.8026.44)
2019-08-12 18:33:45,538 - mainLogger - 75 - INFO - 这个是警告1
2019-08-12 18:33:45,538 - mainLogger - 76 - DEBUG - 这个是调试1
2019-08-12 18:33:45,538 - mainLogger - 77 - ERROR - 这个是错误1
同时会输出文件:
2019-08-12.log
2019-08-12 18:33:45,538 - mainLogger - 75 - INFO - 这个是警告1
2019-08-12 18:33:45,538 - mainLogger - 76 - DEBUG - 这个是调试1
2019-08-12 18:33:45,538 - mainLogger - 77 - ERROR - 这个是错误1
第二种方法:
使用TimedRotatingFileHandler
TimedRotatingFileHandler类可以实现按照时间进行划分,不仅日期,比如每隔一个小时记录一个日志也是可以实现的
代码:
import logging
# 定义日志存放路径
# LOG_PATH = "/data/zaspace/data/AutoRelease/log/"
LOG_PATH = "D:\\software\\laragon\\www\\test\\AutoRelease\\log\\"
def log_init():
"""
日志初始化
:return:
"""
logger = logging.getLogger('main_logger')
logger.setLevel(logging.INFO)
# 定义日志存放路径
log_path = LOG_PATH
# 日志文件名称
filename = log_path + "release"
# 设置日志格式 时间 - 名称 - 行数 - 严重程度 - 日志内容
formatter = logging.Formatter('%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(message)s')
# 以日期输出日志名,从0点开始滚动日志,只保留30天的日志
log_file_handler = TimedRotatingFileHandler(filename, when="MIDNIGHT", interval=1, backupCount=30)
log_file_handler.setFormatter(formatter)
log_file_handler.setLevel(logging.INFO)
logger.addHandler(log_file_handler)
return logger
# 日志初始化
main_logger = log_init()
# 记录日志
main_logger.info('这个是注释')
main_logger.error('这个是注释')
会输出文件:
release
2019-08-12 18:44:25,898 - main_logger - INFO - 这个是警告
2019-08-12 18:44:25,899 - main_logger - ERROR - 这个是错误
如果release日志文件里面有其他日期的内容,会单独分割出来:
release.2019-08-09等文件名
TimedRotatingFileHandler(filename, when="MIDNIGHT", interval=1, backupCount=30)
参数解释
- filename 是输出日志的文件名称前缀,比如说 testServiceLog 这样的就是日志文件名前缀
- when,是一个字符串,定义了日志切分的间隔时间单位,这是一个枚举类,可选参数如下:
"S":Second 秒
"M":Minutes 分钟
"H":Hour 小时
"D":Days 天
"W":Week day(0 = Monday)
"midnight":Roll over at midnight
- interval 是间隔时间单位的个数,指等待多少个 when 的时间后 Logger 会自动重建新闻继续进行日志记录
- backupCount 是保留日志的文件个数,默认的参数是0,这种设置下是不会自动删除文件的。如果设置为 N(正整数),则会在创建新的日志文件时会检查日志文件个数是否到达 N,达到了的话就会从最先创建的开始删除,从而达到维持日志文件个数为 N 个的目标
这里有个问题:
如果when设置为D的话,那么比如今天2019-08-13的14:00:00运行的时候,会记录到filename里面去,然后等到第二天的2019-08-14的14:00:00之后,会切割,把filename里面的2019-08-13的14:00:00到2019-08-14的14:00:00切割出来,切割成filename.2019-08-13这个文件
也就是说,filename.2019-08-13这个文件记录的是2019-08-13的14:00:00到2019-08-14的14:00:00之间的日志,并不是从0点开始滚动切割的,如果想要从0点的话,需要使用midnight
注意:当天的日志文件中不会有,此文件处理程序仅在新的一天开始时添加日期后缀。