1. Python日志系统深度解析
在Python开发中,日志记录是每个项目都绕不开的基础设施。我见过太多项目因为日志处理不当导致线上问题难以排查,也见证过优秀的日志实践如何大幅提升团队效率。Python标准库中的logging模块看似简单,实则暗藏玄机。
logging模块的设计哲学是"足够灵活但不臃肿"。它采用了分层架构,包含Logger、Handler、Filter、Formatter四个核心组件。Logger是入口点,Handler决定输出目的地,Filter提供过滤能力,Formatter控制日志格式。这种设计让开发者可以像搭积木一样组合各种功能。
重要提示:千万不要在代码中直接print,这会导致生产环境无法区分日志级别,也无法实现日志轮转等关键功能。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Django日志最佳实践
2.1 Django默认日志配置解析
Django在settings.py中通过LOGGING字典配置日志系统。默认配置往往过于简单,我建议至少包含以下handler:
python复制LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'verbose'
},
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': '/var/log/django/app.log',
'maxBytes': 1024*1024*5, # 5MB
'backupCount': 5,
'formatter': 'verbose'
},
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
},
'loggers': {
'django': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
}
}
2.2 结构化日志实践
现代日志系统越来越强调结构化。我推荐使用python-json-logger库:
python复制from pythonjsonlogger import jsonlogger
formatter = jsonlogger.JsonFormatter(
'%(asctime)s %(levelname)s %(module)s %(process)d %(message)s'
)
这样日志会被ELK等系统直接解析,实现强大的搜索和聚合功能。
3. 高级日志技巧
3.1 日志采样与限流
高并发场景下,日志可能成为性能瓶颈。我常用的采样方案:
python复制from logging import Filter
class SampleFilter(Filter):
def __init__(self, rate=0.1):
self.rate = rate
def filter(self, record):
import random
return random.random() < self.rate
3.2 请求链路追踪
在微服务架构中,通过logging.Filter实现请求ID透传:
python复制import uuid
from django.utils.deprecation import MiddlewareMixin
class RequestIdMiddleware(MiddlewareMixin):
def process_request(self, request):
request.id = uuid.uuid4().hex
class RequestIdFilter(Filter):
def filter(self, record):
from django.core.handlers.wsgi import WSGIRequest
for item in record.args:
if isinstance(item, WSGIRequest):
record.request_id = item.id
break
return True
4. 常见问题排查
4.1 日志不输出问题
检查顺序:
- Logger的propagate属性是否为False
- Handler的level是否高于Logger的level
- 确保没有调用logging.disable()
4.2 性能优化技巧
- 避免在日志消息中进行耗时计算:使用延迟求值
python复制logger.debug('Slow query: %s', lambda: expensive_query())
- 对于高频日志,先进行级别判断
python复制if logger.isEnabledFor(logging.DEBUG):
logger.debug(...)
5. 生产环境部署建议
5.1 日志轮转方案比较
| 方案 | 优点 | 缺点 |
|---|---|---|
| RotatingFileHandler | 内置支持 | 可能丢失日志 |
| TimedRotatingFileHandler | 按时间切割 | 需要配合logrotate |
| SysLogHandler | 集中管理 | 需要额外设施 |
| WatchedFileHandler | 支持外部轮转 | 需要部署脚本 |
5.2 日志监控告警
推荐使用Sentry进行错误日志监控,配置方法:
python复制import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
sentry_logging = LoggingIntegration(
level=logging.INFO,
event_level=logging.ERROR
)
sentry_sdk.init(
dsn="your_dsn",
integrations=[sentry_logging]
)
6. 异步日志实践
对于高并发场景,考虑使用异步日志方案:
python复制from concurrent.futures import ThreadPoolExecutor
from logging.handlers import QueueHandler, QueueListener
log_queue = Queue()
queue_handler = QueueHandler(log_queue)
executor = ThreadPoolExecutor(max_workers=1)
listener = QueueListener(
log_queue,
console_handler,
file_handler,
respect_handler_level=True,
executor=executor
)
listener.start()
这种方案在我的一个日PV千万级的项目中,将日志IO耗时从平均15ms降到了0.3ms。
