最近的任务经常涉及到日志的记录,特意去又学了一遍logging的记录方法。跟java一样,python的日志记录也是比较繁琐的一件事,在写一条记录之前,要写好多东西。典型的日志记录的步骤是这样的:

创建logger

创建handler

定义formatter

给handler添加formatter

给logger添加handler

写成代码差不多就是酱婶的(这个是照别的网页抄的,参考附注):

1 import logging

2

3 # 1、创建一个logger

4 logger = logging.getLogger('mylogger')

5 logger.setLevel(logging.DEBUG)

6

7 # 2、创建一个handler,用于写入日志文件

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

9 fh.setLevel(logging.DEBUG)

10

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

12 ch = logging.StreamHandler()

13 ch.setLevel(logging.DEBUG)

14

15 # 3、定义handler的输出格式(formatter)

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

17

18 # 4、给handler添加formatter

19 fh.setFormatter(formatter)

20 ch.setFormatter(formatter)

21

22 # 5、给logger添加handler

23 logger.addHandler(fh)

24 logger.addHandler(ch)

之后才可以正式的开始记录日志。Java里面的java.util.Logging类差不多也是这样,代码还要更复杂一点。Golang的日志相对写法简单一些,不过没有什么格式,系统记录一条时间,内容格式完全自己手画。第三方的日志库倒是没有接触过,像Java的Log4j,Golang的log4go和seelog等等,不知道用起来会不会简单一点。我一直都记不住这些,因为不太理解logger和handler为什么要这样写。一直到这次任务中出现的在我看来相当“诡异”的bug,才深入理解了一下。

我的任务是这样的,要做一个日志切割的工具,按天将日志分割开,即每天0点产生一个新日志,将旧日志改名。并且,将超过3个月的日志删除掉,以保证磁盘空间不会被log占满。程序要求可以切割多个目录中的不同日志,具体路径由json中配置。

这里用到了logging.handlers类中的TimedRotatingFileHandler方法,用以获得一个handler。大概的写法为:

1 logger = logging.getLogger() #获得logger

2 handler = logging.handlers.TimedRotatingFileHandler(logfile, 'S', 1, 0) #切割日志

3 handler.suffix = '%Y%m%d' #切割后的日志设置后缀

4 logger.addHandler(handler) #把logger添加上handler

5 logger.fatal(datetime.datetime.now().strftime('%Y-%m-%d')) #在新日志中写上当天的日期

这里我没有设置level和formatter。因为只是分割,对新日志没有什么影响。TimedRotatingFileHandler函数的方法见附注,或查看python的源码,这个函数是python写的,可以找到定义。这里我使用的是每秒生成一个新的日志文件,之后用Crontab在每天0点调度,然后用for循环处理json中的每一个日志文件。

但是奇怪的是,每次运行程序,第一个切割的日志生成一个分割后的文件,而后面的都生成两个新日志。百思不得其解。后检查代码觉得,可能是程序中设置的时间太短了,每秒生成一个文件,有可能一秒钟处理不完,就生成了两个。虽然这个说法没有什么科学根据,但是还是把TimedRotatingFileHandler中的第三个参数改成了60,即每60秒生成一个文件。完成,静静的等待crontab到时间。

叮!时间到。赶紧检查一下结果。一个好消息和一个坏消息。好消息是这次每个日志都只切割生成了一个新文件,没有生成两个。坏消息是每个文件里面添加的当天的日期的数量见鬼了。我切割了4条日志,生成的新日志里面就分别写上了一、二、三、四行当天日期。

此刻我的内心几乎是崩溃的。我开始思考为什么会这样。很明显四行日期是调用了4次logger.fatal('datetime.datetime.now().strftime('%Y-%m-%d')) 这个函数。换句话说,我每一次for循环都在这个log里面写了一句话。可是明明每个for是处理一个日志,下一次for应该是处理下一个日志的,为什么会再处理这个日志一次?我突然想到,logger.addHandler(handler)是每次循环都会运行的,也就是说,logger是同一个logger,添加了4次handler。到第4次循环的时候,这个logger中有4个handler,也就会往4个不同的日志中添加内容了。呃。

如果是这样的话,那么把上面的程序改改,第一句和最后一句放在循环外,循环内只用中间的三句。这次OK了。回头再看log记录的步骤,也就明白了logger和handler到底是个什么鬼:logger可以看做是一个记录日志的人,对于记录的每个日志,他需要有一套规则,比如记录的格式(formatter),等级(level)等等,这个规则就是handler。使用logger.addHandler(handler)添加多个规则,就可以让一个logger记录多个日志。至于logging.getLogger()方法获得的root logger和继承关系,可以详见附注的网页,这里我也只是大概明白了什么意思,还没有具体用过。也许将来在框架中使用,要记录较为复杂的日志时候会用到吧。

python中的logger模块

logger 提供了应用程序可以直接使用的接口handler将(logger创建的)日志记录发送到合适的目的输出filter提供了细度设备来决定输出哪条日志记录formatter决定日志记录的最终输出 ...

python中的logger模块详细讲解

logger 提供了应用程序可以直接使用的接口handler将(logger创建的)日志记录发送到合适的目的输出filter提供了细度设备来决定输出哪条日志记录formatter决定日志记录的最终输出 ...

(转)python中的*args和**kw到底是个啥。看下面的例子就会懂了

先来看个例子: def foo(*args, **kwargs): print 'args = ', args print 'kwargs = ', kwargs print '----------- ...

Python中的@函数装饰器到底是什么?

在解释@函数装饰器之前,先说一下,类中的类方法和静态方法. 在Python中完全支持定义类方法.静态方法.这两种方法很相似,Python它们都使用类来调用(ps:用对象调用也可以). 区别在于:Pyt ...

python中的日志,logger用法

python中自带logger模块,实现方法有两种,一般使用第二种,更灵活 方法一: import logging # 通过logging.basicConfig完成 logging.basicCon ...

python中的cls到底指的是什么

python中的cls到底指的是什么,与self有什么区别? 2018年07月31日 11:13:09 rs勿忘初心 阅读数:7769   作者:秦风链接:https://www.zhihu.com/ ...

Python 中的数字到底是什么?

花下猫语:在 Python 中,不同类型的数字可以直接做算术运算,并不需要作显式的类型转换.但是,它的"隐式类型转换"可能跟其它语言不同,因为 Python 中的数字是一种特殊的对 ...

Python 中的元类到底是什么?这篇恐怕是最清楚的了

类作为对象 在理解元类之前,您需要掌握 Python 的类.Python 从 Smalltalk 语言中借用了一个非常特殊的类概念. 在大多数语言中,类只是描述如何产生对象的代码段.在 Python ...

随机推荐

Android实现自定义带文字和图片的Button

Android实现自定义带文字和图片的Button 在Android开发中经常会需要用到带文字和图片的button,下面来讲解一下常用的实现办法. 一.用系统自带的Button实现 最简单的一种办法就 ...

生物信息 perl 脚本实战

索引 1.统计fasta.fa和fastq文件的长度,统计fastq的reads个数,单个reads长度,reads总长度:统计fasta文件中contig的个数,列出名称,单条的长度,以及总长度. ...

java多线程:并发包中ReentrantReadWriteLock读写锁的原理

一:读写锁解决的场景问题--->数据的读取频率远远大于写的频率的场景,就可以使用读写锁.二:读写锁的结构--->用state一个变量.将其转化成二进制,前16位为高位,标记读线程获取锁的次 ...

WIN7 X64 如何运行debug

WIN7 X64 如何运行debug 下载debug.exe 安装dosbox 安装完成后将debug.exe放入某个盘的根目录下(以c盘为例) 然后运行dosbox,输入 mount c c:\ c ...

Zabbix探索:LDAP的认证方式

这两天部署了Zabbix测试环境,终于用Puppet部署完成了.总是存在一些小问题,如服务不起动啦之类的. LDAP验证方式配置 刚刚配置Zabbix的用户管理,使用LDAP方式认证. 比较惊喜的是L ...

【HDOJ】1098 Ignatius's puzzle

数学归纳法,得证只需求得使18+ka被64整除的a.且a不超过65. #include int main() { int i, j, k; while (scanf(& ...

Shiro 源码分析

http://my.oschina.net/huangyong/blog/215153 Shiro 是一个非常优秀的开源项目,源码非常值得学习与研究. 我想尝试做一次 不一样 的源码分析:源码分析不再 ...

Mongodb使用

Mongodb基本的原则是:条件句是内层文档的键,修改器是外层文档的键[即,修改器要修改的字段声明在修改器内部].1.$size,用于查询数组大小为size的记录db.a.find({"co ...

初识Hibernate之环境搭建

相信所有做后端的程序员同行们,没有不知道Hibernate大名的.这是一个经典的轻量级Java EE持久层的解决方案,它使得我们程序员能以面向对象的思维操作传统的关系型数据库,这也是其存在的 ...

django_视图层_编写url

URL的配置 django中,url也称urlconf,默认的django项目设定两个url地址,分别是admin站点管理和首页地址.from diango.urls import path,incl ...

python logger handler_Python中的logger和handler到底是个什么鬼相关推荐

  1. python logger.debug_python中的logger模块详细讲解

    logger 提供了应用程序可以直接使用的接口 handler将(logger创建的)日志记录发送到合适的目的输出 filter提供了细度设备来决定输出哪条日志记录 formatter决定日志记录的最 ...

  2. python中的logger之一

    简介 基本每种开发语言都有对应的logger库提供,以方便输出和记录logger. python内也提供了logger包,可以方便地使用. 简单使用 首先,需要import日志包logger impo ...

  3. python中的logger模块详细讲解

    logger 提供了应用程序可以直接使用的接口 handler将(logger创建的)日志记录发送到合适的目的输出 filter提供了细度设备来决定输出哪条日志记录 formatter决定日志记录的最 ...

  4. python中logger_python中的logger

    2 logging模块使用 2.1 基本使用 配置logging基本的设置,然后在控制台输出日志, import logging logging.basicConfig(level = logging ...

  5. python logger日志级别_Python logger日志

    1.日志级别有哪些? 日志等级 描述 DEBUG 最详细的日志信息,典型应用场景是 问题诊断 INFO 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作 ...

  6. python logging.getlogger_logging.getLogger与logger的父子关系

    我们用logging.getLogger创建logger,通过logger的名字,我们可以实现不同logger的层次关系,或父子关系. def getLogger(name=None): " ...

  7. golang中创建logger时候踩过的坑

    golang中创建logger时候踩过的坑 错误的代码 package mainimport ("fmt""io""log""os ...

  8. Go 语言中的 logger 和 zap 日志库

    目录 Go 语言中的 logger 和 zap 日志库 Go Logger Zap Logger Logger Sugared Logger 定制 Logger 记录到文件中 Zap logger 中 ...

  9. python大型项目中的日志模块_Python中日志模块的使用

    前言 程序和脚本往往是无人值守运行的,一旦发生问题,就需要我们去追溯当时的情况来定位问题的原因. 这便需要我们在程序和脚本中引入日志的功能. 相比于print信息,使用logging日志有以下优点 可 ...

最新文章

  1. Docker 入门系列(4)- Docker 数据管理(挂载目录、挂载文件、数据卷挂载、数据卷共享、数据卷删除、数据卷容器备份和恢复)
  2. 如何制定客户留存策略_如何制定品牌营销策略?
  3. 正则 -12至+14 闭区间,小数位只能是(0.25,0.5,0.50,0.75,0.0,0.00) 前面的正负符号可选...
  4. 【Unity】12.4 通过网格分层选择行进路线
  5. python删除列表元素 // 列表的切片
  6. java 数组map_Java之数组array和集合list、set、map
  7. MongoDB Array Query Operators
  8. oracle desc卡,Oracle的一个bug,desc的bug,很夸张,这么基础的功能居然有bug
  9. rostcm6情感分析案例分析_情感分析师在线指导情感挽回
  10. html添加鼠标右键菜单,Fabric.js - 添加鼠标右键点击事件响应(附:右键菜单)...
  11. 程序员除了代码,连数字都神神秘秘的
  12. Excel 里筛选手机号码所属运营商
  13. Windows.old文件夹恢复系统解决方案
  14. 交换机基础知识和VLAN概述
  15. 华为暑期实习一面凉经
  16. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析
  17. 计算机考试internet应用好考吗,职称计算机考试《Internet应用》基础习题
  18. 【MQTT基础篇(二)】MQTT基础
  19. 美国项目管理协会宣布从Net Objectives手中收购FLEX
  20. 微服务组件之Hystrix豪猪简介和简单学习-2021-8-20

热门文章

  1. Mac 上面编译POCO C++库
  2. Android开发 mobi格式,Android MobIM的免费使用方法
  3. adb的问题“No command ‘adb’ found, did you mean:”
  4. 力扣 167. 两数之和 II - 输入有序数组
  5. 《只为遇见你》硬生生把爱情片拍成了把妹宝典,真人出镜演绎直男转型
  6. matlab对照片进行磨皮美白,人像照片快速磨皮美白处理的PS技巧
  7. 流程控制语句—顺序、选择、循环
  8. 如何将知识结构化,形成知识管理体系(干货分享)
  9. MySQL系列教程(五)
  10. 2022年上半年计算机技术与软件专业技术资格(水平)考试陕西考区报名须知