ecs-logs-js
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -12,3 +12,3 @@ declare const LEVELS_MAP: { | ||
/** Available log levels. */ | ||
export declare type LEVEL = keyof typeof LEVELS_MAP; | ||
export type LEVEL = keyof typeof LEVELS_MAP; | ||
/** Options that can be passed to the Logger constructor. */ | ||
@@ -20,3 +20,3 @@ export interface LoggerOptions { | ||
*/ | ||
level?: LEVEL | string; | ||
level?: LEVEL; | ||
/** | ||
@@ -39,3 +39,3 @@ * Enables the human friendly development output. | ||
*/ | ||
log: (level: "emerg" | "alert" | "crit" | "error" | "warn" | "notice" | "info" | "debug", message: string, data?: unknown) => void; | ||
log: (level: LEVEL, message: string, data?: unknown) => void; | ||
/** | ||
@@ -42,0 +42,0 @@ * Logs a message at the EMERG log level. |
@@ -6,2 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Logger = void 0; | ||
const fast_safe_stringify_1 = __importDefault(require("fast-safe-stringify")); | ||
@@ -29,2 +30,12 @@ const serialize_error_1 = require("serialize-error"); | ||
} | ||
class ErrorArrayStack { | ||
stack; | ||
message; | ||
name; | ||
constructor(message, stack) { | ||
this.message = message; | ||
this.name = 'ErrorArrayStack'; | ||
this.stack = stack; | ||
} | ||
} | ||
/** JSON.stringify replacer that converts unstringifyable values to stringifyable ones */ | ||
@@ -43,7 +54,12 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
if (value instanceof Error) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const serializedError = serialize_error_1.serializeError(value); | ||
const serializedError = (0, serialize_error_1.serializeError)(value); | ||
// Tidy up the stack trace a bit and convert it to an array | ||
serializedError.stack = extract_stack_1.default.lines(value); | ||
return serializedError; | ||
const s = new ErrorArrayStack(serializedError.message || '', extract_stack_1.default.lines(value)); | ||
for (const key in value) { | ||
if (Object.prototype.hasOwnProperty.call(value, key) && key !== 'message' && key !== 'stack' && key !== 'name') { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment | ||
s[key] = value[key]; | ||
} | ||
} | ||
return s; | ||
} | ||
@@ -54,115 +70,5 @@ return value; | ||
class Logger { | ||
level = 'debug'; | ||
devMode = process.env.NODE_ENV === 'development'; | ||
constructor(options = {}) { | ||
this.level = 'debug'; | ||
this.devMode = process.env.NODE_ENV === 'development'; | ||
/** | ||
* Logs a message at the given log level. | ||
* @param level Log level for the message. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.log = (level, message, data) => { | ||
if (LEVELS_MAP[level] > LEVELS_MAP[this.level]) { | ||
return; | ||
} | ||
const logLineObject = { | ||
level: level.toUpperCase(), | ||
time: new Date().toISOString(), | ||
message, | ||
data, | ||
}; | ||
// Create JSON string with all the exotic values converted to JSON safe versions | ||
let logLine = fast_safe_stringify_1.default(logLineObject, jsonStringifyReplacer); | ||
// Format the logs in a human friendly way in development mode | ||
if (this.devMode) { | ||
// Construct the main log line and add some highlighting styles | ||
// Just parse the production log because it already has all the data conversions applied | ||
const log = JSON.parse(logLine); | ||
logLine = chalk_1.default.bold(`\n${log.level}: ${log.message}`); | ||
if (level === 'warn') { | ||
logLine = chalk_1.default.yellow(logLine); | ||
} | ||
else if (LEVELS_MAP[level] <= LEVELS_MAP.error) { | ||
logLine = chalk_1.default.red(logLine); | ||
} | ||
// Convert data to a compact and readable format | ||
if (log.data) { | ||
let data = js_yaml_1.default.safeDump(log.data, { schema: js_yaml_1.default.JSON_SCHEMA, lineWidth: Infinity }); | ||
// Indent the data slightly | ||
data = data | ||
.trim() | ||
.split('\n') | ||
.map((line) => ` ${line}`) | ||
.join('\n'); | ||
// Shorten the absolute file paths | ||
data = replace_string_1.default(data, process.cwd(), '.'); | ||
logLine += `\n${data}`; | ||
} | ||
} | ||
process.stdout.write(logLine + '\n'); | ||
}; | ||
/** | ||
* Logs a message at the EMERG log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.emerg = (message, data) => { | ||
this.log('emerg', message, data); | ||
}; | ||
/** | ||
* Logs a message at the ALERT log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.alert = (message, data) => { | ||
this.log('alert', message, data); | ||
}; | ||
/** | ||
* Logs a message at the CRIT log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.crit = (message, data) => { | ||
this.log('crit', message, data); | ||
}; | ||
/** | ||
* Logs a message at the ERROR log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.error = (message, data) => { | ||
this.log('error', message, data); | ||
}; | ||
/** | ||
* Logs a message at the WARN log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.warn = (message, data) => { | ||
this.log('warn', message, data); | ||
}; | ||
/** | ||
* Logs a message at the NOTICE log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.notice = (message, data) => { | ||
this.log('notice', message, data); | ||
}; | ||
/** | ||
* Logs a message at the INFO log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.info = (message, data) => { | ||
this.log('info', message, data); | ||
}; | ||
/** | ||
* Logs a message at the DEBUG log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
this.debug = (message, data) => { | ||
this.log('debug', message, data); | ||
}; | ||
if (options.level) { | ||
@@ -176,4 +82,114 @@ validateLevel(options.level); | ||
} | ||
/** | ||
* Logs a message at the given log level. | ||
* @param level Log level for the message. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
log = (level, message, data) => { | ||
if (LEVELS_MAP[level] > LEVELS_MAP[this.level]) { | ||
return; | ||
} | ||
const logLineObject = { | ||
level: level.toUpperCase(), | ||
time: new Date().toISOString(), | ||
message, | ||
data, | ||
}; | ||
// Create JSON string with all the exotic values converted to JSON safe versions | ||
let logLine = (0, fast_safe_stringify_1.default)(logLineObject, jsonStringifyReplacer); | ||
// Format the logs in a human friendly way in development mode | ||
if (this.devMode) { | ||
// Construct the main log line and add some highlighting styles | ||
// Just parse the production log because it already has all the data conversions applied | ||
const log = JSON.parse(logLine); | ||
logLine = chalk_1.default.bold(`\n${log.level}: ${log.message}`); | ||
if (level === 'warn') { | ||
logLine = chalk_1.default.yellow(logLine); | ||
} | ||
else if (LEVELS_MAP[level] <= LEVELS_MAP.error) { | ||
logLine = chalk_1.default.red(logLine); | ||
} | ||
// Convert data to a compact and readable format | ||
if (log.data) { | ||
let data = js_yaml_1.default.safeDump(log.data, { schema: js_yaml_1.default.JSON_SCHEMA, lineWidth: Infinity }); | ||
// Indent the data slightly | ||
data = data | ||
.trim() | ||
.split('\n') | ||
.map((line) => ` ${line}`) | ||
.join('\n'); | ||
// Shorten the absolute file paths | ||
data = (0, replace_string_1.default)(data, process.cwd(), '.'); | ||
logLine += `\n${data}`; | ||
} | ||
} | ||
process.stdout.write(logLine + '\n'); | ||
}; | ||
/** | ||
* Logs a message at the EMERG log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
emerg = (message, data) => { | ||
this.log('emerg', message, data); | ||
}; | ||
/** | ||
* Logs a message at the ALERT log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
alert = (message, data) => { | ||
this.log('alert', message, data); | ||
}; | ||
/** | ||
* Logs a message at the CRIT log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
crit = (message, data) => { | ||
this.log('crit', message, data); | ||
}; | ||
/** | ||
* Logs a message at the ERROR log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
error = (message, data) => { | ||
this.log('error', message, data); | ||
}; | ||
/** | ||
* Logs a message at the WARN log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
warn = (message, data) => { | ||
this.log('warn', message, data); | ||
}; | ||
/** | ||
* Logs a message at the NOTICE log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
notice = (message, data) => { | ||
this.log('notice', message, data); | ||
}; | ||
/** | ||
* Logs a message at the INFO log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
info = (message, data) => { | ||
this.log('info', message, data); | ||
}; | ||
/** | ||
* Logs a message at the DEBUG log level. | ||
* @param message The message to log. | ||
* @param data Any additional data to log with the message. This can be any type. | ||
*/ | ||
debug = (message, data) => { | ||
this.log('debug', message, data); | ||
}; | ||
} | ||
exports.Logger = Logger; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "ecs-logs-js", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Simple Node.js console logger that outputs human friendly and ecs-logs compatible messages", | ||
@@ -34,3 +34,3 @@ "author": "Roland Warmerdam (https://roland.codes)", | ||
"dependencies": { | ||
"chalk": "^3.0.0", | ||
"chalk": "^4.1.2", | ||
"extract-stack": "^2.0.0", | ||
@@ -43,11 +43,12 @@ "fast-safe-stringify": "^2.0.7", | ||
"devDependencies": { | ||
"@types/jest": "^25.1.4", | ||
"@babel/preset-typescript": "^7.23.3", | ||
"@types/jest": "^29.5.11", | ||
"@types/js-yaml": "^3.12.3", | ||
"@types/node": "^10", | ||
"@typescript-eslint/eslint-plugin": "^2.3.1", | ||
"@typescript-eslint/parser": "^2.3.1", | ||
"eslint": "^6.4.0", | ||
"eslint-config-prettier": "^6.3.0", | ||
"@types/node": "^20", | ||
"@typescript-eslint/eslint-plugin": "^6.14.0", | ||
"@typescript-eslint/parser": "^6.14.0", | ||
"eslint": "^8.55.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"husky": "^4.2.3", | ||
"jest": "^25.2.3", | ||
"jest": "^29.7.0", | ||
"jest-date-mock": "^1.0.8", | ||
@@ -57,5 +58,14 @@ "lint-staged": "^10.0.9", | ||
"rimraf": "^3.0.0", | ||
"ts-jest": "^25.2.1", | ||
"typescript": "^3.6.3" | ||
"ts-jest": "^29.1.1", | ||
"typescript": "^5.3.3" | ||
}, | ||
"resolutions": { | ||
"ansi-regex": "^5.0.1", | ||
"@babel/traverse": "^7.23.6", | ||
"@jest/schemas": "^29.6.3", | ||
"json-schema": "^0.4.0", | ||
"json5": "^2.2.3", | ||
"minimist": "^1.2.8", | ||
"strip-ansi": "^6.0.1" | ||
}, | ||
"eslintIgnore": [ | ||
@@ -70,4 +80,3 @@ "/dist/" | ||
"plugin:@typescript-eslint/recommended-requiring-type-checking", | ||
"prettier", | ||
"prettier/@typescript-eslint" | ||
"prettier" | ||
], | ||
@@ -74,0 +83,0 @@ "parserOptions": { |
# ecs-logs-js | ||
A simple Node.js console logger that outputs human friendly messages in development and [ecs-logs](https://github.com/segmentio/ecs-logs) compatible messages in production. Supports all object types, including those that can't be JSON stringified like Error, Map, Set and BigInt. | ||
> **Note** | ||
> | ||
> While this project remains available under its open source license for anyone | ||
> to use, we are not actively maintaining it, so issues and pull requests may be | ||
> ignored. | ||
A simple Node.js console logger that outputs human friendly messages in | ||
development and [ecs-logs](https://github.com/segmentio/ecs-logs) compatible | ||
messages in production. Supports all of Node's primitive data types, including | ||
those that can't be JSON stringified like Error, Map, Set and BigInt. | ||
TypeScript types are also included in the package. | ||
@@ -6,0 +15,0 @@ |
@@ -36,2 +36,17 @@ import safeStringify from 'fast-safe-stringify' | ||
class ErrorArrayStack { | ||
stack: string[]; | ||
message: string; | ||
name: string; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
[key: string]: any; | ||
constructor(message: string, stack: string[]) { | ||
this.message = message; | ||
this.name = 'ErrorArrayStack'; | ||
this.stack = stack; | ||
} | ||
} | ||
/** JSON.stringify replacer that converts unstringifyable values to stringifyable ones */ | ||
@@ -53,7 +68,12 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
if (value instanceof Error) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const serializedError: any = serializeError(value) | ||
const serializedError = serializeError(value) | ||
// Tidy up the stack trace a bit and convert it to an array | ||
serializedError.stack = extractStack.lines(value) | ||
return serializedError | ||
const s = new ErrorArrayStack(serializedError.message || '', extractStack.lines(value)) | ||
for (const key in value) { | ||
if (Object.prototype.hasOwnProperty.call(value, key) && key !== 'message' && key !== 'stack' && key !== 'name') { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment | ||
s[key] = (value as {[key: string]: any})[key]; | ||
} | ||
} | ||
return s; | ||
} | ||
@@ -70,3 +90,3 @@ | ||
*/ | ||
level?: LEVEL | string | ||
level?: LEVEL | ||
/** | ||
@@ -120,3 +140,3 @@ * Enables the human friendly development output. | ||
// Just parse the production log because it already has all the data conversions applied | ||
const log: LogLine = JSON.parse(logLine) | ||
const log: LogLine = JSON.parse(logLine) as LogLine | ||
logLine = chalk.bold(`\n${log.level}: ${log.message}`) | ||
@@ -123,0 +143,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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
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
27593
480
122
16
+ Addedchalk@4.1.2(transitive)
- Removedchalk@3.0.0(transitive)
Updatedchalk@^4.1.2