@restura/logger 1.0.1
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.
- package/dist/index.d.ts +17 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ResturaLogger } from '@restura/core';
|
|
2
|
+
export { ResturaLogger } from '@restura/core';
|
|
3
|
+
import { SerializerFn, Level, TransportTargetOptions, DestinationStream } from 'pino';
|
|
4
|
+
|
|
5
|
+
type ErrorSerializerFactory = (baseSerializer: SerializerFn) => SerializerFn;
|
|
6
|
+
interface LoggerConfig {
|
|
7
|
+
level?: Level;
|
|
8
|
+
transports?: TransportTargetOptions[];
|
|
9
|
+
serializers?: {
|
|
10
|
+
err?: ErrorSerializerFactory;
|
|
11
|
+
};
|
|
12
|
+
stream?: DestinationStream;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare function createLogger(config?: LoggerConfig): ResturaLogger;
|
|
16
|
+
|
|
17
|
+
export { type ErrorSerializerFactory, type LoggerConfig, createLogger };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// src/createLogger.ts
|
|
2
|
+
import { RsError } from "@restura/core";
|
|
3
|
+
import pino from "pino";
|
|
4
|
+
import pinoPretty from "pino-pretty";
|
|
5
|
+
function buildDefaultStream() {
|
|
6
|
+
return pinoPretty({
|
|
7
|
+
colorize: true,
|
|
8
|
+
translateTime: "yyyy-mm-dd HH:MM:ss.l",
|
|
9
|
+
ignore: "pid,hostname,_meta",
|
|
10
|
+
messageFormat: "{msg}",
|
|
11
|
+
levelFirst: true,
|
|
12
|
+
customColors: "error:red,warn:yellow,info:green,debug:blue,trace:magenta",
|
|
13
|
+
destination: process.stdout
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function buildErrorSerializer(loggerConfig) {
|
|
17
|
+
const baseSerializer = pino.stdSerializers.err;
|
|
18
|
+
const defaultSerializer = (error) => {
|
|
19
|
+
const isAxiosError = error !== null && typeof error === "object" && "isAxiosError" in error && error.isAxiosError === true;
|
|
20
|
+
if (isAxiosError) {
|
|
21
|
+
const err = error;
|
|
22
|
+
return {
|
|
23
|
+
type: "AxiosError",
|
|
24
|
+
message: err.message,
|
|
25
|
+
stack: err.stack,
|
|
26
|
+
url: err.config?.url,
|
|
27
|
+
method: err.config?.method?.toUpperCase(),
|
|
28
|
+
status: err.response?.status,
|
|
29
|
+
responseData: err.response?.data
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (RsError.isRsError(error)) return error.toJSON();
|
|
33
|
+
return baseSerializer(error);
|
|
34
|
+
};
|
|
35
|
+
if (!loggerConfig?.serializers?.err) return defaultSerializer;
|
|
36
|
+
try {
|
|
37
|
+
return loggerConfig.serializers.err(baseSerializer);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error("Failed to initialize custom error serializer, falling back to default", err);
|
|
40
|
+
return defaultSerializer;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function buildPinoInstance(loggerConfig, level) {
|
|
44
|
+
const options = { level, serializers: { err: buildErrorSerializer(loggerConfig) } };
|
|
45
|
+
if (loggerConfig?.transports) {
|
|
46
|
+
options.transport = { targets: loggerConfig.transports };
|
|
47
|
+
return pino(options);
|
|
48
|
+
}
|
|
49
|
+
return pino(options, loggerConfig?.stream ?? buildDefaultStream());
|
|
50
|
+
}
|
|
51
|
+
function buildContext(args) {
|
|
52
|
+
const ctx = {};
|
|
53
|
+
const primitives = [];
|
|
54
|
+
for (const arg of args) {
|
|
55
|
+
if (arg instanceof Error && !ctx.err) {
|
|
56
|
+
ctx.err = arg;
|
|
57
|
+
} else if (arg && typeof arg === "object" && !Array.isArray(arg)) {
|
|
58
|
+
Object.assign(ctx, arg);
|
|
59
|
+
} else {
|
|
60
|
+
primitives.push(arg);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (primitives.length) ctx.args = primitives;
|
|
64
|
+
return ctx;
|
|
65
|
+
}
|
|
66
|
+
function log(pinoInstance, level, msg, ...args) {
|
|
67
|
+
if (typeof msg === "string") {
|
|
68
|
+
pinoInstance[level](buildContext(args), msg);
|
|
69
|
+
} else {
|
|
70
|
+
pinoInstance[level](buildContext([msg, ...args]));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function createLogger(config) {
|
|
74
|
+
const VALID_LEVELS = ["fatal", "error", "warn", "info", "debug", "trace"];
|
|
75
|
+
const envLevel = process.env.RESTURA_LOG_LEVEL;
|
|
76
|
+
const level = config?.level ?? (VALID_LEVELS.includes(envLevel) ? envLevel : "info");
|
|
77
|
+
const pinoInstance = buildPinoInstance(config, level);
|
|
78
|
+
return {
|
|
79
|
+
level: pinoInstance.level,
|
|
80
|
+
fatal: (msg, ...args) => log(pinoInstance, "fatal", msg, ...args),
|
|
81
|
+
error: (msg, ...args) => log(pinoInstance, "error", msg, ...args),
|
|
82
|
+
warn: (msg, ...args) => log(pinoInstance, "warn", msg, ...args),
|
|
83
|
+
info: (msg, ...args) => log(pinoInstance, "info", msg, ...args),
|
|
84
|
+
debug: (msg, ...args) => log(pinoInstance, "debug", msg, ...args),
|
|
85
|
+
trace: (msg, ...args) => log(pinoInstance, "trace", msg, ...args)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export {
|
|
89
|
+
createLogger
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/createLogger.ts"],"sourcesContent":["import { RsError, type LogLevel, type ResturaLogger } from '@restura/core';\nimport pino from 'pino';\nimport pinoPretty from 'pino-pretty';\nimport type { LoggerConfig } from './loggerConfigSchema.js';\n\nfunction buildDefaultStream() {\n\treturn pinoPretty({\n\t\tcolorize: true,\n\t\ttranslateTime: 'yyyy-mm-dd HH:MM:ss.l',\n\t\tignore: 'pid,hostname,_meta',\n\t\tmessageFormat: '{msg}',\n\t\tlevelFirst: true,\n\t\tcustomColors: 'error:red,warn:yellow,info:green,debug:blue,trace:magenta',\n\t\tdestination: process.stdout\n\t});\n}\n\nfunction buildErrorSerializer(loggerConfig?: LoggerConfig) {\n\tconst baseSerializer = pino.stdSerializers.err;\n\n\tconst defaultSerializer = (error: unknown) => {\n\t\tconst isAxiosError =\n\t\t\terror !== null &&\n\t\t\ttypeof error === 'object' &&\n\t\t\t'isAxiosError' in error &&\n\t\t\t(error as { isAxiosError: unknown }).isAxiosError === true;\n\n\t\tif (isAxiosError) {\n\t\t\tconst err = error as unknown as {\n\t\t\t\tmessage: string;\n\t\t\t\tstack: string;\n\t\t\t\tconfig: { url: string; method: string };\n\t\t\t\tresponse: { status: number; data: unknown };\n\t\t\t};\n\t\t\treturn {\n\t\t\t\ttype: 'AxiosError',\n\t\t\t\tmessage: err.message,\n\t\t\t\tstack: err.stack,\n\t\t\t\turl: err.config?.url,\n\t\t\t\tmethod: err.config?.method?.toUpperCase(),\n\t\t\t\tstatus: err.response?.status,\n\t\t\t\tresponseData: err.response?.data\n\t\t\t};\n\t\t}\n\n\t\tif (RsError.isRsError(error)) return error.toJSON();\n\t\treturn baseSerializer(error as Error);\n\t};\n\n\tif (!loggerConfig?.serializers?.err) return defaultSerializer;\n\n\ttry {\n\t\treturn loggerConfig.serializers.err(baseSerializer);\n\t} catch (err) {\n\t\tconsole.error('Failed to initialize custom error serializer, falling back to default', err);\n\t\treturn defaultSerializer;\n\t}\n}\n\nfunction buildPinoInstance(loggerConfig: LoggerConfig | undefined, level: string): pino.Logger {\n\tconst options: pino.LoggerOptions = { level, serializers: { err: buildErrorSerializer(loggerConfig) } };\n\n\tif (loggerConfig?.transports) {\n\t\toptions.transport = { targets: loggerConfig.transports };\n\t\treturn pino(options);\n\t}\n\n\treturn pino(options, loggerConfig?.stream ?? buildDefaultStream());\n}\n\nfunction buildContext(args: unknown[]) {\n\tconst ctx: Record<string, unknown> = {};\n\tconst primitives: unknown[] = [];\n\n\tfor (const arg of args) {\n\t\tif (arg instanceof Error && !ctx.err) {\n\t\t\tctx.err = arg;\n\t\t} else if (arg && typeof arg === 'object' && !Array.isArray(arg)) {\n\t\t\tObject.assign(ctx, arg as object);\n\t\t} else {\n\t\t\tprimitives.push(arg);\n\t\t}\n\t}\n\n\tif (primitives.length) ctx.args = primitives;\n\treturn ctx;\n}\n\nfunction log(pinoInstance: pino.Logger, level: pino.Level, msg: string | unknown, ...args: unknown[]) {\n\tif (typeof msg === 'string') {\n\t\tpinoInstance[level](buildContext(args), msg);\n\t} else {\n\t\tpinoInstance[level](buildContext([msg, ...args]));\n\t}\n}\n\nexport function createLogger(config?: LoggerConfig): ResturaLogger {\n\tconst VALID_LEVELS: LogLevel[] = ['fatal', 'error', 'warn', 'info', 'debug', 'trace'];\n\tconst envLevel = process.env.RESTURA_LOG_LEVEL;\n\tconst level = config?.level ?? (VALID_LEVELS.includes(envLevel as LogLevel) ? (envLevel as LogLevel) : 'info');\n\tconst pinoInstance = buildPinoInstance(config, level);\n\n\treturn {\n\t\tlevel: pinoInstance.level as LogLevel,\n\t\tfatal: (msg: unknown, ...args: unknown[]) => log(pinoInstance, 'fatal', msg, ...args),\n\t\terror: (msg: unknown, ...args: unknown[]) => log(pinoInstance, 'error', msg, ...args),\n\t\twarn: (msg: unknown, ...args: unknown[]) => log(pinoInstance, 'warn', msg, ...args),\n\t\tinfo: (msg: unknown, ...args: unknown[]) => log(pinoInstance, 'info', msg, ...args),\n\t\tdebug: (msg: unknown, ...args: unknown[]) => log(pinoInstance, 'debug', msg, ...args),\n\t\ttrace: (msg: unknown, ...args: unknown[]) => log(pinoInstance, 'trace', msg, ...args)\n\t};\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@restura/logger",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Pino-based logger implementation for Restura",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"repository": "https://github.com/redsky-engineering/restura",
|
|
8
|
+
"author": "Joshua Hintze",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**"
|
|
12
|
+
],
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"restura",
|
|
22
|
+
"restura logger",
|
|
23
|
+
"pino",
|
|
24
|
+
"low code api"
|
|
25
|
+
],
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"pino": "^10.3.1",
|
|
28
|
+
"pino-pretty": "^13.1.3",
|
|
29
|
+
"@restura/core": "2.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"tsup": "^8.5.1"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"mocha": {
|
|
38
|
+
"enable-source-maps": true,
|
|
39
|
+
"node-option": [
|
|
40
|
+
"import=tsx"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"test": "mocha 'src/**/*.test.ts'",
|
|
45
|
+
"build": "tsup ./src/index.ts",
|
|
46
|
+
"lint": "eslint src"
|
|
47
|
+
}
|
|
48
|
+
}
|