From f7228b207a4165e39ce29012bc2f470ef7899061 Mon Sep 17 00:00:00 2001 From: Daniel Prange Date: Mon, 3 Jun 2024 15:42:29 +0300 Subject: [PATCH] chore: add user info in uwsgi request logs Refs KER-367 --- Dockerfile | 38 +++++++++++++++++++++++--------------- deploy/escape_json.c | 42 ++++++++++++++++++++++++++++++++++++++++++ deploy/uwsgi.yml | 6 ++++++ 3 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 deploy/escape_json.c diff --git a/Dockerfile b/Dockerfile index edd01f00..0bf02231 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,28 +18,36 @@ ENV STATIC_ROOT /srv/static # while in Docker. Maybe the buffer is larger? ENV PYTHONUNBUFFERED True +COPY --chown=kerrokantasi:kerrokantasi requirements.txt . +COPY --chown=kerrokantasi:kerrokantasi requirements-prod.txt . +COPY --chown=kerrokantasi:kerrokantasi deploy/escape_json.c ./deploy/escape_json.c + # less & netcat-openbsd are there for in-container manual debugging # kerrokantasi needs gdal -RUN apt-get update && apt-get install -y postgresql-client less netcat-openbsd gettext locales gdal-bin python3-gdal - -# we need the Finnish locale built -RUN sed -i 's/^# *\(fi_FI.UTF-8\)/\1/' /etc/locale.gen -RUN locale-gen - -RUN pip install --upgrade pip setuptools wheel && \ - pip install --no-cache-dir uwsgi +RUN apt-get update \ + && apt-get install -y \ + build-essential \ + postgresql-client \ + less \ + netcat-openbsd \ + gettext \ + locales \ + gdal-bin \ + python3-gdal \ + # Build finnish locale + && sed -i 's/^# *\(fi_FI.UTF-8\)/\1/' /etc/locale.gen \ + && locale-gen \ + && pip install --upgrade pip setuptools wheel \ + && pip install --no-cache-dir -r ./requirements.txt \ + && pip install --no-cache-dir -r ./requirements-prod.txt \ + && uwsgi --build-plugin ./deploy/escape_json.c \ + && mv ./escape_json_plugin.so ./deploy/escape_json_plugin.so \ + && apt-get remove -y build-essential # Sentry CLI for sending events from non-Python processes to Sentry # eg. https://docs.sentry.io/cli/send-event/#bash-hook RUN curl -sL https://sentry.io/get-cli/ | bash -# Copy requirements files to image for preloading dependencies -# in their own layer -COPY requirements.txt ./ - -# deploy/requirements.txt must reference the base requirements -RUN pip install --no-cache-dir -r requirements.txt - COPY . . # Statics are kept inside container image for serving using whitenoise diff --git a/deploy/escape_json.c b/deploy/escape_json.c new file mode 100644 index 00000000..f9943c7b --- /dev/null +++ b/deploy/escape_json.c @@ -0,0 +1,42 @@ +/* + https://github.com/velebit-ai/uwsgi-json-logging-plugin/blob/4edb5cc59013b18f32658195b328afb2ac21b2d2/escape_json.c + uWSGI plugin that creates custom json-escaped logging variables. + build plugin with `uwsgi --build-plugin ` + and use it with `uwsgi --plugin ...` +*/ +#include + + +static ssize_t uwsgi_lf_json_uri(struct wsgi_request *wsgi_req, char **buf) { + long pos = offsetof(struct wsgi_request, uri); + long pos_len = offsetof(struct wsgi_request, uri_len); + char **var = (char **) (((char *) wsgi_req) + pos); + uint16_t *varlen = (uint16_t *) (((char *) wsgi_req) + pos_len); + + char *e_json = uwsgi_malloc((*varlen * 2) + 1); + escape_json(*var, *varlen, e_json); + *buf = e_json; + return strlen(*buf); +} + +static ssize_t uwsgi_lf_json_host(struct wsgi_request *wsgi_req, char **buf) { + long pos = offsetof(struct wsgi_request, host); + long pos_len = offsetof(struct wsgi_request, host_len); + char **var = (char **) (((char *) wsgi_req) + pos); + uint16_t *varlen = (uint16_t *) (((char *) wsgi_req) + pos_len); + + char *e_json = uwsgi_malloc((*varlen * 2) + 1); + escape_json(*var, *varlen, e_json); + *buf = e_json; + return strlen(*buf); +} + +static void register_logchunks() { + uwsgi_register_logchunk("json_uri", uwsgi_lf_json_uri, 1); + uwsgi_register_logchunk("json_host", uwsgi_lf_json_host, 1); +} + +struct uwsgi_plugin escape_json_plugin = { + .name = "escape_json", + .on_load = register_logchunks, +}; diff --git a/deploy/uwsgi.yml b/deploy/uwsgi.yml index e825878b..78885b5b 100644 --- a/deploy/uwsgi.yml +++ b/deploy/uwsgi.yml @@ -1,4 +1,5 @@ uwsgi: + plugin: deploy/escape_json_plugin.so # Needed plugins if running against Debian uwsgi-package # python docker image cannot use that due to linker mishaps # plugins: python3,http @@ -20,3 +21,8 @@ uwsgi: ignore-sigpipe: true ignore-write-errors: true disable-write-exception: true + + logger-req: stdio + log-format: '"remote_addr": "%(addr)", "x_forwarded_for":"%(var.HTTP_X_FORWARDED_FOR)", "request_id":"%(var.HTTP_X_REQUEST_ID)", "remote_user":"%(user)", "bytes_sent":%(size), "request_time":%(secs), "status":%(status), "host":"%(json_host)", "request_proto":"%(proto)", "path":"%(json_uri)", "request_length":%(cl), "http_referer":"%(referer)", "http_user_agent":"%(uagent)"' + log-req-encoder: format {"time":"${strftime:%%Y:%%m:%%d %%H:%%M:%%S}", "source":"uwsgi-req", ${msg}} + log-req-encoder: nl