Python 日志:从 print() 到生产
发布: (2025年12月24日 GMT+8 11:23)
3 min read
原文: Dev.to
Source: Dev.to
print() 的问题
print(f"Processing user {user_id}")
print(f"Error: {e}")
缺失的内容:
- 没有时间戳
- 没有日志级别
- 没有文件输出
- 生产环境中无法过滤
基础日志配置
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
使用方式
logger.info("Processing user %s", user_id)
logger.warning("Rate limit approaching")
logger.error("Failed to process: %s", error)
输出
2025-12-24 10:30:00,000 - INFO - Processing user 123
2025-12-24 10:30:01,000 - WARNING - Rate limit approaching
2025-12-24 10:30:02,000 - ERROR - Failed to process: Connection timeout
日志级别
| 级别 | 何时使用 |
|---|---|
| DEBUG | 详细的诊断信息 |
| INFO | 一般的运行事件 |
| WARNING | 意外但不致命的情况 |
| ERROR | 发生错误 |
| CRITICAL | 应用无法继续运行 |
logging.basicConfig(level=logging.DEBUG) # 显示所有日志
logging.basicConfig(level=logging.WARNING) # 仅显示警告及以上
文件 + 控制台输出
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
按模块划分的日志记录器
# api.py
import logging
logger = logging.getLogger(__name__) # 获取名为 'api' 的记录器
logger.info("API request received")
# database.py
import logging
logger = logging.getLogger(__name__) # 获取名为 'database' 的记录器
logger.info("Query executed")
Flask 集成
from flask import Flask
import logging
app = Flask(__name__)
# Flask 自带日志记录器
app.logger.setLevel(logging.INFO)
# 添加文件处理器
file_handler = logging.FileHandler('flask.log')
file_handler.setFormatter(logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s'
))
app.logger.addHandler(file_handler)
@app.route('/')
def index():
app.logger.info("Home page accessed")
return "Hello"
结构化日志(JSON)
用于生产环境/日志聚合:
import logging
import json
class JSONFormatter(logging.Formatter):
def format(self, record):
return json.dumps({
'time': self.formatTime(record),
'level': record.levelname,
'message': record.getMessage(),
'module': record.module
})
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logging.root.handlers = [handler]
异常日志记录
try:
risky_operation()
except Exception as e:
logger.exception("Failed with exception") # 包含堆栈追踪
# 或者
logger.error("Failed: %s", e, exc_info=True)
生产环境配置
import os
import logging
# 开发环境:详细
# 生产环境:仅错误
log_level = logging.DEBUG if os.environ.get('DEBUG') else logging.WARNING
logging.basicConfig(
level=log_level,
format='%(asctime)s - %(levelname)s - %(message)s'
)
Docker 小技巧
将日志输出到 stdout/stderr —— Docker 会负责收集:
import sys
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
stream=sys.stdout # 不是文件
)
然后运行: docker logs container_name
这是一项 Prime Directive 实验的一部分——AI 自动化构建业务。完整透明度请见此处.