如何为Gunicorn的GeventWebSocketWorker配置Web请求日志
解决GeventWebSocketWorker下Gunicorn无法生成访问日志的问题
核心问题
使用GeventWebSocketWorker作为Gunicorn工作进程时,默认WSGI访问日志机制会因websocket中间件拦截请求而失效,导致常规HTTP请求日志无法输出;同时你的Docker Compose启动命令未加载指定的gunicorn.config.py,这也会导致日志配置不生效。
可行解决方案
1. 确保Gunicorn加载配置文件
修改Docker Compose的启动命令,添加-c gunicorn.config.py参数,让Gunicorn读取你的日志配置:
command: - gunicorn - -c - gunicorn.config.py - my_app.wsgi:application
2. 改用Django日志系统捕获请求
由于GeventWebSocketWorker的特性,可通过Django自身日志系统来记录请求:
- 在
settings.py中配置请求日志处理器:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'class': 'logging.StreamHandler', }, }, 'loggers': { 'django.request': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': False, }, }, }
- 可选:自定义中间件生成目标日志格式
创建my_app/middleware.py:
import logging import time from datetime import datetime logger = logging.getLogger('django.request') class CustomRequestLogger: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): start_time = time.time() response = self.get_response(request) duration = round(time.time() - start_time, 2) pid = request.META.get('SERVER_PID', 'unknown') timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S %z') logger.debug( f'[{timestamp}] [{pid}] [DEBUG] {request.method} {request.path} ' f'{response.status_code} {duration}s' ) return response
然后在settings.py的MIDDLEWARE列表中添加:
MIDDLEWARE = [ # 保留原有中间件,添加在合适位置 'my_app.middleware.CustomRequestLogger', ]
3. 直接在启动命令中指定日志参数
如果配置文件加载仍有问题,可跳过配置文件,直接在Docker Compose命令中写全日志相关参数:
command: - gunicorn - --worker-class=geventwebsocket.gunicorn.workers.GeventWebSocketWorker - --bind=0.0.0.0:8000 - --workers=1 - --log-level=debug - --accesslog=- - --errorlog=- - --access-log-format=%(h)s %(l)s %(u)s %(t)s '%(r)s' %(s)s %(b)s '%(f)s' '%(a)s' - my_app.wsgi:application
验证
重启服务后发送测试请求(比如GET /users),查看控制台输出,确认是否生成目标格式的日志。
内容的提问来源于stack exchange,提问作者StuffHappens
相关产品推荐
相关产品推荐

