Logging
模块是python
中一个很重要的日志模块,它提供了灵活的日志记录功能,广泛应用于调试、运行状态监控、错误追踪以及系统运维中。相比于简单的print()
打印调试,Logging
支持不同的日志级别(如DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
),可将日志输出到不同位置(如控制台、文件、网络等),还能自定义日志格式和处理方式,从而更好地满足实际项目中的日志管理需求。
相信各位小伙伴在平时比赛或者项目中写Python代码的时候,肯定会遇到代码出现莫名其妙的报错,而我们一时半会无法快速定位到问题出在哪里。这时候,相信很多同学都会使用 print()
函数在代码的不同地方插入打印输出来不断调试、缩小问题范围。虽然这种方式简单粗暴,在小项目或调试时确实能派上用场,但随着项目复杂度的提高,print()
调试法就显得力不从心了。比如,你可能想区分调试信息和错误信息,或者只在生产环境中输出关键日志,还可能需要将日志写入文件供后续分析抑或是在找到问题之后还需手动删除各处的调试 print()
函数,这不仅麻烦,而且很容易遗漏,甚至可能将调试信息带到线上环境,造成信息泄露或日志污染。
因此,学会使用专业的日志工具显得尤为重要。在Python中,logging
模块正是官方推荐用于记录日志的强大工具。它不仅支持不同的日志等级(如 DEBUG
、INFO
、WARNING
、ERROR
、CRITICAL
),还允许我们将日志灵活地输出到控制台、文件,甚至远程服务器。此外,logging
还支持自定义日志格式和多种处理器组合,能很好地适配各种复杂应用场景。接下来,我们就从最基础的用法入手,带你一步步掌握 logging
模块的强大功能,写出更专业、更易维护的Python代码!!!
首先我们要知道,在Logging
模块中日志根据作用以及重要程度从小到大依次被分为了如下五个等级,具体如下表:
日志等级(level) | 描述 |
---|---|
DEBUG | 调试信息,通常在诊断问题的时候使用 |
INFO | 普通信息,确认程序按照预期运行 |
WARNING | 警告信息,表示发生意想不到的事,或者指示接下来可能会出现一些问题,但是程序还是继续运行 |
ERROR | 错误信息,程序运行中出现了一些问题,程序某些功能可能不能执行 |
CRITICAL | 危险信息,一个严重的错误,导致程序无法继续运行 |
知道了这些,那我们具体该如何在代码中实现日志管理呢?我们接着往下讲,首先我们肯定是要在代码中导入我们的logging
模块,这个模块是Python内置的,无需额外安装,接着我们要引入logging
模块中的basicConfig
函数,这个是配置日志系统最常用、最简单的一种方式,我们可以通过它来设置最低显示的日志等级、日志的显示格式、日志输出位置(默认是终端)以及写入文件的文件名和编码,接着我们结合示例来给大家演示一下:
- 最低显示的日志等级:
从下面的代码中我们可以看到,我们可以使用level
参数来设置日志的最低显示的等级,而当我们在basicConfig
中将最低显示的日志等级level
设置为WARNING
的时候,只有大于 WARNING
的消息才会被显示出来
import logging logging.basicConfig( level=logging.WARNING, ) 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")
- 日志的显示格式:
除了设置最低显示的日志等级之外,我们还可以使用format
参数来对我们的日志显示格式进行设置,format
有很多可供选择的占位符,具体的见下表:
format占位符 | 含义说明 |
---|---|
%(asctime)s | 日志事件发生的时间(默认格式可自定义) |
%(levelname)s | 日志级别名称(如 INFO、DEBUG 等) |
%(message)s | 日志内容主体(你传入的日志消息) |
%(name)s | 日志器的名称(Logger对象的名字) |
%(fi编程客栈lename)s | 当前执行代码的文件名 |
%(funcName)s | 调用日志输出函数的函数名 |
%(lineno)d | 输出日志的代码行号 |
%(pathname)s | 当前执行代码的完整路径 |
%(module)s | 模块名 |
%(threadName)s | 线程名称(在多线程应用中常用) |
%(process)d | 进程 ID(在多进程应用中常用) |
import logging logging.basicConfig( level=logging.WARNING, format="时间:%(asctime)s-日志名称:%(name)s-日志级别:%(levelname)s-日志信息:%(message)s-文件名:%(filename)s-行号:%(lineno)d" ) 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")
- 日志输出位置:
除了将日志信息打印到终端(默认行为)以外,我们还可以通过 filename
参数将日志写入到指定的文件中。这样一来,我们就可以保存程序运行过程中的所有重要信息,便于后续排查问题或对系统进行日志分析。 我们还可以指定文件的编码方式,比如使用 utf-8
,以避免中文乱码等问题。下面我们通过一个示例将日志写入文件中:
import logging logging.basicConfig( level=logging.WARNING, format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(lphpevelname)s] %(message)s', filename='my_log.log', encoding="utf-8" ) 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")
可以看到,运行了这段代码之后终端没有输出了,而在同路径下生成了一个我们指定的my_log.log
文件,这个文件里就有我们需要的日志输出
如果想每次运行都重新生成日志文件,我们可以继续加上 filemode='w'
参数
import logging logging.basicConfig( level=logging.WARNING, format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s', filename='my_log.log', javascript encoding="utf-8", filemode='w' ) 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")
除此之外,我们也可以给当前的日志信息“命个名”,这在大型项目中非常有用!只需要通过 logging.getLogger("名字")
来创建一个具名 Logger,你可以根据模块、功能、组件的不同给它们起不同的名字,这样日志输出的时候就能快速定位日志是从哪个部分打印出来的,非常适合团队协作和大型工程的调试分析。
import logging logging.basicConfig( level=logging.WARNING, format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s', ) logger = logging.getLogger("example") logger.debug("This is a debug message") logger.info("This is an info message") logger.warnnlGTOHSuDing("This is a warning message") logger.error("This is an error message") logger.critical("This is a critical message")
但是有同学就要问了:“哥们哥们,如果我既想让日志在终端显示,又想把日志写进文件保存下来,该怎么办呢?”这个问题非常常见!实际上,basicConfig
方式虽然简单方便,但它本质上是对根日志器(root logger)做一次性配置的,不支持同时配置多个输出目标(Handler)。也就是说,如果你想实现“同时输出到终编程端和文件”,就需要用更灵活的方式——自定义 Logger + Handler + Formatter 的组合配置!
而Handler
是什么呢?Handler
是 logging
模块中的一个核心概念,它负责将日志消息输出到指定的目标,如控制台、文件、网络等。而 Formatter 则负责定义输出日志的格式。通过组合 Logger
、Handler
和 Formatter
,我们能够更加灵活地控制日志的输出方式和格式。我们可以用下图来进行理解
具体的示例如下,我们首先创建一个 logger
对象,并通过 getLogger
方法为其指定一个名称(在这里是 "example_logger"
)。接着,我们使用 setLevel
方法设置日志的最低输出级别为 DEBUG
,这样所有级别(包括 DEBUG
、INFO
、WARNING
、ERROR
和 CRITICAL
)的日志都能被处理。然后,我们创建了两个 Handler
:一个是 StreamHandler
,用于将日志输出到控制台;另一个是 FileHandler
,用于将日志写入名为 logfile.log
的文件。接着,我们使用 Formatter
设置日志输出的格式,包括日志器名称、日志时间、日志级别和日志信息,最后将这个 Formatter
配置应用到两个 Handler
上。最后,通过 addHandler
方法将这两个 Handler
添加到 logger
中,这样我们就能实现同时将日志输出到控制台和文件。
import logging logger = logging.getLogger("example_logger") logger.setLevel(logging.DEBUG) # 创建两个Handler,分别输出到控制台和文件 console_handler = logging.StreamHandler() # 输出到控制台 file_handler = logging.FileHandler("logfile.log", encoding="utf-8") # 输出到文件 # 创建Formatter并设置格式 formatter = logging.Formatter( '[%(name)s] [%(asctime)s] [%(levelname)s] %(message)s' ) console_handler.setFormatter(formatter) # 控制台Handler设置Formatter file_handler.setFormatter(formatter) # 文件Handler设置Formatter # 将Handler添加到Logger中 logger.addHandler(console_handler) 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")
我们运行下这段代码可以发现不仅终端有输出,我们的日志文件里面也有记录:
到此这篇关于Python日志模块Logging使用指北的文章就介绍到这了,更多相关Python日志模块Logging内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论