logging模块,Python自带用来记录日志的模块。

因为工作需要用到关于日志的,最近一直都在看关于日志模块的东西,百度了很多文章,可惜都是看的让人一头雾水,最后运气不错,找到一篇很详细的文章。传送门:https://www.cnblogs.com/testdjt/p/7834856.html

logging模块默认定义了以下几个日志等级

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

级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG >NOTSET 日志的信息量会依次减少

当指定一个日志级别之后,会记录大于或等于这个日志级别的日志信息,小于的将会被丢弃

Logging模块提供了两张记录日志的方式:

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

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

logging模块定义的模块级别函数

函数 说明
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("a")
logging.info("b")
logging.warning('c')
logging.error('d')
logging.critical('e')

只有后面三个打印出来了,因为默认级别是logging.warning,低于该级别的就不输出了

logging.basicConfig(level=logging.DEBUG)# 设置日志级别,需要大写
logging.debug("a")
logging.info("b")
logging.warning('c')
logging.error('d')
logging.critical('e')

Logging.basicConfig()需要在开头就设置,在中间设置没有作用

通过logging.basicConfig可以设置root的日志级别,和日志输出格式。

logging模块的四大组件

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

logging模块提供的模块级别的那些函数实际上也是通过这几个组件的相关实现类来记录日志的,只是在创建这些类的实例时设置了一些默认值

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

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

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

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

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

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

logger类

a = logging.getLogger('mylogger')

getLogger()返回一个logger实例,可以传入一个logger的名字,如果没有传,默认是root logger

如果传了,比如这里是mylogger,在输出日志时候,就会显示是mylogger下的

上面logging.info等,也是显示在root下的

a.setLevel(logging.INFO)

通过setLeverl()方法可以设置logger的日志输出级别

a.debug('xxxxxx')
a.info('cccccc')
#Logger.addHandler() 和 Logger.removeHandler() 为该logger对象添加 和 移除一个handler对象
#Logger.addFilter() 和 Logger.removeFilter() 为该logger对象添加 和 移除一个filter对象

需要之前的logging.basicConfig()的设置,才会输出这个,因为logger的handler还没有加

handler类

通过handler对象可以把日志内容写到不同地方,python提供了十几种实用的handler,比较常用的有:

类型 说明
StreamHandler 输出到控制台
FileHandler 输出到文件
BaseRotatingHandler  可以按时间写入到不同的日志中。比如将日志按天写入不同的日期结尾的文件文件
SocketHandler 用TCP网络连接写LOG
DatagramHandler 用UDP网络连接写LOG
SMTPHandler 把LOG写成EMAIL邮寄出去
fh = logging.FileHandler('D:/lesson/test1.txt')#创建一个输出到文件的handler对象,这个对象叫fh
fh.setLevel(logging.INFO)#给fh加上日志输出级别
a.addHandler(fh)#给logger添加handler
a.info('sfsdf')

常用的方法

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

Formater类

字段/属性名称 使用格式 描述
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)s pathname的文件名部分,包含文件后缀
module %(module)s filename的名称部分,不包含后缀
lineno %(lineno)d 调用日志记录函数的源代码所在的行号
funcName %(funcName)s 调用日志记录函数的函数名
process %(process)d 进程ID
processName %(processName)s 进程名称,Python 3.1新增
thread %(thread)d 线程ID
threadName %(thread)s 线程名称
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')#配置日志输出格式
fh.setFormatter(formatter)#给handle加上格式
a.info('')

formatter不像handler还需要先创建一个对应的实例,直接配置就可以了

详细学习了logging模块之后,开始封装自己的log类

1.需要把日志输出到指定路径,文件名为日期.log

2.需要记录所有文件信息,并且报错信息单独存放,这需要不同的handler

3.info和error需要不同的日志格式

我的文件结构

通过os.path.dirname(os.getcwd())获得项目名,也就是Vuiki。项目路径不同,使用的方法也不同。

使用os.path.join()将路径进行拼接,形成日志存放的路径

import logging
import time
import os class mylog(object):
def __init__(self,logger_name): #创建一个logger
self.logger= logging.getLogger(logger_name)
self.logger.setLevel(logging.INFO) #设置日志存放路径,日志文件名
#获取本地时间,转换为设置的格式
rq = time.strftime('%Y%m%d%H%M',time.localtime(time.time()))
#设置所有日志和错误日志的存放路径
all_log_path = os.path.join(os.path.dirname(os.getcwd()),'Logs/All_Logs/')
error_log_path = os.path.join(os.path.dirname(os.getcwd()),'Logs/Error_Logs/')
#设置日志文件名
all_log_name = all_log_path + rq +'.log'
error_log_name = error_log_path + rq +'.log' #创建handler
#创建一个handler写入所有日志
fh = logging.FileHandler(all_log_name)
fh.setLevel(logging.INFO)
#创建一个handler写入错误日志
eh = logging.FileHandler(error_log_name)
eh.setLevel(logging.ERROR)
#创建一个handler输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.INFO) #定义日志输出格式
#以时间-日志器名称-日志级别-日志内容的形式展示
all_log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#以时间-日志器名称-日志级别-文件名-函数行号-错误内容
error_log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(lineno)s - %(message)s')
#将定义好的输出形式添加到handler
fh.setFormatter(all_log_formatter)
ch.setFormatter(all_log_formatter)
eh.setFormatter(error_log_formatter) #给logger添加handler
self.logger.addHandler(fh)
self.logger.addHandler(eh)
self.logger.addHandler(ch) def getlog(self):
return self.logger

下面是测试代码

from Common import logger
logger = logger.mylog('test').getlog()
try:
logger.info('开始测试...')
r = 10/0
logger.info('result:',r)
except ZeroDivisionError as e:
logger.error('tests',exc_info=1)
logger.info('end')

这是输出到控制台的日志信息

这是所有的日志信息

这是错误的日志信息

使用exc_info=1可以把报错信息完整的打印进日志

Python3学习笔记25-logging模块的更多相关文章

  1. Python3学习笔记(urllib模块的使用)转http://www.cnblogs.com/Lands-ljk/p/5447127.html

    Python3学习笔记(urllib模块的使用)   1.基本方法 urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None,  ...

  2. Python3学习笔记(urllib模块的使用)

    转载地址:https://www.cnblogs.com/Lands-ljk/p/5447127.html 1.基本方法 urllib.request.urlopen(url, data=None,  ...

  3. 【转】Python3学习笔记(urllib模块的使用)

    原文地址:https://www.cnblogs.com/Lands-ljk/p/5447127.html 1.基本方法 urllib.request.urlopen(url, data=None,  ...

  4. python3学习笔记(7)_listComprehensions-列表生成式

    #python3 学习笔记17/07/11 # !/usr/bin/env python3 # -*- conding:utf-8 -*- #通过列表生成式可以生成格式各样的list,这种list 一 ...

  5. python3学习笔记(6)_iteration

    #python3 学习笔记17/07/10 # !/usr/bin/env python3 # -*- coding:utf-8 -*- #类似 其他语言的for循环,但是比for抽象程度更高 # f ...

  6. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

  7. Python3学习笔记 - 准备环境

    前言 最近乘着项目不忙想赶一波时髦学习一下Python3.由于正好学习了Docker,并深深迷上了Docker,所以必须趁热打铁的用它来创建我们的Python3的开发测试环境.Python3的中文教程 ...

  8. python3学习笔记(5)_slice

    #python3 学习笔记17/07/10 # !/usr/bin/env python3 # -*- coding:utf-8 -*- #切片slice 大大简化 对于指定索引的操作 fruits ...

  9. python学习笔记9--日志模块logging

    我们在写程序的时候经常会打一些日志来帮助我们查找问题,这次学习一下logging模块,在python里面如何操作日志.介绍一下logging模块,logging模块就是python里面用来操作日志的模 ...

随机推荐

  1. DHCP的原理和实现过程

    在DHCP过程中有两个对象DHCP客户端和DHCP服务端,而且DHCP在三层是通过可靠地TCP协议实现,DHCP服务运行在67和68端口. DHCP实现的简单过程,如图1所示, 图1 文字描述: 1. ...

  2. Segment 李超线段树

    题目大意: 要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第 i 条被插入的线段的标号为 i 2.给定一个数 k,询问与直线 x = k 相交的线段中,交点最靠上的线段的编号. 若 ...

  3. A1069. The Black Hole of Numbers

    For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in ...

  4. CodeBlocks: 生成的exe文件自定义一个图标

    CodeBlocks生成的exe文件的图标默认是系统图标,如何自定义一个漂亮的小图标呢? 我是C菜鸟,平时只用CodeBlocks练习c,也不开发什么软件,这个问题就难倒我了. 到网上搜索了一下,发现 ...

  5. jar文件放在桌面上双击启动不了,但放在其它任何文件夹里都可以双击启动

    今天本来是想尝试一下Java Network Launching Protocol (JNLP,java网络加载协议) 的,写了一个简单的窗口程序,打包成jar保存到桌面上,双击等了半天没显示出来. ...

  6. Flash10下复制到剪切板的一种新方法

    web开发中常常要实现“复制到剪切板”功能.这个功能很实用,但是由于安全问题,浏览器的限制越来越严,实现的方法也越来越有限了.Firefox默认下不能直接通过Javascript操作剪切板,必须开启相 ...

  7. Java 多线程间通信

    JDK 1.5 以后, 将同步和锁封装成了对象, 并将操作锁的隐式方法定义到了该对象中, 将隐式动作变成了显示动作. Lock 接口 Lock 接口, 位于 java.util.concurrent. ...

  8. (Catalan数 大数) Game of Connections poj2084

    Language: Game of Connections Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8837 Accept ...

  9. 【leetcode】 Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  10. frp中的json模块

    预备知识 Go中的接口的数据结构可以分为两部分: 其中一部分指向或者存储了原始数据的值 另一部分指向或者存储了原始数据的类型描述符(其中包含类型,以及对应于接口中的方法) 所以大体上我们可以粗略的认为 ...