橙好科技logging模块教程


文章目录

  • 1-logging介绍
  • 2-日志作用
  • 3-日志配置basicConfig
  • 3-日志级别level
  • 4-日志格式format
  • 4-输出日志到控制台
  • 5-输出日志到文件
  • 6-输出日志到控制台和文件
  • 7-骚操作

1-logging介绍

logging模块都知道是用来输出日志的,但是我们为什么要用它呢,他到底哪点好看?还是有特长?嘿嘿,今天超哥就来告诉你

以前我们都习惯用print,以为很方便,但是有利必有弊,print虽然能让你一时爽,后期代码部署上线,你需要挨个注释或者删除,代码冗余,费时费力。说到这里,logging的优势也就显而易见了,首先我们使用log代替print后,和print一样可以排查问题,更重要的是他可以全局统一管理,定制输出的日志格式,比如输出代码行,文件名称,日志时间,还可以根据代码逻辑分别输出调试日志和错误日志,更牛逼的是以后代码部署上线的时候,我们可以通过控制日志级别来控制哪些日志可以输出,哪些日志不再输出,是不是很强大?

2-日志作用

  1. ​ 方便排查问题
  2. ​ 对日志进行分级
  3. ​ 方便代码维护部署

先来看下最简单的日志输出代码:

代码示例:import logginglogging.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.")

输出:

日志说明:这是不配置日志时默认的输出内容

​ 1-日志级别 :2-根日志记录器 :3-日志内容

​ 相信你已经看到了,日志只输出了后三者(级别),因为日志默认warning级别,所以其他两个更低的级别不会输出了,但是这样的日志太简单了,不具有配置性,所以我们如果想要定制化的日志,就需要basicConfig了。

3-日志配置basicConfig

日志输出统一使用basicConfig进行配置,配置的参数如下:

参数 描述
filename 指定日志输出的文件名(fileHandler)如果不指定则默认输出到控制台。eg:filename=‘automatio.log’
filemode 指定打开文件的模式,如果指定了filename(如果文件模式未指定,则默认为’a’)。eg: filemode=‘a’
level 将根记录器级别设置为指定的级别。eg:level=loggin.INFO
format 为处理程序使用指定的格式字符串。eg: format=’%(name)s-%(asctime)s’
datefmt 使用指定的日期/时间格式。
handlers 如果指定,这应该是一个已经创建的处理程序的迭代器添加到根记录器。否则默认输出到控制台

代码示例:def log():#使用basicConfig配置日志,level和formatlogging.basicConfig(level=logging.INFO, format='%(name)s-%(asctime)s-%(levelname)s-%(message)s')#使用getLogger方法设置日志记录器,不设置的话默认:rootlogger = logging.getLogger('Test')return loggerlogger = log()
logger.info("这是定制化的日志")

输出:

3-日志级别level

​ log一共五个级别,分别是:

级别 数值
CRITICAL 50
ERROR 40
WARNING 30,默认
INFO 20
DEBUG 10
NOTSET 0

日志配置:basicConfig,默认控制台输出,默认日志级别是WARNING,低于该级别的就不输出了

级别排序 :CRITICAL > ERROR > WARNING > INFO > DEBUG

关于级别的解释:

  • debug : 级别最低的日志,最为详细的日志,一般用来排查问题

  • info : 一般可作为正常输出的日志

  • warning : 一般用来输出警告的日志,但是不会影响代码执行

  • error : 一般在出错的代码逻辑中使用,说明目前代码报错,用来输出具体的错误信息

  • critical : 最高级别日志,一般用在程序崩溃的日志输出

    这时候,如果需要显示低于WARNING级别的内容,可以引入NOTSET级别来显示:

代码示例1:import logging  # 引入logging模块logging.basicConfig(level=logging.INFO)  # 设置日志级别
logging.debug("这是debug级别的日志")       #因为预设置的日志级别为INFO,所以小于该级别的日志不输出
logging.info("这是debug级别的日志")        #正常输出

输出:

日志输出解释:

第一部分:INFO-为日志级别;

第二部分:root-为默认的日志记录器名称;如果通过getlogger指定日志记录器名称,则root会改为指定的名称

第三部分:这是debug级别的日志-这是日志内容

代码示例2:def log():logging.basicConfig(level=logging.DEBUG)logger = logging.getLogger('test')return loggerlogger = log()
logger.debug("这是设置了日志记录器的样子")

输出:

4-日志格式format

日志格式:%(name)s    -------日志器名称,如果不通过getlogger指定,则默认为root%(asctime)s -------日志生成时间%(filename)s ------输出日志的文件名称(源代码文件名)%(lineno)d  -------源代码的行号%(levelname)s -----日志级别%(message)s -------日志内容%(thread)d --------线程ID。可能没有%(threadName)s ----线程名。可能没有%(process)d -------进程ID。可能没有

根据需要添加指定的日志格式,可以让日志输出更加有效,排查问题更加方便。

代码示例:def log():#添加了两个参数,level和format(format内部出了固定的格式字符串,其他可以随便添加)logging.basicConfig(level=logging.INFO,format='%(name)s-%(asctime)s - %(filename)s-[line:%                    (lineno)d] - %(levelname)s -日志信息: %(message)s')logger = logging.getLogger('test')return loggerlogger = log()
logger.info("这是添加了日志格式的样子")

输出:

4-输出日志到控制台

basicConfig只要不配置filename参数,日志默认就会输出到控制台。

代码示例:#1、导入Logging包
import loggingdef log():#2、设置基础配置信息(level:日志级别,格式:)logging.basicConfig(level=logging.INFO,format='%(asctime)s-%(name)s-%(levelname)s-%(message)s')#3、定义日志名称getlogger,在输出日志的时候显示logger = logging.getLogger("log_demo")return loggerif __name__ == '__main__':logger = log()logger.debug("debug")logger.info("info")logger.warning("warning")

输出:

5-输出日志到文件

basicConfig只要配置filename参数,日志默认就会输出到指定文件。

代码示例:#1、导入Logging包
import loggingdef log():#2、设置基础配置信息(level:日志级别,格式:)logging.basicConfig(filename='my.log',level=logging.INFO,format='%(asctime)s-%(name)s-%(levelname)s-%     (message)s')#3、定义日志名称getlogger,在输出日志的时候显示logger = logging.getLogger("log_demo")return loggerif __name__ == '__main__':logger = log()logger.debug("我是debug日志")logger.info("我是info日志")logger.warning("我是warning日志")

输出:(当前目录下会自动生成一个名为“my.log”的文件)文件内容如图:

注:如果pycharm打开的日志乱码,修改一下pycharm右下角的编码格式为GBK即可

图:控制台和文件你都会了,还想怎样?

6-输出日志到控制台和文件

​ 上面我们可以做到让日志输出到控制台,也可以让其输出到指定文件,那如果我们想要即输出到控制台,也输出到文件该怎么办呢,这时候就用到handler了。

在讲handler之前,我们先来看下log的高级需要掌握哪些东西,logging模块包括logger,handler,filter,formatter这四个基本概念。:

  1. logger 提供了应用程序可以直接使用的接口
  2. handler将(logger创建的)日志记录发送到合适的目的输出
  3. filter提供了细度设备来决定输出哪条日志记录
  4. formatter决定日志记录的最终输出格式
  • logger:提供日志接口,供应用代码使用。logger最常用的操作有两类:配置和发送日志消息。可以通过logging.getLogger(name)获取logger对象,如果不指定name则返回root对象,多次使用相同的name调用getLogger方法返回同一个logger对象。
  • handler:将日志记录(log record)发送到合适的目的地(destination),比如文件,socket等。一个logger对象可以通过addHandler方法添加0到多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。
  • filter:提供一种优雅的方式决定一个日志记录是否发送到handler。
  • formatter:指定日志记录输出的具体格式。formatter的构造方法需要两个参数:消息的格式字符串和日期字符串,这两个参数都是可选的。

那么我们想要输出到控制台和文件就得需要两个handler,如下:

​ logging.StreamHandler: 日志输出到流,可以是sys.stderr、sys.stdout或者文件
​ logging.FileHandler: 日志输出到文件

图:废话少说,上代码

函数写法:

代码示例:'''
功能描述:实现控制台和文件同时记录日志的功能
编写人:liangchao
编写日期:2021年2月8日步骤分析:1-配置日志记录器名称2-配置日志级别3-配置日志格式(可以分别设置,也可以统一设置)4-创建并添加handler-控制台5-创建并添加handler-文件6-提供对外获取logger'''import logging
import sysdef log():# 1 - 配置日志记录器名称logger = logging.getLogger('AutoTest')# 2-配置日志级别logger.setLevel(logging.DEBUG)# 3-配置日志格式(可以分别设置,也可以统一设置)format = logging.Formatter('%(name)s-%(asctime)s-%(message)s')# 4 - 创建并添加handler - 控制台sh = logging.StreamHandler()sh.setFormatter(format)logger.addHandler(sh)# 5 - 创建并添加handler - 文件fh = logging.FileHandler('test.log')fh.setFormatter(format)logger.addHandler(fh)# 6 - 提供对外获取loggerreturn loggerif __name__ == '__main__':logger = log()logger.info('使用函数定义的log方法')

下面 是面向对象的写法:

class Log():def __init__(self):"""配置logger记录器名称配置日志级别配置日志格式"""self.logger = logging.getLogger('AutoTest')self.logger.setLevel(logging.DEBUG)self.format = logging.Formatter('%(name)s-%(asctime)s-%(message)s')def __addstreamHan(self):"""定义添加控制台输出handler"""sh = logging.StreamHandler()sh.setFormatter(self.format)self.logger.addHandler(sh)def __addfileHan(self):"""定义添加写入文件handler"""fh = logging.FileHandler('test.log')fh.setFormatter(self.format)self.logger.addHandler(fh)def getLog(self):"""定义对外提供logger的方法注意:此处的方法不要定义为getLogger,否则就是重写log的方法了"""self.__addstreamHan()self.__addfileHan()return self.loggerif __name__ == '__main__':logger = Log().getLog()logger.info('1234?')

注:

​ 1-如何实现部署上线的时候通过控制级别来搞定不输出额外日志?

​ 答:假设我们定义日志级别为DEBUG,在调试输出的时候大部分使用的是logger.debug(‘xxxx’),这时候只需要修改日志级别为更高级别,那么级别为debug的日志就不会再输出

​ 2-如何实现控制台和文件分别输出不同日志格式的日志

​ 答:只需要在定义不同的handler时定义不同的格式即可,比如:

​ format1 = logging.Formatter(‘xxxxx’)

​ format2 = logging.Formatter(‘xxxxx’)

​ fh.setFormatter(self.format1)

​ sh.setFormatter(self.format2)

​ 3-日志打印重复的问题

​ 在我们导入写好的log文件时,比如,当前目录下存在文件:streamAndFileLog.py(内容同上方函数写法),在另外一个文件中导入该文件:

from 日志模块.streamAndFileLog import loglog().info('xxx1')log().info('xxx2')log().info('xxx3')

输出:

这个结果什么鬼?明明三句话,打印出来这么多,这其实是log在使用的常遇到的坑,通过debug你会发现,每次调用都会创建句柄,所以重复,如图:

第一句调用之后,handlers里面已经存在了两个handler,分别是控制台句柄StreamHandler和文件句柄FileHandler,下面图中是第二句调用添加句柄

执行后会发现handlers里面多了一个StreamHandler

怎么解决这种情况,有两个方案,咱们分别列出两种方案代码:

第一种,第一使用单例模式,在log.py文件中增加一行:logger = log() ,这句的作用就是提前实例化好对象,其他模块使用都适用该对象,所以别的模块导入语句要改成:from xxx包.log import logger ,然后使用logger.info(‘xxxx’) 输出日志即可

   ……省略上方代码# 6 - 提供对外获取logg的方法return logger
#增加一行
logger = log()if __name__ == '__main__':logger = log()logger.info('使用函数定义的log方法')

导入:

from 日志模块.streamAndFileLog import loggerlogger.info('xxx1')logger.info('xxx2')logger.info('xxx3')

输出:

第二个方案:log.py每次判断handlers是否已存在

    ……# 4 - 创建并添加handler - 控制台sh = logging.StreamHandler()sh.setFormatter(format)# 5 - 创建并添加handler - 文件fh = logging.FileHandler('test.log')fh.setFormatter(format)#在新增handler时判断是否为空if not logger.handlers:logger.addHandler(sh)logger.addHandler(fh)# 6 - 提供对外获取logg的方法return loggerif __name__ == '__main__':logger = log()logger.info('使用函数定义的log方法')

导入文件代码保持不变:

from 日志模块.streamAndFileLog import loglog().info('xxx1')log().info('xxx2')log().info('xxx3')

输出:

针对面向对象的方案同样是以上两个,请同学们自行解决,如果有任何问题可以联系橙好科技。

介绍到这里,对于log的掌握已经满足日常工作的需要了,接下来的内容可以作为扩展,不再要求必须掌握

7-骚操作

下面看看两种比较实用的日志handler,RotatingFileHandler和TimedRotatingFileHandler

  1. logging.handlers.RotatingFileHandler -> 按照大小自动分割日志文件,一旦达到指定的大小重新生成文件

这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

代码示例:

import logging
import logging.handlers
import sys
import timedef log():# 1 - 配置日志记录器名称logger = logging.getLogger('AutoTest')# 2-配置日志级别logger.setLevel(logging.DEBUG)# 3-配置日志格式(可以分别设置,也可以统一设置)format = logging.Formatter('%(name)s-%(asctime)s-%(message)s')# 5 - 创建并添加handler - 文件,filename为生成日志的文件名称,模式为追加,最大日志文件为100个字节,备份文件的最大数量为5个fh = logging.handlers.RotatingFileHandler(filename="rotating.log", mode='a', maxBytes=100, backupCount=5)fh.setFormatter(format)logger.addHandler(fh)# 6 - 提供对外获取logg的方法return loggerif __name__ == '__main__':logger = log()while True:time.sleep(0.01)logger.info('日志按照文件大小自动切割')

输出:

  1. logging.handlers.TimedRotatingFileHandler -> 按照时间自动分割日志文件

这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨

代码示例:

import logging
import logging.handlers
import sys
import timedef log():# 1 - 配置日志记录器名称logger = logging.getLogger('AutoTest')# 2-配置日志级别logger.setLevel(logging.DEBUG)# 3-配置日志格式(可以分别设置,也可以统一设置)format = logging.Formatter('%(name)s-%(asctime)s-%(message)s')# 添加TimedRotatingFileHandler,间隔2s切割一次,保留3个旧log文件备份fh = logging.handlers.TimedRotatingFileHandler("timeRotaingHandler.log", when='S', interval=2, backupCount=3)# 设置后缀名称,跟strftime的格式一样fh.suffix = "%Y-%m-%d_%H-%M-%S.log"fh.setFormatter(format)logger.addHandler(fh)# 6 - 提供对外获取logg的方法return loggerif __name__ == '__main__':logger = log()while True:time.sleep(0.01)logger.info('日志按照时间自动切割')

输出:

最终log文件咱们就算介绍完了,还不赶紧关注,扫码!


Python日志模块logging,这一篇就够了相关推荐

  1. Python日志详解【两篇就够了系列】--第一篇logging

    目录 第一章 Python日志模块logging详解 一.logging的框架 1.Logger 2.Handler 3.Formater类 4.Filter类 二.Log级别 三.Log格式 四.常 ...

  2. Python日志模块logging高级用法

    推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国,清华大学出版社,2020年6月第1次印刷,2021年12月第11次印刷,山东省一流 ...

  3. python logging模块的作用_【python】【logging】python日志模块logging常用功能

    logging模块:应用程序的灵活事件日志系统,可以打印并自定义日志内容 logging.getLogger 创建一个log对象 >>> log1=logging.getLogger ...

  4. python日志模块----logging

    使用Python的logging模块能很好的帮我们完成程序的日志功能,其实它跟Java中的log4j有不少相似的地方.下面记录下今天学习到的logging的知识(因为有一些还没真正使用过,不知道是否说 ...

  5. Python日志详解【两篇就够了系列】--第二篇loguru

    目录 第二章 Python日志loguru库详解 一.loguru简介 二.日志级别 三.loguru日志常用参数配置解析 1.rotation 2.retention 3.compression 4 ...

  6. python 日志模块 logging

    如何使用python自带的 logging 模块实现日志功能 1.初始化一个logger对象 1)引入模块 import os import logging import sys 2)初始化变量,声明 ...

  7. Python:日志模块logging的应用

    2019独角兽企业重金招聘Python工程师标准>>> 在Python中,上面以实现的和已经实现的,均可以使用logging模块迅速搞定,且仅仅只需要一个配置文件,两行代码,实现过程 ...

  8. python logging模块的作用_Python 日志模块logging分析及使用-2

    本文作为Python日志模块的补充,主要介绍日志回滚RotatingFileHandler和TimedRotatingFileHandler的使用,以及其所带来的问题.Logger对象的日志等级是如何 ...

  9. 【Python】—日志模块logging使用详解1

    文章目录 1.日志级别 2.logging流程 3.几个重要的类 3.1 Logger类 1) 最常用的配置方法 2) 创建`Logger`对象`logging.getLogger([name])` ...

最新文章

  1. 一条 update 语句引起的事故,这回让开发长长记性!!
  2. QQ网页链接打开本地QQ.exe原理
  3. 实战Python:详解利用Python和Pygame实现飞机大战
  4. linux 修改文件夹权限_Linux新手非常实用的20个命令
  5. IntelliJ IDEA如何去掉xml文件背景色
  6. 8.input设备(input子系统)驱动
  7. 关于fragstats内存问题
  8. 搬运: CVonline: 图像数据库(二) (更新于20190821)
  9. 中国移动一句话 苹果丢掉“两个诺基亚”_-Chaz-_新浪博客
  10. 到大观园晨光茶社现场听了场相声
  11. win10应用商店恢复
  12. 第21批符合道路运输车辆卫星定位系统标准 及规范的车载终端
  13. 洛谷 P5322 [BJOI2019]排兵布阵
  14. DOM是什么意思-前端入门
  15. 【转】ST、SC、FC、LC光纤接头区别
  16. 时间同步,自动驾驶里的花好月圆
  17. 简单的《找不同汉字版》,来考考你的眼力吧
  18. Excel查找字符串下标(findsearch)
  19. Web项目的Excel文件上传、解析、导入
  20. 哪吒之魔童降世视听语言影评_《哪吒之魔童降世》影评4篇

热门文章

  1. python特征选择后显示选取的特征名_特征选择 (feature_selection)
  2. P2-Vue-supermall项目-初始化目录结构
  3. python函数操作_python_函数的基本操作
  4. 电商项目实战之缓存与Redis分布式锁
  5. ios 制作手机端拼图游戏及衍生的其他内容
  6. python协程和线程_线程和协程之间的区别
  7. tomcat 配置环境变量
  8. 优化C语言代码常用的几招
  9. 基于AVALON总线的IP核定制 PWM
  10. ANSYS Topology Optimization拓扑优化技术在轻量化设计应用概述