How to write from njs to console in a custom format?
Situation
I'm trying to setup logging for a set of nginx instances in my company. These are heavily relying on njs scripts for the functionality, and produce information that is critical to collect in the given environment.
However the responsibles would like to receive json formatted logs.
Question
Is it possible to log the output of njs in json?
Possible Solutions
Similar to the access_log with log_format specifying a json-like format - seems not possible (similar to how it is impossible to specify it for error messages in general).
Access to console.write, which is not possible during non-cli sessions (scripted, as in this cases, only the HTTP client with its ngx.log is available). The ngx.log however prints with a big format, not easily parseable for services down the line, as it's not json.
Related
https://github.com/nginx/njs/issues/76
https://stackoverflow.com/questions/4246756/is-it-possible-to-specify-custom-error-log-format-on-nginx https://stackoverflow.com/questions/16711573/nginx-error-log-format-documentation https://serverfault.com/questions/805855/how-to-change-the-timestamp-format-in-error-logs?rq=1
Hi @nettnikl
js_var $testlog;
log_format testlog escape=none '$remote_addr - $remote_user [$time_local] "$request" '
'$status $testlog;
server {
listen 8888;
location /test {
js_content test.testlog;
}
access_log /var/log/nginx/access.log testlog;
}
function testlog(r) {
r.variables['testlog'] = JSON.stringify({ a: new Date(), b: 'test', c: 123});
r.return(204);
}
$ curl localhost:8888/test
$ tail /var/log/nginx/access.log -n 1
127.0.0.1 - [19/Jul/2022:18:32:47 +0300] "GET /test HTTP/1.1" 204 {"a":"2022-07-19T15:32:47.171Z","b":"test","c":123}
Hi @drsm , thanks for your reply and the smart solution!
Sadly, this is not applicable for my use case, so let me explain. We are actually using this approach for access logs. However, during one request, there are multiple log entries to be written. So, if i don't want to do a subrequest to a dedicated log-endpoint for each log entry to write, i will have to find a way to print multiple lines. Preferably while the request is being handled, not collected in the end.
@nettnikl
However, during one request, there are multiple log entries to be written.
So, why not to aggregate 'em into array?
var logdata = [];
function logsome(data) {
logdata.push(data);
}
function logflush(r) {
r.variables['whatever'] = JSON.stringify(logdata);
}
i will have to find a way to print multiple lines
Maybe fs.writeFileSync as a last resort.
Thank you again for your suggestions! I will look into both the following day(s).