格式化uWSGI请求日志¶
uWSGI有一个 --logformat 选项,用来构建自定义的请求日志行。语法很简单:
[uwsgi]
logformat = i am a logline reporting "%(method) %(uri) %(proto)" returning with status %(status)
所有用 %() 标记的变量都可以使用特定的规则来替代。定义了三种日志变量 (“offsetof”, 函数和用户定义)。
offsetof¶
这些是一味从当前请求内部的 wsgi_request 结构获取的。
%(uri)-> REQUEST_URI%(method)-> REQUEST_METHOD%(user)-> REMOTE_USER%(addr)-> REMOTE_ADDR%(host)-> HTTP_HOST%(proto)-> SERVER_PROTOCOL%(uagent)-> HTTP_USER_AGENT (自1.4.5起)%(referer)-> HTTP_REFERER (自1.4.5起)
函数¶
这些是简单的函数,调用来生成日志变量值:
%(status)-> HTTP响应状态码%(micros)-> 响应时间,以微秒为单位%(msecs)-> 响应时间,以毫秒为单位%(time)-> 请求开始的时间戳%(ctime)-> 请求开始的ctime%(epoch)-> Unix格式的当前时间%(size)-> 响应体大小 + 响应头大小 (自1.4.5起)%(ltime)-> 人类可读(Apache风格)的请求时间 (自1.4.5起)%(hsize)-> 响应头大小 (自1.4.5起)%(rsize)-> 响应体大小 (自1.4.5起)%(cl)-> 请求内容体大小 (自1.4.5起)%(pid)-> 处理请求的worker的pid (自1.4.6起)%(wid)-> 处理请求的worker的id (自1.4.6起)%(switches)-> 异步切换数 (自1.4.6起)%(vars)-> 请求中的CGI变量数 (自1.4.6起)%(headers)-> 已生成的响应头数 (自1.4.6起)%(core)-> 运行请求的核心 (自1.4.6起)%(vsz)-> 地址空间/虚拟内存使用 (单位为字节) (自1.4.6起)%(rss)-> RSS内存使用 (单位为字节) (自1.4.6起)%(vszM)-> 地址空间/虚拟内存使用 (单位为MB) (自1.4.6起)%(rssM)-> RSS内存使用 (单位为MB) (自1.4.6起)%(pktsize)-> 内部的请求uwsgi包大小 (自1.4.6起)%(modifier1)-> 请求的modifier1 (自1.4.6起)%(modifier2)-> 请求的modifier2 (自1.4.6起)%(metric.XXX)-> 访问XXX度量值 (见 度量(Metrics)子系统)%(rerr)-> 请求的读错误数 (自1.9.21起)%(werr)-> 请求的写错误数 (自1.9.21起)%(ioerr)-> 请求的读写错误数 (自1.9.21起)%(tmsecs)-> 请求开始时间戳,自纪元起,单位为毫秒 (自1.9.21起)%(tmicros)-> 请求开始时间戳,自纪元起,单位为微秒 (自1.9.21起)%(var.XXX)-> 请求变量XXX的内容 (例如var.PATH_INFO,自1.9.21起可用)
用户定义的日志变量¶
你可以在你的请求处理函数中定义日志变量。这些变量只存活在每个请求中。
import uwsgi
def application(env, start_response):
uwsgi.set_logvar('foo', 'bar')
# returns 'bar'
print uwsgi.get_logvar('foo')
uwsgi.set_logvar('worker_id', str(uwsgi.worker_id()))
...
使用以下日志格式,你将能够访问代码定义的日志变量:
uwsgi --logformat 'worker id = %(worker_id) for request "%(method) %(uri) %(proto)" test = %(foo)'
Apache风格相结合的请求日志记录¶
要生成兼容Apache的日志:
[uwsgi]
...
log-format = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"
...
hack日志格式¶
(更新至1.9.21)
你可以这样注册新的”logchunk” (为每个日志格式符号调用的函数)
struct uwsgi_logchunk *uwsgi_register_logchunk(char *name, ssize_t (*func)(struct wsgi_request *, char **), int need_free);
name– 符号名need_free– 如果是1,表示由func设置的指针必须释放(free())func– 日志处理函数中调用的函数
static ssize_t uwsgi_lf_foobar(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->status);
return strlen(*buf);
}
static void register_logchunks() {
uwsgi_register_logchunk("foobar", uwsgi_lf_foobar, 1);
}
struct uwsgi_plugin foobar_plugin = {
.name = "foobar",
.on_load = register_logchunks,
};
现在,如果你加载foobar插件,那么,你将能够使用 %(foobar) 请求日志变量 (它会报告请求状态)。