python 日志 logging模块详细解析

Python日志 logging模块详细解析

1. 简介

Python的logging模块提供了一种灵活而强大的方式来记录应用程序的运行日志。它提供了一组组件来构建灵活的日志系统,使得开发者可以将日志记录到控制台、文件、邮件等目的地,并支持日志级别、日志轮换、日志格式化等特性。

2. 基本用法

2.1 logging模块概览

logging模块包含了四个主要的类:Logger、Handler、Filter和Formatter。详见下表:

| 类名 | 作用 |

| ------ | ------ |

| Logger | 提供应用程序可使用的接口 |

| Handler | 将日志记录发送到指定目的地 |

| Filter | 帮助用户过滤日志信息 |

| Formatter | 指定日志格式 |

2.2 创建Logger实例

Logger是应用程序代码可以直接使用的接口。它提供了许多方法来输出日志信息,例如:debug()、info()、warning()、error()和critical()。我们可以通过以下方式创建Logger实例:

import logging

logger = logging.getLogger('my_logger')

通过getLogger()创建的Logger实例可以设置层次结构。例如:

import logging

logger = logging.getLogger('my_logger.sub_logger')

在这个例子中,'my_logger.sub_logger'是Logger实例的名称。如果你不指定Logger实例的名称,则会默认从根Logger中获取一个。在这个例子中,根Logger的名称是'root'。

2.3 创建Handler实例

Handler将日志记录发送到指定目的地。在使用Logger时,我们需要为它配置Handler。常用的Handler有以下几种:

| Handler类型 | 作用 |

| ------ | ------ |

| StreamHandler | 将日志输出到控制台 |

| FileHandler | 将日志输出到文件 |

| SMTPHandler | 将日志发送到指定邮件地址 |

下面是创建StreamHandler的示例:

import logging

logger = logging.getLogger('my_logger')

# 创建一个StreamHandler实例

stream_handler = logging.StreamHandler()

# 将StreamHandler添加到Logger实例中

logger.addHandler(stream_handler)

这段代码将Logger和StreamHandler实例建立关联,日志信息将输出到控制台。

2.4 设置日志级别

Logger实例可以为不同类型的日志信息设置不同的级别。例如,可以将LEVEL设置为DEBUG、INFO、WARNING、ERROR、CRITICAL中的任意一个。只有设置的日志级别大于等于记录日志的级别,才会输出日志信息。例如,如果日志的级别为ERROR,则只会记录LEVEL >= ERROR的日志信息。以下是设置日志级别的示例:

import logging

logger = logging.getLogger('my_logger')

logger.setLevel(logging.DEBUG)

在这个示例中,日志级别被设置为DEBUG级别。

2.5 设置日志格式

Formatter类用于指定日志的格式。我们可以通过以下方式创建Formatter实例:

import logging

logger = logging.getLogger('my_logger')

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

这种格式包含了日志记录时间、Logger实例名称、日志级别和日志内容。

2.6 记录日志信息

Logger提供了丰富的方法来记录日志信息。我们可以使用以下方法记录不同类型的日志信息:

| 方法 | 作用 |

| ------ | ------ |

| debug(msg, *args, **kwargs) | 记录DEBUG级别的日志信息 |

| info(msg, *args, **kwargs) | 记录INFO级别的日志信息 |

| warning(msg, *args, **kwargs) | 记录WARNING级别的日志信息 |

| error(msg, *args, **kwargs) | 记录ERROR级别的日志信息 |

| critical(msg, *args, **kwargs) | 记录CRITICAL级别的日志信息 |

我们可以通过以下方式调用Logger的不同方法来记录不同类型的日志信息:

import logging

logger = logging.getLogger('my_logger')

logger.setLevel(logging.DEBUG)

stream_handler = logging.StreamHandler()

stream_handler.setLevel(logging.DEBUG)

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

stream_handler.setFormatter(formatter)

logger.addHandler(stream_handler)

logger.debug('debug信息')

logger.info('info信息')

logger.warning('warning信息')

logger.error('error信息')

logger.critical('critical信息')

在这个示例中,我们建立了Logger、StreamHandler和Formatter之间的关联,并使用Logger实例的不同方法记录了不同类型的日志信息。

3. 进阶用法

3.1 日志轮换

有时需要在日志文件达到一定大小后,自动切换到新的日志文件继续记录。这种功能称为日志轮换。logging模块提供了多种轮换方式,包括时间轮换、大小轮换等。

下面是使用TimedRotatingFileHandler类实现日志轮换的示例:

import logging

from logging.handlers import TimedRotatingFileHandler

logger = logging.getLogger('my_logger')

logger.setLevel(logging.DEBUG)

handler = TimedRotatingFileHandler('myapp.log', when='midnight', backupCount=7)

handler.setLevel(logging.DEBUG)

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

handler.setFormatter(formatter)

logger.addHandler(handler)

logger.debug('debug信息')

logger.info('info信息')

logger.warning('warning信息')

logger.error('error信息')

logger.critical('critical信息')

在这个示例中,我们使用了TimedRotatingFileHandler类,当日志文件大小达到一定值或者到了一定时间后,会自动创建新的日志文件并记录日志信息。

3.2 记录异常信息

当程序出现异常时,我们需要对异常信息进行记录。logging模块提供了将捕捉到的异常信息记录到日志信息中的功能。通过捕捉try/except块中的异常信息,我们可以将其记录到日志文件中,以便后续排查问题。

下面是将异常信息记录到日志文件中的示例:

import logging

logger = logging.getLogger('my_logger')

logger.setLevel(logging.DEBUG)

stream_handler = logging.StreamHandler()

stream_handler.setLevel(logging.DEBUG)

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

stream_handler.setFormatter(formatter)

logger.addHandler(stream_handler)

try:

1 / 0

except Exception as e:

logger.error('发生异常了:{}'.format(str(e)))

在这个示例中,我们使用try/except块捕捉了异常信息,并使用Logger实例的error()方法记录了异常信息。通过这种方式,我们可以很方便地记录程序运行中的异常信息,并且防止程序直接崩溃。

3.3 设置日志处理器和格式化器的格式

可以使用logging模块的LogRecord类控制各个处理器和格式化器的格式。例如,可以让所有的日志处理器和格式化器输出线程ID信息:

import logging

import logging.config

LOGGING = {

'version': 1,

'formatters': {

'default': {

'format': '%(asctime)s %(levelname)s [%(thread)d]:%(message)s'

},

},

'handlers': {

'console': {

'class': 'logging.StreamHandler',

'level': 'INFO',

'formatter': 'default',

},

'file': {

'class': 'logging.FileHandler',

'filename': 'myapp.log',

'mode': 'w',

'level': 'DEBUG',

'formatter': 'default',

},

},

'loggers': {

'': {

'handlers': ['console', 'file'],

'level': 'DEBUG'

}

}

}

logging.config.dictConfig(LOGGING)

root_logger = logging.getLogger()

root_logger.debug('debug信息')

root_logger.info('info信息')

root_logger.warning('warning信息')

root_logger.error('error信息')

root_logger.critical('critical信息')

在这个示例中,我们使用了Logging字典配置文件,并设置了日志格式、处理器和Logger等信息。在格式化器中添加了[%(thread)d]格式控制符,以打印线程ID信息。

3.4 性能优化

日志模块耗费的时间和资源比较多。在一些要求性能的应用程序中,可能需要关闭日志或降低日志级别,以减少日志对性能的影响。可以通过以下方式关闭日志:

import logging

logging.basicConfig(level=logging.CRITICAL)

在这个示例中,我们将根Logger的日志级别设置为CRITICAL级别。这意味着除了CRITICAL日志信息以外,所有的日志信息都不会被记录到日志文件中。这可以帮助我们提高应用程序的性能。

4. 总结

logging模块提供了一种强大而灵活的方式记录应用程序的运行日志。通过了解logging模块的基本用法和进阶用法,可以更好地记录和管理应用程序的日志信息。此外,我们还介绍了如何设置日志轮换、记录异常信息、控制日志处理器和格式化器的格式以及性能优化等方面的内容。希望通过本文对logging模块有更深入的了解和掌握。

后端开发标签