UNPKG

pino-clf

Version:

Transform Pino HTTP logs into Common Log Format

287 lines (245 loc) 8.29 kB
'use strict' var clf = require('../') var through = require('through2') var test = require('tap').test var getCLFOffset = require('./lib/get-clf-offset') var log = '{"pid":13961,"hostname":"MacBook-Pro-4","level":30,"time":1469122492244,"msg":"request completed","res":{"statusCode":200,"header":"HTTP/1.1 200 OK\\r\\ncontent-type: application/json; charset=utf-8\\r\\ncache-control: no-cache\\r\\nvary: accept-encoding\\r\\ncontent-encoding: gzip\\r\\ndate: Thu, 21 Jul 2016 17:34:52 GMT\\r\\nconnection: close\\r\\ntransfer-encoding: chunked\\r\\n\\r\\n"},"responseTime":17,"req":{"id":8,"method":"GET","url":"/api/activity/component","headers":{"host":"localhost:20000","connection":"keep-alive","cache-control":"max-age=0","authorization":"Basic QWxhZGRpbjpPcGVuU2VzYW1l","accept":"application/json","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36","referer":"http://localhost:20000/","accept-encoding":"gzip, deflate, sdch","accept-language":"en-US,en;q=0.8,de;q=0.6","cookie":"_ga=GA1.1.204420087.1444842476"},"remoteAddress":"127.0.0.1","remotePort":61543},"v":1}\n' var offset = getCLFOffset(new Date(1469122492244)) var combined = '127.0.0.1 - Aladdin [21/Jul/2016:17:34:52 ' + offset + '] "GET /api/activity/component HTTP/1.1" 200 - "http://localhost:20000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"\n' var access = '127.0.0.1 - Aladdin [21/Jul/2016:17:34:52 ' + offset + '] "GET /api/activity/component HTTP/1.1" 200 -\n' var referral = '[21/Jul/2016:17:34:52 ' + offset + '] "http://localhost:20000/"\n' var agent = '[21/Jul/2016:17:34:52 ' + offset + '] "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"\n' process.stdout.setMaxListeners(Infinity) test('combined', function (t) { var expected = combined var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf('combined', stream) logger.write(log) }) test('combined (default)', function (t) { var expected = combined var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf('', stream) logger.write(log) }) test('combined (one element dest array)', function (t) { var expected = combined var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf('combined', [stream]) logger.write(log) }) test('common (single dest)', function (t) { var expected = access var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf('common', stream) logger.write(log) }) test('common (one element dest array)', function (t) { var expected = access var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf('common', [stream]) logger.write(log) }) test('common (two element dest array)', function (t) { var c = 0 var stream1 = through(function (line) { t.is(line.toString(), access) c++ if (c === 2) t.end() }) var stream2 = through(function (line) { t.is(line.toString(), referral) c++ if (c === 2) t.end() }) var logger = clf('common', [stream1, stream2]) logger.write(log) }) test('common (three element dest array)', function (t) { var c = 0 var stream1 = through(function (line) { t.is(line.toString(), access) c++ if (c === 3) t.end() }) var stream2 = through(function (line) { t.is(line.toString(), referral) c++ if (c === 3) t.end() }) var stream3 = through(function (line) { t.is(line.toString(), agent) c++ if (c === 3) t.end() }) var logger = clf('common', [stream1, stream2, stream3]) logger.write(log) }) test('common (2 log files - skip first)', function (t) { var c = 0 var stream1 = through(function (line) { t.is(line.toString(), referral) c++ if (c === 2) t.end() }) var stream2 = through(function (line) { t.is(line.toString(), agent) c++ if (c === 2) t.end() }) var logger = clf('common', [0, stream1, stream2]) logger.write(log) }) test('common (2 log files - skip middle)', function (t) { var c = 0 var stream1 = through(function (line) { t.is(line.toString(), access) c++ if (c === 2) t.end() }) var stream2 = through(function (line) { t.is(line.toString(), agent) c++ if (c === 2) t.end() }) var logger = clf('common', [stream1, 0, stream2]) logger.write(log) }) test('logs to process.stdout by default (combined)', function (t) { var expected = combined var write = process.stdout.write process.stdout.write = function (chunk, enc, cb) { process.stdout.write = write t.is(chunk.toString(), expected) t.end() } var logger = clf('combined') logger.write(log) }) test('logs to process.stdout by default (common)', function (t) { var expected = access var write = process.stdout.write process.stdout.write = function (chunk, enc, cb) { process.stdout.write = write t.is(chunk.toString(), expected) t.end() } var logger = clf('common') logger.write(log) }) test('logs to process.stdout by default (combined - empty dest array)', function (t) { var expected = combined var write = process.stdout.write process.stdout.write = function (chunk, enc, cb) { process.stdout.write = write t.is(chunk.toString(), expected) t.end() } var logger = clf('combined', []) logger.write(log) }) test('logs to process.stdout by default (common - empty dest array)', function (t) { var expected = access var write = process.stdout.write process.stdout.write = function (chunk, enc, cb) { process.stdout.write = write t.is(chunk.toString(), expected) t.end() } var logger = clf('common', []) logger.write(log) }) test('type as object', function (t) { var expected = combined var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf({type: 'combined'}, stream) logger.write(log) }) test('type as object without specified type', function (t) { var expected = combined var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) var logger = clf({}, stream) logger.write(log) }) test('ancillary: passes non-http messages to alternative stream when specified', function (t) { var msg = '{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1459529098958,"v":1}\n' var logger = clf('combined', through(), through(function (line) { t.is(line.toString(), msg) t.end() })) logger.write(msg) }) test('unknown type causes throw', function (t) { t.throws(function () { clf('unknown') }) t.end() }) test('keep: passes all messages to alternative stream', function (t) { var expected = combined var msg = '{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1459529098958,"v":1}\n' var count = 0 var logger = clf({type: 'combined', keep: true}, through(function (line, _, cb) { t.is(line + '', expected) t.end() cb() }), through(function (line, _, cb) { count++ if (count === 1) { t.is(line + '', msg) } if (count === 2) { } cb() })) logger.write(msg) logger.write(log) }) test('outputs newline when stream ends', function (t) { var expected = '\n' var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) clf('combined', stream) stream.end() }) test('outputs error message when error in pipeline', function (t) { var expected = 'premature close\n' var stream = through(function (line) { t.is(line.toString(), expected) t.end() }) clf('combined', stream) stream.destroy() }) test('filters non-http messages by default', function (t) { var logger = clf('combined', through(function (line) { t.fail() t.end() })) logger.write('{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1459529098958,"v":1}\n') setTimeout(function () { t.pass() t.end() }, 100) })