python将logging模块封装成单独模块并实现动态切换

1. 背景介绍

在Python中,`logging`模块是一个非常常用的日志模块,可以帮助开发者将软件中产生的各种信息记录下来,以便后续的分析和排错。`logging`模块的使用非常灵活,支持多种记录方式和多种日志级别,并且还可以自定义记录格式等等。然而,使用`logging`模块时,常常需要在每个文件中初始化日志对象和配置日志信息,这样会导致开发者每次新建一个文件时都需要重复这些操作,非常繁琐。

针对这个问题,本文将介绍如何将`logging`模块封装成一个单独的模块,以便在新建文件时直接调用已经封装好的日志模块,从而大大提高开发效率。

2. 模块封装

2.1 实现思路

将`logging`模块封装成单独模块的实现思路如下:

1. 定义一个`logger`对象,并设置其级别、输出格式及处理器等属性。

2. 将`logger`对象封装在函数中,函数的输入参数包括日志级别、日志信息、日志输出方式等。函数在被调用时,会根据输入参数动态地配置`logger`对象并输出日志。

3. 在其他文件中引用封装好的日志模块时,只需导入相应的封装函数,并调用该函数即可。

2.2 封装代码实现

下面是`logger`模块的封装代码实现,保存在`utils/logger.py`文件中:

import logging

def init_logger(log_level='INFO', log_filepath=None):

"""

初始化日志模块

:param log_level: 日志级别

:param log_filepath: 日志输出路径

:return: 日志对象

"""

logger = logging.getLogger(__name__)

logger.setLevel(log_level.upper())

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

if log_filepath:

file_handler = logging.FileHandler(log_filepath)

file_handler.setLevel(log_level.upper())

file_handler.setFormatter(formatter)

logger.addHandler(file_handler)

else:

console_handler = logging.StreamHandler()

console_handler.setLevel(log_level.upper())

console_handler.setFormatter(formatter)

logger.addHandler(console_handler)

return logger

函数`init_logger`的输入参数包括日志级别和日志输出路径。该函数会根据输入参数动态地配置`logger`对象,并返回该对象供日志输出使用。

下面对该函数的主要部分进行解释:

- `logger = logging.getLogger(__name__)`:获取`logger`对象,`__name__`表示当前模块的名称。

- `logger.setLevel(log_level.upper())`:设置日志级别,这里采用了`upper()`方法将日志级别字符串转换为大写,以避免大小写不一致的问题。

- `formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')`:设置日志输出的格式,其中`asctime`表示日志记录的时间,`levelname`表示日志级别,`message`表示日志信息。

- `if log_filepath:`:如果日志输出路径不为空,则将日志输出到文件中,否则将日志输出到控制台。其中`logging.FileHandler(log_filepath)`表示输出到文件,`logging.StreamHandler()`表示输出到控制台。

- `handler.setLevel(log_level.upper())`:设置输出handler的日志级别,保证输出的日志符合我们设置的日志级别要求。

- `handler.setFormatter(formatter)`:设置handler输出格式。

3. 动态切换日志级别

3.1 实现思路

动态切换日志级别是指在程序执行过程中,可以根据需要调整日志输出的级别。例如,在开发调试时,工程师常常需要将日志级别设置为`DEBUG`来输出更加详细的信息,以便进行问题排查和修复。而在生产环境中,一般会将日志级别设置为`WARNING`或`ERROR`,以避免过多的日志输出,影响系统性能。

为了实现动态切换日志级别,我们需要修改封装好的日志模块,使其支持动态修改日志级别。

3.2 修改代码实现

下面是修改后的`logger`模块的代码实现,保存在`utils/logger.py`文件中:

import logging

logger = None

def init_logger(log_level='INFO', log_filepath=None):

"""

初始化日志模块

:param log_level: 日志级别

:param log_filepath: 日志输出路径

:return: 日志对象

"""

global logger

logger = logging.getLogger(__name__)

logger.setLevel(log_level.upper())

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

if log_filepath:

file_handler = logging.FileHandler(log_filepath)

file_handler.setLevel(log_level.upper())

file_handler.setFormatter(formatter)

logger.addHandler(file_handler)

else:

console_handler = logging.StreamHandler()

console_handler.setLevel(log_level.upper())

console_handler.setFormatter(formatter)

logger.addHandler(console_handler)

return logger

def set_log_level(log_level):

"""

动态修改日志级别

:param log_level: 日志级别

"""

logger.setLevel(log_level.upper())

与之前的代码相比,主要修改在全局变量`logger`和函数`set_log_level`中。因为需要在不同的模块中动态修改日志级别,全局变量`logger`需要定义在模块外部,以保证不同的模块可以引用同一个`logger`对象。函数`set_log_level`接收一个日志级别作为参数,并将该日志级别设置为当前`logger`对象的级别,从而实现动态修改日志级别的功能。

4. 可复用性和扩展性

4.1 可复用性

将`logging`模块封装成单独模块的实现思路非常简单,只需要定义一个`logger`对象并设置其属性,然后将其封装在一个函数中即可。因此,整个封装过程非常容易应用到其他项目中,且不受任何限制。

4.2 扩展性

由于`logging`模块非常灵活,可以支持多种功能,因此封装的`logger`模块也具有很好的扩展性。例如,我们可以增加一个函数用于设置日志存储时间、增加日志归档等操作,以便更好地管理和分析日志。

5. 总结

本文介绍了如何将`logging`模块封装成单独的模块,并实现了动态切换日志级别的功能。通过封装后的日志模块,可以使得开发者在新建文件时,无需重复地初始化日志对象和配置日志信息,从而提高开发效率。同时,我们还探讨了封装后的日志模块的可复用性和扩展性,使得该模块具备了更好的通用性和应用价值。

在实际开发过程中,良好的日志记录是非常重要的,它可以帮助我们及时发现问题、分析问题和解决问题,保证软件质量和用户体验。因此,我们建议开发过程中养成良好的日志记录习惯,并合理配置日志输出级别和存储方式,以便满足不同场景下的需求。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签