aboutsummaryrefslogtreecommitdiff
path: root/lib/cologne.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cologne.js')
-rw-r--r--lib/cologne.js328
1 files changed, 328 insertions, 0 deletions
diff --git a/lib/cologne.js b/lib/cologne.js
new file mode 100644
index 0000000..646fe79
--- /dev/null
+++ b/lib/cologne.js
@@ -0,0 +1,328 @@
+'use strict';
+
+let LogUtilities = require('./cologne/log_utilities');
+
+/** TYPE DEFINITIONS **/
+
+/**
+ * Main interface for Cologne Loggers
+ *
+ * @memberof Cologne
+ * @interface ILogger
+ */
+
+/**
+ * Receives any number of cologne log objects and logs them.
+ *
+ * @memberof Cologne.ILogger
+ * @function
+ * @name log
+ * @returns {undefined}
+ */
+
+/**
+ * Main interface for Cologne Formatters
+ *
+ * @memberof Cologne
+ * @interface IFormatter
+ */
+
+/**
+ * Receives a cologne log object and returns a formatted string.
+ *
+ * @memberof Cologne.IFormatter
+ * @function
+ * @name format
+ * @param {Cologne.tCologneLog} logObject the log to be formatted
+ * @returns {string} the formatted log
+ */
+
+/**
+ * The main cologne log format.
+ *
+ * @memberof Cologne
+ * @typedef {object} tCologneLog
+ * @property {Number} _timestamp the timestamp in miliseconds with decimal
+ * numbers representing fractions of miliseconds
+ * @property {String} _cologneLog main identifier, encodes the version of the
+ * cologne log format being used.
+ * @property {String} _from the origin of the log message.
+ * @property {String} _level the severity level of the log, uses syslog
+ * priorities.
+ * @property {String} _levelString the severity level keyword of the log,
+ * uses syslog priority keywords.
+ */
+
+/**
+ * Cologne is a logger multiplexer that works mainly with a JSON format. It
+ * can be instantiated with several loggers, or they can be changed after
+ * the fact.
+ *
+ * ## Usage
+ *
+ * ```
+ * require('cologne');
+ *
+ * let co = new Cologne({
+ * from: "Special Worker Logger",
+ * loggers: [
+ * new Cologne.Logger.Console({
+ * formatter: new Cologne.Formatter.Token({
+ * formatString: '[{{_timestamp}}]{{_from}}: {{message}}'
+ * })
+ * })
+ * ]
+ * });
+ * ```
+ *
+ * @class Cologne
+ */
+let Cologne = class Cologne {
+
+ constructor (config) {
+
+ /**
+ * The name of this logger, useful to distinguish between different
+ * loggers.
+ *
+ * @name from
+ * @instance
+ * @memberof Cologne
+ * @type String
+ * @default 'Generic Cologne Logger
+ */
+ this.from = 'Generic Cologne Logger';
+
+ /**
+ * The array containing all the loggers it will call to.
+ *
+ * @name loggers
+ * @instance
+ * @memberof Cologne
+ * @type Cologne.ILogger[]
+ * @default []
+ */
+ this.loggers = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /**
+ * Adds a logger to the current instance.
+ *
+ * @function addLogger
+ * @instance
+ * @memberof Cologne
+ * @param {Cologne.ILogger} logger the logger to add
+ * @return {undefined}
+ */
+ addLogger (logger) {
+ this.loggers.push(logger);
+ }
+
+ /**
+ * Removes a logger from the current instance.
+ *
+ * @function removeLogger
+ * @instance
+ * @memberof Cologne
+ * @param {Cologne.ILogger} logger the logger to remove
+ * @return {Cologne.ILogger[]} the removed log, inside an array.
+ */
+ removeLogger (logger) {
+ let index;
+
+ index = this.loggers.indexOf(logger);
+ if (index >= 0) {
+ this.loggers.splice(index, 1);
+ }
+ }
+
+ /**
+ * Given an item, it builds a cologne log object. this is done
+ * automatically by the logger, though this is useful if you need
+ * to attach metadata before logging.
+ *
+ * @function buildLog
+ * @instance
+ * @memberof Cologne
+ * @param {*} item The item to log
+ * @return {Cologne.tCologneLog} a cologne log object
+ */
+ buildLog (item, level, meta) {
+ let logObject;
+
+ logObject = {};
+
+ if (typeof item === 'undefined' || item === null || !item._cologneLog) {
+ logObject.message = item;
+ logObject._cologneLog = this.constructor._version;
+ logObject._from = this.from;
+ logObject._level = level || 6;
+ logObject._levelString = this._levelString(logObject._level);
+ logObject._timestamp = LogUtilities.now();
+
+ if (meta && typeof meta === 'object') {
+ Object.assign(logObject, meta);
+ }
+
+ return logObject;
+ }
+
+ if (item._cologneLog) {
+ item._level = level || item._level || 6;
+ item._levelString = this._levelString(item._level);
+ }
+
+ return item;
+ }
+
+ /**
+ * Default log function. Sends arguments to loggers. If not specified in log
+ * object, it will set the severity to 6 - INFO.
+ *
+ * @function log
+ * @instance
+ * @memberof Cologne
+ * @return {undefined}
+ */
+ log () {
+ this._log.apply(this, [null].concat(Array.prototype.slice.call(arguments)));
+ }
+
+ /**
+ * Logs with debug level
+ *
+ * @function debug
+ * @instance
+ * @memberof Cologne
+ * @return {undefined}
+ */
+ debug () {
+ this._log.apply(this, [7].concat(Array.prototype.slice.call(arguments)));
+ }
+
+ /**
+ * Logs with info level
+ *
+ * @function info
+ * @instance
+ * @memberof Cologne
+ * @return {undefined}
+ */
+ info () {
+ this._log.apply(this, [6].concat(Array.prototype.slice.call(arguments)));
+ }
+
+ /**
+ * Logs with notice level
+ *
+ * @function notice
+ * @instance
+ * @memberof Cologne
+ * @return {undefined}
+ */
+ notice () {
+ this._log.apply(this, [5].concat(Array.prototype.slice.call(arguments)));
+ }
+
+ /**
+ * Logs with warn level
+ *
+ * @function warn
+ * @instance
+ * @memberof Cologne
+ * @return {undefined}
+ */
+ warn () {
+ this._log.apply(this, [4].concat(Array.prototype.slice.call(arguments)));
+ }
+
+ /**
+ * Logs with error level
+ *
+ * @function error
+ * @instance
+ * @memberof Cologne
+ * @return {undefined}
+ */
+ error () {
+ this._log.apply(this, [3].concat(Array.prototype.slice.call(arguments)));
+ }
+
+ // Private method that builds all the logs and sends them to the loggers.
+ _log (severity) {
+ let remainingArguments, logObjectArray, log, logger;
+
+ remainingArguments = Array.prototype.slice.call(arguments, 1);
+ logObjectArray = [];
+
+ for (log of remainingArguments) {
+ if (typeof log === 'undefined') {
+ logObjectArray.push(this.buildLog('undefined', severity));
+ continue;
+ }
+
+ if (log === null) {
+ logObjectArray.push(this.buildLog('null', severity));
+ continue;
+ }
+
+ logObjectArray.push(this.buildLog(log, severity));
+ }
+
+ for (logger of this.loggers) {
+ logger.log.apply(logger, logObjectArray);
+ }
+ }
+
+ // Private utility method that will return the string for any given
+ // numerical severity level
+ _levelString (level) {
+ switch(level) {
+ case 0:
+ return 'emerg';
+ case 1:
+ return 'alert';
+ case 2:
+ return 'crit';
+ case 3:
+ return 'error';
+ case 4:
+ return 'warning';
+ case 5:
+ return 'notice';
+ case 6:
+ return 'info';
+ case 7:
+ return 'debug';
+ }
+ }
+};
+
+// Version of the Cologne Log Format used.
+Cologne._version = '1.0.0';
+
+/**
+ * Namespace that includes the built-in formatters.
+ *
+ * @namespace Formatter
+ * @memberof Cologne
+ */
+Cologne.Formatter = {};
+Cologne.Formatter.Simple = require('./cologne/formatter/simple');
+Cologne.Formatter.Token = require('./cologne/formatter/token');
+
+/**
+ * Namespace that includes the built-in loggers.
+ *
+ * @namespace Logger
+ * @memberof Cologne
+ */
+Cologne.Logger = {};
+Cologne.Logger.Console = require('./cologne/logger/console');
+Cologne.Logger.File = require('./cologne/logger/file');
+
+Cologne.LogUtilities = require('./cologne/log_utilities');
+
+module.exports = Cologne;