本文摘自:https://zhuanlan.zhihu.com/p/32043593

本篇将会涉及:

  • logging的各个模块化组件
  • 构建一个组件化的日志器

logging的模块组件化

在上一篇文章中,我们介绍了Python的内置模块logging的使用,通过短短的几行代码我们就实现了一个日志记录器。。

import logging

logging.basicConfig(level=logging.INFO,filename='test.log',format="%(levelname)s:%(asctime)s:%(message)s")
logging.error("出现了错误")
logging.info("打印信息")
logging.warning("警告信息")

在上面的例子中我们直接使用了logging模块提供的简单日志记录器。除此之外,logging模块还提供了模块化的方法,通过日志记录器、日志处理器、过滤器和格式处理器等组件来灵活的配置日志器:

  • 日志记录器Loggers提供程序调用日志记录的接口;
  • 日志处理器Handlers用于将日志记录器创建的日志记录发送到相应的目标上;
  • 过滤器Filters提供了对日志记录进行更详细的输出;
  • 格式器Formatters用于指定输出的日志记录的最终格式;

在前面的例子中我们知道,一条日志记录是通过调用一个日志记录器(Logger类的实例)的方法来执行的。每一个日志记录器都有一个name来标识这个日志记录器,比如上一篇文章中我们创建的日志记录起的name就是默认的root。

日志记录器

通过logging的getLogger()方法,我们可以创建一个日志记录器,并指定其名称:

log = logging.getLogger("test_logger")

这样我们就实例化了一个名为test_logger的日志记录器。这个日志记录器除了包含一些基本的功能,比如调用各级别的日志方法外,还能够添加日志处理器、过滤器等。

日志处理器

日志处理器Handlers负责将相应的日志记录消息分发到指定的目标上。在logging模块中,有很多种日志处理器用于不同的用途,下面介绍几个常用的:

  • StreamHandler:用于将日志消息发送到控制台;
  • FileHandler:用于将日志消息写入文件中;
  • SMTPHandler:用于将日志消息发送到指定的电子邮箱;
  • HTTPHandler:使用GET或POST方法将日志消息发送给某个HTTP服务器;

其中我们最常使用的,还是FileHandler处理器,将日志消息写入文件中。
使用logging.FileHandler()可以创建一个FileHandler处理器处理器:

logHandler = logging.FileHandler(filename='log.log')

我们在此创建了一个FileHandler处理器,并指定日志的文件名为log.log。

在创建日志处理器之后,可以通过日志记录器的addHandler()方法,将处理器添加到记录器中。

log.addHandler(logHandler)

日志格式器

在上一篇文章中,我们通过logging.basicConfig()的format参数来指定输出日志消息的格式。而在模块组件化中,我们使用logging.Formatter()方法来创建一个日志格式器。

formats = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s: %(message)s',
datefmt='%Y/%m/%d %I:%M:%S %p')

在创建之后,可以通过日志处理器的setFormatter()方法,将日志格式器添加到日志处理器中:

logHandler.setFormatter(formats)

这样,我们就基本组装好了一个模块化的日志器。接着就能够在程序中调用日志记录器的方法来记录日志:

import logging

def mylog():
print(inspect.stack()[0])
# 创建一个日志记录器
log = logging.getLogger("test_logger")
log.setLevel(logging.DEBUG) # 创建一个日志处理器
logHandler = logging.FileHandler(filename='log.log')
logHandler.setLevel(logging.DEBUG) # 创建一个日志格式器
formats = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s: %(message)s',
datefmt='%Y/%m/%d %I:%M:%S %p') # 将日志格式器添加到日志处理器中
logHandler.setFormatter(formats) # 将日志处理器添加到日志记录器中
log.addHandler(logHandler)
return log # 输出日志
log = mylog()
log.info("这是一个普通信息")
log.debug("这是一个调试信息")
log.warning("这是一个警告信息")
log.error("这是一个错误信息")
log.critical("这是一个危险信息")

运行程序的结果如下:

优雅地记录Python程序日志2:模块组件化日志记录器的更多相关文章

  1. 优雅地记录Python程序日志1:logging模块简介

    本文摘自:https://zhuanlan.zhihu.com/p/31893724 本篇涉及: logging模块的调用: 保存log日志为文件: 调整输入日志等级: 修改日志消息格式: 前言 在使 ...

  2. 使用配置文件方式记录Python程序日志

    开发者可以通过三种方式配置日志记录: 调用配置方法的Python代码显式创建记录器.处理程序和格式化程序. 创建日志配置文件并使用fileConfig() 函数读取. 创建配置信息字典并将其传递给di ...

  3. 如何优雅地退出python程序

    如何优雅地退出python程序 一个单模的python程序,启动之后要能够优雅地关闭.即当用户按Ctrl+C或者kill pid的时候,程序都能从容关闭.实现起来非常简单. is_running = ...

  4. 利用python自动生成verilog模块例化模板

    一.前言 初入职场,一直忙着熟悉工作,就没什么时间更新博客.今天受“利奇马”的影响,只好宅在家中,写写技术文章.芯片设计规模日益庞大,编写脚本成了芯片开发人员必要的软技能.模块端口动不动就几十上百个, ...

  5. 如何用ABP框架快速完成项目(11) - ABP只要加人即可马上加快项目进展- 全栈篇(2) - 不推荐模块组件化, 推荐微服务

    一个人写代码不需要担心会和别人的代码冲突, 不需要做代码合并, 不需要担心自己的代码被覆盖. 但是多个人一起写代码就需要担心这些问题.   解决这些问题的方法很多, 比如用AzureDevOps(TF ...

  6. [转载] 每个 Python 程序员都要知道的日志实践

    原文: http://python.jobbole.com/81666/ 在现实生活中,记录日志非常重要.银行转账时会有转账记录:飞机飞行过程中,会有黑盒子(飞行数据记录器)记录飞行过程中的一切.如果 ...

  7. 每个 Python 程序员都要知道的日志实践

    在现实生活中,记录日志非常重要.银行转账时会有转账记录:飞机飞行过程中,会有黑盒子(飞行数据记录器)记录飞行过程中的一切.如果有出现什么问题,人们可以通过日志数据来搞清楚到底发生了什么. 对于系统开发 ...

  8. hadoop streaming 中跑python程序,自定义模块的导入

    今天在做代码重构,以前将所有python文件放到一个文件夹下,上传到hadoop上跑,没有问题:不过随着任务的复杂性增加,感觉这样甚是不合理,于是做了个重构,建了好几个包存放不同功能的python文件 ...

  9. [转]python执行bash指令,如果指令返回错误,如何优雅的结束python程序

    如果是有返回值的可执行文件可以直接获取return code, 如果error code 直接退出. import os ret = os.system("COMMAND LINE" ...

随机推荐

  1. pprof函数名未翻译、为函数地址0x00000232382788

    这几天在分析一个性能未达预期的功能,使用gperftools cpu profiler生成后,使用pprof格式化的时候,发现pprof出的结果函数名未翻译.为函数地址,如下所示: 每个节点代表一个函 ...

  2. UUID实现之一twitter的分布式自增IDsnowflake算法

    Twitter的分布式自增ID算法snowflake (Java版)   概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点 ...

  3. linux有趣的命令screen

    screen类似一个容器, 可以把当前前台运行的应用shell窗口关闭而不影响运行, 跟后后nohup有点相似, 不过我觉得比nohup还好用 用法1: screen 然后会弹出一个新的shell窗口 ...

  4. 获取RadioButton选中的值

    1.RadioButtonList的RepeatDirection="Horizontal"可以设置按扭选项横对齐: 2.获取选中的RadioButton值; $("#& ...

  5. 20145320《WEB基础实践》

    20145320WEB基础实践 实验问题回答 1.什么是表单 表单可以收集用户的信息和反馈意见,是网站管理者与浏览者之间沟通的桥梁. 一个表单有三个基本组成部分: 表单标签 表单域:包含了文本框.密码 ...

  6. Error: php71w-common conflicts with php-common-5.4.16-46.el7.x86_64

    Centos7.3 阿里云主机 安装zabbix报错 问题: [root@lvhanzhi code]# yum install -y zabbix-web-mysql zabbix-agent ma ...

  7. MongoDB的常用操作总结

    简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. ...

  8. 剥开比原看代码10:比原是如何通过/create-key接口创建密钥的

    作者:freewind 比原项目仓库: Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchai ...

  9. 51nod1057-N的阶乘(大数乘法巧解)

    这道大数乘法开始我是想套板子模拟的..然后就发现2/3的例子都wa了.(惊了).然后在思考后发现n2的板子的确过不了这么多的大数.(不看题的下场).所以,我在网上发现了分块求大数的方法.%%% 思路来 ...

  10. 洛谷P2362 围栏木桩----dp思路

    在翻dp水题的时候找到的有趣的题0v0 原文>>https://www.luogu.org/problem/show?pid=2362<< 题目描述 某农场有一个由按编号排列的 ...