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模块支持以下几种日志级别:

  • DEBUG: 详细信息,通常只在调试问题时使用。
  • INFO: 确认一切按预期运行。
  • WARNING: 指示可能出现的问题,但仍可继续运行。
  • ERROR: 由于更严重的问题,某些功能无法执行。
  • CRITICAL: 严重错误,程序可能无法继续运行。
  • 2. Logger对象

    Logger对象是logging模块的主要接口,用于发送日志信息。你可以通过logging.getLogger(name)获取或创建一个logger对象,其中'name'参数是一个字符串,用于唯一标识这个logger。

    3. Handler对象

    Handler对象决定了日志信息的输出目的地。一些常见的handler包括:

  • StreamHandler: 输出到标准流(如stdout或stderr)。
  • FileHandler: 输出到文件。
  • SocketHandler: 输出到网络socket。
  • SMTPHandler: 发送邮件。
  • HTTPHandler: 发送到HTTP服务器。
  • 在Python的logging模块中,Handler对象决定了日志信息发送的目的地。Handler可以将日志信息发送到控制台、文件、邮件、HTTP服务器等不同的地方。以下是几种常见的Handler:

    1. StreamHandler: 将日志信息发送到类似sys.stdout或sys.stderr的流。这是默认的Handler,如果你不指定任何Handler,那么日志信息将被发送到控制台。

    2. FileHandler: 将日志信息写入到一个文件中。这是最常用的Handler之一,特别是在生产环境中,因为你可以将日志信息保存到文件中,以便于后续的分析和调试。

    3. RotatingFileHandler: 当日志文件达到一定大小时,会自动将日志信息写入到一个新的文件中,旧的日志信息会被保存在旧的文件中。这样可以防止日志文件过大,同时也便于日志信息的管理和查询。

    4. TimedRotatingFileHandler: 当日志文件达到一定时间间隔时,会自动将日志信息写入到一个新的文件中。例如,你可以设置日志文件每天、每小时、每分钟等进行轮换。

    5. SMTPHandler: 可以将日志信息通过邮件的方式发送出去。这在生产环境中非常有用,当你的程序出现错误时,你可以立即收到邮件通知。

    6. HTTPHandler: 可以将日志信息发送到HTTP服务器。这在分布式系统中非常有用,你可以将所有节点的日志信息集中到一个服务器上进行处理。

    7. 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的构造函数接受两个参数:fmtdatefmt,其中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对象,它们之间形成一个层次结构。子logger可以继承父logger的handler和过滤器。
  • 过滤器(Filter):过滤器可以决定哪些日志记录应该被处理。你可以通过logger.addFilter(filter)来添加过滤器。
  • 日志记录器关闭:通过logger.removeHandler(hdlr)logger.removeFilter(filter)可以关闭特定的handler或filter。
  • 日志文件滚动:使用TimedRotatingFileHandlerRotatingFileHandler可以实现日志文件的自动滚动,避免单个日志文件过大。
  • 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对象的详细信息:

    1. 创建Logger对象:你可以通过logging.getLogger(name)函数来创建一个Logger对象。name参数是一个字符串,用于标识这个Logger对象。如果你不提供name参数,那么getLogger()函数将返回一个名为rootLogger对象。

    2. 设置日志级别Logger对象有一个setLevel(level)方法,用于设置这个Logger对象的日志级别。日志级别有DEBUGINFOWARNINGERRORCRITICAL,其中DEBUG级别最低,CRITICAL级别最高。只有当一条日志信息的级别大于等于Logger对象的级别时,这条日志信息才会被处理。

    3. 添加Handler对象Logger对象有一个addHandler(hdlr)方法,用于将一个Handler对象添加到这个Logger对象中。Handler对象决定了日志信息发送的目的地,例如,你可以添加一个StreamHandler对象,将日志信息输出到控制台;或者添加一个FileHandler对象,将日志信息写入到文件中。

    4. 记录日志信息Logger对象有debug()info()warning()error()critical()等方法,用于记录不同级别的日志信息。这些方法接受一个字符串参数,用于描述日志信息的具体内容。

    5. 传递日志信息Logger对象会将日志信息传递给它的所有Handler对象。每个Handler对象都会根据自己的日志级别和格式,决定是否处理这条日志信息,以及如何处理这条日志信息。

    6. 子Logger:你还可以创建一个Logger对象的子Logger对象。子Logger继承父Logger的所有HandlerFilter,但是可以有自己的HandlerFilter。子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

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python的logging模块

    发表回复