Initial import from local backup (Documents-Playground/pakerpale)
This commit is contained in:
211
node_modules/logops/lib/formatters.js
generated
vendored
Normal file
211
node_modules/logops/lib/formatters.js
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*jshint -W072*/
|
||||
'use strict';
|
||||
|
||||
var util = require('util'),
|
||||
colors = require('colors/safe'),
|
||||
safeStringify = require('safe-json-stringify'),
|
||||
serializeErr = require('serr'),
|
||||
_ = require('lodash');
|
||||
|
||||
var DEFAULT_NOT_AVAILABLE = 'n/a';
|
||||
|
||||
var notAvailable = DEFAULT_NOT_AVAILABLE,
|
||||
templateTrace = 'time=%s | lvl=%s | corr=%s | trans=%s | op=%s | msg=';
|
||||
|
||||
/**
|
||||
* The exported formatters.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var API = module.exports = {
|
||||
dev: formatDevTrace,
|
||||
json: formatJsonTrace,
|
||||
stacktracesWith: ['ERROR', 'FATAL'],
|
||||
pipe: formatTrace, // Deprecated
|
||||
setNotAvailable: setNotAvailable // Deprecated
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a value for those fields that are not available in the context. This field
|
||||
* will only be used in the 'pipes' formatter.
|
||||
*
|
||||
* @param {String} na New value for not available fields.
|
||||
* @deprecated
|
||||
*/
|
||||
function setNotAvailable(na) {
|
||||
notAvailable = na;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a trace message with some nice TTY colors
|
||||
*
|
||||
* @param {String} level One of the following values
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
* @param {Object} context Additional information to add to the trace
|
||||
* @param {String} message The main message to be added to the trace
|
||||
* @param {Array} args More arguments provided to the log function
|
||||
* @param {Error|undefined} err A cause error used to log extra information
|
||||
*
|
||||
* @return {String} The trace formatted
|
||||
*/
|
||||
function formatDevTrace(level, context, message, args, err) {
|
||||
var str,
|
||||
mainMessage = util.format.apply(global, [message].concat(args)),
|
||||
printStack = API.stacktracesWith.indexOf(level) > -1,
|
||||
errCommomMessage = err && (err.name + ': ' + err.message),
|
||||
isErrorLoggingWithoutMessage = mainMessage === errCommomMessage;
|
||||
|
||||
switch (level) {
|
||||
case 'DEBUG':
|
||||
str = colors.grey(level);
|
||||
break;
|
||||
case 'INFO':
|
||||
str = colors.blue(level) + ' '; // Pad to 5 chars
|
||||
break;
|
||||
case 'WARN':
|
||||
str = colors.yellow(level) + ' '; // Pad to 5 chars
|
||||
break;
|
||||
case 'ERROR':
|
||||
str = colors.red(level);
|
||||
break;
|
||||
case 'FATAL':
|
||||
str = colors.red.bold(level);
|
||||
break;
|
||||
}
|
||||
str += ' ' + mainMessage;
|
||||
|
||||
if (isErrorLoggingWithoutMessage) {
|
||||
str += colorize(colors.gray, serializeErr(err).toString(printStack).substr(mainMessage.length));
|
||||
} else if (err) {
|
||||
str += '\n' + colorize(colors.gray, serializeErr(err).toString(printStack));
|
||||
}
|
||||
|
||||
var localContext = _.omit(context, formatDevTrace.omit);
|
||||
str += Object.keys(localContext).length ?
|
||||
' ' + colorize(colors.gray, util.inspect(localContext)) :
|
||||
'';
|
||||
|
||||
// pad all subsequent lines with as much spaces as "DEBUG " or "INFO " have
|
||||
return str.replace(new RegExp('\r?\n','g'), '\n ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Context properties that should be skipped from printing in dev format
|
||||
* @type {Array.<String>}
|
||||
*/
|
||||
formatDevTrace.omit = [];
|
||||
|
||||
// Damm! colors are not applied to multilines! split, apply and join!
|
||||
function colorize(color, str) {
|
||||
return str
|
||||
.split('\n')
|
||||
.map(part => color(part))
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a trace message with fields separated by pipes.
|
||||
*
|
||||
* DEPRECATED!
|
||||
*
|
||||
* @param {String} level One of the following values
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
* @param {Object} context Additional information to add to the trace
|
||||
* @param {String} message The main message to be added to the trace
|
||||
* @param {Array} args More arguments provided to the log function
|
||||
* @param {Error|undefined} err A cause error used to log extra information
|
||||
*
|
||||
* @return {String} The trace formatted
|
||||
* @deprecated
|
||||
*/
|
||||
function formatTrace(level, context, message, args, err) {
|
||||
|
||||
var recontext = {
|
||||
time: (new Date()).toISOString(),
|
||||
lvl: level,
|
||||
corr: context.corr || notAvailable,
|
||||
trans: context.trans || notAvailable,
|
||||
op: context.op || notAvailable
|
||||
};
|
||||
|
||||
Object.keys(context)
|
||||
.filter((key) => {
|
||||
return !(context[key] && Object.prototype.toString.call(context[key]) === '[object Function]');
|
||||
})
|
||||
.forEach((key) => {
|
||||
recontext[key] = context[key] || notAvailable;
|
||||
});
|
||||
|
||||
if (message instanceof Date || message instanceof Error) {
|
||||
// Node6 related hack. See https://github.com/telefonicaid/logops/issues/36
|
||||
recontext.msg = util.format(message);
|
||||
} else {
|
||||
recontext.msg = message;
|
||||
}
|
||||
|
||||
var str = Object.keys(recontext)
|
||||
.map((key) => key + '=' + recontext[key])
|
||||
.join(' | ');
|
||||
|
||||
args.unshift(str);
|
||||
if (err && message !== '' + err) {
|
||||
args.push(err);
|
||||
}
|
||||
|
||||
return util.format.apply(global, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a trace message in JSON format
|
||||
*
|
||||
* @param {String} level One of the following values
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
* @param {Object} context Additional information to add to the trace
|
||||
* @param {String} message The main message to be added to the trace
|
||||
* @param {Array} args More arguments provided to the log function
|
||||
* @param {Error|null} err A cause error used to log extra information
|
||||
*
|
||||
* @return {String} The trace formatted
|
||||
*/
|
||||
function formatJsonTrace(level, context, message, args, err) {
|
||||
return formatJsonTrace.stringify(formatJsonTrace.toObject(level, context, message, args, err));
|
||||
}
|
||||
|
||||
formatJsonTrace.stringify = (obj) => {
|
||||
try {
|
||||
return JSON.stringify(obj);
|
||||
} catch (err) {
|
||||
return safeStringify(obj);
|
||||
}
|
||||
};
|
||||
formatJsonTrace.toObject = (level, context, message, args, err) => {
|
||||
let log = {};
|
||||
|
||||
for (let attrname in context) {
|
||||
log[attrname] = context[attrname];
|
||||
}
|
||||
|
||||
log.time = new Date();
|
||||
log.lvl = level;
|
||||
log.err = err && serializeErr(err).toObject(API.stacktracesWith.indexOf(level) > -1);
|
||||
log.msg = util.format.apply(global, [message].concat(args));
|
||||
|
||||
return log;
|
||||
};
|
||||
354
node_modules/logops/lib/logops.d.ts
generated
vendored
Normal file
354
node_modules/logops/lib/logops.d.ts
generated
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
/** Simple and performant nodejs JSON logger */
|
||||
|
||||
|
||||
interface Logops {
|
||||
/**
|
||||
* The NODEJS stream where the logger will write string traces
|
||||
* Defaults to process.stdout
|
||||
*/
|
||||
setStream(stream: NodeJS.WritableStream): void;
|
||||
stream: NodeJS.WritableStream;
|
||||
|
||||
/**
|
||||
* Gets the current log level. The default level is INFO
|
||||
*/
|
||||
getLevel(): Level;
|
||||
|
||||
/**
|
||||
* Sets the enabled logging level.
|
||||
* All the disabled logging methods are replaced by a noop,
|
||||
* so there is not any performance penalty at production using an undesired level
|
||||
* You can also set the logging level using the `LOGOPS_LEVEL` environment variable:
|
||||
* ```
|
||||
* $> LOGOPS_LEVEL=DEBUG node app.js
|
||||
* ```
|
||||
*
|
||||
* @param level one of 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'
|
||||
*/
|
||||
setLevel(level: Level): void;
|
||||
|
||||
/**
|
||||
* Sets a global context that should be printed and merged with specific
|
||||
* log context props
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* logops.setContextGetter(function getContext() {
|
||||
* return {
|
||||
* hostname: require('os').hostname,
|
||||
* pid: process.pid
|
||||
* };
|
||||
* });
|
||||
*
|
||||
* logger.info({app: 'server'}, 'Startup');
|
||||
* // {"hostname":"host.local","pid":35502,"app":"server","time":"2015-12-23T11:47:25.862Z","lvl":"INFO","msg":"Startup"}
|
||||
* ```
|
||||
* @return The context object
|
||||
*/
|
||||
setContextGetter(getContext: () => Context): void;
|
||||
getContext(): Context;
|
||||
|
||||
/**
|
||||
* Specifies the Formatter used for printing traces
|
||||
* @example
|
||||
* ```
|
||||
* logops.setFormat(logops.formatters.dev);
|
||||
* ```
|
||||
*
|
||||
* You can also set the format specifying the formatter with `LOGOPS_FORMAT` environment variable:
|
||||
* @example
|
||||
* ```
|
||||
* $> LOGOPS_FORMAT=json node app.js
|
||||
* ```
|
||||
*/
|
||||
setFormat(format: Formatter): void;
|
||||
format: Formatter;
|
||||
|
||||
/**
|
||||
* Creates a child logger with the this logger settings that will append the
|
||||
* passed context to the parent one (if any)
|
||||
* ```
|
||||
* let child = logger.child({hostname: 'host.local'});
|
||||
* child.info({app: 'server'}, 'Startup');
|
||||
* // {"hostname":"host.local","app":"server","time":"2015-12-23T11:47:25.862Z","lvl":"INFO","msg":"Startup"}
|
||||
* ```
|
||||
*/
|
||||
child(context?: Context): Logops;
|
||||
|
||||
/**
|
||||
* The available formatters
|
||||
*/
|
||||
formatters: Formatters;
|
||||
|
||||
/**
|
||||
* Logs a debug trace with the provided Context
|
||||
* ```
|
||||
* logger.debug({ip: '127.0.0.0'}, 'Something went wrong');
|
||||
* // {"ip":"127.0.0.0","time":"2015-12-22T16:33:17.002Z","lvl":"DEBUG","msg":"Something went wrong"}
|
||||
* ```
|
||||
*
|
||||
* @param props the Context to print
|
||||
* @param format A printf-like format string as you will use in console.log()
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
debug(props: Context, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs an Error as a debug trace.
|
||||
* See Logops.stacktracesWith to print the stack traces
|
||||
* ```
|
||||
* logger.debug(new Error('Out of memory'), 'SYSTEM UNSTABLE. BYE');
|
||||
* ```
|
||||
*
|
||||
* @param error the Error to serialize and print
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* If not present, the message will be the Error message itself
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
debug(error: Error, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a debug trace, as you will do with console.log
|
||||
* ```
|
||||
* logger.debug('Request %s %d %j', 'is', 5, {key: 'value'}, 'guy');
|
||||
* // {"time":"2015-12-22T16:31:56.184Z","lvl":"DEBUG","msg":"Request is 5 {\"key\":\"value\"} guy"}
|
||||
* ```
|
||||
*
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
debug(format: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs an info trace with the provided Context
|
||||
* ```
|
||||
* logger.info({ip: '127.0.0.0'}, 'Something went wrong');
|
||||
* // {"ip":"127.0.0.0","time":"2015-12-22T16:33:17.002Z","lvl":"INFO","msg":"Something went wrong"}
|
||||
* ```
|
||||
*
|
||||
* @param props the Context to print
|
||||
* @param format A printf-like format string as you will use in console.log()
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
|
||||
info(props: Context, format?: string, ...params: any[]): void;
|
||||
/**
|
||||
* Logs an Error as a info trace.
|
||||
* See Logops.stacktracesWith to print the stack traces
|
||||
* ```
|
||||
* logger.info(new Error('Out of memory'), 'SYSTEM UNSTABLE. BYE');
|
||||
* ```
|
||||
*
|
||||
* @param error the Error to serialize and print
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* If not present, the message will be the Error message itself
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
info(error: Error, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a info trace, as you will do with console.log
|
||||
* ```
|
||||
* logger.info('Request %s %d %j', 'is', 5, {key: 'value'}, 'guy');
|
||||
* // {"time":"2015-12-22T16:31:56.184Z","lvl":"INFO","msg":"Request is 5 {\"key\":\"value\"} guy"}
|
||||
* ```
|
||||
*
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
info(format: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a warning trace with the provided Context
|
||||
* ```
|
||||
* logger.warn({ip: '127.0.0.0'}, 'Something went wrong');
|
||||
* // {"ip":"127.0.0.0","time":"2015-12-22T16:33:17.002Z","lvl":"WARN","msg":"Something went wrong"}
|
||||
* ```
|
||||
*
|
||||
* @param props the Context to print
|
||||
* @param format A printf-like format string as you will use in console.log()
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
|
||||
warn(props: Context, format?: string, ...params: any[]): void;
|
||||
/**
|
||||
* Logs an Error as a warn trace.
|
||||
* See Logops.stacktracesWith to print the stack traces
|
||||
* ```
|
||||
* logger.warn(new Error('Out of memory'), 'SYSTEM UNSTABLE. BYE');
|
||||
* ```
|
||||
*
|
||||
* @param error the Error to serialize and print
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* If not present, the message will be the Error message itself
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
warn(error: Error, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a warn trace, as you will do with console.log
|
||||
* ```
|
||||
* logger.warn('Request %s %d %j', 'is', 5, {key: 'value'}, 'guy');
|
||||
* // {"time":"2015-12-22T16:31:56.184Z","lvl":"WARN","msg":"Request is 5 {\"key\":\"value\"} guy"}
|
||||
* ```
|
||||
*
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
warn(format: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs an error trace with the provided Context
|
||||
* ```
|
||||
* logger.error({ip: '127.0.0.0'}, 'Something went wrong');
|
||||
* // {"ip":"127.0.0.0","time":"2015-12-22T16:33:17.002Z","lvl":"ERROR","msg":"Something went wrong"}
|
||||
* ```
|
||||
*
|
||||
* @param props the Context to print
|
||||
* @param format A printf-like format string as you will use in console.log()
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
error(props: Context, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs an Error as an error trace.
|
||||
* See Logops.stacktracesWith to print the stack traces
|
||||
* ```
|
||||
* logger.error(new Error('Out of memory'), 'SYSTEM UNSTABLE. BYE');
|
||||
* ```
|
||||
*
|
||||
* @param error the Error to serialize and print
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* If not present, the message will be the Error message itself
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
error(error: Error, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a error trace, as you will do with console.log
|
||||
* ```
|
||||
* logger.error('Request %s %d %j', 'is', 5, {key: 'value'}, 'guy');
|
||||
* // {"time":"2015-12-22T16:31:56.184Z","lvl":"ERROR","msg":"Request is 5 {\"key\":\"value\"} guy"}
|
||||
* ```
|
||||
*
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
error(format: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a fatal trace with the provided Context
|
||||
* ```
|
||||
* logger.fatal({ip: '127.0.0.0'}, 'Something went wrong');
|
||||
* // {"ip":"127.0.0.0","time":"2015-12-22T16:33:17.002Z","lvl":"FATAL","msg":"Something went wrong"}
|
||||
* ```
|
||||
*
|
||||
* @param props the Context to print
|
||||
* @param format A printf-like format string as you will use in console.log()
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
fatal(props: Context, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs an Error as a debug trace.
|
||||
* See Logops.stacktracesWith to print the stack traces
|
||||
* ```
|
||||
* logger.fatal(new Error('Out of memory'), 'SYSTEM UNSTABLE. BYE');
|
||||
* ```
|
||||
*
|
||||
* @param error the Error to serialize and print
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* If not present, the message will be the Error message itself
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
fatal(error: Error, format?: string, ...params: any[]): void;
|
||||
|
||||
/**
|
||||
* Logs a fatal trace, as you will do with console.log
|
||||
* ```
|
||||
* logger.fatal('Request %s %d %j', 'is', 5, {key: 'value'}, 'guy');
|
||||
* // {"time":"2015-12-22T16:31:56.184Z","lvl":"FATAL","msg":"Request is 5 {\"key\":\"value\"} guy"}
|
||||
* ```
|
||||
*
|
||||
* @param format A printf-like format string as you will use in console.log().
|
||||
* @param params Additional properties to be coerced in the format string
|
||||
*/
|
||||
fatal(format: string, ...params: any[]): void;
|
||||
}
|
||||
|
||||
declare let logops: Logops;
|
||||
|
||||
export = logops;
|
||||
|
||||
/**
|
||||
* Log levels
|
||||
*/
|
||||
type Level = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL';
|
||||
|
||||
/**
|
||||
* A key value map that should be printed and serialized as first class
|
||||
* citizien in the traces.
|
||||
*/
|
||||
interface Context {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for a logops formatter, that formats the user input as a readable
|
||||
* string ready to be written to a Stream
|
||||
*/
|
||||
interface Formatter {
|
||||
/**
|
||||
* Format the user input as a readable string ready to be written to a Stream
|
||||
* @param level One of the following values
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
* @param context Additional information to add to the trace
|
||||
* @param message The main message to be added to the trace
|
||||
* @param args More arguments provided to the log function
|
||||
* @param err A cause error used to log extra information
|
||||
*/
|
||||
format(level: string, context: Context, message: string, args: any[], err?: Error): string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The additional properties in a DevFormatter
|
||||
*/
|
||||
interface DevFormatter extends Formatter {
|
||||
/**
|
||||
* Context properties keys that should be skipped from printing in dev format
|
||||
*/
|
||||
omit: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* The formatters interface. All relative to customization of how a trace
|
||||
* is printed is located here
|
||||
*/
|
||||
interface Formatters {
|
||||
/**
|
||||
* Formats a trace message in JSON format
|
||||
*/
|
||||
json: Formatter;
|
||||
/**
|
||||
* Formats a trace message with some nice TTY colors
|
||||
*/
|
||||
dev: DevFormatter;
|
||||
/**
|
||||
* Formats a trace message with fields separated by pipes.
|
||||
* @deprecated
|
||||
*/
|
||||
pipe: Formatter;
|
||||
/**
|
||||
* Array of logger levels that will print error stacktraces
|
||||
* Defaults to `['ERROR', 'FATAL']
|
||||
*/
|
||||
stacktracesWith: Level[];
|
||||
/**
|
||||
* Sets a value for those fields that are not available in the context. This field
|
||||
* will only be used in the 'pipes' formatter.
|
||||
*
|
||||
* @param str New value for not available fields.
|
||||
* @deprecated
|
||||
*/
|
||||
setNotAvailable(str: string): void;
|
||||
}
|
||||
276
node_modules/logops/lib/logops.js
generated
vendored
Normal file
276
node_modules/logops/lib/logops.js
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const formatters = require('./formatters');
|
||||
|
||||
const levels = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'];
|
||||
const DEFAULT_LEVEL = 'INFO';
|
||||
|
||||
module.exports = logops();
|
||||
|
||||
function noop() {};
|
||||
|
||||
function logops(options) {
|
||||
let opts = merge({
|
||||
level: process.env.LOGOPS_LEVEL || DEFAULT_LEVEL,
|
||||
format: formatters[process.env.LOGOPS_FORMAT] || (process.env.NODE_ENV === 'development' ?
|
||||
formatters.dev :
|
||||
formatters.json
|
||||
),
|
||||
getContext: noop,
|
||||
stream: process.stdout,
|
||||
}, options);
|
||||
|
||||
let API = {};
|
||||
/**
|
||||
* Internal private function that implements a decorator to all
|
||||
* the level functions.
|
||||
*
|
||||
* @param {String} level one of
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
*/
|
||||
function logWrap(level) {
|
||||
return function log() {
|
||||
let context, message, args, trace, err;
|
||||
|
||||
if (arguments[0] instanceof Error) {
|
||||
// log.<level>(err, ...)
|
||||
context = API.getContext();
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
if (!args.length) {
|
||||
// log.<level>(err)
|
||||
err = arguments[0];
|
||||
message = err.name + ': ' + err.message;
|
||||
} else {
|
||||
// log.<level>(err, "More %s", "things")
|
||||
// Use the err as context information
|
||||
err = arguments[0];
|
||||
message = arguments[1];
|
||||
args = Array.prototype.slice.call(args, 1);
|
||||
}
|
||||
} else if (arguments[0] == null || (typeof (arguments[0]) !== 'object' && arguments[0] !== null) ||
|
||||
Array.isArray(arguments[0])) {
|
||||
// log.<level>(msg, ...)
|
||||
context = API.getContext();
|
||||
message = arguments[0];
|
||||
args = Array.prototype.slice.call(arguments, 1);
|
||||
} else {
|
||||
// log.<level>(fields, msg, ...)
|
||||
context = merge(API.getContext(), arguments[0]);
|
||||
message = arguments[1];
|
||||
args = Array.prototype.slice.call(arguments, 2);
|
||||
}
|
||||
|
||||
trace = API.format(level, context || {}, message, args, err);
|
||||
API.stream.write(trace + '\n');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled logging level.
|
||||
* All the disabled logging methods are replaced by a noop,
|
||||
* so there is not any performance penalty at production using an undesired level
|
||||
*
|
||||
* @param {String} level
|
||||
*/
|
||||
function setLevel(level) {
|
||||
opts.level = level;
|
||||
let logLevelIndex = levels.indexOf(opts.level.toUpperCase());
|
||||
|
||||
levels.forEach((logLevel) => {
|
||||
let fn;
|
||||
if (logLevelIndex <= levels.indexOf(logLevel)) {
|
||||
fn = logWrap(logLevel);
|
||||
} else {
|
||||
fn = noop;
|
||||
}
|
||||
API[logLevel.toLowerCase()] = fn;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The exported API.
|
||||
* The following methods are added dynamically
|
||||
* API.debug
|
||||
* API.info
|
||||
* API.warn
|
||||
* API.error
|
||||
* API.fatal
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
API = {
|
||||
/**
|
||||
* The stream where the logger will write string traces
|
||||
* Defaults to process.stdout
|
||||
*/
|
||||
stream: opts.stream,
|
||||
setStream: (stream) => {
|
||||
API.stream = stream;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the enabled logging level.
|
||||
* All the disabled logging methods are replaced by a noop,
|
||||
* so there is not any performance penalty at production using an undesired level
|
||||
*
|
||||
* @param {String} level one of the following values
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
*/
|
||||
setLevel: setLevel,
|
||||
|
||||
/**
|
||||
* Gets the current log level.
|
||||
*/
|
||||
getLevel: () => opts.level,
|
||||
|
||||
/**
|
||||
* Gets the context for a determinate trace. By default, this is a noop that
|
||||
* you can override if you are managing your execution context with node domains
|
||||
*
|
||||
* This function must return an object with the following fields
|
||||
* {
|
||||
* corr: {String},
|
||||
* trans: {String},
|
||||
* op: {String}
|
||||
* }
|
||||
*
|
||||
* If you are not using domain, you should pass the context information for
|
||||
* EVERY log call
|
||||
*
|
||||
* Both examples will produce the same trace
|
||||
*
|
||||
* Example usage not using getContext:
|
||||
* var logger = require('logops');
|
||||
* req.context = {
|
||||
* corr: 'cbefb082-3429-4f5c-aafd-26b060d6a9fc',
|
||||
* trans: 'cbefb082-3429-4f5c-aafd-26b060d6a9fc',
|
||||
* op: 'SendEMail'
|
||||
* }
|
||||
* logger.info(req.context, 'This is an example');
|
||||
*
|
||||
* Example using this feature:
|
||||
* var logger = require('logops'),
|
||||
* domain = require('domain');
|
||||
*
|
||||
* logger.getContext = function domainContext() {
|
||||
* return domain.active.myCustomContext;
|
||||
* }
|
||||
* //...
|
||||
*
|
||||
* logger.info('This is an example');
|
||||
*
|
||||
* @return {Object} The context object
|
||||
*/
|
||||
getContext: opts.getContext,
|
||||
setContextGetter: (fn) => {
|
||||
API.getContext = fn;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a string representation for a trace.
|
||||
*
|
||||
* It checks the `LOGOPS_FORMAT` environment variable to use the built-in
|
||||
* format functions. It fallbacks to check the de-facto `NODE_ENV` env var
|
||||
* to use the `formatters.dev` when the value is `development`. Otherwise, it
|
||||
* will use the `formatters.pipe` (while in production, for example)
|
||||
*
|
||||
* Example
|
||||
* NODE_ENV=development node index.js
|
||||
* the logger will write traces for developers
|
||||
*
|
||||
* node index.js
|
||||
* the logger will write traces in a pipe format (assuming NODE_ENV nor
|
||||
* LOGOPS_FORMAT environment vars are defined with valid values)
|
||||
*
|
||||
* LOGOPS_FORMAT=json node index.js
|
||||
* the logger will write json traces
|
||||
*
|
||||
* You can override this func and manage by yourself the formatting.
|
||||
*
|
||||
* @param {String} level One of the following values
|
||||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
||||
* @param {Object} context Additional information to add to the trace
|
||||
* @param {String} message The main message to be added to the trace
|
||||
* @param {Array} args More arguments provided to the log function
|
||||
*
|
||||
* @return {String} The trace formatted
|
||||
*/
|
||||
format: opts.format,
|
||||
setFormat: (format) => {
|
||||
API.format = format;
|
||||
},
|
||||
/**
|
||||
* Return an Object containing the available formatters ("dev", "pipe", "json").
|
||||
*
|
||||
* Example using this feature to write JSON logs.
|
||||
*
|
||||
* var logger = require('logops');
|
||||
* logger.format = logger.formatters.json;
|
||||
* logger.info('This is an example')
|
||||
*
|
||||
* @return {Object} The available formatters.
|
||||
*/
|
||||
formatters: formatters,
|
||||
|
||||
/**
|
||||
* Creates a child logger with the this logger settings that will append the
|
||||
* passed context to the parent one (if any)
|
||||
* ```
|
||||
* let child = logger.child({hostname: 'host.local'});
|
||||
* child.info({app: 'server'}, 'Startup');
|
||||
* // {"hostname":"host.local","app":"server","time":"2015-12-23T11:47:25.862Z","lvl":"INFO","msg":"Startup"}
|
||||
* ```
|
||||
*/
|
||||
child: (localContext) => {
|
||||
// the current limitation for this approach is that child
|
||||
// loggers will overwrite the parent and localcontext when
|
||||
// calling againg `child.setContextGetter(fn)` or assign a function
|
||||
// to `child.getContext = fn`
|
||||
// But as the context is specified then creating the child, we can
|
||||
// considerer it a corner case and dont optimize for the use case
|
||||
return logops({
|
||||
level: API.getLevel(),
|
||||
getContext: () => merge(API.getContext(), localContext),
|
||||
format: API.format,
|
||||
stream: API.stream,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
setLevel(opts.level);
|
||||
return API;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges accesible properties in two objects.
|
||||
* obj2 takes precedence when common properties are found
|
||||
*
|
||||
* @param {Object} obj1
|
||||
* @param {Object} obj2
|
||||
* @returns {{}} The merged, new, object
|
||||
*/
|
||||
function merge(obj1, obj2) {
|
||||
var res = {}, attrname;
|
||||
|
||||
for (attrname in obj1) {
|
||||
res[attrname] = obj1[attrname];
|
||||
}
|
||||
for (attrname in obj2) {
|
||||
res[attrname] = obj2[attrname];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
Reference in New Issue
Block a user