代码解析python标准库logging模块

1. 简介

logging是Python标准库中提供的一个标准日志工具模块,其主要的作用是用来记录应用程序的运行时信息。通过使用logging来输出日志可以更加方便的进行开发、调试、测试以及发布运行等的工作。

2. logging模块的基础用法

2.1 创建Logger对象

创建Logger对象是logging模块的第一步,Logger对象主要用于向后端输出日志信息,可以设置日志的级别、输出格式等相关信息,例如:

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

其中,__name__参数是用来设置该Logger对象的名称,对于不同的模块和函数,Logger名称也可以不同,从而可以根据名称对不同的模块进行区分。

2.2 创建处理器(Handler)对象

同样可以通过设置不同的Handler对象来将日志输出到不同的地方,例如输出到控制台、文件、网络等等,常见的Handler类型有:StreamHandler、FileHandler、NetworkHandler等等。例如:

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

其中,我们创建了一个名为console_handler的StreamHandler对象,将其设置日志级别为DEBUG。

2.3 设置Formatter对象

Formatter对象用于设置日志格式,例如我们需要以这样的格式输出日志:"时间-模块名称-日志级别-日志内容",可以通过以下形式去创建这样一个Formatter对象:

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

其中,%(asctime)s用于表示时间信息,%(name)s用于表示模块名称,%(levelname)s用于表示日志级别,%(message)s用于表示日志内容。

2.4 将Handler添加到Logger对象上

一旦我们创建好了Logger对象、Handler对象和Formatter对象,就可以将它们组合起来,将日志信息输出到不同的地方了。例如,我们可以将一个StreamHandler添加到Logger对象上,以输出到控制台:

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

2.5 输出日志

最后,我们就可以在代码中像这样输出日志信息了:

logger.debug('this is a debug message')
logger.info('this is an info message')
logger.warning('this is a warning message')
logger.error('this is an error message')
logger.critical('this is a critical message')

这样就可以将不同级别(DEBUG、INFO、WARNING、ERROR和CRITICAL)的日志信息输出到控制台(或其他Handler)上了。

3. logging模块的进阶用法

3.1 日志信息的存储和分级

用logging模块,我们可以在控制台把程序运行过程中的信息输出,但这些信息并不能作为程序的正式日志文件,因此需要将日志信息记录到文件中。

import logging

logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)

handler = logging.FileHandler("output.log")
handler.setLevel(level=logging.INFO)

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

logger.addHandler(handler)

logger.info("Start reading database")
# read database here
records = {"john": 55, "tom": 66}
logger.debug("Records: %s", records)
logger.info("Update records...")
# update records here
logger.info("Finish updating records")

以上代码,正常情况下是没有触发任何warning或error信息的,因此只有INFO级别的日志信息会被输出到控制台和日志文件中。

3.2 日志信息的格式化

格式化指输出内容的控制,可以输出文件名,行号,函数名等等。

例如,我们要将输出内容加上上下文信息,使得日志输出层次更加清晰,可以使用logger自带的Adapter方法,代码如下:

import logging

logger = logging.getLogger()

class ContextFilter(logging.Filter):
    """
    This is a filter which injects contextual information into the log.
    """

    def filter(self, record):
        # Adds context to the log record
        record.context = "Context information"
        return True


class ContextAdapter(logging.LoggerAdapter):
    """
    This adapter adds extra context information to the log messages.
    """
    def process(self, msg, kwargs):
        """
        Override LoggerAdapter's process function to add contextual info.
        """
        return '[%s] %s' % (self.extra['context'], msg), kwargs

def main():
    """
    Test logger
    """
    logger.addFilter(ContextFilter())
    logger.setLevel(logging.DEBUG)
    logger.info('Program started')
    adapter = ContextAdapter(logger, {'context': 'Extra Context'})
    adapter.debug('Debug event')
    adapter.warning('Warning event')
    adapter.error('Error event')
    logger.info('Program terminated')


if __name__ == '__main__':
    main()

输出内容将会是:

[2022-03-14 18:48:23,451] [INFO] [__main__] [11] Program started
[2022-03-14 18:48:23,451] [DEBUG] [__main__] [33] [Extra Context] Debug event
[2022-03-14 18:48:23,451] [WARNING] [__main__] [34] [Extra Context] Warning event
[2022-03-14 18:48:23,451] [ERROR] [__main__] [35] [Extra Context] Error event
[2022-03-14 18:48:23,451] [INFO] [__main__] [37] Program terminated

示例解析

示例1 配置logging模块

在本示例中,我们将Logger的日志级别设为DEBUG级别,输出的Handler设为console_handler以便输出到控制台,而formatter则是为了定义输出日志的格式。

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

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

logger.addHandler(console_handler)

在以上的代码中,我们使用了一个长度为5的日志级别,分别是:
* DEBUG:详细程度从低到高依次是NOTSET、DEBUG、INFO、WARNING、ERROR和CRITICAL。
* INFO:输出程序运行的一些一般性信息。
* WARNING:表示某些意外发生,或者不准备马上解决,但是在发生问题后仍能继续工作。
* ERROR:表示非常严重的问题,包括程序中的错误和异常以及其他不同寻常的情况。
* CRITICAL:表示严重错误,严重到系统无法继续运行的程度。

示例2 测试日志信息含上下文信息

该示例主要通过创建ContextFilter和ContextAdapter这两个类来定制化过滤器和适配器,为日志信息加上了上下文信息。

import logging

logger = logging.getLogger()

class ContextFilter(logging.Filter):
    """
    This is a filter which injects contextual information into the log.
    """

    def filter(self, record):
        # Adds context to the log record
        record.context = "Context information"
        return True


class ContextAdapter(logging.LoggerAdapter):
    """
    This adapter adds extra context information to the log messages.
    """
    def process(self, msg, kwargs):
        """
        Override LoggerAdapter's process function to add contextual info.
        """
        return '[%s] %s' % (self.extra['context'], msg), kwargs

def main():
    """
    Test logger
    """
    logger.addFilter(ContextFilter())
    logger.setLevel(logging.DEBUG)
    logger.info('Program started')
    adapter = ContextAdapter(logger, {'context': 'Extra Context'})
    adapter.debug('Debug event')
    adapter.warning('Warning event')
    adapter.error('Error event')
    logger.info('Program terminated')


if __name__ == '__main__':
    main()

在运行该示例后,我们可以看到日志的格式变为:

[2022-03-15 17:06:43,857] [INFO] [__main__] [11] Program started
[2022-03-15 17:06:43,857] [DEBUG] [__main__] [33] [Extra Context] Debug event
[2022-03-15 17:06:43,857] [WARNING] [__main__] [34] [Extra Context] Warning event
[2022-03-15 17:06:43,857] [ERROR] [__main__] [35] [Extra Context] Error event
[2022-03-15 17:06:43,857] [INFO] [__main__] [37] Program terminated

可以发现,已经在日志信息添加了上下文信息,并在内容前面加以了区分,方便开发者阅读和排查问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:代码解析python标准库logging模块 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • 状态机的概念和在Python下使用状态机的教程

    状态机的概念 状态机(英文:Finite-state machine,缩写为FSM),又称有限状态自动机,简称状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。状态机是描述对象(通常为计算机程序、计算机内部操作或者电路)在其生命周期中所经历的状态转变以及引起状态转变的事件等的方法。 在实际编程中,状态机常被用于解决诸如流程控制、自动…

    python 2023年5月23日
    00
  • Python中变量的作用域详解

    在Python中,变量的作用域是指变量在程序中可见的范围。Python中的变量作用域分为全局作用域和局部作用域。本文将详细讲解Python中变量的作用域,包括全局变量、局部变量、global关键字、nonlocal关键字等内容,并提供两个示例。 全局变量 全局变量是在函数外部定义的变量,可以在程序的任何地方访问。以下是一个使用全局变量的示例: x = 10 …

    python 2023年5月15日
    00
  • 如何用python清洗文件中的数据

    下面我将为您详细讲解如何用Python清洗文件中的数据。 简介 数据清洗是数据分析的重要步骤,通常包括缺失值处理、重复值删除、异常值处理、数据类型转换等过程。Python作为一门流行的编程语言,提供了丰富的数据清洗库和函数,可以帮助我们轻松地完成数据清洗工作。 准备工作 在进行数据清洗之前,我们需要先准备好数据。下面是一份模拟的数据,存储在txt文件中: 名…

    python 2023年5月13日
    00
  • Python常用的json标准库

    下面是Python常用的json标准库的完整攻略。 什么是JSON? JSON 全称为 JavaScript Object Notation,是一种轻量级数据交换格式。它基于 ECMAScript 的一个子集。 JSON 格式最初由 Douglas Crockford 发明,它是一种语法简洁清晰的数据格式,并且易于读写,同时也易于机器解析和生成。 JSON …

    python 2023年6月3日
    00
  • pytorch查看通道数 维数 尺寸大小方式

    PyTorch 是一种流行的开源深度学习框架,我们经常需要查看数据的通道数、维数以及尺寸大小等信息。在本文中,我将为大家介绍在 PyTorch 中如何查看数据的通道数、维数、尺寸大小的方法。 查看数据的通道数 在 PyTorch 训练和测试深度学习模型时,经常需要查看一个张量的通道数。我们可以使用 size() 函数来获取张量的形状,然后通过形状的最后一个元…

    python 2023年6月2日
    00
  • Python中的布尔类型bool

    当我们需要进行判断时,布尔类型(bool)就显得尤为重要。Python 中的布尔类型是 True 和 False,可以理解为真和假。 布尔类型的基本使用 在 Python 中,可以用 bool() 把一个值转换为布尔类型。 >>> bool(1) True >>> bool(0) False >>> bo…

    python 2023年5月14日
    00
  • Python中tkinter的用户登录管理的实现

    简介 在Python中,tkinter是常用的GUI库之一,提供了丰富的控件和布局方式。本文将介绍如何使用tkinter实现用户登录管理的功能。 创建登录界面 首先需要创建一个登录界面,可以包括用户名和密码输入框以及登录按钮。下面是一个例子: import tkinter as tk def login(): # 用户名和密码验证 pass # 创建窗口和控…

    python 2023年6月13日
    00
  • Python – 选择出现在第二个数据框中的数据框中的行

    【问题标题】:Python – Select lines in dataframe that appear in a second data framePython – 选择出现在第二个数据框中的数据框中的行 【发布时间】:2023-04-02 11:24:01 【问题描述】: 我有两个 Pandas 数据框,列数相同,行数不同。 dfA = pd.Data…

    Python开发 2023年4月8日
    00
合作推广
合作推广
分享本页
返回顶部