5.2 日志系统
引言
小白理解 - 什么是日志?
日志 = 程序运行时写的"日记"
类比:飞机的黑匣子
- 飞机正常飞行时:记录高度、速度、方向...
- 飞机出事后:查看黑匣子,分析原因
为什么需要日志?
场景 没有日志 有日志 程序崩溃 "反正坏了,不知道为啥" "看日志,原来是 API 超时" 用户投诉 "我也不知道他做了什么" "看日志,他输入了非法字符" 性能问题 "感觉慢,不知道哪里慢" "看日志,数据库查询用了 10 秒" print 不行吗?
- print 只能输出到屏幕,程序关了就没了
- logging 可以保存到文件、分级别、带时间戳
logging 基础
小白理解 - 日志级别是什么?
日志有"紧急程度",从低到高:
级别 用途 类比 DEBUG详细调试信息 便签纸 INFO常规运行信息 日记本 WARNING警告(还没出错但要注意) 黄色信号灯 ERROR出错了 红色警报 CRITICAL严重错误(系统要挂了) 紧急求救信号 设置 level=INFO 的意思:只记录 INFO 及以上级别的日志
- DEBUG 不记录(太琐碎)
- INFO、WARNING、ERROR、CRITICAL 都记录
python
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# 不同级别的日志
logger.debug("调试信息") # 不会显示(级别太低)
logger.info("常规信息") # ✅ 显示
logger.warning("警告信息") # ✅ 显示
logger.error("错误信息") # ✅ 显示
logger.critical("严重错误") # ✅ 显示代码解读:
代码 含义 logging.basicConfig(...)配置日志系统 level=logging.INFO只记录 INFO 及以上级别 format='...'日志输出格式 %(asctime)s时间 %(name)s日志器名称 %(levelname)s级别(INFO/ERROR...) %(message)s日志内容 输出示例:
2024-01-15 10:30:00,123 - __main__ - INFO - 常规信息 2024-01-15 10:30:00,124 - __main__ - WARNING - 警告信息
Agent 日志系统
小白理解 - 为什么要自定义日志类?
基础的 logging 只能输出到一个地方
实际需求:
- 详细日志 → 保存到文件(方便查问题)
- 重要日志 → 显示在屏幕(实时看)
解决:创建自定义日志类,同时输出到多个地方
小白理解 - Handler(处理器)是什么?
Handler = 日志输出到哪里
Handler 输出位置 FileHandler文件 StreamHandler屏幕/控制台 RotatingFileHandler自动分割的文件 一个 logger 可以有多个 Handler,日志同时输出到多个地方
python
import logging
from pathlib import Path
class AgentLogger:
"""Agent 日志管理器"""
def __init__(self, name: str, log_file: str = "agent.log"):
self.logger = logging.getLogger(name)
self.logger.setLevel(logging.DEBUG)
# 文件处理器(所有日志都写入文件)
fh = logging.FileHandler(log_file, encoding="utf-8")
fh.setLevel(logging.DEBUG)
# 控制台处理器(只显示 INFO 及以上)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
# 格式化
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
fh.setFormatter(formatter)
ch.setFormatter(formatter)
self.logger.addHandler(fh)
self.logger.addHandler(ch)
def log_api_call(self, endpoint: str, status: str):
"""记录 API 调用"""
self.logger.info(f"API 调用: {endpoint} - 状态: {status}")
def log_error(self, error: Exception):
"""记录错误"""
self.logger.error(f"错误: {error}", exc_info=True)
# 使用
logger = AgentLogger("ResearchBot")
logger.log_api_call("/chat", "success")代码结构图解:
AgentLogger │ └── logger(日志器) │ ├── FileHandler(文件处理器) │ └── 所有日志 → agent.log 文件 │ └── StreamHandler(控制台处理器) └── INFO 及以上 → 屏幕显示效果:
- DEBUG 日志:只写入文件
- INFO/WARNING/ERROR:既写入文件,又显示在屏幕
实战:给 Agent 添加日志
python
class Agent:
def __init__(self, name: str):
self.name = name
self.logger = AgentLogger(name)
def chat(self, user_input: str) -> str:
self.logger.logger.info(f"用户输入: {user_input}")
try:
# 处理逻辑
response = f"收到: {user_input}"
self.logger.logger.info(f"响应: {response}")
return response
except Exception as e:
self.logger.log_error(e)
return "抱歉,出错了"
# 使用
agent = Agent("ChatBot")
agent.chat("你好")本节小结
| 概念 | 一句话解释 | 记忆口诀 |
|---|---|---|
| logging | Python 内置日志模块 | logging = 日记本 |
| 日志级别 | DEBUG < INFO < WARNING < ERROR < CRITICAL | 越严重越高 |
| Handler | 日志输出到哪里 | Handler = 输出口 |
| Formatter | 日志格式 | 格式化 = 排版 |
何时用什么级别?
级别 用途 DEBUG 开发调试时的详细信息 INFO 正常运行的记录(API 调用、用户操作) WARNING 不影响运行但需要注意(配额快用完) ERROR 出错了但程序还能继续 CRITICAL 严重错误,程序可能要挂
下一节:5.3 调试技巧