Comparing version 2.0.0 to 2.1.0
@@ -23,5 +23,5 @@ /** | ||
colors = require('colors/safe'), | ||
stringify = require('json-stringify-safe'), | ||
safeStringify = require('safe-json-stringify'), | ||
serializeErr = require('serr'), | ||
omit = require('lodash').omit; | ||
_ = require('lodash'); | ||
@@ -45,2 +45,3 @@ var DEFAULT_NOT_AVAILABLE = 'n/a'; | ||
}; | ||
/** | ||
@@ -97,9 +98,7 @@ * Sets a value for those fields that are not available in the context. This field | ||
str += colorize(colors.gray, serializeErr(err).toString(printStack).substr(mainMessage.length)); | ||
} else { | ||
if (err) { | ||
str += '\n' + colorize(colors.gray, serializeErr(err).toString(printStack)); | ||
} | ||
} else if (err) { | ||
str += '\n' + colorize(colors.gray, serializeErr(err).toString(printStack)); | ||
} | ||
var localContext = omit(context, formatDevTrace.omit); | ||
var localContext = _.omit(context, formatDevTrace.omit); | ||
str += Object.keys(localContext).length ? | ||
@@ -112,2 +111,3 @@ ' ' + colorize(colors.gray, util.inspect(localContext)) : | ||
} | ||
/** | ||
@@ -123,5 +123,3 @@ * Context properties that should be skipped from printing in dev format | ||
.split('\n') | ||
.map(function(part) { | ||
return color(part); | ||
}) | ||
.map(part => color(part)) | ||
.join('\n'); | ||
@@ -156,6 +154,6 @@ } | ||
Object.keys(context) | ||
.filter(function(key) { | ||
.filter((key) => { | ||
return !(context[key] && Object.prototype.toString.call(context[key]) === '[object Function]'); | ||
}) | ||
.forEach(function(key) { | ||
.forEach((key) => { | ||
recontext[key] = context[key] || notAvailable; | ||
@@ -172,5 +170,3 @@ }); | ||
var str = Object.keys(recontext) | ||
.map(function(key) { | ||
return key + '=' + recontext[key]; | ||
}) | ||
.map((key) => key + '=' + recontext[key]) | ||
.join(' | '); | ||
@@ -202,8 +198,13 @@ | ||
formatJsonTrace.stringify = stringify; | ||
formatJsonTrace.toObject = function toObject(level, context, message, args, err) { | ||
var log = {}, | ||
printStack = API.stacktracesWith.indexOf(level) > -1; | ||
formatJsonTrace.stringify = (obj) => { | ||
try { | ||
return JSON.stringify(obj); | ||
} catch (err) { | ||
return safeStringify(obj); | ||
} | ||
}; | ||
formatJsonTrace.toObject = (level, context, message, args, err) => { | ||
let log = {}; | ||
for (var attrname in context) { | ||
for (let attrname in context) { | ||
log[attrname] = context[attrname]; | ||
@@ -214,3 +215,3 @@ } | ||
log.lvl = level; | ||
log.err = err && serializeErr(err).toObject(printStack); | ||
log.err = err && serializeErr(err).toObject(API.stacktracesWith.indexOf(level) > -1); | ||
log.msg = util.format.apply(global, [message].concat(args)); | ||
@@ -217,0 +218,0 @@ |
/** Simple and performant nodejs JSON logger */ | ||
/** | ||
* The NODEJS stream where the logger will write string traces | ||
* Defaults to process.stdout | ||
*/ | ||
export function setStream(stream: NodeJS.WritableStream): void; | ||
export let stream: NodeJS.WritableStream; | ||
/** | ||
* Log levels | ||
*/ | ||
type Level = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL'; | ||
/** | ||
* Gets the current log level. The default level is INFO | ||
*/ | ||
export function getLevel(): Level; | ||
interface Logops { | ||
/** | ||
* The NODEJS stream where the logger will write string traces | ||
* Defaults to process.stdout | ||
*/ | ||
setStream(stream: NodeJS.WritableStream): void; | ||
stream: NodeJS.WritableStream; | ||
/** | ||
* 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' | ||
*/ | ||
export function setLevel(level: Level): void; | ||
/** | ||
* Gets the current log level. The default level is INFO | ||
*/ | ||
getLevel(): Level; | ||
/** | ||
* 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 | ||
*/ | ||
export function setContextGetter(getContext: () => Context): void; | ||
export function getContext(): Context; | ||
/** | ||
* 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; | ||
/** | ||
* 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 | ||
* ``` | ||
*/ | ||
export function setFormat(format: Formatter): void; | ||
export let format: Formatter; | ||
/** | ||
* 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; | ||
/** | ||
* The available formatters | ||
*/ | ||
export let formatters: Formatters; | ||
/** | ||
* 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; | ||
/** | ||
* 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 | ||
*/ | ||
export function debug(props:Context, format?:string, ...params:any[]): void; | ||
/** | ||
* 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; | ||
/** | ||
* 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 | ||
*/ | ||
export function debug(error:Error, format?:string, ...params:any[]): void; | ||
/** | ||
* The available formatters | ||
*/ | ||
formatters: Formatters; | ||
/** | ||
* 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 | ||
*/ | ||
export function debug(format:string, ...params:any[]): void; | ||
/** | ||
* 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 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 | ||
*/ | ||
/** | ||
* 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; | ||
export function 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 | ||
*/ | ||
export function info(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 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 | ||
*/ | ||
export function info(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 | ||
*/ | ||
/** | ||
* 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 | ||
*/ | ||
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; | ||
export function 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 | ||
*/ | ||
export function warn(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 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 | ||
*/ | ||
export function warn(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 | ||
*/ | ||
/** | ||
* 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 | ||
*/ | ||
export function error(props:Context, format?:string, ...params:any[]): void; | ||
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 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 | ||
*/ | ||
export function error(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 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 | ||
*/ | ||
export function error(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 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 | ||
*/ | ||
export function fatal(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 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 | ||
*/ | ||
export function fatal(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; | ||
/** | ||
* 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 | ||
* Log levels | ||
*/ | ||
export function fatal(format:string, ...params:any[]): void; | ||
type Level = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'FATAL'; | ||
@@ -274,3 +293,3 @@ /** | ||
interface Context { | ||
[key: string]: any; | ||
[key: string]: any; | ||
} | ||
@@ -283,12 +302,12 @@ | ||
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; | ||
/** | ||
* 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; | ||
} | ||
@@ -300,6 +319,6 @@ | ||
interface DevFormatter extends Formatter { | ||
/** | ||
* Context properties keys that should be skipped from printing in dev format | ||
*/ | ||
omit: string[]; | ||
/** | ||
* Context properties keys that should be skipped from printing in dev format | ||
*/ | ||
omit: string[]; | ||
} | ||
@@ -312,28 +331,28 @@ | ||
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; | ||
/** | ||
* 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; | ||
} |
@@ -17,59 +17,241 @@ /** | ||
*/ | ||
const formatters = require('./formatters'); | ||
'use strict'; | ||
const levels = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']; | ||
const DEFAULT_LEVEL = 'INFO'; | ||
var formatters = require('./formatters'); | ||
module.exports = logops(); | ||
var levels = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'], | ||
currentLevel, | ||
DEFAULT_LEVEL = 'INFO', | ||
API = {}; | ||
function noop() {}; | ||
/* | ||
* Shorcuts | ||
*/ | ||
var toString = Object.prototype.toString, | ||
noop = 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); | ||
/** | ||
* 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) { | ||
var context, message, args, trace, err; | ||
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[1] instanceof Error) { | ||
// log.<level>(err, ...) | ||
context = API.getContext(); | ||
args = Array.prototype.slice.call(arguments, 2); | ||
if (!args.length) { | ||
// log.<level>(err) | ||
err = arguments[1]; | ||
message = err.name + ': ' + err.message; | ||
} else { | ||
// log.<level>(err, "More %s", "things") | ||
// Use the err as context information | ||
err = arguments[1]; | ||
message = arguments[2]; | ||
args = Array.prototype.slice.call(args, 1); | ||
} | ||
} else if ((typeof (arguments[1]) !== 'object' && arguments[1] !== null) || | ||
arguments[1] == null || | ||
Array.isArray(arguments[1])) { | ||
// log.<level>(msg, ...) | ||
context = API.getContext(); | ||
message = arguments[1]; | ||
args = Array.prototype.slice.call(arguments, 2); | ||
} else { | ||
// log.<level>(fields, msg, ...) | ||
context = merge(API.getContext(), arguments[1]); | ||
message = arguments[2]; | ||
args = Array.prototype.slice.call(arguments, 3); | ||
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'); | ||
}; | ||
} | ||
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; | ||
} | ||
@@ -87,2 +269,3 @@ | ||
var res = {}, attrname; | ||
for (attrname in obj1) { | ||
@@ -96,165 +279,1 @@ res[attrname] = obj1[attrname]; | ||
} | ||
/** | ||
* 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) { | ||
currentLevel = level || DEFAULT_LEVEL; | ||
var logLevelIndex = levels.indexOf(currentLevel.toUpperCase()); | ||
levels.forEach(function(logLevel) { | ||
var fn; | ||
if (logLevelIndex <= levels.indexOf(logLevel)) { | ||
fn = logWrap.bind(global, logLevel); | ||
} else { | ||
fn = noop; | ||
} | ||
API[logLevel.toLowerCase()] = fn; | ||
}); | ||
} | ||
/** | ||
* Gets the current log level. | ||
* | ||
* @return {String} One of the following values | ||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'] | ||
*/ | ||
function getLevel() { | ||
return currentLevel || DEFAULT_LEVEL; | ||
} | ||
/** | ||
* The exported API. | ||
* The following methods are added dynamically | ||
* API.debug | ||
* API.info | ||
* API.warn | ||
* API.error | ||
* API.fatal | ||
* | ||
* @type {Object} | ||
*/ | ||
module.exports = API = { | ||
/** | ||
* The stream where the logger will write string traces | ||
* Defaults to process.stdout | ||
*/ | ||
stream: process.stdout, | ||
setStream: function(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. | ||
* | ||
* @return {String} One of the following values | ||
* ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'] | ||
*/ | ||
getLevel: getLevel, | ||
/** | ||
* 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: noop, | ||
setContextGetter: function(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: formatters[process.env.LOGOPS_FORMAT] || | ||
(process.env.NODE_ENV === 'development' ? formatters.dev : formatters.json), | ||
setFormat: function(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 | ||
}; | ||
setLevel(process.env.LOGOPS_LEVEL); |
{ | ||
"name": "logops", | ||
"description": "Simple and performant nodejs JSON logger", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"homepage": "https://github.com/telefonicaid/logops", | ||
@@ -36,11 +36,11 @@ "license": "Apache-2.0", | ||
"coveralls": "^2.11.2", | ||
"eslint": "^2.2.0", | ||
"eslint": "^3.19.0", | ||
"istanbul": "^0.4.0", | ||
"jscs": "^3.0.3", | ||
"mocha": "^2.2.5", | ||
"mocha": "^3.3.0", | ||
"release-it": "^2.3.1", | ||
"sinon": "^1.15.0", | ||
"sinon": "^2.2.0", | ||
"sinon-chai": "^2.8.0", | ||
"tslint": "^3.14.0", | ||
"tslint-config-typings": "^0.2.3", | ||
"tslint": "^5.2.0", | ||
"tslint-config-typings": "^0.3.1", | ||
"typescript": "^2.0.3" | ||
@@ -55,4 +55,4 @@ }, | ||
"colors": "^1.1.2", | ||
"json-stringify-safe": "^5.0.1", | ||
"lodash": "^4.1.0", | ||
"safe-json-stringify": "^1.0.4", | ||
"serr": "^1.0.0" | ||
@@ -59,0 +59,0 @@ }, |
@@ -54,5 +54,6 @@ # logops | ||
## Context support | ||
Logops supports using global properties that will be merged with the specific ones defined in the call. Simply override the `logger.getContext` method to let the logger to get it. | ||
Logops supports using global properties that will be merged with the specific ones defined in the call. Simply override the `logger.getContext` method to let the logger get it. See `logops.child` to see how to also create loggers with context | ||
@@ -125,2 +126,25 @@ ```js | ||
## Child Loggers | ||
You can create an specialized logger for a part of your app with bound static context/properties. The child logger | ||
will inherit its parent config: level, format, stream and context. If the parent logger has a context returned by `parent.getContext()`, the conflicting child logger context will take precedence | ||
```js | ||
let child = logger.child({component: 'client'}); | ||
child.info('Startup'); | ||
// {"component":"client","time":"2015-12-23T11:47:25.862Z","lvl":"INFO","msg":"Startup"} | ||
``` | ||
**TIP: Using with express/connect** | ||
You can create a simply middleware to add a logger to every request with something like | ||
```js | ||
app.use(function(req, res, next) { | ||
req.logger = logger.child({ | ||
requestId: uuid.v4() | ||
}); | ||
next(); | ||
}); | ||
``` | ||
So your `req.logger` will log the requestId to allow correlation of traces in your server traces. | ||
_Note: setting `child.getContext` property, will override the context used to create the logger and its merge with its parent one. So you can use it to create a context free logger_ | ||
## Advanced Usage | ||
@@ -203,19 +227,15 @@ | ||
Running on a MAC OS X Yosemite, 2,5 GHz Intel Core i5, 8 GB 1333 MHz DDR3, SSD disk, node 4.2.2 | ||
Running on a MAC OS X Yosemite, 2,5 GHz Intel Core i5, 8 GB 1333 MHz DDR3, SSD disk, node 6.10.0 | ||
``` | ||
$ cd benchmark; npm start | ||
> benchmarklogops@1.0.0 start /Users/javier/Documents/Proyectos/logops/benchmark | ||
> npm run tee && npm run file && npm run null && rm out.log | ||
> benchmarklogops@1.0.0 tee /Users/javier/Documents/Proyectos/logops/benchmark | ||
> node index.js | tee -a out.log > /dev/null | ||
logops x 39,560 ops/sec ±3.00% (75 runs sampled) | ||
bunyan x 27,365 ops/sec ±2.23% (79 runs sampled) | ||
Basic logging: Fastest is logops | ||
logops x 73,150,310 ops/sec ±1.64% (79 runs sampled) | ||
bunyan x 1,569,549 ops/sec ±3.67% (78 runs sampled) | ||
logops x 70,675 ops/sec ±11.89% (65 runs sampled) | ||
bunyan x 81,981 ops/sec ±4.76% (70 runs sampled) | ||
Basic logging: Fastest is bunyan,logops | ||
logops x 67,169,402 ops/sec ±2.79% (80 runs sampled) | ||
bunyan x 5,774,822 ops/sec ±5.74% (75 runs sampled) | ||
Disabled logging: Fastest is logops | ||
@@ -226,7 +246,7 @@ | ||
logops x 43,136 ops/sec ±1.31% (82 runs sampled) | ||
bunyan x 28,653 ops/sec ±1.05% (84 runs sampled) | ||
logops x 37,479 ops/sec ±5.69% (76 runs sampled) | ||
bunyan x 36,211 ops/sec ±2.72% (77 runs sampled) | ||
Basic logging: Fastest is logops | ||
logops x 80,439,813 ops/sec ±1.17% (85 runs sampled) | ||
bunyan x 1,645,447 ops/sec ±1.66% (85 runs sampled) | ||
logops x 70,740,515 ops/sec ±1.71% (82 runs sampled) | ||
bunyan x 6,324,283 ops/sec ±2.68% (78 runs sampled) | ||
Disabled logging: Fastest is logops | ||
@@ -237,7 +257,7 @@ | ||
logops x 52,947 ops/sec ±1.80% (80 runs sampled) | ||
bunyan x 33,696 ops/sec ±0.96% (84 runs sampled) | ||
logops x 49,509 ops/sec ±4.92% (77 runs sampled) | ||
bunyan x 47,759 ops/sec ±4.34% (69 runs sampled) | ||
Basic logging: Fastest is logops | ||
logops x 77,479,942 ops/sec ±1.47% (79 runs sampled) | ||
bunyan x 1,411,108 ops/sec ±1.92% (85 runs sampled) | ||
logops x 68,293,618 ops/sec ±2.64% (80 runs sampled) | ||
bunyan x 6,232,825 ops/sec ±2.42% (81 runs sampled) | ||
Disabled logging: Fastest is logops | ||
@@ -244,0 +264,0 @@ ``` |
Sorry, the diff of this file is not supported yet
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
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
149427
768
270
+ Addedsafe-json-stringify@^1.0.4
+ Addedsafe-json-stringify@1.2.0(transitive)
- Removedjson-stringify-safe@^5.0.1
- Removedjson-stringify-safe@5.0.1(transitive)