【Python】自动化编程之基础库 logging 库

内容分享1周前发布
0 1 0

#python##python自学#

【Python】自动化编程之基础库 logging 库

在编写应用程序时,我们一般需要对应用程序的运行过程进行记录,以便在程序出现问题时进行排查和调试。Python 中的 logging 模块提供了一种灵活且功能强劲的记录方式,可以将记录输出到控制台、文件、网络等各种位置。

logging 模块包括四个主要组件:记录器(Logger)、处理器(Handler)、格式化器(Formatter)和过滤器(Filter)。其中,记录器是记录日志信息的主要组件,处理器是用于将记录器产生的日志信息发送到不同的位置,格式化器是用于将日志信息格式化为指定的样式,而过滤器则是用于过滤掉不需要记录的日志信息。

logging 基本用法

在使用 logging 模块时,一般需要按照以下步骤进行操作:

创建记录器
使用 logging.getLogger(name) 方法创建一个记录器,其中 name 是记录器的名称,可以根据需要自行命名。如果不指定名称,则使用根记录器。

import logging

logger = logging.getLogger('my_logger')
创建处理器
使用 logging.StreamHandler()、logging.FileHandler()、logging.SocketHandler() 等方法创建一个处理器,用于将日志信息发送到控制台、文件、网络等不同位置。

python
Copy code
import logging

logger = logging.getLogger('my_logger')

# 创建一个控制台处理器
console_handler = logging.StreamHandler()

创建格式化器
使用 logging.Formatter() 方法创建一个格式化器,用于将日志信息格式化为指定的样式。

import logging

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

绑定处理器和格式化器
使用处理器的 setFormatter() 方法将格式化器绑定到处理器上。

import logging

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 创建一个控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)

绑定处理器和记录器
使用记录器的 addHandler() 方法将处理器绑定到记录器上。

import logging

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 创建一个控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)

# 绑定处理器和记录器
logger.addHandler(console_handler)

记录日志信息
使用记录器的 debug()、info()、warning()、error()、critical() 等方法记录日志信息。

import logging

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 创建一个控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)

# 绑定处理器和记录器
logger.addHandler(console_handler)

# 记录日志信息
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')

上述代码中,第一创建了一个记录器 my_logger,然后创建了一个格式化器 % (asctime) s -% (name) s -% (levelname) s -% (message) s,表明记录日志信息的时间、记录器的名称、日志级别和日志内容。然后创建了一个控制台处理器 console_handler,并将格式化器绑定到处理器上。最后将处理器绑定到记录器上,并使用记录器的不同方法记录了不同级别的日志信息。

在默认情况下,记录器将所有的日志信息发送到其直接父级别,直到根记录器。如果需要将日志信息发送到其他位置,可以使用不同的处理器,例如 FileHandler、RotatingFileHandler、SMTPHandler 等。还可以通过 setLevel() 方法设置记录器的日志级别,以便过滤掉不需要记录的日志信息。此外,还可以使用过滤器来进一步过滤日志信息,只记录满足特定条件的日志信息。

logging 高级用法

除了基本的记录日志信息的功能之外,logging 库还提供了许多高级用法,如下:
日志轮换
logging.handlers 模块提供了多种处理器,其中 RotatingFileHandler 和 TimedRotatingFileHandler 可以实现日志轮换的功能。

RotatingFileHandler 根据指定的文件大小,循环记录日志信息,如果文件大小超过了指定大小,则将当前日志文件重命名为备份文件,并创建一个新的日志文件继续记录日志信息。使用 maxBytes 参数设置日志文件的最大大小。

TimedRotatingFileHandler 根据指定的时间,循环记录日志信息,可以设置循环周期(例如每天、每小时等)。使用 when 参数设置循环周期,支持 S、M、H、D、W、midnight 等值,分别表明每秒、每分钟、每小时、每天、每周、每天午夜等。

import logging
import logging.handlers

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 创建一个轮换文件处理器
file_handler = logging.handlers.RotatingFileHandler('my.log', maxBytes=1024, backupCount=3)
file_handler.setFormatter(formatter)

# 绑定处理器和记录器
logger.addHandler(file_handler)

# 记录日志信息
logger.info('This is a test message')

上述代码中,创建了一个 RotatingFileHandler 处理器,指定日志文件名为 my.log,最大大小为 1024 字节,备份文件数量为 3。然后将处理器绑定到记录器上,并使用记录器记录了一条日志信息。

日志邮件通知
使用 SMTPHandler 处理器可以实现将日志信息通过电子邮件发送给指定的收件人。

import logging
import logging.handlers

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 创建一个 SMTP 处理器
mail_handler = logging.handlers.SMTPHandler(mailhost=('smtp.gmail.com', 587),
                                            fromaddr='sender@gmail.com',
                                            toaddrs='receiver@gmail.com',
                                            subject='Test Logging')
mail_handler.setFormatter(formatter)

# 绑定处理器和记录器
logger.addHandler(mail_handler)

# 记录日志信息
logger.error('This is an error message')

上述代码中,创建了一个 SMTPHandler 处理器,指定了 SMTP 服务器地址、发件人地址、收件人地址和邮件主题。然后将处理器绑定到记录器上,并使用记录器记录了一条错误级别的日志信息。当记录器记录了错误级别的日志信息时,SMTPHandler 处理器会自动将邮件发送给指定的收件人。

日志归档
logging.handlers 模块还提供了 RotatingFileHandler 和 TimedRotatingFileHandler 的派生类,可以将历史日志信息归档到不同的文件中。
例如,RotatingFileHandler 的派生类
ConcurrentRotatingFileHandler 可以将历史日志信息归档到不同的文件中,归档的文件名可以包含时间信息和序号信息。使用 filename 参数设置归档文件名的格式,例如:

import logging
import logging.handlers

logger = logging.getLogger('my_logger')

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# 创建一个并发轮换文件处理器
file_handler = logging.handlers.ConcurrentRotatingFileHandler('my.log', maxBytes=1024, backupCount=3, filename='my_%Y%m%d_%H%M%S.log')
file_handler.setFormatter(formatter)

# 绑定处理器和记录器
logger.addHandler(file_handler)

# 记录日志信息
logger.info('This is a test message')

上述代码中,创建了一个
ConcurrentRotatingFileHandler 处理器,指定日志文件名为 my.log,最大大小为 1024 字节,备份文件数量为 3,归档文件名格式为 my_年月日_时分秒.log。然后将处理器绑定到记录器上,并使用记录器记录了一条日志信息。当日志文件大小超过指定大小时,会自动将当前日志文件归档到一个新的文件中。

自定义日志处理器
logging.handlers 模块提供了多种日志处理器,但有时候需要自定义特定的日志处理器来满足特定的需求。可以通过继承 logging.Handler 类并重写其方法来实现自定义日志处理器。

例如,下面的代码定义了一个 MyHandler 类,可以将日志信息输出到标准输出,并在每条日志信息前添加指定的前缀字符串。

import logging

class MyHandler(logging.Handler):
    def __init__(self, prefix=''):
        super().__init__()
        self.prefix = prefix
    
    def emit(self, record):
        message = self.format(record)
        message = f'{self.prefix} {message}'
        print(message)

使用 MyHandler 处理器和 logging 模块中的其他组件一样,例如:

logger = logging.getLogger('my_logger')

# 创建一个 MyHandler 处理器
handler = MyHandler(prefix='[INFO]')
handler.setLevel(logging.INFO)

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# 绑定处理器和记录器
logger.addHandler(handler)

# 记录日志信息
logger.info('This is a test message')

上述代码中,创建了一个 MyHandler 处理器,指定前缀字符串为 [INFO]。然后将处理器绑定到记录器上,并使用记录器记录了一条日志信息。当记录器记录日志信息时,MyHandler 处理器会将信息输出到标准输出,并在每条信息前添加前缀字符串。

自定义日志过滤器
logging.Filter 类可以用于定义日志过滤器,根据需要过滤掉一些不需要记录的日志信息。可以通过继承 logging.Filter 类实现自定义日志过滤器。
例如,下面的代码定义了一个 MyFilter 类,可以过滤掉日志信息中包含指定字符串的记录。

import logging

class MyFilter(logging.Filter):
    def __init__(self, exclude_str=''):
        super().__init__()
        self.exclude_str = exclude_str
    
    def filter(self, record):
        message = record.getMessage()
        return self.exclude_str not in message

使用 MyFilter 过滤器和 logging 模块中的其他组件一样,例如:

logger = logging.getLogger('my_logger')

# 创建一个过滤器
filter = MyFilter(exclude_str='warning')
filter.setLevel(logging.WARNING)

# 创建一个处理器
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)

# 创建一个格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# 绑定过滤器、处理器和记录器
handler.addFilter(filter)
logger.addHandler(handler)

# 记录日志信息
logger.info('This is a test message')
logger.warning('This is a warning message')

上述代码中,创建了一个 MyFilter 过滤器,指定排除包含 warning 字符串的日志信息。然后创建了一个处理器和格式化器,并将过滤器、处理器和记录器绑定在一起。当记录器记录日志信息时,MyFilter 过滤器会过滤掉包含 warning 字符串的日志信息,并将其它日志信息输出到标准输出。

日志模块的配置文件
logging 模块可以使用配置文件来配置日志记录器、处理器、格式化器和过滤器等组件的参数,这样可以方便地在多个应用程序中重复使用配置。

例如,下面是一个 logging 模块的配置文件示例 logging.conf:

[loggers]
keys=root

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('my.log', 'a')

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=%Y-%m-%d %H:%M:%S

上述配置文件定义了一个记录器 root,它有两个处理器 consoleHandler 和 fileHandler,使用的格式化器为 simpleFormatter。consoleHandler 处理器将日志信息输出到标准输出,fileHandler 处理器将日志信息输出到文件 my.log 中,文件模式为追加模式。

在 Python 代码中使用配置文件可以使用 logging.config 模块中的 fileConfig 函数,例如:

import logging.config

logging.config.fileConfig('logging.conf')

logger = logging.getLogger('root')

logger.info('This is a test message')

上述代码中,通过调用 fileConfig 函数加载配置文件 logging.conf,然后获取 logger 对象并使用它记录日志信息。

© 版权声明

相关文章

1 条评论

您必须登录才能参与评论!
立即登录
none
暂无评论...