logixia 1.2.1 → 1.3.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/.tsbuildinfo +1 -0
- package/dist/{index-BDRSTjUt.d.ts → index-CHIsdA9n.d.ts} +53 -2
- package/dist/index-CHIsdA9n.d.ts.map +1 -0
- package/dist/{index-Drrzn-Yg.d.mts → index-iDTW2-eY.d.mts} +53 -2
- package/dist/index-iDTW2-eY.d.mts.map +1 -0
- package/dist/index.d.mts +89 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +89 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{logitron-logger.module-iO8DPE7_.mjs → logitron-logger.module-2AzkadqZ.mjs} +226 -8
- package/dist/logitron-logger.module-2AzkadqZ.mjs.map +1 -0
- package/dist/{logitron-logger.module-CY3t8yK6.d.mts → logitron-logger.module-Bq3_KckP.d.ts} +6 -4
- package/dist/logitron-logger.module-Bq3_KckP.d.ts.map +1 -0
- package/dist/{logitron-logger.module-X6nGDVGC.js → logitron-logger.module-BqNKp0Fs.js} +240 -4
- package/dist/logitron-logger.module-BqNKp0Fs.js.map +1 -0
- package/dist/{logitron-logger.module-DgEldK9V.d.ts → logitron-logger.module-DW_mmXbj.d.mts} +6 -4
- package/dist/logitron-logger.module-DW_mmXbj.d.mts.map +1 -0
- package/dist/middleware.d.mts +83 -0
- package/dist/middleware.d.mts.map +1 -0
- package/dist/middleware.d.ts +83 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +132 -0
- package/dist/middleware.js.map +1 -0
- package/dist/middleware.mjs +130 -0
- package/dist/middleware.mjs.map +1 -0
- package/dist/nest.d.mts +2 -2
- package/dist/nest.d.ts +2 -2
- package/dist/nest.js +2 -2
- package/dist/nest.mjs +2 -2
- package/dist/testing.d.mts +67 -0
- package/dist/testing.d.mts.map +1 -0
- package/dist/testing.d.ts +67 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +164 -0
- package/dist/testing.js.map +1 -0
- package/dist/testing.mjs +163 -0
- package/dist/testing.mjs.map +1 -0
- package/dist/{transport.manager-Vi__pagn.mjs → transport.manager-5VVdqS3o.mjs} +51 -2
- package/dist/transport.manager-5VVdqS3o.mjs.map +1 -0
- package/dist/{transport.manager-C3Xr7Tvi.js → transport.manager-DCOm4uIQ.js} +51 -2
- package/dist/transport.manager-DCOm4uIQ.js.map +1 -0
- package/dist/transports.d.mts +38 -1
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +38 -1
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +1 -1
- package/dist/transports.mjs +1 -1
- package/package.json +31 -9
- package/dist/index-BDRSTjUt.d.ts.map +0 -1
- package/dist/index-Drrzn-Yg.d.mts.map +0 -1
- package/dist/logitron-logger.module-CY3t8yK6.d.mts.map +0 -1
- package/dist/logitron-logger.module-DgEldK9V.d.ts.map +0 -1
- package/dist/logitron-logger.module-X6nGDVGC.js.map +0 -1
- package/dist/logitron-logger.module-iO8DPE7_.mjs.map +0 -1
- package/dist/transport.manager-C3Xr7Tvi.js.map +0 -1
- package/dist/transport.manager-Vi__pagn.mjs.map +0 -1
|
@@ -1,10 +1,79 @@
|
|
|
1
1
|
import { a as __toESM, t as __commonJS } from "./chunk-uEZWKkIX.mjs";
|
|
2
|
-
import { d as internalLog, f as internalWarn, t as TransportManager, u as internalError } from "./transport.manager-
|
|
2
|
+
import { d as internalLog, f as internalWarn, t as TransportManager, u as internalError } from "./transport.manager-5VVdqS3o.mjs";
|
|
3
3
|
import buildFastStringify from "fast-json-stringify";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
-
import crypto from "crypto";
|
|
5
|
+
import crypto$1 from "crypto";
|
|
6
6
|
import { Injectable, Module, RequestMethod, Scope } from "@nestjs/common";
|
|
7
7
|
|
|
8
|
+
//#region src/context/async-context.ts
|
|
9
|
+
const _storage = new AsyncLocalStorage();
|
|
10
|
+
const LogixiaContext = {
|
|
11
|
+
run(store, callback) {
|
|
12
|
+
const parent = _storage.getStore() ?? {};
|
|
13
|
+
return _storage.run({
|
|
14
|
+
...parent,
|
|
15
|
+
...store
|
|
16
|
+
}, callback);
|
|
17
|
+
},
|
|
18
|
+
get() {
|
|
19
|
+
return _storage.getStore();
|
|
20
|
+
},
|
|
21
|
+
set(fields) {
|
|
22
|
+
const store = _storage.getStore();
|
|
23
|
+
if (!store) return;
|
|
24
|
+
Object.assign(store, fields);
|
|
25
|
+
},
|
|
26
|
+
getStorage() {
|
|
27
|
+
return _storage;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Create an Express/Connect-compatible middleware that wraps each request in
|
|
32
|
+
* a `LogixiaContext.run()` scope populated with common request fields.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { createExpressContextMiddleware } from 'logixia';
|
|
37
|
+
* app.use(createExpressContextMiddleware());
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
function createExpressContextMiddleware(options = {}) {
|
|
41
|
+
const { enrich, requestIdHeader = "x-request-id", traceIdHeader = "x-trace-id" } = options;
|
|
42
|
+
return function logixiaContextMiddleware(req, _res, next) {
|
|
43
|
+
const headers = req["headers"] ?? {};
|
|
44
|
+
const traceId = headers[traceIdHeader];
|
|
45
|
+
const base = {
|
|
46
|
+
requestId: headers[requestIdHeader] ?? crypto.randomUUID().slice(0, 8),
|
|
47
|
+
...traceId !== void 0 ? { traceId } : {}
|
|
48
|
+
};
|
|
49
|
+
LogixiaContext.run({
|
|
50
|
+
...base,
|
|
51
|
+
...enrich ? enrich(req) : {}
|
|
52
|
+
}, next);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a Fastify lifecycle hook that wraps each request in a context scope.
|
|
57
|
+
*
|
|
58
|
+
* Register with `fastify.addHook('onRequest', createFastifyContextHook())`.
|
|
59
|
+
*/
|
|
60
|
+
function createFastifyContextHook(options = {}) {
|
|
61
|
+
const { enrich, requestIdHeader = "x-request-id", traceIdHeader = "x-trace-id" } = options;
|
|
62
|
+
return function logixiaFastifyHook(request, _reply, done) {
|
|
63
|
+
const headers = request["headers"] ?? {};
|
|
64
|
+
const traceId = headers[traceIdHeader];
|
|
65
|
+
const base = {
|
|
66
|
+
requestId: headers[requestIdHeader] ?? request["id"] ?? crypto.randomUUID().slice(0, 8),
|
|
67
|
+
...traceId !== void 0 ? { traceId } : {}
|
|
68
|
+
};
|
|
69
|
+
LogixiaContext.run({
|
|
70
|
+
...base,
|
|
71
|
+
...enrich ? enrich(request) : {}
|
|
72
|
+
}, done);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
8
77
|
//#region src/types/index.ts
|
|
9
78
|
const LogLevel = {
|
|
10
79
|
ERROR: "error",
|
|
@@ -223,6 +292,137 @@ function isPlainObject(value) {
|
|
|
223
292
|
return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date) && !(value instanceof Error) && !(value instanceof RegExp);
|
|
224
293
|
}
|
|
225
294
|
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/utils/sampling.utils.ts
|
|
297
|
+
const ALWAYS_EMIT_LEVELS = new Set(["error", "fatal"]);
|
|
298
|
+
var Sampler = class {
|
|
299
|
+
constructor(config, onStats) {
|
|
300
|
+
this.sampledTraces = /* @__PURE__ */ new Set();
|
|
301
|
+
this.droppedTraces = /* @__PURE__ */ new Set();
|
|
302
|
+
this._tokenBucket = 0;
|
|
303
|
+
this._lastRefillMs = Date.now();
|
|
304
|
+
this._stats = {
|
|
305
|
+
evaluated: 0,
|
|
306
|
+
emitted: 0,
|
|
307
|
+
dropped: 0,
|
|
308
|
+
byLevel: {},
|
|
309
|
+
windowStart: Date.now()
|
|
310
|
+
};
|
|
311
|
+
this.config = config;
|
|
312
|
+
if (config.maxLogsPerSecond && config.maxLogsPerSecond > 0) this._tokenBucket = config.maxLogsPerSecond;
|
|
313
|
+
const interval$1 = config.statsIntervalMs ?? 6e4;
|
|
314
|
+
if (interval$1 > 0 && onStats) {
|
|
315
|
+
this._statsTimer = setInterval(() => {
|
|
316
|
+
onStats(this.getStats());
|
|
317
|
+
this.resetStats();
|
|
318
|
+
}, interval$1);
|
|
319
|
+
if (this._statsTimer.unref) this._statsTimer.unref();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Decide whether a given log entry should be emitted.
|
|
324
|
+
*
|
|
325
|
+
* @param level Log level string (lowercase)
|
|
326
|
+
* @param traceId Active trace ID, if any
|
|
327
|
+
* @returns true → emit, false → drop
|
|
328
|
+
*/
|
|
329
|
+
shouldEmit(level, traceId) {
|
|
330
|
+
var _this$config$perLevel;
|
|
331
|
+
const lvl = level.toLowerCase();
|
|
332
|
+
this._trackEvaluated(lvl);
|
|
333
|
+
if (ALWAYS_EMIT_LEVELS.has(lvl) && ((_this$config$perLevel = this.config.perLevel) === null || _this$config$perLevel === void 0 ? void 0 : _this$config$perLevel[lvl]) === void 0) {
|
|
334
|
+
this._trackEmitted(lvl);
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
if (this.config.traceConsistent && traceId) {
|
|
338
|
+
if (this.sampledTraces.has(traceId)) {
|
|
339
|
+
this._trackEmitted(lvl);
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
if (this.droppedTraces.has(traceId)) {
|
|
343
|
+
this._trackDropped(lvl);
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
const emit = this._sampleByRate(lvl);
|
|
347
|
+
if (emit) this.sampledTraces.add(traceId);
|
|
348
|
+
else this.droppedTraces.add(traceId);
|
|
349
|
+
if (emit) this._trackEmitted(lvl);
|
|
350
|
+
else this._trackDropped(lvl);
|
|
351
|
+
return emit;
|
|
352
|
+
}
|
|
353
|
+
if (!this._sampleByRate(lvl)) {
|
|
354
|
+
this._trackDropped(lvl);
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
if (this.config.maxLogsPerSecond && this.config.maxLogsPerSecond > 0) {
|
|
358
|
+
if (!this._consumeToken()) {
|
|
359
|
+
this._trackDropped(lvl);
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
this._trackEmitted(lvl);
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
getStats() {
|
|
367
|
+
return {
|
|
368
|
+
...this._stats,
|
|
369
|
+
byLevel: { ...this._stats.byLevel }
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
resetStats() {
|
|
373
|
+
this._stats = {
|
|
374
|
+
evaluated: 0,
|
|
375
|
+
emitted: 0,
|
|
376
|
+
dropped: 0,
|
|
377
|
+
byLevel: {},
|
|
378
|
+
windowStart: Date.now()
|
|
379
|
+
};
|
|
380
|
+
this.sampledTraces.clear();
|
|
381
|
+
this.droppedTraces.clear();
|
|
382
|
+
}
|
|
383
|
+
destroy() {
|
|
384
|
+
if (this._statsTimer) clearInterval(this._statsTimer);
|
|
385
|
+
}
|
|
386
|
+
_sampleByRate(level) {
|
|
387
|
+
var _this$config$perLevel2, _this$config$perLevel3;
|
|
388
|
+
const rate = ((_this$config$perLevel2 = this.config.perLevel) === null || _this$config$perLevel2 === void 0 ? void 0 : _this$config$perLevel2[level]) ?? ((_this$config$perLevel3 = this.config.perLevel) === null || _this$config$perLevel3 === void 0 ? void 0 : _this$config$perLevel3["*"]) ?? this.config.rate ?? 1;
|
|
389
|
+
if (rate >= 1) return true;
|
|
390
|
+
if (rate <= 0) return false;
|
|
391
|
+
return Math.random() < rate;
|
|
392
|
+
}
|
|
393
|
+
_consumeToken() {
|
|
394
|
+
const now = Date.now();
|
|
395
|
+
const elapsed = (now - this._lastRefillMs) / 1e3;
|
|
396
|
+
const max$1 = this.config.maxLogsPerSecond;
|
|
397
|
+
this._tokenBucket = Math.min(max$1, this._tokenBucket + elapsed * max$1);
|
|
398
|
+
this._lastRefillMs = now;
|
|
399
|
+
if (this._tokenBucket >= 1) {
|
|
400
|
+
this._tokenBucket -= 1;
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
_ensure(level) {
|
|
406
|
+
if (!this._stats.byLevel[level]) this._stats.byLevel[level] = {
|
|
407
|
+
evaluated: 0,
|
|
408
|
+
emitted: 0
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
_trackEvaluated(level) {
|
|
412
|
+
this._stats.evaluated++;
|
|
413
|
+
this._ensure(level);
|
|
414
|
+
this._stats.byLevel[level].evaluated++;
|
|
415
|
+
}
|
|
416
|
+
_trackEmitted(level) {
|
|
417
|
+
this._stats.emitted++;
|
|
418
|
+
this._ensure(level);
|
|
419
|
+
this._stats.byLevel[level].emitted++;
|
|
420
|
+
}
|
|
421
|
+
_trackDropped(_level) {
|
|
422
|
+
this._stats.dropped++;
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
|
|
226
426
|
//#endregion
|
|
227
427
|
//#region src/utils/shutdown.utils.ts
|
|
228
428
|
/** Module-level registry of all logger instances that have opted into graceful shutdown */
|
|
@@ -286,7 +486,7 @@ const rnds8Pool = new Uint8Array(256);
|
|
|
286
486
|
let poolPtr = rnds8Pool.length;
|
|
287
487
|
function rng() {
|
|
288
488
|
if (poolPtr > rnds8Pool.length - 16) {
|
|
289
|
-
crypto.randomFillSync(rnds8Pool);
|
|
489
|
+
crypto$1.randomFillSync(rnds8Pool);
|
|
290
490
|
poolPtr = 0;
|
|
291
491
|
}
|
|
292
492
|
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
@@ -306,7 +506,7 @@ function unsafeStringify(arr, offset = 0) {
|
|
|
306
506
|
|
|
307
507
|
//#endregion
|
|
308
508
|
//#region node_modules/uuid/dist/esm-node/native.js
|
|
309
|
-
var native_default = { randomUUID: crypto.randomUUID };
|
|
509
|
+
var native_default = { randomUUID: crypto$1.randomUUID };
|
|
310
510
|
|
|
311
511
|
//#endregion
|
|
312
512
|
//#region node_modules/uuid/dist/esm-node/v4.js
|
|
@@ -544,6 +744,13 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
544
744
|
};
|
|
545
745
|
this.context = context$1 ?? "";
|
|
546
746
|
if (this.config.transports) this.transportManager = new TransportManager(this.config.transports);
|
|
747
|
+
if (this.config.sampling) this._sampler = new Sampler(this.config.sampling, (stats) => {
|
|
748
|
+
process.stdout.write(JSON.stringify({
|
|
749
|
+
level: "info",
|
|
750
|
+
message: "[logixia/sampling] stats",
|
|
751
|
+
...stats
|
|
752
|
+
}) + "\n");
|
|
753
|
+
});
|
|
547
754
|
this.setupGracefulShutdown();
|
|
548
755
|
this.createCustomLevelMethods();
|
|
549
756
|
this._buildPerfCaches();
|
|
@@ -783,6 +990,7 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
783
990
|
return this.transportManager.healthCheck();
|
|
784
991
|
}
|
|
785
992
|
async close() {
|
|
993
|
+
var _this$_sampler;
|
|
786
994
|
for (const [label, timer$1] of this.timers) await this.warn(`Timer '${label}' was not ended properly`, {
|
|
787
995
|
startTime: new Date(timer$1.startTime).toISOString(),
|
|
788
996
|
duration: `${Date.now() - timer$1.startTime}ms (incomplete)`
|
|
@@ -792,15 +1000,25 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
792
1000
|
await this.transportManager.flush();
|
|
793
1001
|
await this.transportManager.close();
|
|
794
1002
|
}
|
|
1003
|
+
(_this$_sampler = this._sampler) === null || _this$_sampler === void 0 || _this$_sampler.destroy();
|
|
795
1004
|
deregisterFromShutdown(this);
|
|
796
1005
|
}
|
|
797
1006
|
async log(level, message, data) {
|
|
798
1007
|
if (this.config.silent) return;
|
|
799
1008
|
if (!this.shouldLog(level)) return;
|
|
800
|
-
|
|
801
|
-
|
|
1009
|
+
if (this._sampler) {
|
|
1010
|
+
const traceId$1 = this.config.traceId ? getCurrentTraceId() ?? this.fallbackTraceId : void 0;
|
|
1011
|
+
if (!this._sampler.shouldEmit(level, traceId$1)) return;
|
|
1012
|
+
}
|
|
1013
|
+
const alsContext = LogixiaContext.get();
|
|
1014
|
+
const mergedData = alsContext && Object.keys(alsContext).length > 0 ? {
|
|
1015
|
+
...alsContext,
|
|
802
1016
|
...data
|
|
803
1017
|
} : data;
|
|
1018
|
+
const rawPayload = this._hasContextData ? {
|
|
1019
|
+
...this.contextData,
|
|
1020
|
+
...mergedData
|
|
1021
|
+
} : mergedData;
|
|
804
1022
|
let payload;
|
|
805
1023
|
if (rawPayload !== void 0 && rawPayload !== null) payload = this._hasRedact ? applyRedaction(rawPayload, this.config.redact) ?? rawPayload : rawPayload;
|
|
806
1024
|
const traceId = this.config.traceId ? getCurrentTraceId() ?? this.fallbackTraceId : void 0;
|
|
@@ -10303,5 +10521,5 @@ let LogixiaLoggerModule = class LogixiaLoggerModule$1 {
|
|
|
10303
10521
|
LogixiaLoggerModule = _LogixiaLoggerModule = __decorate([Module({})], LogixiaLoggerModule);
|
|
10304
10522
|
|
|
10305
10523
|
//#endregion
|
|
10306
|
-
export { redactObject as C, DEFAULT_LOG_COLORS as D, serializeError as E, DEFAULT_LOG_LEVELS as O, applyRedaction as S, normalizeError as T, traceStorage as _, TraceMiddleware as a, registerForShutdown as b, LogixiaLogger as c, createTraceMiddleware as d, extractTraceId as f, setTraceId as g, runWithTraceId as h, WebSocketTraceInterceptor as i, LogLevel as k, createLogger as l, getCurrentTraceId as m, LOGIXIA_LOGGER_PREFIX as n, KafkaTraceInterceptor as o, generateTraceId as p, LogixiaLoggerModule as r, LogixiaLoggerService as s, LOGIXIA_LOGGER_CONFIG as t, DEFAULT_TRACE_HEADERS$1 as u, deregisterFromShutdown as v, isError as w, resetShutdownHandlers as x, flushOnExit as y };
|
|
10307
|
-
//# sourceMappingURL=logitron-logger.module-
|
|
10524
|
+
export { LogixiaContext as A, redactObject as C, DEFAULT_LOG_COLORS as D, serializeError as E, createFastifyContextHook as M, DEFAULT_LOG_LEVELS as O, applyRedaction as S, normalizeError as T, traceStorage as _, TraceMiddleware as a, registerForShutdown as b, LogixiaLogger as c, createTraceMiddleware as d, extractTraceId as f, setTraceId as g, runWithTraceId as h, WebSocketTraceInterceptor as i, createExpressContextMiddleware as j, LogLevel as k, createLogger as l, getCurrentTraceId as m, LOGIXIA_LOGGER_PREFIX as n, KafkaTraceInterceptor as o, generateTraceId as p, LogixiaLoggerModule as r, LogixiaLoggerService as s, LOGIXIA_LOGGER_CONFIG as t, DEFAULT_TRACE_HEADERS$1 as u, deregisterFromShutdown as v, isError as w, resetShutdownHandlers as x, flushOnExit as y };
|
|
10525
|
+
//# sourceMappingURL=logitron-logger.module-2AzkadqZ.mjs.map
|