python自定义日志(亲测可用)日志滚动
参考:
http://python.jobbole.com/81666/
https://www.cnblogs.com/rollenholt/p/5392338.html
NOSET 0
DEBUG 10
INFO 20
WARNING 30
ERROR 40
CRITICAL 50
DEBUG 诊断问题时使用,在生产环境默认是关闭的。为了方便我们开发和调试,记录流程的关键路径。
INFO 需要开发者确认的信息,关键系统参数的回显、后台服务的初始化状态。
WARNING 出现了异常情况,但是又在合理范围之类的时候
ERROR 系统出现了异常情况,需要修改代码处理。
CRITICAL 说实话我没有用过,我都用ERROR代替了。
一、自定义日志(简单版)
import os import logging # 用字典保存输出格式 format_dict = { 1: logging.Formatter('%(asctime)s - %(filename)-9s - line:%(lineno)3d - %(levelname)-5s - %(message)s'), 2: logging.Formatter( '%(asctime)s - %(name)s - %(filename)s - line:%(lineno)d - pid:%(process)d - %(levelname)s - %(message)s'), 3: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'), 4: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'), 5: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') } # 日志文件配置 LOG_DIR_NAME = 'log' # 日志统一存放文件夹 LOG_DIR_PATH = os.path.join(os.getcwd(), LOG_DIR_NAME) # 日志统一存放完整路径 if not os.path.exists(LOG_DIR_PATH): # 日志统一存放路径不存在,则创建该路径 os.makedirs(LOG_DIR_PATH) class Logger(object): def __init__(self, logfile, logname, logformat): ''' 指定保存日志的文件路径,日志级别,以及调用文件 将日志存入到指定的文件中 ''' # 创建一个logger self.logger = logging.getLogger(logname) self.logger.setLevel(logging.DEBUG) # 创建一个handler,用于写入日志文件 fh = logging.FileHandler(logfile, encoding="utf-8") fh.setLevel(logging.DEBUG) # 日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # 定义handler的输出格式 # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter = format_dict[int(logformat)] fh.setFormatter(formatter) ch.setFormatter(formatter) # 给logger添加handler self.logger.addHandler(fh) self.logger.addHandler(ch) def getlog(self): return self.logger if __name__ == '__main__': # print(LOG_DIR_PATH) # 定义日志记录器1 logfile1 = os.path.join(LOG_DIR_PATH, "log1.log") logger1 = Logger(logfile=logfile1, logname="fox1", logformat=1).getlog() logger1.debug('i am debug') logger1.info('i am info') logger1.warning('i am warning') # 定义日志记录器2 logfile2 = os.path.join(LOG_DIR_PATH, "log2.log") logger2 = Logger(logfile=logfile2, logname="fox2", logformat=2).getlog() logger2.debug('i am debug2') logger2.info('i am info2') logger2.warning('i am warning2')
控制台输出:
2021-08-08 20:45:43,586 - logRecord.py - line: 59 - DEBUG - i am debug
2021-08-08 20:45:43,586 - logRecord.py - line: 60 - INFO - i am info
2021-08-08 20:45:43,586 - logRecord.py - line: 61 - WARNING - i am warning
2021-08-08 20:45:43,586 - fox2 - logRecord.py - line:66 - pid:8884 - DEBUG - i am debug2
2021-08-08 20:45:43,586 - fox2 - logRecord.py - line:67 - pid:8884 - INFO - i am info2
2021-08-08 20:45:43,586 - fox2 - logRecord.py - line:68 - pid:8884 - WARNING - i am warning2
文件中写入
log1.txt
2018-01-29 15:53:28,861 - fox1 - mytest4.py - DEBUG - i am debug
2018-01-29 15:53:28,861 - fox1 - mytest4.py - INFO - i am info
2018-01-29 15:53:28,861 - fox1 - mytest4.py - WARNING - i am warning
log2.txt
2018-01-29 15:53:28,862 - fox2 - DEBUG - i am debug2
2018-01-29 15:53:28,862 - fox2 - INFO - i am info2
2018-01-29 15:53:28,862 - fox2 - WARNING - i am warning2
二、自定义日志(高级版,带日志滚动功能)【推荐使用】
import os import logging import logging.handlers # 用字典保存输出格式 format_dict = { 1: logging.Formatter('%(asctime)s - %(filename)-9s - line:%(lineno)3d - %(levelname)-5s - %(message)s'), 2: logging.Formatter( '%(asctime)s - %(name)s - %(filename)s - line:%(lineno)d - pid:%(process)d - %(levelname)s - %(message)s'), 3: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'), 4: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'), 5: logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') } # 日志文件配置 LOG_DIR_NAME = 'log' # 日志统一存放文件夹 LOG_DIR_PATH = os.path.join(os.getcwd(), LOG_DIR_NAME) # 日志统一存放完整路径 if not os.path.exists(LOG_DIR_PATH): # 日志统一存放路径不存在,则创建该路径 os.makedirs(LOG_DIR_PATH) class Logger(object): def __init__(self, logfile, logname, logformat): ''' 指定保存日志的文件路径,日志级别,以及调用文件 将日志存入到指定的文件中 ''' # 一、创建一个logger self.logger = logging.getLogger(logname) self.logger.setLevel(logging.DEBUG) # 二、定义日志格式样本 # formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter = format_dict[int(logformat)] # 三、定义两类handler # 1、定义日志文件handler # 1-1 日志滚动功能。按时间,1d滚动一次,保留30个旧log文件。 # 创建一个日志文件handler。 tfh = logging.handlers.TimedRotatingFileHandler( logfile, when='D', interval=1, backupCount=30, encoding="utf-8" ) # 设置滚动后缀名称。如:app1.log.2021-08-03.log tfh.suffix = "%Y-%m-%d.log" # 设置日志最低输出级别 tfh.setLevel(logging.DEBUG) # 定义handler的输出格式 tfh.setFormatter(formatter) # 给logger添加这个类型的handler self.logger.addHandler(tfh) # ===============【测试使用 开始 1-1 和 1-2 只能 二选一】================= # # 1-2 日志滚动功能。按时间,1s滚动一次,保留3个旧log文件。测试使用。 # # 创建一个日志文件handler。 # tfh = logging.handlers.TimedRotatingFileHandler( # logfile, # when='s', # interval=1, # backupCount=3, # encoding = "utf-8" # ) # # # 设置滚动后缀名称。如:app1.log.2021-08-03_15-09-09.log # tfh.suffix = "%Y-%m-%d_%H-%M-%S.log" # # # 设置日志最低输出级别 # tfh.setLevel(logging.DEBUG) # # # 定义handler的输出格式 # tfh.setFormatter(formatter) # # # 给logger添加这个类型的handler # self.logger.addHandler(tfh) # ===============【测试使用 结束】================= # 2、定义日志控制台handler # 创建一个handler,用于输出到控制台 ch = logging.StreamHandler() # 设置日志最低输出级别 ch.setLevel(logging.DEBUG) # 定义handler的输出格式 ch.setFormatter(formatter) # 给logger添加这个类型的handler self.logger.addHandler(ch) def getlog(self): return self.logger if __name__ == '__main__': # print(LOG_DIR_PATH) # 定义日志记录器1 logfile1 = os.path.join(LOG_DIR_PATH, "app1.log") logger1 = Logger(logfile=logfile1, logname="fox1", logformat=1).getlog() logger1.debug('i am debug') logger1.info('i am info') logger1.warning('i am warning') # 定义日志记录器2 logfile2 = os.path.join(LOG_DIR_PATH, "app2.log") logger2 = Logger(logfile=logfile2, logname="fox2", logformat=2).getlog() logger2.debug('i am debug2') logger2.info('i am info2') logger2.warning('i am warning2')
三、日志格式
fmt中允许使用的变量可以参考下表。
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名|
%(funcName)s 调用日志输出函数的函数名|
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮点数表示|
%(relativeCreated)d 输出日志信息时的,自Logger创建以来的毫秒数|
%(asctime)s 字符串形式的当前时间。默认格式是“2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s 用户输出的消息
空格补充:%(process)5d
左对齐: %(process)-5d
参考:https://www.cnblogs.com/andy9468/p/8435854.html
四、日志滚动时间间隔设置
注意:filehanlder.suffix的格式必须这么写,才能自动删除旧文件,如果设定是天,就必须写成“%Y-%m-%d.log”,写成其他格式会导致删除旧文件不生效。这个配置在源码里能看出来,但是在官方文档并没有说明这一点!!!!!!!!!!
TimedRotatingFileHandler的构造函数定义如下:
TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]])
filename 是输出日志文件名的前缀,比如log/myapp.log
when 是一个字符串的定义如下:
“S”: Seconds
“M”: Minutes
“H”: Hours
“D”: Days
“W”: Week day (0=Monday)
“midnight”: Roll over at midnight
interval 是指等待多少个单位when的时间后,Logger会自动重建文件,当然,这个文件的创建
取决于filename+suffix,若这个文件跟之前的文件有重名,则会自动覆盖掉以前的文件,所以
有些情况suffix要定义的不能因为when而重复。
backupCount 是保留日志个数。默认的0是不会自动删除掉日志。若设3,则在文件的创建过程中
库会判断是否有超过这个3,若超过,则会从最先创建的开始删除。
参考:https://www.cnblogs.com/andy9468/p/8378492.html
相关文章
- [Python]架设python虚拟环境以及部署PythonWeb服务
- Python实现串口通信(pyserial)
- python+selenium自动化框架的POM思想
- Python动态监控日志的内容
- Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算
- linux执行python命令后没有反应,不打印日志信息
- python:ERROR: No matching distribution found for Pillow==9.1.0的处理(Python 3.6.8)
- python: 安装DeOldify库:黑白图片上色(Python 3.7.15)
- 华为OD机试 - 过滤组合字符串(Java & JS & Python)
- 推荐python入门进阶到大神的书籍
- Python编程语言学习:python语言中快速查询python自带模块&函数的用法及其属性方法、如何查询某个函数&关键词的用法、输出一个类或者实例化对象的所有属性和方法名之详细攻略
- Python语言学习:Python语言学习之python包/库package的简介(模块的封装/模块路径搜索/模块导入方法/自定义导入模块实现华氏-摄氏温度转换案例应用)、使用方法、管理工具之详细攻略
- Python:python代码编程带你玩转双色球(了解双色球的概率逻辑)
- 已解决2.Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and wi
- 已解决2. Set PROTOCOL_BUPFERS_PYTHON_iMPLEMENTATION=python (but this will use pure-Python parsing and w
- python 编程语言的优点和缺点是什么?
- 新年找工作?python带你批量采集招聘数据
- 【python】这么**得小姐姐网~不敢赶紧采集一波~免得它没了
- 【Python成长之路】python 基础篇 -- global/nonlocal关键字使用
- Python编程:查看python语法中的关键字keyword
- python里使用string.Template怎么避免抛出异常
- python基础===一行 Python 代码实现并行(转)
- python基础===pendulum '''Python datetimes made easy.'''
- Python: strace 日志分析示例1
- Python 面向对象编程详解
- 【异常】前端ERR! stack Error: Can‘t find Python executable “python“, you can set the PYTHON env variable.
- opencv-python处理图片的一些列操作之几何变换
- Python定义函数及引用
- Python .py 文件打包成 .exe 文件(Windows平台,python 3.x)