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")
    
  • 相关阅读:
    mysql将一个表的数据 重复复制多份到表中
    PHP中将指定文本内容导入到word中
    系统安全-SElinux
    通过身份证号码提取年龄,性别
    MySQL-获取某天的数据
    mysql-介绍、MySQL部署、数据类型、存储引擎
    监控系统-ELK
    监控系统-Grafana
    监控系统-zabbix
    监控系统-openfalcon
  • 原文地址:https://www.cnblogs.com/zimskyzeng/p/13660883.html
Copyright © 2011-2022 走看看