diff --git a/README.md b/README.md index 1dba8d3..9404b88 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ accessors, though, and invalid values will be ignored. serialization. Applied before error transformation. - **timestamp**: If truthy, prefix entries with an ISO timestamp (if strings) or add the same as a property (if objects). Default: `false`. + - **withHostname**: Will prepend(string) or add property (object) indicating the + hostname from which the log was sent. - **withLevel**: Will prepend (string) or add property (object) indicating the log level. Default: `true`. - **withStack**: If an object is or contains an `Error` object, setting this to diff --git a/src/logger.js b/src/logger.js index 7cbcf0e..f5b5bcf 100644 --- a/src/logger.js +++ b/src/logger.js @@ -1,5 +1,6 @@ import _ from 'lodash'; import semver from 'semver'; +import os from 'os'; import net from 'net'; import tls from 'tls'; import urlUtil from 'url'; @@ -127,6 +128,7 @@ class Logger extends Writable { this.console = opts.console; this.withLevel = 'withLevel' in opts ? opts.withLevel : true; this.withStack = opts.withStack; + this.withHostname = opts.withHostname || false; this.timestamp = opts.timestamp || false; // string or numeric options @@ -286,6 +288,7 @@ class Logger extends Writable { if (_.isObject(modifiedLog)) { let safeTime; let safeLevel; + let safeHost; if (this.timestamp) { safeTime = getSafeProp(modifiedLog, 'time'); @@ -297,6 +300,11 @@ class Logger extends Writable { modifiedLog[safeLevel] = lvlName; } + if (this.withHostname) { + safeHost = getSafeProp(modifiedLog, 'host'); + modifiedLog[safeHost] = os.hostname(); + } + modifiedLog = this._serialize(modifiedLog); if (!modifiedLog) { @@ -310,6 +318,7 @@ class Logger extends Writable { if (safeTime) delete modifiedLog[safeTime]; if (safeLevel) delete modifiedLog[safeLevel]; + if (safeHost) delete modifiedLog[safeHost]; } else { if (_.isEmpty(modifiedLog)) { this.emit(errorEvent, new LogentriesError(text.noLogMessage())); @@ -322,6 +331,10 @@ class Logger extends Writable { modifiedLog.unshift(lvlName); } + if (this.withHostname) { + modifiedLog.unshift(os.hostname()); + } + if (this.timestamp) { modifiedLog.unshift((new Date()).toISOString()); } @@ -640,6 +653,14 @@ class Logger extends Writable { this._timestamp = !!val; } + get withHostname() { + return this._withHostname; + } + + set withHostname(val) { + this._withHostname = val; + } + get withLevel() { return this._withLevel; } diff --git a/test/test.js b/test/test.js index 4813101..939b2ea 100644 --- a/test/test.js +++ b/test/test.js @@ -163,6 +163,24 @@ tape('Logger allows specification of minLevel at construction', function (t) { }); + +tape('Logger allows specification of withHostname at construction', function (t) { + + const logger1 = new Logger({ token: x, withHostname: true }); + + t.equal(logger1.withHostname, true, 'withHostname'); + + const logger2 = new Logger({ token: x }); + + t.equal(logger2.withHostname, false, 'withHostname'); + + t.end(); + +}); + + + + // CUSTOM JSON SERIALIZATION tape('Error objects are serialized nicely.', function (t) { @@ -465,6 +483,45 @@ tape('Non-JSON logs may carry timestamp.', function (t) { logger[lvl]('test'); }); + +tape('Non-JSON logs may carry Hostname.', function (t) { + t.plan(1); + t.timeoutAfter(2000); + + mockTest(function (data) { + t.true(pattern.test(data), 'matched'); + + }); + const os = require('os'); + const lvl = defaults.levels[3]; + const tkn = x; + const pattern = new RegExp('^' + x +' ' + os.hostname() + ' \\w+ test\\n$' + ); + + const logger = new Logger({ token: tkn, withHostname: true }); + + logger[lvl]('test'); +}); + + +tape('JSON logs may carry Hostname.', function (t) { + t.plan(1); + t.timeoutAfter(2000); + + mockTest(function (data) { + const log = JSON.parse(data.substr(37)); + t.true(log.host, 'has property'); + }); + const os = require('os'); + const lvl = defaults.levels[3]; + const tkn = x; + + const logger = new Logger({ token: tkn, withHostname: true }); + + logger[lvl]({msg: "Testing!"}); +}); + + tape('JSON logs match expected pattern.', function (t) { t.timeoutAfter(2000);