2020-09-17

logging

基本概念:

日志:日志可以记录我们一些软件的运行的情况,追踪某些软件在运行时所发生事件的方法。

作用:通过日志的记录与分析日志,我们可以快速的去了解一个程序是否允许正常,出现故障可以快速的去排查定位问题的所在点。

• 程序调试

• 了解软件程序运行情况,是否正常

• 软件程序运行故障分析与问题定位

• 用户行为分析

日志的等级(level):

不同的级别代表不同的概念(有轻有重),同样不同的应用程序所定义的日志级别也会有所差别,大致分为八种级别:

• DEBUG

• INFO

• NOTICE

• WARNING

• ERROR

• CRITICAL

• ALERT

• EMERGENCY

日志字段信息与日志格式:

一条日志信息对应的是一个事件的发生,而一个事件通常需要包括以下几个内容:

• 事件发生时间

• 事件发生位置

• 事件的严重程度–日志级别

• 事件内容

python中的logging:

logging模块是Python的一个标准库模块,定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统。

logging模块的日志级别:
描述日志等级(level数值
最详细的日志信息,典型应用场景是 问题诊断DEBUG10
信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作INFO20
当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的WARNING30,默认
由于一个更严重的问题导致某些功能不能正常运行时记录的信息ERROR40
当发生严重错误,导致应用程序不能继续运行时记录的信息CRITICAL50
logging模块的使用方式介绍:

logging模块提供了两种记录日志的方式:

• 第一种方式是使用logging提供的模块级别的函数

• 第二种方式是使用Logging日志系统的四大组件

一、使用logging提供的模块级别的函数

logging模块定义的模块级别的常用函数:

​ msg是传过去的信息,*args, **kwargs 分别为可变长参数和可变长关键字参数

函数说明
logging.debug(msg,*args, **kwargs)创建一条严重级别为DEBUG的日志记录
logging.info(msg,*args, **kwargs)创建一条严重级别为INFO的日志记录
logging.warning(msg,*args, **kwargs)创建一条严重级别为WARNING的日志记录
logging.error(msg,*args, **kwargs)创建一条严重级别为ERROR的日志记录
logging.critical(msg,*args, **kwargs)创建一条严重级别为CRITICAL的日志记录
logging.log(level, *args, **kwargs)创建一条严重级别为level的日志记录
logging.basicConfig(**kwargs)对root logger进行一次性配置

简单示例:

import logging

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.”)

测试:

>>> import logging

>>> logging.debug(“This is a debug log.”)

>>> logging.info(“This is a info log.”)

>>> logging.warning(“This is a warning log.”)

WARNING:root:This is a warning log.

>>> logging.error(“This is a error log.”)

ERROR:root:This is a error log.

>>> logging.critical(“This is a critical log.”)

CRITICAL:root:This is a critical log.

问题:为什么只输出warning、errocritical?

因为我们默认的日志等级是warning,只有级别大于等于warning的等级才会输出到屏幕。

这样的原因是一般低等级的错误一般不影响运行,如果全部记录就会影响性能,在程序的运行过程中、开发中就会用到debug、info等信息。

logging.basicConfig()

对于日志的格式我们可以进行一个配置,需要用到logging.basicConfig()。

参数名称描述
filename指定日志输出目标文件的文件名,指定该设置项后日志信息就不会被输出到控制台了
filemode指定日志文件的打开模式,默认为’a’。需要注意的是,该选项要在filename指定时才有效
format指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。logging模块定义的格式字段下面会列出。
datefmt指定日期/时间格式。需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效
level指定日志器的日志级别
stream指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。需要说明的是,stream和filename不能同时提供,否则会引发 ValueError异常
stylePython 3.2中新添加的配置项。指定format格式字符串的风格,可取值为’%’、’{‘和’$’,默认为’%’
handlersPython 3.3中新添加的配置项。该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,不能同时出现2个或3个,否则会引发ValueError异常。

logging模块定义的格式字符串字段

字段**/**属性名称使用格式描述
asctime%(asctime)s日志事件发生的时间–人类可读时间,如:2003-07-08 16:49:45,896
created%(created)f日志事件发生的时间–时间戳,就是当时调用time.time()函数返回的值
relativeCreated%(relativeCreated)d日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)
msecs%(msecs)d日志事件发生事件的毫秒部分
levelname%(levelname)s该日志记录的文字形式的日志级别(‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’)
levelno%(levelno)s该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)
name%(name)s所使用的日志器名称,默认是’root’,因为默认使用的是 rootLogger
message%(message)s日志记录的文本内容,通过 msg % args计算得到的
pathname%(pathname)s调用日志记录函数的源码文件的全路径
filename%(filename)spathname的文件名部分,包含文件后缀
module%(module)sfilename的名称部分,不包含后缀
lineno%(lineno)d调用日志记录函数的源代码所在的行号
funcName%(funcName)s调用日志记录函数的函数名
process%(process)d进程ID
processName%(processName)s进程名称,Python 3.1新增
thread%(thread)d线程ID
threadName%(thread)s线程名称

示例:

LOG_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.")


练习:

1、输出日志级别为error的日志

2、输出到文件取名test.log

3、日志格式: 时间-文件名-行数-日志等级:日志消息

4、日志的时间格式“22/May/2020 10:00:00”

做法:

import* logging
LOG_FORMAT = "%(asctime)s - %(filename)s - %(lineno)s - %(levelno)s - %(message)s"
Tim_FORMAT = "%d/%B/%Y %H:%M:%S"

logging.basicConfig(filename = 'test.log', level = logging.ERROR, format = LOG_FORMAT, datefmt=Tim_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.")

输出文件的结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JOCVUCr2-1600299345974)(file:///C:\Users\86155\AppData\Local\Temp\ksohtml15260\wps1.jpg)]

二、使用Logging日志系统的四大组件

logging日志模块四大组件

组件名称对应类名功能描述
日志器Logger提供了应用程序可一直使用的接口
处理器Handler将logger创建的日志记录发送到合适的目的输出
过滤器Filter提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录
格式器Formatter决定日志记录的最终输出格式

上面所使用的logging模块级别的函数也是通过这些组件对应的类来实现的。

这些组件之间的关系描述:

• 日志器(logger)需要通过处理器(handler)将日志信息输出到目标位置,如:文件、sys.stdout、网络等;

• 不同的处理器(handler)可以将日志输出到不同的位置;

• 日志器(logger)可以设置多个处理器(handler)将同一条日志记录输出到不同的位置;

• 每个处理器(handler)都可以设置自己的过滤器(filter)实现日志过滤,从而只保留感兴趣的日志;

• 每个处理器(handler)都可以设置自己的格式器(formatter)实现同一条日志以不同的格式输出到不同的地方。

简单点说就是:日志器(logger)是入口,真正干活儿的是处理器(handler),处理器(handler)还可以通过过滤器(filter)和格式器(formatter)对要输出的日志内容做过滤和格式化等处理操作。

logging模块组件的使用

使用组件记录日志的大致步骤如下:
1)logging.getLogger() 获取 logger对象
2)创建一个或多个 handler,用于指定日志信息的输出流向
3)创建一个或多个 formatter,指定日志的格式,并分别将 formatter 绑定到 上
4)将 handler 绑定到 logger对象 上
5)logger.setLevel(logging.DEBUG) 设置日志级别
5)最后便可使用 logger对象 记录日志

简单示例:

import logging

 

*#* 获取 *logger*对象

logger = logging.getLogger()

 

*#* 创建一个 *handler*,用于写入日志文件

fh = logging.FileHandler('test.log')

 

*#* 再创建一个 *handler*,用于输出到控制台

ch = logging.StreamHandler()

 

*#* 创建一个 *formatter*,两个 *handler* 使用相同的日志格式

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

 

*#* 绑定 *formatter* 到 *handler* 上

fh.setFormatter(formatter)

ch.setFormatter(formatter)

 

*#* 绑定 *handler* 到 *logger*对象 上

logger.addHandler(fh) *#logger*对象可以添加多个*fh*和*ch*对象

logger.addHandler(ch)

 

*#* 设置日志级别

logger.setLevel(logging.WARNING)

 

logger.debug('logger debug message')

logger.info('logger info message')

logger.warning('logger warning message')

logger.error('logger error message')

logger.critical('logger critical message')

练习:

test.log   test-2.log   test.log格式:时间-日志器名-文件名-等级-msg    test-2.log的格式: 时间-文件名-日志等级数字显示-msg

 

答案:

*import* logging

logger = logging.getLogger()

fh = logging.FileHandler("test1.log")
fh1 = logging.FileHandler("test2.log")
\# ch = logging.StreamHandler()

formatter = logging.Formatter("%(asctime)s - %(name)s -%(filename)s - %(levelname)s - %(message)s")
formatter1 = logging.Formatter("%(asctime)s --%(filename)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
fh1.setFormatter(formatter1)

\# ch.setFormatter(formatter)
\# ch.setFormatter(formatter1)

logger.addHandler(fh)
logger.addHandler(fh1)
\# logger.addHandler(ch)

logger.setLevel(logging.WARNING)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')
四大组件的解释:

Logger对象:

Logger对象最常用的方法分为两类:配置方法 和 消息发送方法

创建logger对象:

logging.getLogger()

logging.getLogger()方法有一个可选参数name,该参数表示将要返回的日志器的名称标识,如果不提供该参数,则其值为’root’,即根Logger。

Logger是层次结构的,使用 ‘.’ 点号分割,如’a’、‘a.b’或’a.b.c.d’,'a’是’a.b’的父parent,a.b是a的子child。

logger对象方法

方法描述
Logger.setLevel()设置日志器将会处理的日志消息的最低严重级别
Logger.addHandler() 和 Logger.removeHandler()为该logger对象添加 和 移除一个handler对象
Logger.addFilter() 和 Logger.removeFilter()为该logger对象添加 和 移除一个filter对象

handler类:

常用创建:

Handler描述
logging.StreamHandler将日志消息发送到输出到Stream,如std.out, std.err或任何file-like对象。
logging.FileHandler将日志消息发送到磁盘文件,默认情况下文件大小会无限增长
logging.handlers.RotatingFileHandler将日志消息发送到磁盘文件,并支持日志文件按大小切割(日志轮转)
logging.hanlders.TimedRotatingFileHandler将日志消息发送到磁盘文件,并支持日志文件按时间切割
logging.handlers.HTTPHandler将日志消息以GET或POST的方式发送给一个HTTP服务器
logging.handlers.SMTPHandler将日志消息发送给一个指定的email地址
logging.NullHandler该Handler实例会忽略error messages,通常被想使用logging的library开发者使用来避免’No handlers could be found for logger XXX’信息的出现。

logging.StreamHandler([strm]):可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息,默认是sys.stderr

FileHandler(filename[,mode]):和StreamHandler类似,用于向一个文件输出日志信息。mode是文件的打开方式,默认是‘a’

logging.handlers.RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]): 这个Handler类似于上面的FileHandler,但是它可以管理文件大小,文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出

​ maxBytes用于指定日志文件的最大文件大小,backupCount用于指定保留的备份文件的个数。

logging.handlers.TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]) 其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义

​ interval是时间间隔。when表示单位。

​ S 秒

​ M 分

​ H 小时

​ D 天

​ W 每星期

Handler对象的作用是(基于日志消息的level)将消息分发到handler指定的位置(文件、网络、邮件等)。Logger对象可以通过addHandler()方法为自己添加0个或者更多个handler对象。

方法描述
Handler.setLevel()设置handler将会处理的日志消息的最低严重级别
Handler.setFormatter()为handler设置一个格式器对象
Handler.addFilter() 和 Handler.removeFilter()为handler添加 和 删除一个过滤器对象

Formater类:

Formater对象用于配置日志信息的最终顺序、结构和内容。

构造方法:

logging.Formatter.init(fmt=None, datefmt=None, style=’%’)

• fmt:指定消息格式化字符串,如果不指定该参数则默认使用message的原始值

• datefmt:指定日期格式字符串,如果不指定该参数则默认使用"%Y-%m-%d %H:%M:%S"

• style:Python 3.2新增的参数,可取值为 ‘%’, ‘{‘和 ‘$’,如果不指定该参数则默认使用’%’

Filter类:

Filter是一个过滤器基类,它只允许某个logger层级下的日志事件通过过滤。

一个filter实例化时传递的name参数值为’A.B’,那么该filter实例将只允许名称为类似如下规则的loggers产生的日志记录通过过滤:‘A.B’,‘A.B,C’,‘A.B.C.D’,‘A.B.D’,而名称为’A.BB’, 'B.A.B’的loggers产生的日志则会被过滤掉。如果name的值为空字符串,则允许所有的日志事件通过过滤。

日志轮转:

作用:节约存储空间、方便查看。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UTsyucSV-1600299345983)(D:\有道云笔记\qq02FDCA8BE3AA1CFC42A579835F388591\81388ad3096448ccaf6ba227c48a8bbb\clipboard.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值