@opuscapita/logger
Advanced tools
Comparing version 1.0.16-beta.1 to 1.0.16-beta.2
377
index.js
'use strict' | ||
module.exports = require('./src/logger') | ||
const extend = require('extend'); | ||
const util = require('util'); | ||
const cwd = process.cwd(); | ||
const correlator = require("correlation-id"); | ||
const { v4: uuidv4 } = require('uuid'); | ||
let debugMode = false; | ||
const origOutputFuncs = Object.freeze({ | ||
log : console.log, | ||
trace: console.trace, | ||
debug : console.debug, | ||
info : console.info, | ||
warn : console.warn, | ||
error : console.error, | ||
fatal : console.fatal | ||
}) | ||
/** | ||
* Module for general logging. | ||
* @requires extend | ||
*/ | ||
/** | ||
* Logging class for a common log style and behavior. | ||
* | ||
* This logging class provides muliple methods for different purposes. It is capable of sending | ||
* formatted messages to a stream object and/or to callback function. All methods always output a JSON | ||
* formatted string containing a timestamp, level and the actual message. Additional information may be added using the | ||
* [contextify()]{@link Logger#contextify} method or the context property of the constructor | ||
* configuration. For further information see [DefaultConfig]{@link Logger.DefaultConfig}. | ||
* | ||
* @param {object} config - For a list of possible configuration values see [DefaultConfig]{@link DefaultConfig}. | ||
* @constructor | ||
*/ | ||
const Logger = function(config) | ||
{ | ||
this.config = extend(true, { }, Logger.DefaultConfig, config); | ||
} | ||
/** | ||
* Gets the name of the current service this module is running in. It simply takes the last directory | ||
* name of the main processes path. | ||
*/ | ||
Logger.serviceName = cwd.slice(cwd.lastIndexOf('/') + 1); | ||
/** | ||
* Enumeration representing all available log levels to log messages. | ||
* @enum {string} | ||
*/ | ||
Logger.LogLevel = Object.freeze({ Invalid : '', Trace: 'trace', Debug : 'debug', Info : 'info', Warning : 'warn', Error : 'error', Fatal: 'fatal'}); | ||
const logLevelMapping = Object.freeze({ | ||
[Logger.LogLevel.Trace] : 800, | ||
[Logger.LogLevel.Debug] : 700, | ||
[Logger.LogLevel.Invalid] : 600, | ||
[Logger.LogLevel.Warning] : 400, | ||
[Logger.LogLevel.Error] : 300, | ||
[Logger.LogLevel.Fatal] : 100, | ||
[Logger.LogLevel.Exception] : 100 // do not use | ||
}) | ||
/** | ||
* Redirects all calls to console.log, console.info, console.debug, console.warn and console.error | ||
* to an instance of Logger. | ||
*/ | ||
Logger.prototype.redirectConsoleOut = function() | ||
{ | ||
const printMessage = (level, params) => | ||
{ | ||
const firstParam = params && params.length && params[0]; | ||
if(typeof firstParam === 'string') | ||
{ | ||
this.onWrite(level, params); | ||
} | ||
else | ||
{ | ||
for(const i in params) | ||
this.onWrite(level, { '0' : params[i] }); | ||
} | ||
} | ||
console.log = (...args) => printMessage(Logger.LogLevel.Info, args); | ||
console.trace = (...args) => printMessage(Logger.LogLevel.Trace, args); | ||
console.debug = (...args) => printMessage(Logger.LogLevel.Debug, args); | ||
console.info = (...args) => printMessage(Logger.LogLevel.Info, args); | ||
console.warn = (...args) => printMessage(Logger.LogLevel.Warning, args); | ||
console.error = (...args) => printMessage(Logger.LogLevel.Error, args); | ||
console.fatal = (...args) => printMessage(Logger.LogLevel.Fatal, args); | ||
} | ||
Logger.prototype.resetConsoleOut = function() | ||
{ | ||
console.log = origOutputFuncs.log; | ||
console.trace = origOutputFuncs.trace; | ||
console.debug = origOutputFuncs.debug; | ||
console.info = origOutputFuncs.info; | ||
console.warn = origOutputFuncs.warn; | ||
console.error = origOutputFuncs.error; | ||
console.fatal = origOutputFuncs.fatal; | ||
} | ||
Logger.prototype.onWrite = function(level, message) | ||
{ | ||
if(logLevelMapping[level] >= logLevelMapping[this.config.minLogLevel] || debugMode) | ||
{ | ||
message = Array.prototype.slice.call(message); | ||
let callback; | ||
if(typeof message[message.length - 1] === 'function') | ||
{ | ||
callback = message[message.length - 1]; | ||
message = message.slice(0, -1); | ||
} | ||
let obj = { | ||
timestamp : new Date().toISOString(), | ||
level : level, | ||
message : util.format.apply(util, message) | ||
}; | ||
obj = extend(false, this.config.context, obj); | ||
if(debugMode) | ||
{ | ||
origOutputFuncs.debug(obj.message); | ||
} | ||
else | ||
{ | ||
const formatted = this.config.formatter(obj); | ||
this.config.outputStreams[level].write(formatted + '\n'); | ||
if(typeof callback === 'function') | ||
callback(formatted); | ||
} | ||
} | ||
} | ||
/** | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Debug". | ||
* Most detailed information. Expect these to be written to logs only. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.trace = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Trace, arguments); | ||
} | ||
/** | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Debug". | ||
* Detailed information on the flow through the system. Expect these to be written to logs only. | ||
* Generally speaking, most lines logged by your application should be written as DEBUG. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.debug = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Debug, arguments); | ||
} | ||
/** | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Info". | ||
* Interesting runtime events (startup/shutdown). | ||
* Expect these to be immediately visible on a console, so be conservative and keep to a minimum. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.info = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Info, arguments); | ||
} | ||
/** | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Warning". | ||
* Use of deprecated APIs, poor use of API, 'almost' errors, other runtime situations that are undesirable or unexpected, but not necessarily "wrong". | ||
* Expect these to be immediately visible on a status console. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.warn = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Warning, arguments); | ||
} | ||
/** | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Error". | ||
* Other runtime errors or unexpected conditions. | ||
* Expect these to be immediately visible on a status console. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.error = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Error, arguments); | ||
} | ||
/** | ||
* @Deprecated since 2.0.0 - pass exception message as a parameter to other log levels instead | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Exception". | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.except = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Exception, arguments); | ||
} | ||
/** | ||
* Logs a message with the [LogLevel]{@link Logger.LogLevel} "Fatal". | ||
* Severe errors that cause premature termination. | ||
* Expect these to be immediately visible on a status console. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.fatal = function(message, params, callback) | ||
{ | ||
this.onWrite(Logger.LogLevel.Fatal, arguments); | ||
} | ||
/** | ||
* @Deprecated since 2.0.0 | ||
* Logs a message with the default [LogLevel]{@link Logger.LogLevel} passed to the constructor. | ||
* For further information see [DefaultConfig]{@link Logger.DefaultConfig}. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.log = function(message, params, callback) | ||
{ | ||
this.onWrite(this.config.defaultLogLevel, arguments); | ||
} | ||
/** | ||
* Logs a message with the default [LogLevel]{@link Logger.LogLevel} passed to the constructor. | ||
* For further information see [DefaultConfig]{@link Logger.DefaultConfig}. | ||
* | ||
* @param {string} message - Message to log. May contain formatting placeholders. | ||
* @param {object} params - A **variable** list of parameters replacing actual formatters in *message*. | ||
* @param {function} callback - An optional callback as last parameter to be called in addition with the logged message. | ||
*/ | ||
Logger.prototype.write = function(message, params, callback) | ||
{ | ||
this.onWrite(this.config.defaultLogLevel, arguments); | ||
} | ||
/** | ||
* Method for changing the context of log messages. A context can either be specified using the constructor's | ||
* config value (see [DefaultConfig]{@link Logger.DefaultConfig}) or this method. Every time .contextify() is called, | ||
* all following log message will populate the passed context as general meta data in every log entry. | ||
* | ||
* Be aware that the passed context object will always be extended by the defaul context object from [DefaultConfig]{@link Logger.DefaultConfig}. | ||
* In order to fully remove all basic information from beeing populated, set the context object to an empty | ||
* object when calling the constructor of this class. | ||
* | ||
* @param {object} context - Context object. | ||
*/ | ||
Logger.prototype.contextify = function(context) | ||
{ | ||
this.config.context = extend(true, { }, this.config.context, context); | ||
} | ||
/** | ||
* Creates a deep copy of a Logger object and returns it. | ||
* @returns {Logger} The cloned Logger object. | ||
*/ | ||
Logger.prototype.clone = function() | ||
{ | ||
return extend(true, { }, this); | ||
} | ||
/** | ||
* Static object representing a default configuration set for logger-cache. | ||
* | ||
* In order to pass configuration values directly to the underlying cache back-end, just add a key to | ||
* the configuration named the same as the value of the **driver** property. | ||
* | ||
* @deprecated since 2.0.0 | ||
* @property {Logger.LogLevel} defaultLogLevel - The default log level for methods like [write()]{@link Logger#write} or [log()]{@link Logger#log}. | ||
* | ||
* @property {Logger.LogLevel} minLogLevel - The minimum log level that is required to log messages. All logging done with a level below this level gets ignored. | ||
* | ||
* @property {object} outputStreams - Object containing different output streams for different log levels. | ||
* @property {string} outputStreams.trace - Output stream for {@link Logger.LogLevel} "Trace". | ||
* @property {string} outputStreams.debug - Output stream for {@link Logger.LogLevel} "Debug". | ||
* @property {string} outputStreams.info - Output stream for {@link Logger.LogLevel} "Info". | ||
* @property {string} outputStreams.warn - Output stream for {@link Logger.LogLevel} "Warning". | ||
* @property {string} outputStreams.error - Output stream for {@link Logger.LogLevel} "Error". | ||
* @property {string} outputStreams.fatal - Output stream for {@link Logger.LogLevel} "Fatal". | ||
* | ||
* @deprecated since 2.0.0 | ||
* @property {string} outputStreams.except - Output stream for {@link Logger.LogLevel} "Exception". | ||
* | ||
* @property {object} context - Object for setting general meta information on every log entry. | ||
* @property {string} context.name | ||
* @property {string} context.serviceName | ||
* @property {object} context.serviceInstanceId | ||
* @property {object} context.correlationId | ||
* @property {object} context.userId | ||
* @property {string} context.requestUri | ||
*/ | ||
Logger.DefaultConfig = { | ||
defaultLogLevel : Logger.LogLevel.Info, | ||
minLogLevel : Logger.LogLevel.Info, | ||
outputStreams : { | ||
[Logger.LogLevel.Trace] : process.stdout, | ||
[Logger.LogLevel.Debug] : process.stdout, | ||
[Logger.LogLevel.Info] : process.stdout, | ||
[Logger.LogLevel.Warning] : process.stdout, | ||
[Logger.LogLevel.Error] : process.stderr, | ||
[Logger.LogLevel.Fatal] : process.stderr, | ||
[Logger.LogLevel.Exception] : process.stderr | ||
}, | ||
formatter : (obj) => util.format('%j', obj), | ||
context: { | ||
name : null, | ||
serviceName : Logger.serviceName, | ||
serviceInstanceId : 0, | ||
correlationId : correlator.getId() || 'INVALID:' + uuidv4(), | ||
userId : null, | ||
requestUri : null | ||
} | ||
} | ||
/** | ||
* Provides a full Logger instance that will output nothing. | ||
* @returns {Logger} Logger object not outputting anything. | ||
*/ | ||
Logger.DummyLogger = new Logger({ | ||
minLogLevel : Logger.LogLevel.Debug, | ||
outputStreams : { | ||
[Logger.LogLevel.Trace] : { write : () => null }, | ||
[Logger.LogLevel.Debug] : { write : () => null }, | ||
[Logger.LogLevel.Info] : { write : () => null }, | ||
[Logger.LogLevel.Warning] : { write : () => null }, | ||
[Logger.LogLevel.Error] : { write : () => null }, | ||
[Logger.LogLevel.Fatal] : { write : () => null }, | ||
[Logger.LogLevel.Exception] : { write : () => null } | ||
} | ||
}); | ||
/** | ||
* Provides a full Logger instance that will output all data as it is without reformatting. | ||
* @returns {Logger} Logger object not outputting anything. | ||
*/ | ||
Logger.DebugLogger = new Logger({ | ||
defaultLogLevel : Logger.LogLevel.Debug | ||
}); | ||
module.exports = Logger; | ||
/** | ||
* Turn on debug mode to always log messages | ||
* @deprecated since 1.0.15 | ||
* @param {Boolean} debugOn | ||
*/ | ||
module.exports.setDebugMode = function(debugOn) { debugMode = debugOn; } |
{ | ||
"name": "@opuscapita/logger", | ||
"version": "1.0.16-beta.1", | ||
"version": "1.0.16-beta.2", | ||
"description": "Unified logging component for OpusCapita Andariel platform.", | ||
@@ -8,3 +8,3 @@ "main": "index.js", | ||
"start": "npm run test", | ||
"test:unit": "npx nyc --reporter=text --reporter=lcov mocha 'src/**/*.test.js'", | ||
"test:unit": "npx nyc --reporter=text --reporter=lcov mocha '*.test.js'", | ||
"test:integ": "npx nyc --reporter=text --reporter=lcov 'test/**/*.spec.js'", | ||
@@ -11,0 +11,0 @@ "test": "npm run test:integ", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Trivial Package
Supply chain riskPackages less than 10 lines of code are easily copied into your own project and may not warrant the additional supply chain risk of an external dependency.
Found 1 instance in 1 package
18253
341