代码解析python标准库logging模块

yizhihongxing

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中下标和切片的使用方法解析

    Python中下标和切片的使用方法解析 在Python中,下标和切片是非常重要的操作。针对列表、元组、字符串等序列类型的数据结构,下标和切片可以非常方便的进行元素访问和截取等操作。 一、下标 下标是表示序列中元素位置的数字,下标从0开始计数。通过下标可以获取序列中特定位置的元素。 示例1:访问列表中的元素 lst = ["apple", …

    python 2023年6月5日
    00
  • python获取中文字符串长度的方法

    获取中文字符串长度是Python编程中常见的需求之一。下面,我将为你讲解一下Python获取中文字符串长度的方法的完整攻略。 1. 中文字符编码方式 首先,我们需要了解中文字符在计算机中的编码方式。在Python 3中,中文字符常常采用Unicode编码(UTF-8或UTF-16)进行存储和传输,一个中文字符占用3或4个字节的存储空间。而在Python 2中…

    python 2023年6月5日
    00
  • 从 JSON 数据库中提取数据 (Python 3)

    【问题标题】:Extracting data from a JSON database (Python 3)从 JSON 数据库中提取数据 (Python 3) 【发布时间】:2023-04-07 11:27:01 【问题描述】: 我想编写一个程序,将 JSON 数据库中的数据加载到 Python 字典列表中,并添加平均温度高于冰点和低于冰点的所有次数。但是…

    Python开发 2023年4月8日
    00
  • python time.strptime格式化实例详解

    Python time.strptime格式化实例详解 介绍 在 Python 中,time.strptime 函数可以将字符串解析为时间元组(time tuple),并支持自定义解析格式(format)。本文将详细介绍 time.strptime 的使用方法和示例。 函数定义 time.strptime(string[, format]) 函数接收两个参数…

    python 2023年6月2日
    00
  • python实现图片转字符画

    下面是“Python实现图片转字符画”的完整攻略: 1. 了解字符画 字符画是指使用字符来描述图像的一种方式。在计算机应用中,通常是用等宽字符来表示,即给每个字符一个固定的宽度,比如常用的像素宽度为8。字符画通常用于做图像压缩或者风格化处理,同时也有很多艺术家使用字符画来创作绘画等艺术作品。 2. 准备需要的工具 为了实现图片转字符画,我们需要准备以下工具:…

    python 2023年6月2日
    00
  • python实现壁纸批量下载代码实例

    Python实现壁纸批量下载攻略 壁纸是我们日常生活中非常重要的信息之一,使用Python可以方便地批量下载壁纸。本攻略将介绍使用Python实现壁纸批量下载的示例代码,包括数据获取、数据处理、文件操作和示例。 步骤1:获取数据 在Python中,我们可以使用requests库获取壁纸数据。以下是获取壁纸数据的示例: import requests from…

    python 2023年5月15日
    00
  • 解决python执行较大excel文件openpyxl慢问题

    以下是关于解决Python执行较大Excel文件openpyxl慢的完整实例教程: 问题描述 当我们使用Python的openpyxl库读取或处理较大的Excel文件时,往往会遇到执行缓慢或卡死的问题。这是由于openpyxl库读取Excel文件时需要将整个文件读入内存中,导致内存占用过大,CPU占用率剧增,从而影响程序的执行效率和响应速度。 解决方案 1.…

    python 2023年5月14日
    00
  • 跟老齐学Python之Python文档

    了解“跟老齐学Python之Python文档”的完整攻略,可以按照以下步骤进行: 1. 确定学习目标 首先,需要明确自己的学习目标。例如,想要学习Python的基础语法、掌握Python的常用函数等。 2. 获取Python文档 要学习Python文档,需要先获取Python文档。一般情况下,Python文档可以在Python官网上下载到,下载地址是 htt…

    python 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部