@rf-logger/logger 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ import { Logform } from "winston";
2
+ import { Options } from "../types";
3
+ /**
4
+ * This format accepts:
5
+ * - errors in the log message --> src.error(new Error("test"))
6
+ * - errors in the second argument --> src.error("Something bad happened", new Error("test"))
7
+ * - errors in the log context --> src.error("Something bad happened", { err })
8
+ * The error message will be added to the log (either in the context, or in the message depending on the situation).
9
+ * The exception be sent to Sentry where the Stacktrace will accessible thanks to its sourcemap.
10
+ */
11
+ export declare const errorFormat: (options: Options) => Logform.Format;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.errorFormat = void 0;
4
+ const triple_beam_1 = require("triple-beam");
5
+ const uuid_1 = require("uuid");
6
+ const winston_1 = require("winston");
7
+ function generateTraceId(error) {
8
+ error.traceId = (0, uuid_1.v4)();
9
+ }
10
+ /**
11
+ * This format accepts:
12
+ * - errors in the log message --> src.error(new Error("test"))
13
+ * - errors in the second argument --> src.error("Something bad happened", new Error("test"))
14
+ * - errors in the log context --> src.error("Something bad happened", { err })
15
+ * The error message will be added to the log (either in the context, or in the message depending on the situation).
16
+ * The exception be sent to Sentry where the Stacktrace will accessible thanks to its sourcemap.
17
+ */
18
+ const errorFormat = (options) => {
19
+ var _a;
20
+ const errorMetaGenerators = [];
21
+ const errorForwarders = [];
22
+ (_a = options.plugins) === null || _a === void 0 ? void 0 : _a.forEach((plugin) => {
23
+ plugin.registerErrorMetaGenerators &&
24
+ errorMetaGenerators.push(...plugin.registerErrorMetaGenerators());
25
+ plugin.registerErrorForwarders &&
26
+ errorForwarders.push(...plugin.registerErrorForwarders());
27
+ });
28
+ function forwardError(error, info) {
29
+ generateTraceId(error);
30
+ const meta = errorMetaGenerators.reduce((previousMeta, metaGenerator) => (Object.assign(Object.assign({}, previousMeta), metaGenerator(error))), {});
31
+ errorForwarders.forEach((forward) => forward(error, info, meta));
32
+ }
33
+ return (0, winston_1.format)((info) => {
34
+ if (info instanceof Error) {
35
+ forwardError(info, info);
36
+ const message = `${info.name}: ${info.message}`;
37
+ return Object.assign(Object.assign({}, info), { level: info.level, [triple_beam_1.LEVEL]: info.level, message, [triple_beam_1.MESSAGE]: message, stack: errorForwarders.length ? undefined : info.stack });
38
+ }
39
+ // case where the error is passed down the log context
40
+ let lastTraceId = null;
41
+ ["error", "err", "e"].forEach((prop) => {
42
+ const value = info[prop];
43
+ if (!(info[prop] instanceof Error))
44
+ return;
45
+ forwardError(value, info);
46
+ lastTraceId = value.traceId;
47
+ info[prop] = Object.assign(Object.assign({}, value), { message: `${value.name}: ${value.message}`, stack: errorForwarders.length ? undefined : info[prop].stack });
48
+ });
49
+ if (lastTraceId) {
50
+ info.traceId = lastTraceId;
51
+ return info;
52
+ }
53
+ // case where the error is passed down as second argument
54
+ if (info[triple_beam_1.SPLAT]) {
55
+ let traceId;
56
+ info[triple_beam_1.SPLAT].forEach((error) => {
57
+ if (!(error instanceof Error))
58
+ return;
59
+ forwardError(error, info);
60
+ traceId = error.traceId;
61
+ });
62
+ return Object.assign(Object.assign({}, info), { traceId, stack: errorForwarders.length ? undefined : info.stack });
63
+ }
64
+ return info;
65
+ })();
66
+ };
67
+ exports.errorFormat = errorFormat;
@@ -0,0 +1,2 @@
1
+ import winston from "winston";
2
+ export declare const gcpFormat: winston.Logform.FormatWrap;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.gcpFormat = void 0;
7
+ const winston_1 = __importDefault(require("winston"));
8
+ // see https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity
9
+ const mapWinstonLevelToGcpLevel = (level) => {
10
+ switch (level) {
11
+ case "warn":
12
+ return "WARNING";
13
+ case "http":
14
+ case "verbose":
15
+ case "silly":
16
+ return "DEBUG";
17
+ }
18
+ return level.toUpperCase();
19
+ };
20
+ exports.gcpFormat = winston_1.default.format((info) => {
21
+ info.severity = mapWinstonLevelToGcpLevel(info.level);
22
+ return info;
23
+ });
@@ -0,0 +1,3 @@
1
+ export { errorFormat } from "./error.format";
2
+ export { gcpFormat } from "./gcp.format";
3
+ export { simpleFormatWithTimestamp } from "./simple.format";
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.simpleFormatWithTimestamp = exports.gcpFormat = exports.errorFormat = void 0;
4
+ var error_format_1 = require("./error.format");
5
+ Object.defineProperty(exports, "errorFormat", { enumerable: true, get: function () { return error_format_1.errorFormat; } });
6
+ var gcp_format_1 = require("./gcp.format");
7
+ Object.defineProperty(exports, "gcpFormat", { enumerable: true, get: function () { return gcp_format_1.gcpFormat; } });
8
+ var simple_format_1 = require("./simple.format");
9
+ Object.defineProperty(exports, "simpleFormatWithTimestamp", { enumerable: true, get: function () { return simple_format_1.simpleFormatWithTimestamp; } });
@@ -0,0 +1,6 @@
1
+ import winston from "winston";
2
+ /**
3
+ * Like the winston.format.simple but with the timestamp in front of it.
4
+ * see https://github.com/winstonjs/logform/blob/master/simple.js
5
+ */
6
+ export declare const simpleFormatWithTimestamp: winston.Logform.Format;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.simpleFormatWithTimestamp = void 0;
18
+ const chalk_1 = require("chalk");
19
+ const json_colorizer_1 = __importDefault(require("json-colorizer"));
20
+ const safe_stable_stringify_1 = __importDefault(require("safe-stable-stringify"));
21
+ const winston_1 = __importDefault(require("winston"));
22
+ const shift = (string, spaces = 2) => string
23
+ .split("\n")
24
+ .map((line) => " ".repeat(spaces) + line)
25
+ .join("\n");
26
+ /**
27
+ * Like the winston.format.simple but with the timestamp in front of it.
28
+ * see https://github.com/winstonjs/logform/blob/master/simple.js
29
+ */
30
+ exports.simpleFormatWithTimestamp = winston_1.default.format.printf((info) => {
31
+ const { level, message, timestamp, stack, channel } = info, rest = __rest(info, ["level", "message", "timestamp", "stack", "channel"]);
32
+ const context = (0, safe_stable_stringify_1.default)(rest, null, 2);
33
+ const padding = (info.padding && info.padding[info.level]) || "";
34
+ let log = `[${timestamp}] ${level}:${padding}${(channel && ` [${channel}]`) || ""} ${message}`;
35
+ if (context !== "{}") {
36
+ log += shift(`\n> ${(0, chalk_1.underline)("Context")}: ${shift((0, json_colorizer_1.default)(context)).trim()}`, 15);
37
+ }
38
+ if (stack) {
39
+ log += shift(`\n> ${(0, chalk_1.underline)("Stacktrace")}: ${shift(stack).trim()}`, 15);
40
+ }
41
+ return log;
42
+ });
@@ -0,0 +1,2 @@
1
+ export { Logger } from "./logger";
2
+ export * from "./types";
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Logger = void 0;
18
+ var logger_1 = require("./logger");
19
+ Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
20
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,8 @@
1
+ import type { Logger as WinstonLogger } from "winston";
2
+ import { Options } from "./types";
3
+ export declare class Logger {
4
+ private readonly options;
5
+ constructor(inputOptions?: Options);
6
+ private createLogger;
7
+ init: () => WinstonLogger;
8
+ }
package/dist/logger.js ADDED
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Logger = void 0;
4
+ const winston_1 = require("winston");
5
+ const formats_1 = require("./formats");
6
+ const defaultOptions = {
7
+ silent: false,
8
+ format: "json",
9
+ level: "silly",
10
+ handleWarnings: true,
11
+ };
12
+ class Logger {
13
+ constructor(inputOptions) {
14
+ this.init = () => {
15
+ var _a, _b;
16
+ const formats = [(0, formats_1.errorFormat)(this.options)];
17
+ (_a = this.options.plugins) === null || _a === void 0 ? void 0 : _a.forEach((plugin) => {
18
+ plugin.registerFormats && formats.push(...plugin.registerFormats());
19
+ });
20
+ const baseFormat = winston_1.format.combine(...formats);
21
+ const logger = this.createLogger(baseFormat);
22
+ (_b = this.options.plugins) === null || _b === void 0 ? void 0 : _b.forEach((plugin) => {
23
+ plugin.registerInterceptors && plugin.registerInterceptors(logger);
24
+ });
25
+ // displays stacktrace for warnings
26
+ if (this.options.handleWarnings) {
27
+ process.on("warning", (err) => logger.warn(err));
28
+ }
29
+ return logger;
30
+ };
31
+ this.options = Object.assign(Object.assign({}, defaultOptions), inputOptions);
32
+ }
33
+ createLogger(baseFormat) {
34
+ return (0, winston_1.createLogger)({
35
+ transports: this.options.transports || [
36
+ new winston_1.transports.Console({
37
+ level: this.options.level,
38
+ handleExceptions: true,
39
+ handleRejections: true,
40
+ }),
41
+ ],
42
+ silent: this.options.silent,
43
+ format: this.options.format === "json"
44
+ ? winston_1.format.combine(baseFormat, (0, formats_1.gcpFormat)(), winston_1.format.json())
45
+ : winston_1.format.combine(baseFormat, winston_1.format.timestamp({ format: "HH:mm:ss.SSS" }), winston_1.format.colorize(), formats_1.simpleFormatWithTimestamp),
46
+ });
47
+ }
48
+ }
49
+ exports.Logger = Logger;
@@ -0,0 +1,28 @@
1
+ import { Logger, Logform } from "winston";
2
+ import TransportStream from "winston-transport";
3
+ export type Options = {
4
+ format?: "json" | "plain";
5
+ silent?: boolean;
6
+ level?: LogLevel;
7
+ handleWarnings?: boolean;
8
+ plugins?: LoggerPlugin[];
9
+ transports?: TransportStream[];
10
+ };
11
+ /**
12
+ * Default Winston's logging levels,
13
+ * see https://github.com/winstonjs/winston#logging-levels
14
+ */
15
+ export type LogLevel = "error" | "warn" | "info" | "http" | "verbose" | "debug" | "silly";
16
+ export type ErrorLog = Error & {
17
+ traceId: string;
18
+ };
19
+ export type ErrorMetaDeep = Record<string, string>;
20
+ export type ErrorMeta = Record<string, string | ErrorMetaDeep>;
21
+ export type ErrorMetaGenerator = (error: ErrorLog) => ErrorMeta;
22
+ export type ErrorForwarder = (error: ErrorLog, info: Logform.TransformableInfo, meta: ErrorMeta) => void;
23
+ export type LoggerPlugin = {
24
+ registerFormats?: () => Logform.Format[];
25
+ registerInterceptors?: (logger: Logger) => void;
26
+ registerErrorMetaGenerators?: () => ErrorMetaGenerator[];
27
+ registerErrorForwarders?: () => ErrorForwarder[];
28
+ };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@rf-logger/logger",
3
+ "files": [
4
+ "dist/**"
5
+ ],
6
+ "main": "dist/index.js",
7
+ "dependencies": {
8
+ "chalk": "^4.1.2",
9
+ "json-colorizer": "^2.2.2",
10
+ "safe-stable-stringify": "^2.3.1",
11
+ "triple-beam": "^1.3.0",
12
+ "uuid": "^8.3.2",
13
+ "winston": "^3.8.2",
14
+ "winston-transport": "^4.5.0"
15
+ },
16
+ "devDependencies": {
17
+ "@types/triple-beam": "^1.3.2",
18
+ "@types/uuid": "^8.3.4",
19
+ "ts-node": "^10.9.1"
20
+ },
21
+ "engines": {
22
+ "node": ">=16.0.0"
23
+ },
24
+ "version": "0.0.9",
25
+ "scripts": {
26
+ "test": "jest",
27
+ "version": "pnpm version --no-git-tag-version"
28
+ }
29
+ }