Formatting uWSGI requests logs¶
uWSGI has a --logformat option for building custom request loglines. The
syntax is simple:
[uwsgi]
logformat = i am a logline reporting "%(method)``%(uri) %(proto)" returning with status %(status)``
All of the %() marked variables are substituted using specific rules. Three kinds of logvars are defined:
offsetof¶
These are taken blindly from the internal wsgi_request structure of the current request.
%(uri)-> REQUEST_URI%(method)-> REQUEST_METHOD%(user)-> REMOTE_USER%(addr)-> REMOTE_ADDR%(host)-> HTTP_HOST%(proto)-> SERVER_PROTOCOL%(uagent)-> HTTP_USER_AGENT (starting from 1.4.5)%(referer)-> HTTP_REFERER (starting from 1.4.5)
functions¶
These are simple functions called for generating the logvar value
%(status)-> HTTP response status code%(micros)-> response time in microseconds%(msecs)-> respone time in milliseconds%(time)-> timestamp of the start of the request%(ctime)-> ctime of the start of the request%(epoch)-> the current time in unix format%(size)-> response body size + response headers size (since 1.4.5)%(ltime) -> human-formatted (apache style)request time (since 1.4.5)%(hsize)-> response headers size (since 1.4.5)%(rsize)-> response body size (since 1.4.5)%(cl)-> request content body size (since 1.4.5)%(pid)-> pid of the worker handling the request (since 1.4.6)%(wid)-> id of the worker handling the request (since 1.4.6)%(switches)-> number of async switches (since 1.4.6)%(vars)-> number of CGI vars in the request (since 1.4.6)%(headers)-> number of generated response headers (since 1.4.6)%(core)-> the core running the request (since 1.4.6)%(vsz)-> address space/virtual memory usage (in bytes) (since 1.4.6)%(rss)-> RSS memory usage (in bytes) (since 1.4.6)%(vszM)-> address space/virtual memory usage (in megabytes) (since 1.4.6)%(rssM)-> RSS memory usage (in megabytes) (since 1.4.6)%(pktsize)-> size of the internal request uwsgi packet (since 1.4.6)%(modifier1)-> modifier1 of the request (since 1.4.6)%(modifier2)-> modifier2 of the request (since 1.4.6)
User-defined logvars¶
You can define logvars within your request handler. The variables live only per-request.
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()))
...
With the following log format you will be able to access code-defined logvars.
uwsgi --logformat "worker id =``%(worker_id) for request \"%(method) %(uri)`` %(proto)\" test = %(foo)"
Apache style combined request logging¶
To generate Apache compatible logs:
[uwsgi]
...
log-format =``%(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)`` "%(referer)" "%(uagent)"
...
Hacking logformat¶
To add more C-based variables, open logging.c and add them to the end of the file.
if (!uwsgi_strncmp(ptr, len, "uri", 3)) {
logchunk->pos = offsetof(struct wsgi_request, uri);
logchunk->pos_len = offsetof(struct wsgi_request, uri_len);
}
else if (!uwsgi_strncmp(ptr, len, "method", 6)) {
logchunk->pos = offsetof(struct wsgi_request, method);
logchunk->pos_len = offsetof(struct wsgi_request, method_len);
}
else if (!uwsgi_strncmp(ptr, len, "user", 4)) {
logchunk->pos = offsetof(struct wsgi_request, remote_user);
logchunk->pos_len = offsetof(struct wsgi_request, remote_user_len);
}
else if (!uwsgi_strncmp(ptr, len, "addr", 4)) {
logchunk->pos = offsetof(struct wsgi_request, remote_addr);
logchunk->pos_len = offsetof(struct wsgi_request, remote_addr_len);
}
else if (!uwsgi_strncmp(ptr, len, "host", 4)) {
logchunk->pos = offsetof(struct wsgi_request, host);
logchunk->pos_len = offsetof(struct wsgi_request, host_len);
}
else if (!uwsgi_strncmp(ptr, len, "proto", 5)) {
logchunk->pos = offsetof(struct wsgi_request, protocol);
logchunk->pos_len = offsetof(struct wsgi_request, protocol_len);
}
else if (!uwsgi_strncmp(ptr, len, "status", 6)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_status;
logchunk->free = 1;
}
For function-based vars the prototype is:
ssize_t uwsgi_lf_foobar(struct wsgi_request *wsgi_req, char **buf);
where buf is the destination buffer for the logvar value (this will be
automatically freed if you set logchunk->free as in the “status” related
C-code previously reported).
ssize_t uwsgi_lf_status(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->status);
return strlen(*buf);
}