Skip to content

Instantly share code, notes, and snippets.

@lcrilly
Last active July 19, 2024 15:50
Show Gist options
  • Save lcrilly/dd269ece9b8575a1bbab764fcc270d4b to your computer and use it in GitHub Desktop.
Save lcrilly/dd269ece9b8575a1bbab764fcc270d4b to your computer and use it in GitHub Desktop.
Logging request headers with njs

Logging request headers with njs

This configuration can be used to log all of the request headers presented by a client. We use the JavaScript (njs) module to iterate over each header, returning a list of JSON key-value pairs which are then included in a JSON log format.

nginx.conf

js_include functions.js;
js_set $headers_json headers_to_json;

log_format json escape=none '{"timestamp":"$time_iso8601",'
                             '"client":"$remote_addr",'
                             '"uri":"$request_uri",'
                             '"status":$status,'
                             '"size":$bytes_sent,'
                             '"request headers":{$headers_json}}';
…
server {
   listen 80;
   access_log /var/log/nginx/access.log json;
   …
}

Example log output: $ tail -1 access.log | jq

{
   "timestamp": "2018-10-04T22:51:20+01:00",
   "client": "172.16.52.1",
   "uri": "/api/f1/current/last",
   "status": 200,
   "size": 681,
   "request headers": {
      "host": "api.example.com",
      "cache-control": "max-age=0",
      "upgrade-insecure-requests": 1,
      "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
      "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
      "accept-encoding": "gzip, deflate, br",
      "accept-language": "en-GB,en-US;q=0.9,en;q=0.8"
   }
}
function headers_to_json(r) {
    var kvpairs = '';
    for (var h in req.headers) {
        if ( kvpairs.length ) {
            kvpairs += ',';
        }
        kvpairs += '"' + h + '":';
        if ( isNaN(r.headers[h]) ) {
            kvpairs += '"' + r.headers[h] + '"';
        } else {
            kvpairs += req.headers[h];
        }
    }
    return kvpairs;
}
@ducnn7301-cowell
Copy link

ducnn7301-cowell commented May 31, 2024

Dear lcrilly,
js_include functions.js;
I have an error nginx: [emerg] unknown directive "js_include"
Can you help me?
Thank you so much

@lcrilly
Copy link
Author

lcrilly commented May 31, 2024

Hi! You need to install and load the njs module. See https://docs.nginx.com/nginx/admin-guide/dynamic-modules/nginscript/#configuration

@ducnn7301-cowell
Copy link

Dear lcrilly,
I added to my config nginx.conf :(

@lcrilly
Copy link
Author

lcrilly commented May 31, 2024

Why the sad-face?

Presumably not working? Did you also install the module?
https://nginx.org/en/docs/njs/install.html

@btdahl
Copy link

btdahl commented Jul 19, 2024

Wasn't js_include removed as far back as 0.7.1?

js_import functions.js;
js_set $headers_json functions.headers_to_json;

should work.

@lcrilly
Copy link
Author

lcrilly commented Jul 19, 2024

@btdahl you are correct. This Gist is from 2018.

A more sophisticated way to do this is captured in https://www.f5.com/company/blog/nginx/diagnostic-logging-nginx-javascript-module but I’ll update this too. Thanks for catching it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment