zoukankan      html  css  js  c++  java
  • python之logging模块

    logging由logger,handler,filter,formater四个部分组成,logger是提供我们记录日志的方法;handler是让我们选择日志的输出地方,如:控制台,文件,邮件发送等,一个logger添加多个handler;filter是给用户提供更加细粒度的控制日志的输出内容;formater用户格式化输出日志的信息。

    Logging 模块有很多优势,比如:

    1.多线程支持

    2.通过不同级别的日志分类

    3.灵活性和可配置性

    4.将如何记录日志与记录什么内容分离

    Logging 模块中包含什么

    Logging 模块完美地将它的每个部分的职责分离(遵循 Apache Log4j API 的方法)。让我们看看一个日志线是如何通过这个模块的代码,并且研究下它的不同部分。

    记录器(Logger)

    记录器是开发者经常交互的对象。那些主要的 API 说明了我们想要记录的内容。

    举个记录器的例子,我们可以分类请求发出一条信息,而不用担心它们是如何从哪里被发出的。

    比如,当我们写下 logger.info(“Stock was sold at %s”, price) 我们在头脑中就有如下模块:

     

    日志记录

    日志记录是 logging 模块用来满足所有需求信息的包。它们包含了需要记录日志的地方、变化的字符串、参数、请求的信息队列等信息。

    它们都是被记录的对象。每次我们调用记录器时,都会生成这些对象。但这些对象是如何序列化到流中的呢?通过处理器!

    处理器

    处理器将日志记录发送给其他输出终端,他们获取日志记录并用相关函数中处理它们。

    比如,一个文件处理器将会获取一条日志记录,并且把它添加到文件中。

    标准的 logging 模块已经具备了多种内置的处理器,例如:

    多种文件处理器(TimeRotated, SizeRotated, Watched),可以写入文件中

    1.StreamHandler 输出目标流比如 stdout 或 stderr

    2.SMTPHandler 通过 email 发送日志记录

    3.SocketHandler 将日志文件发送到流套接字

    4.SyslogHandler、NTEventHandler、HTTPHandler及MemoryHandler等

    目前我们有个类似于真实情况的模型:

    大部分的处理器都在处理字符串(SMTPHandler和FileHandler等)。

    格式器

    格式器负责将丰富的元数据日志记录转换为字符串,如果什么都没有提供,将会有个默认的格式器。

    一般的格式器类由 logging 库提供,采用模板和风格作为输入。然后占位符可以在一个 LogRecord 对象中声明所有属性。

    比如:'%(asctime)s %(levelname)s %(name)s: %(message)s' 将会生成日志类似于 2017-07-19 15:31:13,942 INFO parent.child: Hello EuroPython.

    请注意:属性信息是通过提供的参数对日志的原始模板进行插值的结果。(比如,对于 logger.info(“Hello %s”, “Laszlo”) 这条信息将会是 “Hello Laszlo”)

    所有默认的属性都可以在日志文档中找到。

    过滤器

    我们日志工具的最后一个对象就是过滤器。

    过滤器允许对应该发送的日志记录进行细粒度控制。多种过滤器能同时应用在记录器和处理器中。对于一条发送的日志来说,所有的过滤器都应该通过这条记录。

    用户可以声明他们自己的过滤器作为对象,使用 filter 方法获取日志记录作为输入,反馈 True / False 作为输出。

    出于这种考虑,以下是当前的日志工作流:

    记录器层级

    此时,你可能会对大量复杂的内容和巧妙隐藏的模块配置印象深刻,但是还有更需要考虑的:记录器分层。

    我们可以通过 logging.getLogger() 创建一个记录器。这条字符向 getLogger 传递了一个参数,这个参数可以通过使用圆点分隔元素来定义一个层级。

    举个例子,logging.getLogger(“parent.child”) 将会创建一个 “child” 的记录器,它的父级记录器叫做 “parent.” 记录器是被 logging 模块管理的全局对象,所以我们可以方便地在项目中的任何地方检索他们。

    记录器的例子通常也被认为是渠道。层级允许开发者去定义渠道和他们的层级。

    在日志记录被传递到所有记录器内的处理器时,父级处理器将会进行递归处理,直到我们到达顶级的记录器(被定义为一个空字符串),或者有一个记录器设置了 propagate = False。我们可通过更新的图中看出:

     请注意父级记录器没有被调用,只有它的处理器被调用。这意味着过滤器和其他在记录器类中的代码不会在父级中被执行。当我们在记录器中增加过滤器时,这通常是个陷阱。

    小结

    我们已经阐明过职责的划分以及我们是如何微调日志过滤。然而还是有两个其他的属性我们没有提及:

    1.记录器可以是残缺的,从而不允许任何记录从这被发出。

    2.一个有效的层级可以同时在记录器和处理器中被设置。

    举个例子,当一个记录器被设置为 INFO 的等级,只有 INFO 等级及以上的才会被传递,同样的规则适用于处理器。

    基于以上所有的考虑,最后的日志记录的流程图看起来像这样:

     参考:https://www.jb51.net/article/135560.htm

  • 相关阅读:
    Android按返回键退出程序但不销毁,程序后台运行,同QQ退出处理方式
    android 下动态获取控件的id
    Android大图片裁剪终极解决方案 原理分析
    如何使用Android MediaStore裁剪大图片
    最新的Android Sdk 使用Ant多渠道批量打包
    nodejs学习(1)
    C#——企业微信一般操作之一
    html(1)——转圈等待效果+鼠标移动悬浮显示相关信息
    SQL注入小结
    Java实现二叉树地遍历、求深度和叶子结点的个数
  • 原文地址:https://www.cnblogs.com/wind666/p/10818676.html
Copyright © 2011-2022 走看看