Python日志模块Logging的全面使用指南
笔记哥 /
04-19 /
20点赞 /
0评论 /
403阅读
# Python日志模块Logging使用指北
`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`的消息才会被显示出来
```csharp
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对象的名字) |
| `%(filename)s` | 当前执行代码的文件名 |
| `%(funcName)s` | 调用日志输出函数的函数名 |
| `%(lineno)d` | 输出日志的代码行号 |
| `%(pathname)s` | 当前执行代码的完整路径 |
| `%(module)s` | 模块名 |
| `%(threadName)s` | 线程名称(在多线程应用中常用) |
| `%(process)d` | 进程 ID(在多进程应用中常用) |
```csharp
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`,以避免中文乱码等问题。下面我们通过一个示例将日志写入文件中:
```csharp
import logging
logging.basicConfig(
level=logging.WARNING,
format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)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'` 参数
```csharp
import logging
logging.basicConfig(
level=logging.WARNING,
format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s',
filename='my_log.log',
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**,你可以根据模块、功能、组件的不同给它们起不同的名字,这样日志输出的时候就能快速定位日志是从哪个部分打印出来的,非常适合团队协作和大型工程的调试分析。
```csharp
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.warning("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` 中,这样我们就能实现同时将日志输出到控制台和文件。
```csharp
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")
```
我们运行下这段代码可以发现不仅终端有输出,我们的日志文件里面也有记录:


本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/2388
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利
- 相关联分享
- Browser-use:基于 Python 的智能浏览器自动化 AI 工具调研与实战
- Python多线程编程:线程池使用与性能评估
- 神库Docx预览推荐
- Python在PDF中添加与删除超链接的操作实现
- Python 实现小说网站数据爬取
- Python requests代理(Proxy)使用教程
- 邮件自动回复助手:Rasa与SMTP实现教程
- 在windows11 安装CUDA Toolkit,Python,Anaconda,PyTorch并使用DeepSeek 多模态模型 Janus-Pro识别和生成图片
- trae开发的win10端口占用检测工具
- Python 网络请求:urllib 与 requests 模块深度解析与爬虫实战
- Python基础训练题分享
- Browser-use 详细介绍&使用文档
- Python日志模块Logging的全面使用指南
- N+1查询:数据库性能的隐形杀手与终极拯救指南