Skip to content

Instantly share code, notes, and snippets.

@qu1j0t3
Last active May 11, 2025 23:50
Show Gist options
  • Select an option

  • Save qu1j0t3/571b51eaaf3bffceb5fd668ac4fac681 to your computer and use it in GitHub Desktop.

Select an option

Save qu1j0t3/571b51eaaf3bffceb5fd668ac4fac681 to your computer and use it in GitHub Desktop.
Conditional response logging for nginx/php-fpm

Conditional response logging for nginx/php-fpm

Dependencies

The nginx-js module, e.g.

...
FROM nginx:1.24-alpine

RUN apk update && apk add --no-cache nginx-mod-http-js

RUN ln -s /dev/stderr /var/log/nginx/apierror.log
...

Enable module in nginx.conf:

#...

load_module modules/ngx_http_js_module.so;

http {
    js_path "/etc/nginx";
    js_import http.js;
    js_var $resp_body "";

  log_format main
    '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';

  log_format apierror
    '$remote_addr - $remote_user [$time_local] "$request" '
    '$status apierror: $resp_body';

  access_log /var/log/nginx/access.log main;

  map $status $errstatus {
    ~^[23] 0;
    default 1;
  }

  # segregate the API error responses into their own log file
  access_log /var/log/nginx/apierror.log apierror if=$errstatus;
#...
  include /etc/nginx/conf.d/*.conf;
}

nginx default.conf:

# N.B. Many settings will be different for your installation

upstream fastcgi_backend {
  server unix:/sock/docker.sock; 
}

server {
  listen 8000;

  root           /var/www/html;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~* \.php$ {
    js_body_filter http.filter;   # <------- configure response filter function

    try_files $uri =404;
    fastcgi_pass fastcgi_backend;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include fastcgi_params;
  }
}

JavaScript filter function:

/**
 * The filter function is called for each data chunk of a response body.
 */

function filter(r, data, flags) {
    r.variables.resp_body += data;
    r.sendBuffer(data, flags);
    r.done();
}

export default {filter};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment