Python日志详解【两篇就够了系列】--第一篇logging
目录
第一章 Python日志模块logging详解
一、logging的框架
1.Logger
2.Handler
3.Formater类
4.Filter类
二、Log级别
三、Log格式
四、常用方式
1.不添加handler用法
2.SysLogHandler
3.RotatingFileHandler
4.TimedRotatingFileHandler
5.自定义Handler,继承TimedRotatingFileHandler实现压缩
五、其他说明
1.参考文献
2.Python其他日志模块
3. syslog与logging谁更好
4. logging.SysLogHandler和syslog
第一章 Python日志模块logging详解
一、logging的框架
logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。logging模块是Python的一个标准库模块,由标准库模块提供日志记录API的关键好处是所有Python模块都可以使用这个日志记录功能。logging模块主要包括以下几个组件。
组件 |
说明 |
loggers |
提供应用程序代码直接使用的接口 |
handlers |
用于将日志记录发送到指定的目的位置 |
filters |
提供更细粒度的日志过滤功能,用于决定哪些日志记录将会被输出。 |
formatters |
用于控制日志信息的最终输出格式 |
1.Logger
Logger对象有3个任务要做:
1)向应用程序代码暴露几个方法,使应用程序可以在运行时记录日志消息;
2)基于日志严重等级(默认的过滤设施)或filter对象来决定要对哪些日志进行后续处理;
3)将日志消息传送给所有感兴趣的日志handlers。
Logger对象最常用的配置方法如下:
方法 |
描述 |
Logger.setLevel() |
设置日志器将会处理的日志消息的最低严重级别 |
Logger.addHandler() |
为该logger对象添加一个handler对象 |
Logger.addFilter() |
为该logger对象添加一个filter对象 |
2.Handler
Handler对象的作用是(基于日志消息的level)将消息分发到handler指定的位置(文件、网络、邮件等)。Logger对象可以通过addHandler()方法为自己添加0个或者多个handler对象。比如,一个应用程序可能想要实现以下几个日志需求:
1)把所有日志都发送到一个日志文件中;
2)把所有严重级别大于等于error的日志发送到stdout(标准输出);
3)把所有严重级别为critical的日志发送到一个email邮件地址。
这种场景就需要3个不同的handlers,每个handler复杂发送一个特定严重级别的日志到一个特定的位置。
一个handler中只有非常少数的方法是需要应用开发人员去关心的。对于使用内建handler对象的应用开发人员来说,似乎唯一相关的handler方法就是下面这几个配置方法:
方法 |
描述 |
Handler.setLevel() |
设置handler将会处理的日志消息的最低严重级别 |
Handler.setFormatter() |
为handler设置一个格式器对象 |
Handler.addFilter() |
为handler添加一个过滤器对象 |
需要说明的是,应用程序代码不应该直接实例化和使用Handler实例。因为Handler是一个基类,它只定义了素有handlers都应该有的接口,同时提供了一些子类可以直接使用或覆盖的默认行为。下面是python提供的全部handler。
Handler |
说明 |
StreamHandler |
实例将消息发送到流(类似文件的对象) |
FileHandler |
实例将消息发送到磁盘文件 |
BaseRotatingHandler |
是RotatingFileHandler和TimedRotatingFileHandler的基类 |
RotatingFileHandler |
实例将消息发送到磁盘文件,支持日志按大小切割 |
TimedRotatingFileHandler |
实例将消息发送到磁盘文件,支持按时间切割 |
SocketHandler |
实例将消息发送到TCP / IP套接字。 |
DatagramHandler |
实例将消息发送到UDP套接字。 |
SMTPHandler |
实例将消息发送到指定的电子邮件地址 |
SysLogHandler |
实例将消息发送到Unix syslog守护程序(可能在远程计算机上) |
NTEventLogHandler |
实例将消息发送到Windows NT / 2000 / XP事件日志。 |
MemoryHandler |
实例将消息发送到内存中的缓冲区,只要满足特定条件,该缓冲区就会被刷新。 |
HTTPHandler |
实例使用GET或POST语义将消息发送到HTTP服务器。 |
WatchedFileHandler |
实例监视他们正在登录的文件。如果文件更改,则使用文件名将其关闭并重新打开。该处理程序仅在类似Unix的系统上有用。Windows不支持所使用的基础机制。 |
QueueHandler |
实例将消息发送到队列,例如在queue或multiprocessing模块中实现的消息。 |
NullHandler |
实例不处理错误消息。希望使用日志记录但希望避免出现“找不到用于记录器XXX的处理程序”消息的库开发人员会使用它们,如果库用户未配置日志记录,则会显示该消息。有关更多信息,请参见为库配置日志。 |
3.Formater类
Formater对象用于配置日志信息的最终顺序、结构和内容。与logging.Handler基类不同的是,应用代码可以直接实例化Formatter类。
4.Filter类
Filter可以被Handler和Logger用来做比level更细粒度的、更复杂的过滤功能。Filter是一个过滤器基类,它只允许某个logger层级下的日志事件通过过滤。日志事件信息流如图所示。
二、Log级别
系统默认有6个级别,优先级:
级别 |
数值 |
使用时 |
CRITICAL |
50 |
严重错误,表明程序本身可能无法继续运行。 |
ERROR |
40 |
由于存在更严重的问题,该软件无法执行某些功能。 |
WARNING |
30 |
表示发生了意外情况,或者表示在不久的将来出现了某些问题(例如“磁盘空间不足”)。该软件仍按预期运行。 |
INFO |
20 |
确认一切正常。 |
DEBUG |
10 |
详细信息,通常仅在诊断问题时才需要。 |
NOTSET |
0 |
设置要打印的log时只需要设置优先级,比如设置打印INFO,那么比INFO优先级高的WARNING/ERROR/CRITICAL都将被打印,默认级别为WARNING。
三、Log格式
%(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 |
用户输出的消息 |
四、常用方式
1.不添加handler用法
import loggingLOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_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.")
打印日志结果
11/26/2020 04:14:38 AM - DEBUG - This is a debug log. 11/26/2020 04:14:38 AM - INFO - This is a info log. 11/26/2020 04:14:38 AM - WARNING - This is a warning log. 11/26/2020 04:14:38 AM - ERROR - This is a error log. 11/26/2020 04:14:38 AM - CRITICAL - This is a critical log. |
2.SysLogHandler
SysLogHandler是logging中的一个handler,是把日志输入的系统日志。
使用方法
import loggingfrom logging.handlers import SysLogHandlerlogger = logging.getLogger("kyc")logger.setLevel(logging.DEBUG)handler = SysLogHandler(address='/dev/log')logger.addHandler(handler)log = logging.getLogger("kyc")log.info("kangyucheng test SysLogHandler")
运行程序,可以发现。
在/var/log/messages中打印一条消息
当然,这个也可把日志配置到其他的位置。
3.RotatingFileHandler
RotatingFileHandler可以实现将日志按大小切割,当日志文件达到预设大小后,会将这个日志拷贝到一个新的文件当中。实现如下。
# -*- encoding= utf-8 -*-import loggingfrom logging.handlers import RotatingFileHandler"""log_file_name是日志路径file_size是文件切割大小log_level是日志级别backup_count是文件数量formatter是日志的格式"""rotating_log_conf = {"yuhceng": {"log_file_name": "/var/log/yucheng/yucheng.log","file_size": 5000,"log_level": logging.DEBUG,"backup_count": 10,"formatter": "yuhcheng:[%(levelname)s] %(pathname)s line-%(lineno)d:%(message)s"}}def config_log():for name, conf in rotating_log_conf.items():logger = logging.getLogger(name)log_level = conf.get("log_level", logging.INFO)logger.setLevel(log_level)rotating_handler = RotatingFileHandler(filename=conf.get("log_file_name"),maxBytes=conf.get("file_size", 0),backupCount=conf.get("backup_count", 0))rotating_handler.setFormatter(logging.Formatter(conf.get("formatter")))logger.addHandler(rotating_handler)if __name__ == '__main__':config_log()log = logging.getLogger("yucheng")for i in range(1000000000000):log.info("yucheng".format(str(i)))
结果如下。
4.TimedRotatingFileHandler
import loggingimport timefrom logging.handlers import TimedRotatingFileHandlerlogHandler = TimedRotatingFileHandler(filename="log/yucheng.log", when="S", interval=5,backupCount=3, encoding='utf-8')logHandler.suffix = "%Y%m%d%H%M"logFormatter = logging.Formatter('[%(asctime)s %(filename)s:%(lineno)d %(levelname)s] %(message)s')logHandler.setFormatter(logFormatter)logger = logging.getLogger('MyLogger')logger.addHandler(logHandler)logger.setLevel(logging.INFO)for k in range(30000000):logger.error("eror info: %d" % k)time.sleep(0.1)
log文件夹下面,每分钟会对日志进行切割,随时间变化。
5.自定义Handler,继承TimedRotatingFileHandler实现压缩
虽然TimedRotatingFileHandler可以实现按照时间切割,但是不能对日志文件压缩。可以通过继承TimedRotatingFileHandler,覆盖其doRollover方法,在该方法中实现压缩日志文件和删除旧日志文件。日志文件按照预期,压缩。
分别查看两个压缩后的日志内容,日志没有缺失。
实验结果表明,这种日志压缩的方式可行。
在查看日志的时候,不能够直接用vim 或vi或tail或cat查看,
需要使用zcat。
例如,把文件内容重定向到文件中
zcat test.log.2021-01-01_16-03-20.gz >>2.txt |
以上方法的有点在于,对于日志压缩确实能够实现日志空间减少。
但也引入了风险,压缩方法需要自行实现,若自行实现引入bug反而得不偿失。
五、其他说明
1.参考文献
https://docs.python.org/3/howto/logging.html
2.Python其他日志模块
syslog模块为提供了rsyslog模块的一个接口。可以记录程序运行时的输出信息。
使用方法
import syslog syslog.syslog("kangyucheng") |
运行程序,可以发现。
在/var/log/messages中打印一条消息
3. syslog与logging谁更好
(1)syslog只是对rsyslog的一个调用,依赖于系统rsyslog,而在实际的使用过程中rsyslog并不稳定。在系统运行过程中,日志多次报错。从这一点考虑要使用logging更好。
(2)当然上文说rsyslog并不稳定,也可能是在使用过程中配置有误。除此之外,仍有其他理由。软件的设计要高内聚低耦合,日志模块本属于软件程序本身,倘若将日志压缩等任务交给系统来做,显然不符合软件设计的理念。除此之外,每次部署都要去修改日志配置,这无疑增加了部署难度。
4. logging.SysLogHandler和syslog
SysLogHandler是logging中的一个handler。syslog是另外一个包,两个都可以将日志写入系统日志。
Python日志详解【两篇就够了系列】--第一篇logging相关推荐
- Python日志详解【两篇就够了系列】--第二篇loguru
目录 第二章 Python日志loguru库详解 一.loguru简介 二.日志级别 三.loguru日志常用参数配置解析 1.rotation 2.retention 3.compression 4 ...
- Python yield 详解(嚼碎了喂你,一篇精通,无需再看其他文章)
Python yield详解 文章目录 Python yield详解 由"斐波那契"深入理解yield案例 第一个版本 第二个版本 问题的引出 第三个版本 第四个版本 总结 细化总 ...
- Python|SQL详解之DDL|DML|DQL|DCL|索引|视图、函数和过程|JSON类型|窗口函数|接入MySQL|清屏|正则表达式|executemany|语言基础50课:学习(14)
文章目录 系列目录 原项目地址 第41课:SQL详解之DDL 建库建表 删除表和修改表 第42课:SQL详解之DML insert操作 delete 操作 update 操作 完整的数据 第43课:S ...
- JVM GC 日志详解
本文采用的JDK版本: java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) ...
- python 最小二乘法_最小二乘法及其python实现详解
最小二乘法Least Square Method,做为分类回归算法的基础,有着悠久的历史(由马里·勒让德于1806年提出).它通过最小化误差的平方和寻找数据的最佳函数匹配.利用最小二乘法可以简便地求得 ...
- Python数据类型详解03
原文博客地址: Python数据类型详解03 第一篇Python数据类型详解01中主要介绍了Python中的一些常用的数据类型的基础知识 第二篇Python数据类型详解02文章中, 详细介绍了数字(N ...
- pydicom读取头文件_.dcm格式文件软件读取及python处理详解
要处理一些.dcm格式的焊接缺陷图像,需要读取和显示.dcm格式的图像.通过搜集资料收集到一些医学影像,并通过pydicom模块查看.dcm格式文件. 若要查看dcm格式文件,可下echo viewe ...
- 基于模糊C均值聚类(FCM)的图像分割原理+python代码详解
一.模糊 "模糊":一个元素可以不同程度的属于某几个子集,也就是说元素对于集合的隶属度可以在[0,1]上取连续值. 二.步骤 2.1步骤 翻译一下: S1:初始化参数:加权指数m, ...
- MySQL管理之日志详解
MySQL日志详解 错误日志 MySQL的错误信息是在data目录下的 错误日志本身所定义的内容本身是可以定义的 编辑配置文件,定义错误日志: log-error=/path/to/xx.err ...
最新文章
- CEPH核心理论 相关导图(持续更新)
- 皮一皮:说了那么多,原来不是馋我的长相?
- 应用更新iOS 开发:应用内实现 更新提醒
- python无法安装tensorflow_python – 无法安装Tensorflow Mac
- filebeat获取nginx的access日志配置
- python 知识点记录二
- php 多表查询输出,ThinkPHP多表查询
- 双向链表(代码、分析、汇编)
- QQ浏览器怎样在首页显示优先推荐的网站
- 导入,导出字符和数字的转换
- keypairgenerator生成的公钥是不变的么_bitcoin 地址是如何生成的
- Android使用软引用和弱引用
- 聊聊Memcached的应用
- mysql存储日期 jsp_JSP+MySql的时间处理
- Shell脚本学习-阶段二十九-运维使用的
- python软件下载3版本-Python3.9下载
- 程序员应该练练太极拳
- Proteus软件初学笔记
- U盘被写保护无法格式化的解决方法
- 2D图片转3D模型软件介绍
热门文章
- Couldn‘t connect to session bus: Did not receive a reply. Possible causes include: the remote applic
- 元素与核素有什么区别?
- windows上不同版本的CUDA、cudnn是否能够共用?
- GCD Game 博弈论-Nim-质因数应用-质因数个数预处理
- Java进阶:Semaphore信号量基本使用
- Linux运维:如何根据端口号查看哪个应用占用?
- 快速排序法(思想及代码实现)
- 一年级大括号问题专项训练_一年级小学生自信满满地交了试卷,以为会考满分,结果很打脸...
- hadoop namenode启动不了_Hadoop框架:HDFS高可用环境配置
- java http参数传递_Java在HTTP请求中传递数组参数的方法