]> git.r.bdr.sh - rbdr/cologne/blame - lib/cologne.js
Run all stages always
[rbdr/cologne] / lib / cologne.js
CommitLineData
58906d77
RBR
1'use strict';
2
ae85c067
RBR
3const Utilities = require('./utilities');
4
5const internals = {
6
7 // Maps log levels to their syslog labels
8
9 kLevelStrings: [
10 'emerg',
11 'alert',
12 'crit',
13 'error',
14 'warning',
15 'notice',
16 'info',
17 'debug'
18 ],
19
20 // Version of the Cologne Log Format used
21
22 kLogVersion: '2.0.0'
23};
58906d77
RBR
24
25/** TYPE DEFINITIONS **/
26
27/**
28 * Main interface for Cologne Loggers
29 *
58906d77
RBR
30 * @interface ILogger
31 */
32
33/**
34 * Receives any number of cologne log objects and logs them.
35 *
ae85c067 36 * @memberof ILogger
58906d77
RBR
37 * @function
38 * @name log
58906d77
RBR
39 */
40
41/**
42 * Main interface for Cologne Formatters
43 *
58906d77
RBR
44 * @interface IFormatter
45 */
46
47/**
48 * Receives a cologne log object and returns a formatted string.
49 *
ae85c067 50 * @memberof IFormatter
58906d77
RBR
51 * @function
52 * @name format
ae85c067 53 * @param {tCologneLog} logObject the log to be formatted
58906d77
RBR
54 * @returns {string} the formatted log
55 */
56
57/**
58 * The main cologne log format.
59 *
58906d77 60 * @typedef {object} tCologneLog
ae85c067 61 * @property {Bigint} _timestamp the timestamp in nanoseconds
58906d77
RBR
62 * @property {String} _cologneLog main identifier, encodes the version of the
63 * cologne log format being used.
64 * @property {String} _from the origin of the log message.
65 * @property {String} _level the severity level of the log, uses syslog
66 * priorities.
67 * @property {String} _levelString the severity level keyword of the log,
68 * uses syslog priority keywords.
69 */
70
71/**
ae85c067
RBR
72 * The main logger class. It can be instantiated with loggers in order to
73 * send messages to different destinations.
58906d77
RBR
74 *
75 * @class Cologne
76 */
ae85c067 77const Cologne = class Cologne {
58906d77 78
ae85c067 79 constructor(config) {
58906d77
RBR
80
81 /**
82 * The name of this logger, useful to distinguish between different
83 * loggers.
84 *
85 * @name from
86 * @instance
87 * @memberof Cologne
88 * @type String
89 * @default 'Generic Cologne Logger
90 */
91 this.from = 'Generic Cologne Logger';
92
93 /**
94 * The array containing all the loggers it will call to.
95 *
96 * @name loggers
97 * @instance
98 * @memberof Cologne
ae85c067 99 * @type ILogger[]
58906d77
RBR
100 * @default []
101 */
102 this.loggers = [];
103
ae85c067 104 Object.assign(this, config);
58906d77
RBR
105 }
106
107 /**
108 * Adds a logger to the current instance.
109 *
110 * @function addLogger
111 * @instance
112 * @memberof Cologne
ae85c067 113 * @param {ILogger} logger the logger to add
58906d77 114 */
ae85c067
RBR
115 addLogger(logger) {
116
58906d77
RBR
117 this.loggers.push(logger);
118 }
119
120 /**
121 * Removes a logger from the current instance.
122 *
123 * @function removeLogger
124 * @instance
125 * @memberof Cologne
ae85c067
RBR
126 * @param {ILogger} logger the logger to remove
127 * @return {ILogger[]} the removed log, inside an array.
58906d77 128 */
ae85c067 129 removeLogger(logger) {
58906d77 130
ae85c067 131 const index = this.loggers.indexOf(logger);
58906d77
RBR
132 if (index >= 0) {
133 this.loggers.splice(index, 1);
134 }
135 }
136
137 /**
ae85c067
RBR
138 * Given a message, it builds a cologne log object without logging it.
139 * If you send a cologne log object, it will only update the level.
140 *
141 * If the message is an object, the log object will be extended with
142 * its properties.
58906d77
RBR
143 *
144 * @function buildLog
145 * @instance
146 * @memberof Cologne
ae85c067
RBR
147 * @param {*} message The message to log
148 * @param {number} [level=6] The level of the message to log
149 * @return {tCologneLog} a cologne log object
58906d77 150 */
ae85c067
RBR
151 buildLog(rawMessage, level) {
152
153 if (typeof rawMessage === 'undefined' || rawMessage === null || !rawMessage._cologneLog) {
58906d77 154
ae85c067 155 const message = typeof rawMessage === 'object' ? Utilities.stringify(rawMessage) : rawMessage;
58906d77 156
ae85c067
RBR
157 const logObject = {
158 message: String(message),
159 _cologneLog: internals.kLogVersion,
160 _from: this.from,
161 _level: level || 6,
162 _timestamp: Utilities.now()
163 };
58906d77 164
ae85c067
RBR
165 logObject._levelString = internals.kLevelStrings[logObject._level];
166
167 if (typeof rawMessage === 'object') {
168 Object.assign(logObject, rawMessage);
58906d77
RBR
169 }
170
171 return logObject;
172 }
173
ae85c067
RBR
174 rawMessage._level = level || rawMessage._level;
175 rawMessage._levelString = internals.kLevelStrings[rawMessage._level];
58906d77 176
ae85c067 177 return rawMessage;
58906d77
RBR
178 }
179
180 /**
181 * Default log function. Sends arguments to loggers. If not specified in log
182 * object, it will set the severity to 6 - INFO.
183 *
184 * @function log
185 * @instance
186 * @memberof Cologne
58906d77 187 */
ae85c067
RBR
188 log(...logs) {
189
190 this._log(null, ...logs);
58906d77
RBR
191 }
192
193 /**
194 * Logs with debug level
195 *
196 * @function debug
197 * @instance
198 * @memberof Cologne
58906d77 199 */
ae85c067
RBR
200 debug(...logs) {
201
202 this._log(7, ...logs);
58906d77
RBR
203 }
204
205 /**
206 * Logs with info level
207 *
208 * @function info
209 * @instance
210 * @memberof Cologne
58906d77 211 */
ae85c067
RBR
212 info(...logs) {
213
214 this._log(6, ...logs);
58906d77
RBR
215 }
216
217 /**
218 * Logs with notice level
219 *
220 * @function notice
221 * @instance
222 * @memberof Cologne
58906d77 223 */
ae85c067
RBR
224 notice(...logs) {
225
226 this._log(5, ...logs);
58906d77
RBR
227 }
228
229 /**
230 * Logs with warn level
231 *
232 * @function warn
233 * @instance
234 * @memberof Cologne
58906d77 235 */
ae85c067
RBR
236 warn(...logs) {
237
238 this._log(4, ...logs);
58906d77
RBR
239 }
240
241 /**
242 * Logs with error level
243 *
244 * @function error
245 * @instance
246 * @memberof Cologne
58906d77 247 */
ae85c067
RBR
248 error(...logs) {
249
250 this._log(3, ...logs);
58906d77
RBR
251 }
252
253 // Private method that builds all the logs and sends them to the loggers.
58906d77 254
ae85c067 255 _log(level, ...logs) {
58906d77 256
ae85c067 257 const structuredLogs = logs.map((log) => this.buildLog(log, level));
58906d77 258
ae85c067
RBR
259 for (const logger of this.loggers) {
260 logger.log(...structuredLogs);
58906d77
RBR
261 }
262 }
263};
264
58906d77
RBR
265/**
266 * Namespace that includes the built-in formatters.
267 *
ae85c067 268 * @namespace Formatters
58906d77 269 */
ae85c067
RBR
270const Formatters = {};
271Formatters.Simple = require('./formatters/simple');
272Formatters.Token = require('./formatters/token');
58906d77
RBR
273
274/**
275 * Namespace that includes the built-in loggers.
276 *
ae85c067 277 * @namespace Loggers
58906d77 278 */
ae85c067
RBR
279const Loggers = {};
280Loggers.Console = require('./loggers/console');
281Loggers.File = require('./loggers/file');
282
283module.exports = {
284 Cologne,
285 Formatters,
286 Loggers,
287 Utilities
288};