zoukankan      html  css  js  c++  java
  • Python日志功能与处理逻辑

    前言

    在应用程序执行过程中,我们希望通过规范格式输出程序执行的详细信息,这时我们需要用到日志功能。在Python语言中,有个內建模块logging能够很好的实现日志功能。整体来说,logging配置可以分成4个部分: LoggersHandlersFiltersFormatters。接下来我们详细探讨其处理逻辑和配置方法。

    1.日志功能逻辑

    LogRecord

    每个事件生成日志条目称之为LogRecord,在LogRecord中包含了日志级别日志元数据信息两个重要组成部分。在Python语言中日志级别可以分为5个等级:

    • DEBUG: Low level system information for debugging purposes.
    • INFO: General system information.
    • WARNING: Information describing a minor problem that has occurred.
    • ERROR: Information describing a major problem that has occurred.
    • CRITICAL: Information describing a critical problem that has occurred.
      当LogRecord传入Logger中处理时,会比较LogRecord和Logger中的日志级别。若日志级别相等或者高于Logger的日志级别,该条LogRecord才会被Logger处理。

    Formatter

    Formatter主要用于渲染日志的输出格式,在Python中给定了内置的格式变量,我们可以自定义日志信息的输出格式。

    格式变量列举:
    %(name)s Logger的名字
    %(levelno)s 数字形式的日志级别
    %(levelname)s 文本形式的日志级别
    %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    %(filename)s 调用日志输出函数的模块的文件名
    %(module)s 调用日志输出函数的模块名
    %(funcName)s 调用日志输出函数的函数名
    %(lineno)d 调用日志输出函数的语句所在的代码行
    %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
    %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    %(thread)d 线程ID。可能没有
    %(threadName)s 线程名。可能没有
    %(process)d 进程ID。可能没有
    %(message)s用户输出的消息
    

    Filter

    Filter用来为日志信息的处理提供额外的过滤选项。在默认情况下,从Logger获取到的每一条LogRecord都会交给Handler处理。但是,当我们有一些额外的处理逻辑,比方说我希望将LogRecord的日志级别变更,或者我希望后续仅处理ERROR类型的记录,那么就可以使用Filter来过滤。

    Handler

    Handler是日志处理的核心,描述了程序日志的后续执行方式。一般而言,我们希望日志能够输出到Console显示,或者写成文件本地持久化存储,都要靠Handler来实现。为此,Python中主要提供了FileHandlerStreamHandler两种Handler来分别执行文件存储和控制台打印两种日志处理方式。

    2.函数式配置日志

    函数式配置日志输出是最简单的方式,我们可以将日志打印到文件中。但是,这种方式有个缺陷,即无法将日志打印到Console。
    特点:配置简单,但无法同时输出控制台和文件

    import logging
    logging.basicConfig(
        level=logging.DEBUG, # 设定打印日志的级别
        # 日志消息格式,level=日志级别 format=日志格式 asctime=对应下面的datefmt filename=日志文件路径
        format="%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s",
        datefmt="%Y-%d-%d %H:%M:%S",
        filename="1.log",
        # a=追加 w=覆盖
        filemode="a"
    )
    logging.debug("debug")
    logging.info("info")
    

    3.对象式配置日志

    对象式配置日志能够较强的进行定制化配置,包括日志的输出格式、控制台输出、输出本地文件持久化存储。因此,在实际使用时一般都采用对象式配置日志的方式来处理。
    特点:定制化强,配置较为复杂

    配置流程

    1. 创建并获取logger对象;
    2. 创建FileHandler对象;
    3. 创建StreamHandler对象;
    4. 创建Formatter对象;
    5. 给Handler对象绑定Formatter;
    6. 给logger对象绑定Handler
    import logging
    logger = logging.RootLogger("DEBUG") # 如果要自定义level,则可使用RootLogger,或者logger.setLevel()
    # logger = logging.getLogger() # 使用getLogger默认level为WARNING
    fh = logging.FileHandler('test.log', encoding='utf-8')  # 创建FileHandler对象
    sh = logging.StreamHandler()  # 创建StreamHandler对象
    
    fmt = logging.Formatter("%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s")
    fh.setFormatter(fmt)  # 给Handler对象绑定Formatter
    sh.setFormatter(fmt)  # 给Handler对象绑定Formatter
    
    logger.addHandler(fh)  # 给logger对象绑定Handler
    logger.addHandler(sh) # 给logger对象绑定Handler
    
    logger.info('info')
    logger.debug('debug')
    logger.error("error")
    
  • 相关阅读:
    网站安全编程 黑客入侵 脚本黑客 高级语法入侵 C/C++ C# PHP JSP 编程
    【算法导论】贪心算法,递归算法,动态规划算法总结
    cocoa2dx tiled map添加tile翻转功能
    8月30日上海ORACLE大会演讲PPT下载
    【算法导论】双调欧几里得旅行商问题
    Codeforces Round #501 (Div. 3) B. Obtaining the String (思维,字符串)
    Codeforces Round #498 (Div. 3) D. Two Strings Swaps (思维)
    Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)
    洛谷 P1379 八数码难题 (BFS)
    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)
  • 原文地址:https://www.cnblogs.com/zimskyzeng/p/13660883.html
Copyright © 2011-2022 走看看