@rawnodes/logger 2.5.0 → 2.6.0
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/README.md +62 -0
- package/dist/index.d.mts +50 -6
- package/dist/index.d.ts +50 -6
- package/dist/index.js +96 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -683,6 +683,7 @@ function createFormattedFilterStream(format, level, rules, store, destination) {
|
|
|
683
683
|
}
|
|
684
684
|
function createStreams(config, store) {
|
|
685
685
|
const streams = [];
|
|
686
|
+
const transports = [];
|
|
686
687
|
const consoleStream = createFormattedFilterStream(
|
|
687
688
|
config.console.format,
|
|
688
689
|
config.console.level,
|
|
@@ -730,6 +731,7 @@ function createStreams(config, store) {
|
|
|
730
731
|
}
|
|
731
732
|
for (const discordConfig of toArray(config.discord)) {
|
|
732
733
|
const transport = new DiscordTransport(discordConfig);
|
|
734
|
+
transports.push(transport);
|
|
733
735
|
const discordStream = createHttpTransportStream(transport, discordConfig.level, discordConfig.rules, store);
|
|
734
736
|
streams.push({
|
|
735
737
|
level: "trace",
|
|
@@ -738,6 +740,7 @@ function createStreams(config, store) {
|
|
|
738
740
|
}
|
|
739
741
|
for (const telegramConfig of toArray(config.telegram)) {
|
|
740
742
|
const transport = new TelegramTransport(telegramConfig);
|
|
743
|
+
transports.push(transport);
|
|
741
744
|
const telegramStream = createHttpTransportStream(transport, telegramConfig.level, telegramConfig.rules, store);
|
|
742
745
|
streams.push({
|
|
743
746
|
level: "trace",
|
|
@@ -746,13 +749,17 @@ function createStreams(config, store) {
|
|
|
746
749
|
}
|
|
747
750
|
for (const cloudwatchConfig of toArray(config.cloudwatch)) {
|
|
748
751
|
const transport = new CloudWatchTransport(cloudwatchConfig, config.hostname);
|
|
752
|
+
transports.push(transport);
|
|
749
753
|
const cwStream = createHttpTransportStream(transport, cloudwatchConfig.level, cloudwatchConfig.rules, store);
|
|
750
754
|
streams.push({
|
|
751
755
|
level: "trace",
|
|
752
756
|
stream: cwStream
|
|
753
757
|
});
|
|
754
758
|
}
|
|
755
|
-
return
|
|
759
|
+
return {
|
|
760
|
+
destination: pino.multistream(streams),
|
|
761
|
+
transports
|
|
762
|
+
};
|
|
756
763
|
}
|
|
757
764
|
function toArray(value) {
|
|
758
765
|
if (!value) return [];
|
|
@@ -837,14 +844,14 @@ function createState(config, store) {
|
|
|
837
844
|
levelOverrides.set(key, rule);
|
|
838
845
|
}
|
|
839
846
|
const { contextIndex, complexRules } = buildIndexes(levelOverrides);
|
|
840
|
-
const
|
|
847
|
+
const { destination, transports } = createStreams(config, loggerStore);
|
|
841
848
|
const options = {
|
|
842
849
|
level: "trace",
|
|
843
850
|
// Accept all, we filter in shouldLog()
|
|
844
851
|
customLevels: CUSTOM_LEVELS,
|
|
845
852
|
base: { hostname: config.hostname ?? hostname() }
|
|
846
853
|
};
|
|
847
|
-
const pinoLogger = pino(options,
|
|
854
|
+
const pinoLogger = pino(options, destination);
|
|
848
855
|
let callerConfig;
|
|
849
856
|
if (config.caller === true) {
|
|
850
857
|
callerConfig = {};
|
|
@@ -858,7 +865,8 @@ function createState(config, store) {
|
|
|
858
865
|
levelOverrides,
|
|
859
866
|
contextIndex,
|
|
860
867
|
complexRules,
|
|
861
|
-
callerConfig
|
|
868
|
+
callerConfig,
|
|
869
|
+
transports
|
|
862
870
|
};
|
|
863
871
|
}
|
|
864
872
|
function rebuildIndexes(state) {
|
|
@@ -1004,6 +1012,10 @@ var CallerConfigSchema = z.object({
|
|
|
1004
1012
|
depth: z.number().int().nonnegative().optional(),
|
|
1005
1013
|
fullPath: z.boolean().optional()
|
|
1006
1014
|
});
|
|
1015
|
+
var AutoShutdownConfigSchema = z.object({
|
|
1016
|
+
timeout: z.number().int().positive().optional(),
|
|
1017
|
+
signals: z.array(z.string()).optional()
|
|
1018
|
+
});
|
|
1007
1019
|
var LoggerConfigSchema = z.object({
|
|
1008
1020
|
level: LevelConfigSchema,
|
|
1009
1021
|
console: ConsoleConfigSchema,
|
|
@@ -1012,7 +1024,8 @@ var LoggerConfigSchema = z.object({
|
|
|
1012
1024
|
telegram: z.union([TelegramConfigSchema, z.array(TelegramConfigSchema)]).optional(),
|
|
1013
1025
|
cloudwatch: z.union([CloudWatchConfigSchema, z.array(CloudWatchConfigSchema)]).optional(),
|
|
1014
1026
|
caller: z.union([z.boolean(), CallerConfigSchema]).optional(),
|
|
1015
|
-
hostname: z.string().optional()
|
|
1027
|
+
hostname: z.string().optional(),
|
|
1028
|
+
autoShutdown: z.union([z.boolean(), AutoShutdownConfigSchema]).optional()
|
|
1016
1029
|
});
|
|
1017
1030
|
function validateConfig(config) {
|
|
1018
1031
|
return LoggerConfigSchema.parse(config);
|
|
@@ -1081,6 +1094,53 @@ function formatCallerInfo(info) {
|
|
|
1081
1094
|
return location;
|
|
1082
1095
|
}
|
|
1083
1096
|
|
|
1097
|
+
// src/utils/shutdown.ts
|
|
1098
|
+
var DEFAULT_OPTIONS2 = {
|
|
1099
|
+
timeout: 5e3,
|
|
1100
|
+
exitCode: 0,
|
|
1101
|
+
signals: ["SIGTERM", "SIGINT"]
|
|
1102
|
+
};
|
|
1103
|
+
var registered = false;
|
|
1104
|
+
function registerShutdown(logger, options = {}) {
|
|
1105
|
+
const opts = { ...DEFAULT_OPTIONS2, ...options };
|
|
1106
|
+
const shutdown = async (signal) => {
|
|
1107
|
+
if (signal) {
|
|
1108
|
+
console.error(`[Logger] Received ${signal}, shutting down gracefully...`);
|
|
1109
|
+
}
|
|
1110
|
+
try {
|
|
1111
|
+
if (opts.onShutdown) {
|
|
1112
|
+
await opts.onShutdown();
|
|
1113
|
+
}
|
|
1114
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1115
|
+
setTimeout(() => {
|
|
1116
|
+
reject(new Error(`Shutdown timed out after ${opts.timeout}ms`));
|
|
1117
|
+
}, opts.timeout);
|
|
1118
|
+
});
|
|
1119
|
+
await Promise.race([
|
|
1120
|
+
logger.shutdown(),
|
|
1121
|
+
timeoutPromise
|
|
1122
|
+
]);
|
|
1123
|
+
if (signal) {
|
|
1124
|
+
console.error("[Logger] Graceful shutdown completed");
|
|
1125
|
+
process.exit(opts.exitCode);
|
|
1126
|
+
}
|
|
1127
|
+
} catch (error) {
|
|
1128
|
+
console.error("[Logger] Shutdown error:", error instanceof Error ? error.message : error);
|
|
1129
|
+
if (signal) {
|
|
1130
|
+
process.exit(1);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
if (!registered) {
|
|
1135
|
+
for (const signal of opts.signals) {
|
|
1136
|
+
process.on(signal, () => void shutdown(signal));
|
|
1137
|
+
}
|
|
1138
|
+
process.on("beforeExit", () => void shutdown());
|
|
1139
|
+
registered = true;
|
|
1140
|
+
}
|
|
1141
|
+
return shutdown;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1084
1144
|
// src/logger.ts
|
|
1085
1145
|
var Logger = class _Logger {
|
|
1086
1146
|
constructor(state, context) {
|
|
@@ -1091,7 +1151,12 @@ var Logger = class _Logger {
|
|
|
1091
1151
|
static create(config, store) {
|
|
1092
1152
|
const validatedConfig = validateConfig(config);
|
|
1093
1153
|
const state = createState(validatedConfig, store);
|
|
1094
|
-
|
|
1154
|
+
const logger = new _Logger(state, "APP");
|
|
1155
|
+
if (validatedConfig.autoShutdown) {
|
|
1156
|
+
const shutdownConfig = typeof validatedConfig.autoShutdown === "object" ? validatedConfig.autoShutdown : {};
|
|
1157
|
+
registerShutdown(logger, shutdownConfig);
|
|
1158
|
+
}
|
|
1159
|
+
return logger;
|
|
1095
1160
|
}
|
|
1096
1161
|
for(context) {
|
|
1097
1162
|
return new _Logger(this.state, context);
|
|
@@ -1133,6 +1198,15 @@ var Logger = class _Logger {
|
|
|
1133
1198
|
getLevelOverrides() {
|
|
1134
1199
|
return Array.from(this.state.levelOverrides.values());
|
|
1135
1200
|
}
|
|
1201
|
+
// Shutdown
|
|
1202
|
+
/**
|
|
1203
|
+
* Gracefully shutdown the logger, flushing all pending messages.
|
|
1204
|
+
* Should be called before process exit to ensure no logs are lost.
|
|
1205
|
+
*/
|
|
1206
|
+
async shutdown() {
|
|
1207
|
+
const closePromises = this.state.transports.map((transport) => transport.close());
|
|
1208
|
+
await Promise.all(closePromises);
|
|
1209
|
+
}
|
|
1136
1210
|
// Profiling
|
|
1137
1211
|
profile(id, meta) {
|
|
1138
1212
|
const existing = this.profileTimers.get(id);
|
|
@@ -1399,16 +1473,28 @@ function createMasker(options = {}) {
|
|
|
1399
1473
|
}
|
|
1400
1474
|
|
|
1401
1475
|
// src/formatters.ts
|
|
1402
|
-
|
|
1476
|
+
var MAX_FLATTEN_DEPTH = 10;
|
|
1477
|
+
var CIRCULAR_REF = "[Circular]";
|
|
1478
|
+
function flattenObject(obj, prefix = "", ancestors = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
1403
1479
|
const result = {};
|
|
1480
|
+
if (depth > MAX_FLATTEN_DEPTH) {
|
|
1481
|
+
result[prefix || "value"] = "[Max depth exceeded]";
|
|
1482
|
+
return result;
|
|
1483
|
+
}
|
|
1484
|
+
ancestors.add(obj);
|
|
1404
1485
|
for (const [key, value] of Object.entries(obj)) {
|
|
1405
1486
|
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
1406
1487
|
if (value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Error)) {
|
|
1407
|
-
|
|
1488
|
+
if (ancestors.has(value)) {
|
|
1489
|
+
result[newKey] = CIRCULAR_REF;
|
|
1490
|
+
} else {
|
|
1491
|
+
Object.assign(result, flattenObject(value, newKey, ancestors, depth + 1));
|
|
1492
|
+
}
|
|
1408
1493
|
} else {
|
|
1409
1494
|
result[newKey] = value;
|
|
1410
1495
|
}
|
|
1411
1496
|
}
|
|
1497
|
+
ancestors.delete(obj);
|
|
1412
1498
|
return result;
|
|
1413
1499
|
}
|
|
1414
1500
|
function formatLogfmtValue(value) {
|
|
@@ -1437,6 +1523,6 @@ function formatLogfmt(data) {
|
|
|
1437
1523
|
return Object.entries(flattened).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${formatLogfmtValue(value)}`).join(" ");
|
|
1438
1524
|
}
|
|
1439
1525
|
|
|
1440
|
-
export { BaseHttpTransport, CallerConfigSchema, CloudWatchConfigSchema, CloudWatchTransport, ConsoleConfigSchema, DiscordConfigSchema, DiscordTransport, FileConfigSchema, HttpTransportBaseConfigSchema, LOG_LEVELS, LevelConfigObjectSchema, LevelConfigSchema, LevelRuleSchema, LogFormatSchema, LogLevelSchema, LogStreamNameSchema, LogStreamPatternConfigSchema, LogStreamPatternSchema, LogStreamTemplateConfigSchema, Logger, LoggerConfigSchema, LoggerStore, MessageBuffer, TelegramConfigSchema, TelegramTransport, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatCallerInfo, formatLogfmt, formatLogfmtValue, generateRequestId, getCallerInfo, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync, safeValidateConfig, validateConfig };
|
|
1526
|
+
export { AutoShutdownConfigSchema, BaseHttpTransport, CallerConfigSchema, CloudWatchConfigSchema, CloudWatchTransport, ConsoleConfigSchema, DiscordConfigSchema, DiscordTransport, FileConfigSchema, HttpTransportBaseConfigSchema, LOG_LEVELS, LevelConfigObjectSchema, LevelConfigSchema, LevelRuleSchema, LogFormatSchema, LogLevelSchema, LogStreamNameSchema, LogStreamPatternConfigSchema, LogStreamPatternSchema, LogStreamTemplateConfigSchema, Logger, LoggerConfigSchema, LoggerStore, MessageBuffer, TelegramConfigSchema, TelegramTransport, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatCallerInfo, formatLogfmt, formatLogfmtValue, generateRequestId, getCallerInfo, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync, registerShutdown, safeValidateConfig, validateConfig };
|
|
1441
1527
|
//# sourceMappingURL=index.mjs.map
|
|
1442
1528
|
//# sourceMappingURL=index.mjs.map
|