将所有请求记录到文件Django

时间:2016-06-09 21:00:05

标签: python django apache logging wsgi

当我运行django开发服务器(./manage.py runserver)时,所有请求的URL都可以方便地登录到进程标准输出,具有准确的时间和响应代码:

[09/Jun/2016 23:35:53] "GET /api/game/ HTTP/1.1" 404 3185
[09/Jun/2016 23:36:01] "GET /api/game/123/ HTTP/1.1" 404 1735

非常方便,因为在分析输出时,您会立即看到与日志消息对应的请求,例如:

WARNING:2016-06-09 23:41:27,806:views:7449:140139847718656: No such object in the database: u'123'
[09/Jun/2016 23:41:27] "GET /api/game/123/ HTTP/1.1" 404 1735

我曾经和uwsgi + nginx一起工作,所以我使用了' console'记录处理程序的所有内容,然后像这样启动uwsgi:

exec uwsgi --master --die-on-term --logto /var/log/uwsgi.log

因此,我获得了所有必要的日志记录/var/log/uwsgi.log,uwsgi的请求记录和我自己的日志消息。

现在我想用Apache + mod WSGI + django实现相同的结果。我希望唯一的文件在一个地方包含我的django应用程序中的所有请求和所有日志。

我已尝试使用Django日志记录配置实现此目的,但即使我将django.requests重定向到同一文件,我在日志中只获得自己的消息,根本没有请求。以下是配置的一部分:

'handlers': {
    'file_handler': {
        'level': DEBUG and 'DEBUG' or 'INFO',
        'class': 'logging.handlers.RotatingFileHandler',
        'filename': join(LOG_DIRECTORY, 'api_log.log'),
        'maxBytes': 1024 * 1024 * 5,  # 5 MB
        'backupCount': 15,
        'formatter': 'verbose',
    },
},
'loggers': {
    'api': {
        'handlers': ['file_handler'],
        'level': DEBUG and 'DEBUG' or 'INFO',
    },
    'django': {
        'handlers': ['file_handler'],
        'level': DEBUG and 'DEBUG' or 'INFO',
    },
    'django.request': {
        'handlers': ['file_handler'],
        'level': DEBUG and 'DEBUG' or 'INFO',
    },
    'django.db.backends': {
        'handlers': ['file_handler'],
        'level': DEBUG and 'INFO' or 'WARNING',
        'propagate': False,
    },
}

有没有办法用apache + WSGI + django实现nginx + uwsgi + django日志记录行为?或者唯一的方法是将apache access.log和我的日志保存在单独的文件中?

我想在第一种情况下是开发服务器记录了请求,而在第二种情况下是uwsgi进程。也许有一种方法可以告诉WSGIDaemonProcess做同样的事情吗?

1 个答案:

答案 0 :(得分:3)

对于标准的Apache安装,您将通过尝试将访问日志和错误日志混合在一起来反对被认为是最佳实践。传统上它们是分开的,因此可以对服务器流量上的访问日志进行分析。

那就是说,您是否尝试更改Apache中的ErrorLogCustomLog指令以使用相同的文件?

当我使用mod_wsgi-express时使用命令:

mod_wsgi-express start-server --access-log --access-log-name application.log --error-log-name application.log

正在产生:

<IfDefine MOD_WSGI_ROTATE_LOGS>
ErrorLog "|/usr/sbin/rotatelogs \
    /tmp/mod_wsgi-localhost:8000:502/application.log.%Y-%m-%d-%H_%M_%S 5M"
</IfDefine>
<IfDefine !MOD_WSGI_ROTATE_LOGS>
ErrorLog "/tmp/mod_wsgi-localhost:8000:502/application.log"
</IfDefine>
LogLevel warn

<IfDefine MOD_WSGI_ACCESS_LOG>
<IfModule !log_config_module>
LoadModule log_config_module ${MOD_WSGI_MODULES_DIRECTORY}/mod_log_config.so
</IfModule>
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
LogFormat "undefined" custom
<IfDefine MOD_WSGI_ROTATE_LOGS>
CustomLog "|/usr/sbin/rotatelogs \
    /tmp/mod_wsgi-localhost:8000:502/application.log.%Y-%m-%d-%H_%M_%S 5M" common
</IfDefine>
<IfDefine !MOD_WSGI_ROTATE_LOGS>
CustomLog "/tmp/mod_wsgi-localhost:8000:502/application.log" common
</IfDefine>
</IfDefine>

结果application.log为:

[Fri Jun 10 07:17:30.845264 2016] [mpm_prefork:notice] [pid 84334] AH00163: Apache/2.4.18 (Unix) mod_wsgi/4.5.2 Python/2.7.10 configured -- resuming normal operations
[Fri Jun 10 07:17:30.845518 2016] [core:notice] [pid 84334] AH00094: Command line: 'httpd (mod_wsgi-express)  -f /tmp/mod_wsgi-localhost:8000:502/httpd.conf -D MOD_WSGI_ACCESS_LOG -D FOREGROUND'
::1 - - [10/Jun/2016:07:17:36 +1000] "GET / HTTP/1.1" 200 709
::1 - - [10/Jun/2016:07:17:37 +1000] "GET / HTTP/1.1" 200 709
::1 - - [10/Jun/2016:07:17:37 +1000] "GET / HTTP/1.1" 200 709
::1 - - [10/Jun/2016:07:17:38 +1000] "GET / HTTP/1.1" 200 709
::1 - - [10/Jun/2016:07:17:38 +1000] "GET / HTTP/1.1" 200 709
[Fri Jun 10 07:17:39.784486 2016] [mpm_prefork:notice] [pid 84334] AH00169: caught SIGTERM, shutting down

从技术上讲,它应该适用于独立的Apache安装,只需将ErrorLogCustomLog设置为同一文件,同时将错误和访问日志转到同一文件。

对于额外的Django日志记录,它可能由于异常而在内部生成,您仍然需要:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
    },
}

这告诉Django在概念上登录到终端,mod_wsgi将拦截并发送到Apache错误日志,其中上面将是组合的应用程序日志。

顺便说一句,如果想在日志需要转到标准输出的容器中运行Apache / mod_wsgi,请不要自己动手。使用mod_wsgi-express,因为它专门设计用于容器。在这种情况下,您只需使用:

mod_wsgi-express start-server --access-log --log-to-terminal

如果想要启用访问日志记录(默认情况下关闭,通常只是容器部署的噪音),它会担心将访问和错误日​​志发送到终端,以便Docker可以捕获它。

如果需要更多信息或帮助,请使用mod_wsgi邮件列表。