diff --git a/README.md b/README.md index 47debcb..5c589f3 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,19 @@ gelf pro Sends logs to Graylog2 server in GELF (Graylog Extended Log Format) format. **Features:** -- JS object marshalling -- UDP/TCP/TLS support +- JS object marshalling. +- UDP/TCP/TLS support. - Filtering, Transforming, Broadcasting. +- Custom aliases. ![Build Status](https://github.com/kkamkou/node-gelf-pro/actions/workflows/node.js.yml/badge.svg?branch=master) ![Coverage Status](https://coveralls.io/repos/github/kkamkou/node-gelf-pro/badge.svg?branch=master) ## Installation ``` -"dependencies": { - "gelf-pro": "~1.4" // see the "releases" section +"dependencies": { // see the "releases" section + "gelf-pro": "~1.4" // proven by years of stable operation + "gelf-pro": "~2.0" // future-oriented and volatile } ``` @@ -115,7 +117,7 @@ log.info( ``` ##### Filtering -Sometimes we have to discard a message which is not suitable for the current environment. It is `NOT` possible to modify the data. +Sometimes we have to discard a message which is not suitable for the current environment. It is `NOT ALLOWED` to modify the data. ```javascript log.setConfig({ filter: [ @@ -143,7 +145,7 @@ log.setConfig({ ``` ##### Broadcasting -`broadcasting` happens after `transforming`. It is `NOT` possible to modify the data. +`broadcasting` happens after `transforming`. It is `NOT ALLOWED` to modify the data. ```javascript log.setConfig({ @@ -156,11 +158,36 @@ log.setConfig({ ``` ### Levels ([1](https://httpd.apache.org/docs/current/mod/core.html#loglevel), [2](https://logging.apache.org/log4j/2.0/log4j-api/apidocs/org/apache/logging/log4j/Level.html), [3](http://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels)) +> [!WARNING] +> It is `NOT ALLOWED` to modify the levels. If you need it, consider <2.0 version. + +| Level | Severity | +|-----------|-----------| +| emergency | 0 | +| alert | 1 | +| critical | 2 | +| error | 3 | +| warning | 4 | +| notice | 5 | +| info | 6 | +| debug | 7 | + +### Aliases +**Default:** `log -> debug`, `warn -> warning` + +Custom example: + +> [!WARNING] +> It is `NOT ALLOWED` to redefine a name [used by the library](lib/gelf-pro.js#L202). -Default: -`{emergency: 0, alert: 1, critical: 2, error: 3, warning: 4, notice: 5, info: 6, debug: 7}` -Example: `log.emergency(...)`, `log.critical(...)`, etc. -Custom example: `{alert: 0, notice: 1, ...}` +```javascript +// via config +log.setConfig({aliases: {waaagh: 'emergency', oopsie: 'alert'}}); // (!) overwrite existing +log.waaagh('Da ooman base iz got walls an'); + +// via api (aliasMapping: HashMap, aliasesToRemove: Set) +log.bindAliases({waaagh: 'emergency', oopsie: 'alert'}, /*optional*/ ['warn', 'log']); +``` ### Third party adapters You can force using custom adapter by setting the `adapter` right after initialisation. The [signature](lib/adapter/abstract.js) might be found here. @@ -171,12 +198,6 @@ You can force using custom adapter by setting the `adapter` right after initiali // (!) adapterName and adapterOptions will be ignored ``` -### Aliases - -Default: `{log: 'debug', warn: 'warning'}` -Example: `log.log(...) -> log.debug(...)`, `log.warn(...) -> log.warning(...)`, etc. -Custom example: `{red: 'alert', yellow: 'notice', ...}` - ### Tests #### Cli ```bash diff --git a/lib/gelf-pro.js b/lib/gelf-pro.js index 62acf52..651ac24 100644 --- a/lib/gelf-pro.js +++ b/lib/gelf-pro.js @@ -27,22 +27,24 @@ var gelf = Object.create(null, { host: '127.0.0.1', port: 12201 }, - levels: { - emergency: 0, - alert: 1, - critical: 2, - error: 3, - warning: 4, - notice: 5, - info: 6, - debug: 7 - }, aliases: { log: 'debug', warn: 'warning' } } }, + levels: { + value: { + emergency: 0, + alert: 1, + critical: 2, + error: 3, + warning: 4, + notice: 5, + info: 6, + debug: 7 + } + }, adapter: { writable: true // the adapter holder (opened on test purpose) } @@ -54,6 +56,9 @@ var gelf = Object.create(null, { * @returns {gelf} */ gelf.setConfig = function (conf) { + if (conf.aliases) { + this.bindAliases(conf.aliases, _.keys(this.config.aliases)); + } this.config = _.merge({}, this.config, conf); return this; }; @@ -190,16 +195,30 @@ gelf.message = function (message, lvl, extra, cb) { }); }; +// aliases to be console alike +gelf.bindAliases = function (aliasMapping, aliasesToRemove) { + var self = this; + var blacklist = _(self.levels).keys().concat([ + 'config', 'levels', 'adapter', 'getadapter', 'getstringfromobject', 'send', + 'setconfig', 'message', 'bindaliases' + ]).value(); + + _(aliasesToRemove).omit(blacklist).forEach(function (alias) { + self[alias] && delete self[alias]; + }); + _(aliasMapping).toPairs().filter(function (p) { + return !_.includes(blacklist, p[0]); + }).forEach(function (p) { + Object.defineProperty(self, p[0], {enumerable: true, value: self[p[1]]}); + }); + return this; +} + // defining default functions like info(), error(), etc. -_.forEach(gelf.config.levels, function (idx, lvl) { +_.forEach(gelf.levels, function (idx, lvl) { this[lvl] = function (message, extra, cb) { this.message(message, idx, extra, cb); }; }.bind(gelf)); -// aliases to be console alike -_.forEach(gelf.config.aliases, function (from, to) { - this[to] = this[from]; -}.bind(gelf)); - -module.exports = gelf; +module.exports = gelf.bindAliases(gelf.config.aliases); diff --git a/package.json b/package.json index b6d7c6f..fe34383 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gelf-pro", - "version": "1.4.0", + "version": "2.0.0", "main": "./lib/gelf-pro.js", "typings": "./typings/index.d.ts", "author": "Kanstantsin Kamkou ", diff --git a/test/tests.js b/test/tests.js index 65994b3..4b27b65 100644 --- a/test/tests.js +++ b/test/tests.js @@ -39,12 +39,12 @@ module.exports = { }, 'Expose pre-defined levels': function () { + var gelf = _.cloneDeep(gelfOriginal); var levels = { - emergency: 0, alert: 1, critical: 2, error: 3, warning: 4, warn: 4, notice: 5, info: 6, - debug: 7, log: 7 + emergency: 0, alert: 1, critical: 2, error: 3, + warning: 4, notice: 5, info: 6, debug: 7 }; - var gelf = _.cloneDeep(gelfOriginal); sinon.spy(gelf, 'getStringFromObject'); _.forEach(levels, function (lvl, fnc) { @@ -53,6 +53,26 @@ module.exports = { }); }, + 'Modify aliases': function () { + var gelf = _.cloneDeep(gelfOriginal); + var verifyAliasExists = function (obj) { + _.forEach(obj, function (lvl, fnc) { + gelf[fnc]('test'); + JSON.parse(gelf.getStringFromObject.lastCall.returnValue).level.should.equal(lvl); + }); + } + + sinon.spy(gelf, 'getStringFromObject'); + + verifyAliasExists({log: 7, warn: 4}); + + gelf.setConfig({aliases: {waaagh: 'emergency', oopsie: 'alert', send: 'dEBug', message: 'warning'}}); + should.not.exist(gelf.log); + should.not.exist(gelf.warn); + + verifyAliasExists({waaagh: 0, oopsie: 1}); + }, + 'Manually set level': function () { var gelf = _.cloneDeep(gelfOriginal), mock = sinon.mock(gelf); @@ -105,7 +125,7 @@ module.exports = { sinon.spy(gelf, 'getStringFromObject'); gelf.info('Test message'); ("" + JSON.parse(gelf.getStringFromObject.lastCall.returnValue).timestamp) - .should.match(/^\d{10}\.\d{2,3}$/); + .should.match(/^\d{10}\.\d{1,3}$/); }, 'Normalize extra fields': function () {