Python的logging模块
Python的logging模块是一个非常强大的工具,用于在Python应用程序中生成日志。
目录
一、当不使用时log:
二、下面是对logging模块的详细介绍:
1. 日志级别
2. Logger对象
3. Handler对象
4. Formatter对象
5.日志信息保存为文件
6. 进阶功能
7. 配置logging模块
三、实战:
1.操作步骤
2.操作示例
四、总结
一、当不使用时log:
log_1 = '第1个日志运行OK'
print(log_1)
log_2 = '第2个日志运行OK'
print(log_2)
log_3 = '第3个日志运行OK'
print(log_3)
结果:
第1个日志运行OK
第2个日志运行OK
第3个日志运行OK
# 使用logging代替print
import logging
logging.basicConfig(level=logging.INFO)
log_1 = '第1个日志运行OK'
logging.debug(log_1)
log_2 = '第2个日志运行OK'
logging.debug(log_2)
log_3 = '第3个日志运行OK'
logging.debug(log_3)
此时终端并无输出。
import logging
logging.basicConfig(level=logging.DEBUG)
log_1 = '第1个日志运行OK'
logging.debug(log_1)
log_2 = '第2个日志运行OK'
logging.debug(log_2)
log_3 = '第3个日志运行OK'
logging.debug(log_3)
结果:
DEBUG:root:第1个日志运行OK
DEBUG:root:第2个日志运行OK
DEBUG:root:第3个日志运行OK会发现,此时就会以DEBUG级别输出信息。
在这个例子中,日志级别是由配置文件中的参数决定的。如果配置文件中的"log_level"参数被设置为"DEBUG",那么所有级别的日志信息都会被记录下来。如果"log_level"参数被设置为"INFO",那么只有INFO, WARNING, ERROR, CRITICAL级别的日志信息会被记录下来。如果"log_level"参数被设置为"ERROR",那么只有ERROR和CRITICAL级别的日志信息会被记录下来。因此,使用logging模块可以让你更方便地控制日志信息的输出,而无需反复添加或删除print()函数。
将所有的
print()
语句改为logging.debug()
,logging.info()
,logging.warning()
,logging.error()
, 或logging.critical()
,可以让你更好地控制日志信息的输出和级别。以下是一个示例:import logging # 配置日志 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') # 使用logging代替print logging.debug('This is a debug message') logging.info('This is an info message') logging.warning('This is a warning message') logging.error('This is an error message') logging.critical('This is a critical message') # 通常在程序中,你会在某个特定的模块或类中使用logger logger = logging.getLogger('my_module') def my_function(): try: # 假设这里有一些可能出错的操作 result = 10 / 0 except ZeroDivisionError: logger.error('Tried to divide by zero!', exc_info=True) my_function() # 输出一些成功的信息 logger.info('Function completed successfully.')
在这个例子中,我们首先配置了logging模块,设置了日志级别为DEBUG,这意味着所有级别的日志信息都将被记录。然后,我们使用
logging.debug()
,logging.info()
,logging.warning()
,logging.error()
, 和logging.critical()
函数来记录不同级别的日志信息。在
my_function()
函数中,我们使用了logger.error()
函数来记录一个错误信息,并且通过exc_info=True
参数来包含异常信息。最后,我们在函数完成时记录了一条信息级别的日志。如果你运行这个程序,你将会看到所有级别的日志信息都被记录了下来,包括日期时间、日志级别和实际的日志消息。如果将logging模块的级别设置为更高的级别,如INFO或ERROR,那么只有那些级别或更高级别的日志信息才会被记录。
注意:在实际应用中,你应该为每个模块或类创建一个独立的logger对象,这样可以更精确地控制每个部分的日志输出。
使用Python的logging模块可以极大地提高代码的可维护性和调试效率。当你在开发阶段,可能需要大量的日志信息来帮助你理解程序的运行情况,这时你可以将日志级别设置为DEBUG,这样所有级别的日志信息都会被记录下来。
二、下面是对logging模块的详细介绍:
1. 日志级别
Logging模块支持以下几种日志级别:
2. Logger对象
Logger对象是logging模块的主要接口,用于发送日志信息。你可以通过logging.getLogger(name)
获取或创建一个logger对象,其中'name'参数是一个字符串,用于唯一标识这个logger。
3. Handler对象
Handler对象决定了日志信息的输出目的地。一些常见的handler包括:
在Python的logging模块中,Handler对象决定了日志信息发送的目的地。Handler可以将日志信息发送到控制台、文件、邮件、HTTP服务器等不同的地方。以下是几种常见的Handler:
StreamHandler: 将日志信息发送到类似sys.stdout或sys.stderr的流。这是默认的Handler,如果你不指定任何Handler,那么日志信息将被发送到控制台。
FileHandler: 将日志信息写入到一个文件中。这是最常用的Handler之一,特别是在生产环境中,因为你可以将日志信息保存到文件中,以便于后续的分析和调试。
RotatingFileHandler: 当日志文件达到一定大小时,会自动将日志信息写入到一个新的文件中,旧的日志信息会被保存在旧的文件中。这样可以防止日志文件过大,同时也便于日志信息的管理和查询。
TimedRotatingFileHandler: 当日志文件达到一定时间间隔时,会自动将日志信息写入到一个新的文件中。例如,你可以设置日志文件每天、每小时、每分钟等进行轮换。
SMTPHandler: 可以将日志信息通过邮件的方式发送出去。这在生产环境中非常有用,当你的程序出现错误时,你可以立即收到邮件通知。
HTTPHandler: 可以将日志信息发送到HTTP服务器。这在分布式系统中非常有用,你可以将所有节点的日志信息集中到一个服务器上进行处理。
SocketHandler: 可以将日志信息通过socket发送到远程的日志服务器。
每个Handler都有自己的setLevel()方法,用于设置该Handler的日志级别。只有当日志信息的级别大于等于Handler的级别时,该Handler才会处理这条日志信息。
此外,每个Handler都有自己的setFormatter()方法,用于设置该Handler的日志信息格式。你可以创建一个Formatter对象,然后将其添加到Handler中,这样Handler就会按照你定义的格式来输出日志信息。
例如,以下是一个使用FileHandler和Formatter的例子:
import logging # 创建logger logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) # 创建file handler,设置其日志级别 fh = logging.FileHandler('日志文件/app.log') fh.setLevel(logging.DEBUG) # 创建formatter,设置其日志格式 formatter = logging.Formatter('时间:%(asctime)s - 日志等级:%(levelname)s - 日志信息:%(message)s') # 将formatter添加到fh fh.setFormatter(formatter) # 将fh添加到logger logger.addHandler(fh) # 记录日志信息 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')
在这个例子中,我们首先创建了一个logger对象,并将其日志级别设置为DEBUG。然后,我们创建了一个FileHandler对象,并将其日志级别也设置为DEBUG。接着,我们创建了一个Formatter对象,用于定义日志信息的格式。
然后,我们将Formatter对象添加到FileHandler对象中,再将FileHandler对象添加到logger对象中。这样,每当logger对象接收到一条日志信息,它就会通过FileHandler对象将这条信息写入到app.log文件中。
4. Formatter对象
Formatter对象决定了日志信息的格式。你可以通过logging.Formatter(fmt, datefmt=None)
来创建一个Formatter对象,其中'fmt'参数是一个字符串,用于定义日志信息的格式,'datefmt'参数用于定义日期/时间的格式。
Formatter
是Python的logging
模块中的一个类,用于定义日志信息的格式。Formatter
的构造函数接受两个参数:fmt
和datefmt
,其中fmt
用于定义日志信息的格式,datefmt
用于定义日期/时间的格式。
fmt
参数是一个字符串,其中可以包含各种占位符,这些占位符会被替换为实际的日志信息。以下是一些常用的占位符:%(name)s
:Logger的名字,默认是" root"。%(levelno)s
:打印日志级别的数值。%(levelname)s
:打印日志级别的名称。%(pathname)s
:完整路径名,指向当前执行的脚本。%(filename)s
:脚本的文件名。%(module)s
:调用日志记录函数的模块(脚本)名。%(funcName)s
:调用日志记录函数的函数名。%(lineno)d
:调用日志记录函数的代码行号。%(created)f
:打印日志的时间,用UNIX标准的表示时间的浮点数表示。%(relativeCreated)d
:打印日志时间与Logger创建时间的差值。%(asctime)s
:字符串形式的当前时间。默认格式是“2003-07-08 16:49:45,896”。逗号后面的是毫秒。例如,以下是一个日志格式的例子:
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s')
在这个例子中,日志信息的格式被定义为:日期和时间 – 日志器的名字 – 日志级别 – 文件名:行号 – 实际的日志消息。
datefmt
参数也是一个字符串,用于定义日期/时间的格式。例如:formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
在这个例子中,日期/时间的格式被定义为:年-月-日 时:分:秒。
import logging # 设置输出的格式 LOG_FORMAT = "时间:%(asctime)s - 日志等级:%(levelname)s - 日志信息:%(message)s" # 对logger进行配置——日志等级&输出格式 logging.basicConfig(level=logging.WARNING, format=LOG_FORMAT) # logging.level(message)创建一条level级别的日志 logging.debug("This is a debug log") logging.info("This is a info log") logging.warning("This is a warning log") logging.error("This is a error log") logging.critical("This is a critical log")
结果:
时间:2024-09-21 10:44:50,290 – 日志等级:WARNING – 日志信息:This is a warning log
时间:2024-09-21 10:44:50,290 – 日志等级:ERROR – 日志信息:This is a error log
时间:2024-09-21 10:44:50,290 – 日志等级:CRITICAL – 日志信息:This is a critical log只有WARNING级别及以上的日志信息(即WARNING, ERROR, CRITICAL)会被记录和输出,而DEBUG和INFO级别的日志信息则会被忽略。
5.日志信息保存为文件
上述日志显示在终端,关掉电脑就没有了,将其保存为文件。
import logging
# 设置输出的格式
LOG_FORMAT = "时间:%(asctime)s - 日志等级:%(levelname)s - 日志信息:%(message)s"
# 对logger进行配置——日志等级&输出格式
logging.basicConfig(level=logging.WARNING, format=LOG_FORMAT,filename="日志文件/my.log")
# logging.level(message)创建一条level级别的日志
logging.debug("This is a debug log")
logging.info("This is a info log")
logging.warning("This is a warning log")
logging.error("This is a error log")
logging.critical("This is a critical log")
6. 进阶功能
logger.addFilter(filter)
来添加过滤器。logger.removeHandler(hdlr)
或logger.removeFilter(filter)
可以关闭特定的handler或filter。TimedRotatingFileHandler
或RotatingFileHandler
可以实现日志文件的自动滚动,避免单个日志文件过大。7. 配置logging模块
你可以通过logging.basicConfig()
函数进行基本配置,也可以使用配置文件(如.ini文件)或字典来配置logging模块。
logging.basicConfig(filename='app.log', level=logging.INFO,
format='%(asctime)s:%(levelname)s:%(message)s')
以上就是对Python的logging模块的详细介绍,通过它,你可以轻松地在Python应用程序中生成和管理日志信息。
三、实战:
1.操作步骤
创建logger对象:首先,你需要创建一个logger对象。你可以通过调用 logging.getLogger(name)
函数来创建一个logger对象,其中'name'参数是用于标识logger的字符串。import logging logger = logging.getLogger('my_logger')
设置日志级别:然后,你需要设置logger对象的日志级别。你可以通过调用logger对象的 setLevel(level)
方法来设置日志级别,其中'level'参数可以是以下之一:DEBUG, INFO, WARNING, ERROR, CRITICAL。logger.setLevel(logging.DEBUG)
添加handler:handler决定了日志信息的输出方式,如输出到控制台、文件或网络服务器等。你可以通过调用logger对象的 addHandler(handler)
方法来添加handler。# 输出到控制台 console_handler = logging.StreamHandler() logger.addHandler(console_handler) # 输出到文件 file_handler = logging.FileHandler('app.log') logger.addHandler(file_handler)
设置日志格式:你可以通过创建一个formatter对象,并将其添加到handler中,来设置日志信息的格式。 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) file_handler.setFormatter(formatter)
记录日志信息:最后,你可以通过调用logger对象的 debug()
,info()
,warning()
,error()
,critical()
方法来记录日志信息。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')
使用过滤器:你还可以使用过滤器来决定哪些日志信息应该被记录。过滤器是一个实现了 filter(record)
方法的对象,该方法返回True或False,以决定是否记录日志信息。import logging class MyFilter(logging.Filter): def filter(self, record): # 使用record.getMessage()方法获取日志记录 msg = record.getMessage() return 'happy' in msg logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) logger.addFilter(MyFilter()) logger.info('This is an info message') logger.warning('This is an happy warning message')
以上就是Python的logging模块的一些基本使用方法。通过使用logging模块,你可以更方便地在Python应用程序中生成和管理日志
2.操作示例
在Python的logging模块中,一个logger对象可以有多个handler对象,这意味着你可以将日志信息同时发送到多个目的地。但是,如果你希望一个logger对象只对应一个handler对象,你可以按照以下方式操作:
import logging
# 创建logger
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# 创建file handler,设置其日志级别
fh = logging.FileHandler('app.log')
fh.setLevel(logging.DEBUG)
# 创建formatter,设置其日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 将formatter添加到fh
fh.setFormatter(formatter)
# 将fh添加到logger
logger.addHandler(fh)
# 记录日志信息
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')
在这个例子中,我们创建了一个logger对象my_logger
,并为其添加了一个FileHandler对象fh
。这意味着my_logger
只会将日志信息写入到app.log
文件中,而不会在控制台或其他地方输出。
然而,值得注意的是,虽然一个logger对象可以只对应一个handler对象,但这并不意味着你不能为其他的logger对象添加其他的handler对象。实际上,你可以为每个logger对象添加不同的handler对象,这样每个logger对象就可以将日志信息发送到不同的目的地。
例如,你可以创建一个logger对象my_logger1
,并为其添加一个FileHandler对象fh1
,使其将日志信息写入到app1.log
文件中。同时,你也可以创建另一个logger对象my_logger2
,并为其添加一个StreamHandler对象sh
,使其将日志信息输出到控制台。
import logging
# 创建logger1
logger1 = logging.getLogger('my_logger1')
logger1.setLevel(logging.DEBUG)
# 创建file handler1,设置其日志级别
fh1 = logging.FileHandler('日志文件/app1.log')
fh1.setLevel(logging.DEBUG)
# 创建formatter,设置其日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 将formatter添加到fh1
fh1.setFormatter(formatter)
# 将fh1添加到logger1
logger1.addHandler(fh1)
# 创建logger2
logger2 = logging.getLogger('my_logger2')
logger2.setLevel(logging.DEBUG)
# 创建stream handler,设置其日志级别
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
# 使用相同的formatter
sh.setFormatter(formatter)
# 将sh添加到logger2
logger2.addHandler(sh)
# 记录日志信息
logger1.debug('This is a debug message from logger1')
logger2.debug('This is a debug message from logger2')
在这个例子中,my_logger1
的debug信息会被写入到app1.log
文件中,而my_logger2
的debug信息则会被输出到控制台。
四、总结
在Python的
logging
模块中,Logger
对象是用于生成日志的核心组件。以下是一些关于Logger
对象的详细信息:
创建Logger对象:你可以通过
logging.getLogger(name)
函数来创建一个Logger
对象。name
参数是一个字符串,用于标识这个Logger
对象。如果你不提供name
参数,那么getLogger()
函数将返回一个名为root
的Logger
对象。设置日志级别:
Logger
对象有一个setLevel(level)
方法,用于设置这个Logger
对象的日志级别。日志级别有DEBUG
,INFO
,WARNING
,ERROR
,CRITICAL
,其中DEBUG
级别最低,CRITICAL
级别最高。只有当一条日志信息的级别大于等于Logger
对象的级别时,这条日志信息才会被处理。添加Handler对象:
Logger
对象有一个addHandler(hdlr)
方法,用于将一个Handler
对象添加到这个Logger
对象中。Handler
对象决定了日志信息发送的目的地,例如,你可以添加一个StreamHandler
对象,将日志信息输出到控制台;或者添加一个FileHandler
对象,将日志信息写入到文件中。记录日志信息:
Logger
对象有debug()
,info()
,warning()
,error()
,critical()
等方法,用于记录不同级别的日志信息。这些方法接受一个字符串参数,用于描述日志信息的具体内容。传递日志信息:
Logger
对象会将日志信息传递给它的所有Handler
对象。每个Handler
对象都会根据自己的日志级别和格式,决定是否处理这条日志信息,以及如何处理这条日志信息。子Logger:你还可以创建一个
Logger
对象的子Logger
对象。子Logger
继承父Logger
的所有Handler
和Filter
,但是可以有自己的Handler
和Filter
。子Logger
的日志级别默认与父Logger
相同,但是可以被单独设置。例如,以下是一个使用
Logger
对象的例子:import logging # 创建logger logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) # 创建file handler,设置其日志级别 fh = logging.FileHandler('app.log') fh.setLevel(logging.DEBUG) # 创建formatter,设置其日志格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 将formatter添加到fh fh.setFormatter(formatter) # 将fh添加到logger logger.addHandler(fh) # 记录日志信息 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')
在这个例子中,我们首先创建了一个
Logger
对象my_logger
,并将其日志级别设置为DEBUG
。然后,我们创建了一个FileHandler
对象fh
,并将其日志级别也设置为DEBUG
。接着,我们创建了一个Formatter
对象,用于定义日志信息的格式。然后,我们将
Formatter
对象添加到FileHandler
对象中,再将FileHandler
对象添加到Logger
对象中。这样,每当my_logger
对象接收到一条日志信息,它就会通过FileHandler
对象将这条信息写入到app.log
文件中。
作者:kimi-222