logger python
在编程中,日志是一种非常重要的组件,可以帮助我们记录代码运行过程中的信息,错误和警告。Python的标准库中提供了一个日志记录模块,即logging
模块,可以方便地进行日志记录和管理。在本文中,我们将详细介绍如何使用logging
模块来实现日志记录。
为什么需要日志记录
在开发和维护一个应用程序时,我们通常会遇到一些问题,比如程序运行时发生错误、程序运行较慢等。这时候我们就需要一种方法来记录这些问题,以便我们能够快速定位和解决它们。而日志记录就是一种非常好的方法,它可以帮助我们:
- 跟踪程序的运行状态
- 发现程序中的错误
- 监控程序的性能
logging模块的基本用法
logging
模块是Python内置的日志模块,我们可以使用它来创建和配置日志记录器。下面是一个简单的示例来演示如何使用logging
模块记录日志:
import logging
# 创建一个logger
logger = logging.getLogger('example_logger')
logger.setLevel(logging.DEBUG)
# 创建一个文件处理器,并设置日志级别为DEBUG
file_handler = logging.FileHandler('example.log')
file_handler.setLevel(logging.DEBUG)
# 创建一个格式化器,并添加到handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
# 将handler添加到logger
logger.addHandler(file_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')
在这个示例中,我们首先创建了一个名为example_logger
的logger
对象,并设置了日志级别为DEBUG
。然后我们创建了一个输出到文件的文件处理器,并设置了文件处理器的日志级别为DEBUG
。接着我们创建了一个格式化器,并将其添加到文件处理器中。最后,我们将文件处理器添加到logger
中,并使用logger
对象记录了5条不同级别的日志。
运行上面的代码后,会在当前目录下生成一个名为example.log
的日志文件,并内容如下:
2021-01-01 12:00:00,000 - example_logger - DEBUG - This is a debug message
2021-01-01 12:00:00,001 - example_logger - INFO - This is an info message
2021-01-01 12:00:00,002 - example_logger - WARNING - This is a warning message
2021-01-01 12:00:00,003 - example_logger - ERROR - This is an error message
2021-01-01 12:00:00,004 - example_logger - CRITICAL - This is an critical message
日志级别
logging
模块定义了5种不同的日志级别,分别是DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
,级别从低到高。通过控制日志级别,我们可以过滤掉低于某个级别的日志,只记录高于等于该级别的日志。
在使用logger.setLevel()
方法设置日志级别时,会同时设置该日志级别及以上的所有级别:
logger.setLevel(logging.DEBUG)
除了logger.setLevel()
方法外,我们也可以通过在handler上设置日志级别来实现过滤日志:
file_handler = logging.FileHandler('example.log')
file_handler.setLevel(logging.DEBUG)
格式化日志
在日志记录中,我们通常会想要记录更多的信息,比如记录日志的时间、logger名称、日志级别等。logging
模块提供了Formatter
类来实现格式化日志信息。我们可以通过设置格式字符串来指定我们想要的日志格式。
下面是一个示例,展示了如何自定义日志格式:
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
在这个示例中,我们自定义了一个格式字符串'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
,其中%(asctime)s
表示日志的时间,%(name)s
表示logger的名称,%(levelname)s
表示日志的级别,%(message)s
表示日志的内容。最后将这个格式字符串赋值给了Formatter
对象,并将其添加到了文件处理器中。
添加多个handler
在实际应用中,我们可能需要将同一条日志信息同时输出到不同的地方,比如输出到终端和文件中。logging
模块允许我们为一个logger
对象添加多个handler
,从而可以实现将同一条日志信息输出到不同的地方。
下面是一个示例,展示了如何添加多个handler
:
# 创建一个终端处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
# 创建一个新的格式化器
console_formatter = logging.Formatter('%(message)s')
console_handler.setFormatter(console_formatter)
# 将终端处理器添加到logger
logger.addHandler(console_handler)
在这个示例中,我们创建了一个新的终端处理器console_handler
,并设置了console_handler
的日志级别为DEBUG
。然后,我们创建了一个新的格式化器console_formatter
,并将其绑定到console_handler
上。最后,我们将console_handler
添加到了logger
中。这样,当我们记录日志时,日志信息就会同时输出到文件和终端上。
设置日志文件滚动
在实际应用中,日志文件可能会变得很大,为了节省磁盘空间,我们可以通过设置日志文件滚动的方式来限制日志文件的大小,或者限制日志文件的数量。
下面是一个示例,演示了如何设置日志文件滚动:
from logging.handlers import RotatingFileHandler
# 创建一个滚动文件处理器
rotating_file_handler = RotatingFileHandler('example.log', maxBytes=1024, backupCount=3)
rotating_file_handler.setLevel(logging.DEBUG)
# 创建一个新的格式化器
rotating_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
rotating_file_handler.setFormatter(rotating_formatter)
# 将滚动文件处理器添加到logger
logger.addHandler(rotating_file_handler)
在这个示例中,我们首先导入RotatingFileHandler
类,创建一个RotatingFileHandler
对象rotating_file_handler
。然后,我们设置rotating_file_handler
的maxBytes
参数为1024字节,表示当日志文件大小超过1024字节时,会自动创建一个新的日志文件,并最多保留3个日志文件。最后,我们将滚动文件处理器添加到了logger
中。这样,当日志文件大小超过指定大小时,会自动滚动到新的文件中,以便管理和节省磁盘空间。
日志记录器的传递
在Python中,每个logger
对象都有一个名为propagate
的属性,默认值为True
。当设置propagate
为True
时,日志消息将会被传递给其父logger
,以便继续传播日志消息。如果我们不想让日志消息传播到父logger
,可以将propagate
设置为False
。
下面是一个示例,演示了如何设置propagate
属性:
# 创建一个子日志器
child_logger = logging.getLogger('example_logger.child')
child_logger.propagate = False
# 记录日志
child_logger.error('This is an error message')
在这个示例中,我们首先创建了一个名为example_logger.child
的子logger
对象,并将其propagate
属性设置为False
,表示不传递日志消息给其父logger
。接着我们通过子logger
对象记录了一条错误日志。由于propagate
属性被设置为False
,这条错误日志不会传递给父logger
,只会在子logger
中被处理。
自定义日志处理器
除了使用已经提供的日志处理器外,我们也可以自定义日志处理器,以满足特定的需求。通过继承logging.Handler
类并重写emit
方法,我们可以创建一个自定义的日志处理器。
下面是一个示例,展示了如何自定义一个简单的日志处理器,用于将日志信息输出到标准输出:
class MyHandler(logging.Handler):
def emit(self, record):
# 输出日志信息到标准输出
print(self.format(record))
# 创建自定义处理器
my_handler = MyHandler()
my_handler.setLevel(logging.INFO)
# 将自定义处理器添加到logger
logger.addHandler(my_handler)
# 记录日志
logger.info('This is a custom handler message')
在这个示例中,我们定义了一个名为MyHandler
的自定义处理器,继承自logging.Handler
类,并重写了emit
方法,该方法用于处理日志信息。然后我们创建了一个MyHandler
对象my_handler
,设置日志级别为INFO
,并将其添加到logger
中。最后,我们使用logger
对象记录了一条信息,并由自定义处理器将该信息输出到标准输出。
总结
在本文中,我们详细介绍了Python中日志记录的基本原理和logging
模块的用法。通过了解日志记录的重要性以及logging
模块的功能,我们可以更好地处理程序运行时的异常、错误和警告信息,提高代码的可维护性和稳定性。