我们在写程序的时候经常会打一些日志来帮助我们查找问题,这次学习一下logging模块,在python里面如何操作日志。
介绍一下logging模块,logging模块就是python里面用来操作日志的模块,logging模块中主要有4个类,分别负责不同的工作:

Logger 记录器,暴露了应用程序代码能直接使用的接口;简单点说就是一个创建一个办公室,让人在里头工作

Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地;这个简单点说就是办事的人,你可以指定是让在控制输出日志,还是在文件里面打印日志,常用的有4种:

StreamHandler 控制台输出

FileHandler 文件输出

下面两种需要导入

handlers
                        from logging import handlers

TimedRotatingFileHandler 按照时间自动分割日志文件

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

Filter
过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。(不常用)

Formatter
格式化器,指明了最终输出中日志记录的布局。指定输出日志的格式

import logging
from logging import handlers
#只在控制台打印日志
logging.basicConfig(level=logging.ERROR,#控制台打印的日志级别
format=
'%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
#日志格式
)
logging.debug('debug级别,最低级别,一般开发人员用来打印一些调试信息')
logging.info('info级别,正常输出信息,一般用来打印一些正常的操作')
logging.warning('waring级别,一般用来打印警信息')
logging.error('error级别,一般用来打印一些错误信息')
logging.critical('critical级别,一般用来打印一些致命的错误信息')

日志级别 debug < info < warning < error < critical
设置了日志级别之后,会打印该级别以及比该级别高的所有日志,举个例子,如果日志级别是warning,那么就会打印warning、error、critical,这三个级别的日志,不会打印debug和info级别的,如果是debug,最低级别的日志,那么所有的日志都会打印。
上面的只是在控制台打印日志,并没有把日志写在文件里面,一般我们都会把日志写在日志文件里面,也很简单,只需要加个参数指定文件名就行了。

logging.basicConfig(level=logging.ERROR,#控制台打印的日志级别
filename='log.txt',#文件名
filemode='a',#模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
#a是追加模式,默认如果不写的话,就是追加模式
format=
'%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
#日志格式
)
logging.debug('debug级别,最低级别,一般开发人员用来打印一些调试信息')
logging.info('info级别,正常输出信息,一般用来打印一些正常的操作')
logging.warning('waring级别,一般用来打印警信息')
logging.error('error级别,一般用来打印一些错误信息')
可以指定日志的输出格式format,这个参数可以输出很多有用的信息,如下面的几种格式:
%(levelno)s: 打印日志级别的数值 %(levelname)s: 打印日志级别名称 %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0] %(filename)s: 打印当前执行程序名 %(funcName)s: 打印日志的当前函数 %(lineno)d: 打印日志的当前行号 %(asctime)s: 打印日志的时间 %(thread)d: 打印线程ID %(threadName)s: 打印线程名称 %(process)d: 打印进程ID %(message)s: 打印日志信息 我在工作中给的常用格式在前面已经看到了。就是:
format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
这个格式可以输出日志的打印时间,是哪个文件第几行输出的,输出的日志级别是什么,以及输入的日志内容。

加上文件名之后就会发现控制台不会输出日志了,日志文件也产生了,那么如何既在控制台输出日志,也在文件中写入呢?

怎么实现呢,就得有个办公室,里面塞俩人,一个给负责往控制台输出日志,一个负责写文件,你把他俩往办公室一塞,他俩就能干活了。

import logging
from logging import handlers
logger = logging.getLogger('my_log')
#先创建一个logger对象,相当于这个办公室,也就是上面说的Logger
logger.setLevel(logging.INFO)#设置日志的总级别
fh = logging.FileHandler('test.log',mode='a',encoding='utf-8')#创建一个文件处理器,也就是把日志写到文件里头
fh.setLevel(logging.INFO)#设置文件输出的级别
sh = logging.StreamHandler()#创建一个控制台输出的处理器,这两个就是上面说的Handler
sh.setLevel(logging.INFO)
#设置控制台输出的日志级别,这两个级别都可以单独设置,他们俩和logger的级别区别是如果logger设置的级别比里面的handler级别设置的高,那么就以logger的级别为准
th = handlers.TimedRotatingFileHandler('time',when='S',interval=1,backupCount=2)
#指定间隔时间自动生成文件的处理器
#interval是时间间隔,backupCount是备份文件的个数,如果超过这个超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
# S 秒
# M 分
# H 小时、
# D 天、
# W 每星期(interval==0时代表星期一)
# midnight 每天凌晨
th.setLevel(logging.INFO)
formater = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
#指定日志格式,上面咱们写了常用的格式,直接指定了就行了,这也就是咱们上面说的Formatter
sh.setFormatter(formater)
fh.setFormatter(formater)
th.setFormatter(formater)
#设置两个处理器的日志格式 logger.addHandler(sh)
logger.addHandler(fh)
logger.addHandler(th)
#把两个handler加入容器里头,相当于把工作人员培训完了,你们可以上班了
logger.debug('debug级别,最低级别,一般开发人员用来打印一些调试信息')
logger.info('info级别,正常输出信息,一般用来打印一些正常的操作')
logger.warning('waring级别,一般用来打印警信息')
logger.error('error级别,一般用来打印一些错误信息')
logger.critical('critical级别,一般用来打印一些致命的错误信息')

这样logger这个日志办公室已经搞好了,咱们就可以直接用了,运行完发现文件也产生了,控制台也有日志。如果不设置日志级别的话,默认级别是waring。
下面我们自己封装一个类来使用logging模块,方便使用,默认加一些配置

import logging
from logging import handlers
class Logger(object):
level_relations = {
'debug':logging.DEBUG,
'info':logging.INFO,
'warning':logging.WARN,
'error':logging.ERROR,
'crit':logging.CRITICAL
}#日志级别关系映射
def __init__(self,fp,level='debug',when='midnight',interval=1,backCount=5,encoding='utf-8'):
''' :param fp:日志文件路径
:param level: 日志级别 默认是debug
:param when: 分割日志的单位 S 秒、M 分、 H 小时、 D 天、 W 每星期(interval==0时代表星期一)、midnight 每天凌晨
:param interval: 时间间隔 默认每天凌晨
:param backCount: 备份文件个数 默认5个
:param encoding: 日志文件编码
'''
self.level = self.level_relations.get(level)
self.logger = logging.getLogger(fp)
self.logger.setLevel(self.level)
fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
sh = logging.StreamHandler()
sh.setFormatter(fmt)
sh.setLevel(self.level)
th = handlers.TimedRotatingFileHandler(fp,when=when,interval=interval,backupCount=backCount,encoding=encoding)
th.setFormatter(fmt)
th.setLevel(self.level)
self.logger.addHandler(th)
self.logger.addHandler(sh)
def debug(self,msg):
self.logger.debug(msg)
def info(self,msg):
self.logger.info(msg)
def warning(self,msg):
self.logger.warning(msg)
def error(self,msg):
self.logger.error(msg)
def crit(self,msg):
self.logger.critical(msg)
if __name__ == '__main__':
l = Logger('a.log')#实例化
l.info('hehehe')#调用

  

  

  

  

python学习笔记9--日志模块logging的更多相关文章

  1. python中的第三方日志模块logging

    基本上每个系统都有自己的日志系统,可以使自己写的,也可以是第三方的.下面来简单介绍一下python中第三方的日志模块,入手还是比较简单的,但是也很容易给自己埋雷. 下面是我参考的资料链接 入手demo ...

  2. python学习笔记之常用模块(第五天)

    参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...

  3. Python学习笔记十一:模块

    标准库(内置模块) time与datetime 模块 时间表示方式 1.时间戳 2.格式化的字符串 3.元组形式 时间戳就是一个秒数 x=time.time(),从1970年1月1日0时0分0秒到现在 ...

  4. Python 学习笔记(6)--常用模块(2)

    一.下载安装 下载安装有两种方式: yum\pip\apt-get 或者源码 下载源码 解压源码 进入目录 编译源码 python setup.py build 安装源码 python setup.p ...

  5. python学习笔记13(模块、包)

    在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 模块文件以.py后缀结 ...

  6. Python学习笔记十_模块、第三方模块安装、模块导入

    一.模块.包 1.模块 模块实质上就是一个python文件.它是用来组织代码的,意思就是把python代码写到里面,文件名就是模块的名称,test.py test就是模块的名称 2.包 包,packa ...

  7. Python学习笔记:bisect模块实现二分搜索

    在Python中可以利用bisect模块来实现二分搜索,该模块包含函数只有几个: import bisect L = [1,3,4,5,5,5,8,10] x = 5 bisect.bisect_le ...

  8. python学习笔记(六):常用模块

    一.模块.包 什么是模块? 模块实质上就是一个python文件,它是用来组织代码的,意思就是说把python代码写到里面,文件名就是模块的名称,test.py test就是模块名称. 什么是包? 包, ...

  9. 吴裕雄--天生自然python学习笔记:Python3 模块

    Python3 模块 在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了. 为此 Python 提供了一个办 ...

随机推荐

  1. pycharm5.0 快捷键大全osx

    官网链接https://resources.jetbrains.com/assets/products/pycharm/PyCharm_ReferenceCard_mac.pdf 一直想给别人安利py ...

  2. 自省 另外一种python 生成随机在base36 之间的兑换码生成。

    放假无聊,翻看自己博客的时候发现自己前面写的 那个base36兑换码在翻阅的时候 想到一个更简单的办法实现.但是随机上来说可能没有前者那么高 但是觉得也没有多大的问题 发上来 自己再想想 import ...

  3. rhel6+apache2.4+mysql5.7+php5.6部署LAMP架构

    rhel6+apache2.4+mysql5.7+php5.6部署LAMP架构 2017年10月01日 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~准备阶段~~~~~~~~~~~~~ ...

  4. Bootstrap手风琴效果

    前面的话 Bootstrap 框架中 Collapse插件(折叠)其实就是我们常见的手风琴效果.当单击一个触发元素时,在另外一个可折叠区域进行显示或隐藏,再次单击时可以反转显示状态.经典的场景是多个折 ...

  5. CSS实现水平居中的5种思路

    前面的话 水平居中是经常遇到的问题.看似方法较多,条条大路通罗马.但系统梳理下,其实都围绕着几个思路展开.本文将介绍关于水平居中的5种思路 text-align [思路一]:在父元素中设置text-a ...

  6. codeforces146A

    Lucky Ticket CodeForces - 146A Petya loves lucky numbers very much. Everybody knows that lucky numbe ...

  7. codeforces 777C

    C.Alyona and Spreadsheet During the lesson small girl Alyona works with one famous spreadsheet compu ...

  8. 【BZOJ1880】[Sdoi2009]Elaxia的路线(最短路)

    [BZOJ1880][Sdoi2009]Elaxia的路线(最短路) 题面 BZOJ 洛谷 题解 假装我们知道了任意两点间的最短路,那么我们怎么求解答案呢? 不难发现公共路径一定是一段连续的路径(如果 ...

  9. List does not exist. The page you selected contains a list that does not exist. It may have been deleted by another user

    当我在subsite里点击"Add a document",报这个错,后来一看event log: 在AAM里加上一条: 问题搞定:

  10. 牛客练习赛 小D的剑阵 解题报告

    小D的剑阵 题意链接: https://ac.nowcoder.com/acm/contest/369/F 来源:牛客网 现在你有 \(n\) 把灵剑,其中选择第i把灵剑会得到的 \(w_i\) 攻击 ...