logixia 1.12.6 → 1.13.3

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.
Files changed (154) hide show
  1. package/README.md +19 -4
  2. package/dist/{async-context-CwBNMm2E.mjs → async-context-BzJrbfQs.mjs} +8 -4
  3. package/dist/async-context-BzJrbfQs.mjs.map +1 -0
  4. package/dist/{async-context-CSHWoHMB.js → async-context-DyQQYq3I.js} +8 -4
  5. package/dist/async-context-DyQQYq3I.js.map +1 -0
  6. package/dist/{azure-monitor.transport-CG7ClkYj.d.ts → azure-monitor.transport-BDFO4F-i.d.ts} +2 -2
  7. package/dist/{azure-monitor.transport-CG7ClkYj.d.ts.map → azure-monitor.transport-BDFO4F-i.d.ts.map} +1 -1
  8. package/dist/{azure-monitor.transport-Cm74kXZS.d.mts → azure-monitor.transport-D5wQEH04.d.mts} +2 -2
  9. package/dist/{azure-monitor.transport-Cm74kXZS.d.mts.map → azure-monitor.transport-D5wQEH04.d.mts.map} +1 -1
  10. package/dist/azure.d.mts +2 -2
  11. package/dist/azure.d.ts +2 -2
  12. package/dist/cli/index.js +98 -52
  13. package/dist/cloudwatch.d.mts +2 -2
  14. package/dist/cloudwatch.d.ts +2 -2
  15. package/dist/cloudwatch.js +2 -1
  16. package/dist/cloudwatch.mjs +2 -1
  17. package/dist/{cloudwatch.transport-CGHY4buE.d.mts → cloudwatch.transport-B00st6Xv.d.ts} +9 -2
  18. package/dist/cloudwatch.transport-B00st6Xv.d.ts.map +1 -0
  19. package/dist/{cloudwatch.transport-pNBNWJLt.js → cloudwatch.transport-BO1ahxw-.js} +26 -19
  20. package/dist/cloudwatch.transport-BO1ahxw-.js.map +1 -0
  21. package/dist/{cloudwatch.transport-DK_8cKd3.d.ts → cloudwatch.transport-Blc7Gtxt.d.mts} +9 -2
  22. package/dist/cloudwatch.transport-Blc7Gtxt.d.mts.map +1 -0
  23. package/dist/{cloudwatch.transport-yBwm4OeO.mjs → cloudwatch.transport-DZ6ies7g.mjs} +26 -19
  24. package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +1 -0
  25. package/dist/{coerce.utils-BN980Y9V.js → coerce.utils-B-LilukN.js} +1 -1
  26. package/dist/{coerce.utils-BN980Y9V.js.map → coerce.utils-B-LilukN.js.map} +1 -1
  27. package/dist/{coerce.utils-Dxv4_ikC.mjs → coerce.utils-Cu6IUTgX.mjs} +1 -1
  28. package/dist/{coerce.utils-Dxv4_ikC.mjs.map → coerce.utils-Cu6IUTgX.mjs.map} +1 -1
  29. package/dist/correlation.d.mts +31 -6
  30. package/dist/correlation.d.mts.map +1 -1
  31. package/dist/correlation.d.ts +31 -6
  32. package/dist/correlation.d.ts.map +1 -1
  33. package/dist/correlation.js +45 -20
  34. package/dist/correlation.js.map +1 -1
  35. package/dist/correlation.mjs +45 -20
  36. package/dist/correlation.mjs.map +1 -1
  37. package/dist/entry-fields-BJkuPnIg.mjs +30 -0
  38. package/dist/entry-fields-BJkuPnIg.mjs.map +1 -0
  39. package/dist/entry-fields-BvOLFlJ4.js +36 -0
  40. package/dist/entry-fields-BvOLFlJ4.js.map +1 -0
  41. package/dist/gcp.d.mts +2 -2
  42. package/dist/gcp.d.ts +2 -2
  43. package/dist/gcp.js +2 -1
  44. package/dist/gcp.mjs +2 -1
  45. package/dist/{gcp.transport-SHdtc1n0.js → gcp.transport-CHV8MGgz.js} +5 -5
  46. package/dist/gcp.transport-CHV8MGgz.js.map +1 -0
  47. package/dist/{gcp.transport-BJuNRFe_.mjs → gcp.transport-DBX5TPIy.mjs} +5 -5
  48. package/dist/gcp.transport-DBX5TPIy.mjs.map +1 -0
  49. package/dist/{gcp.transport-BOhkVKlI.d.ts → gcp.transport-m4fVw0b1.d.ts} +2 -2
  50. package/dist/gcp.transport-m4fVw0b1.d.ts.map +1 -0
  51. package/dist/{gcp.transport-Bi6CUqZR.d.mts → gcp.transport-zzNyIoih.d.mts} +2 -2
  52. package/dist/gcp.transport-zzNyIoih.d.mts.map +1 -0
  53. package/dist/{index-BPKwwERo.d.mts → index-BPwEisy4.d.mts} +2 -2
  54. package/dist/{index-BPKwwERo.d.mts.map → index-BPwEisy4.d.mts.map} +1 -1
  55. package/dist/{index-C1X-TE5I.d.ts → index-nZEeCr3X.d.ts} +2 -2
  56. package/dist/{index-C1X-TE5I.d.ts.map → index-nZEeCr3X.d.ts.map} +1 -1
  57. package/dist/index.d.mts +63 -98
  58. package/dist/index.d.mts.map +1 -1
  59. package/dist/index.d.ts +63 -98
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +167 -443
  62. package/dist/index.js.map +1 -1
  63. package/dist/index.mjs +98 -377
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/middleware.d.mts +11 -4
  66. package/dist/middleware.d.mts.map +1 -1
  67. package/dist/middleware.d.ts +11 -4
  68. package/dist/middleware.d.ts.map +1 -1
  69. package/dist/middleware.js +148 -24
  70. package/dist/middleware.js.map +1 -1
  71. package/dist/middleware.mjs +148 -24
  72. package/dist/middleware.mjs.map +1 -1
  73. package/dist/nest.d.mts +4 -4
  74. package/dist/nest.d.ts +4 -4
  75. package/dist/nest.js +20 -11
  76. package/dist/nest.mjs +7 -5
  77. package/dist/{logitron-logger.module-BsDZR5BH.js → nestjs-extras-DnJ6vrIC.js} +562 -444
  78. package/dist/nestjs-extras-DnJ6vrIC.js.map +1 -0
  79. package/dist/{logitron-logger.module-Bs3XYZgF.mjs → nestjs-extras-ImbuDhs1.mjs} +505 -349
  80. package/dist/nestjs-extras-ImbuDhs1.mjs.map +1 -0
  81. package/dist/{logitron-logger.module-zDKVd_o0.d.mts → nestjs-extras-OkC796py.d.mts} +113 -6
  82. package/dist/nestjs-extras-OkC796py.d.mts.map +1 -0
  83. package/dist/{logitron-logger.module-CxT1F6Cm.d.ts → nestjs-extras-mKrHE9S6.d.ts} +113 -6
  84. package/dist/nestjs-extras-mKrHE9S6.d.ts.map +1 -0
  85. package/dist/{search-njTI2hdo.js → search-B0MH1SJJ.js} +23 -10
  86. package/dist/search-B0MH1SJJ.js.map +1 -0
  87. package/dist/{search-DujhR94O.d.ts → search-BfBzDIT9.d.mts} +2 -3
  88. package/dist/search-BfBzDIT9.d.mts.map +1 -0
  89. package/dist/{search-CQOo-Iq6.d.mts → search-CHUZPl0h.d.ts} +2 -3
  90. package/dist/search-CHUZPl0h.d.ts.map +1 -0
  91. package/dist/{search-CFQRISUv.mjs → search-DjXSn6v5.mjs} +23 -10
  92. package/dist/search-DjXSn6v5.mjs.map +1 -0
  93. package/dist/search.d.mts +3 -3
  94. package/dist/search.d.ts +3 -3
  95. package/dist/search.js +2 -2
  96. package/dist/search.mjs +2 -2
  97. package/dist/testing.d.mts +2 -2
  98. package/dist/testing.d.ts +2 -2
  99. package/dist/trace.utils-CvXgaiQT.mjs +278 -0
  100. package/dist/trace.utils-CvXgaiQT.mjs.map +1 -0
  101. package/dist/trace.utils-DpBOLDtq.js +358 -0
  102. package/dist/trace.utils-DpBOLDtq.js.map +1 -0
  103. package/dist/{transport.manager-D6KL3t9V.mjs → transport.manager-CpdVHEGP.mjs} +365 -86
  104. package/dist/transport.manager-CpdVHEGP.mjs.map +1 -0
  105. package/dist/{transport.manager-BivyUTtU.js → transport.manager-Crau3Rle.js} +370 -85
  106. package/dist/transport.manager-Crau3Rle.js.map +1 -0
  107. package/dist/{transport.types-B5vcyv2k.d.mts → transport.types-CtNr3D7S.d.mts} +19 -2
  108. package/dist/transport.types-CtNr3D7S.d.mts.map +1 -0
  109. package/dist/{transport.types-BuY84TwO.d.ts → transport.types-DqVLZTyf.d.ts} +19 -2
  110. package/dist/transport.types-DqVLZTyf.d.ts.map +1 -0
  111. package/dist/transports.d.mts +38 -13
  112. package/dist/transports.d.mts.map +1 -1
  113. package/dist/transports.d.ts +38 -13
  114. package/dist/transports.d.ts.map +1 -1
  115. package/dist/transports.js +6 -5
  116. package/dist/transports.mjs +6 -5
  117. package/dist/worker-entry.js +307 -55
  118. package/dist/worker.d.mts +2 -2
  119. package/dist/worker.d.ts +2 -2
  120. package/dist/worker.js +1 -1
  121. package/dist/worker.mjs +1 -1
  122. package/dist/{worker.transport-BP8Q28Z2.d.mts → worker.transport-Bgv9heDI.d.mts} +2 -2
  123. package/dist/{worker.transport-BP8Q28Z2.d.mts.map → worker.transport-Bgv9heDI.d.mts.map} +1 -1
  124. package/dist/{worker.transport-mKXgNK0L.d.ts → worker.transport-Bj-i0P9V.d.ts} +2 -2
  125. package/dist/{worker.transport-mKXgNK0L.d.ts.map → worker.transport-Bj-i0P9V.d.ts.map} +1 -1
  126. package/dist/{worker.transport-CfH6z37Z.js → worker.transport-JP8YHBuU.js} +1 -1
  127. package/dist/{worker.transport-CfH6z37Z.js.map → worker.transport-JP8YHBuU.js.map} +1 -1
  128. package/dist/{worker.transport-BhMyvqQ2.mjs → worker.transport-otwhJ_Et.mjs} +1 -1
  129. package/dist/{worker.transport-BhMyvqQ2.mjs.map → worker.transport-otwhJ_Et.mjs.map} +1 -1
  130. package/package.json +10 -6
  131. package/dist/.tsbuildinfo +0 -1
  132. package/dist/async-context-CSHWoHMB.js.map +0 -1
  133. package/dist/async-context-CwBNMm2E.mjs.map +0 -1
  134. package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +0 -1
  135. package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +0 -1
  136. package/dist/cloudwatch.transport-pNBNWJLt.js.map +0 -1
  137. package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +0 -1
  138. package/dist/gcp.transport-BJuNRFe_.mjs.map +0 -1
  139. package/dist/gcp.transport-BOhkVKlI.d.ts.map +0 -1
  140. package/dist/gcp.transport-Bi6CUqZR.d.mts.map +0 -1
  141. package/dist/gcp.transport-SHdtc1n0.js.map +0 -1
  142. package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +0 -1
  143. package/dist/logitron-logger.module-BsDZR5BH.js.map +0 -1
  144. package/dist/logitron-logger.module-CxT1F6Cm.d.ts.map +0 -1
  145. package/dist/logitron-logger.module-zDKVd_o0.d.mts.map +0 -1
  146. package/dist/search-CFQRISUv.mjs.map +0 -1
  147. package/dist/search-CQOo-Iq6.d.mts.map +0 -1
  148. package/dist/search-DujhR94O.d.ts.map +0 -1
  149. package/dist/search-njTI2hdo.js.map +0 -1
  150. package/dist/transport.manager-BivyUTtU.js.map +0 -1
  151. package/dist/transport.manager-D6KL3t9V.mjs.map +0 -1
  152. package/dist/transport.types-B5vcyv2k.d.mts.map +0 -1
  153. package/dist/transport.types-BuY84TwO.d.ts.map +0 -1
  154. package/scripts/postinstall.js +0 -61
package/dist/index.mjs CHANGED
@@ -1,368 +1,15 @@
1
- import { n as internalLog, r as internalWarn, t as internalError } from "./internal-log-Cm8SOWSV.mjs";
1
+ import { n as internalLog, r as internalWarn } from "./internal-log-Cm8SOWSV.mjs";
2
2
  import { i as stringifyForLog, n as retrocycle, r as safeStringify, t as decycleValue } from "./safe-stringify-DJ66tW5I.mjs";
3
3
  import { i as HttpError, n as DEFAULT_MAX_BUFFER_SIZE, r as DEFAULT_REQUEST_TIMEOUT_MS, t as BatchBuffer } from "./batch-buffer-PGvSgbmd.mjs";
4
- import { n as createExpressContextMiddleware, r as createFastifyContextHook, t as LogixiaContext } from "./async-context-CwBNMm2E.mjs";
5
- import { A as resetShutdownHandlers, B as DEFAULT_LOG_COLORS, C as runWithTraceId, D as deregisterFromShutdown, E as _shutdownRegistrySize, F as getOtelMetaFields, G as usePlugin, H as LogLevel, I as initOtelBridge, L as isError, M as redactObject, N as disableOtelBridge, O as flushOnExit, P as getActiveOtelContext, R as normalizeError, S as getTraceContextKey, T as traceStorage, U as PluginRegistry, V as DEFAULT_LOG_LEVELS, W as globalPluginRegistry, _ as TraceContext, a as WebSocketTraceInterceptor, b as extractTraceId, c as __decorateParam, d as __decorate, f as __decorateMetadata, g as TRACE_CONTEXT_KEY, h as DEFAULT_TRACE_HEADERS, i as LogixiaLoggerModule, j as applyRedaction, k as registerForShutdown, l as KafkaTraceInterceptor, m as createLogger$1, n as LOGIXIA_LOGGER_PREFIX, p as LogixiaLogger, r as LOGIXIA_TRACE_CONFIG, s as resolveResponseHeader, t as LOGIXIA_LOGGER_CONFIG, u as LogixiaLoggerService, v as _setActiveContextKey, w as setTraceId, x as getCurrentTraceId, y as createTraceMiddleware, z as serializeError } from "./logitron-logger.module-Bs3XYZgF.mjs";
6
- import { t as safeToString } from "./coerce.utils-Dxv4_ikC.mjs";
7
- import "./transport.manager-D6KL3t9V.mjs";
8
- import { a as BasicSearchEngine, i as CorrelationEngine, n as PatternRecognitionEngine, o as BasicLogIndexer, r as NLPSearchEngine, t as SearchManager } from "./search-CFQRISUv.mjs";
4
+ import "./entry-fields-BJkuPnIg.mjs";
5
+ import { a as _setActiveContextKey, c as getCurrentTraceId, d as sanitizeIncomingId, f as setTraceId, i as TraceContext, l as getTraceContextKey, n as MAX_INCOMING_ID_LENGTH, o as createTraceMiddleware, p as traceStorage, r as TRACE_CONTEXT_KEY, s as extractTraceId, t as DEFAULT_TRACE_HEADERS, u as runWithTraceId } from "./trace.utils-CvXgaiQT.mjs";
6
+ import { n as createExpressContextMiddleware, r as createFastifyContextHook, t as LogixiaContext } from "./async-context-BzJrbfQs.mjs";
7
+ import { A as initOtelBridge, C as registerForShutdown, D as disableOtelBridge, E as redactObject, F as DEFAULT_LOG_LEVELS, I as LogLevel, L as PluginRegistry, M as normalizeError, N as serializeError, O as getActiveOtelContext, P as DEFAULT_LOG_COLORS, R as globalPluginRegistry, S as flushOnExit, T as applyRedaction, _ as LogixiaLoggerService, a as ErrorResponseBuilder, b as _shutdownRegistrySize, c as LogixiaException, d as LOGIXIA_LOGGER_PREFIX, f as LOGIXIA_TRACE_CONFIG, g as KafkaTraceInterceptor, i as LogixiaExceptionFilter, j as isError, k as getOtelMetaFields, l as isLogixiaException, m as WebSocketTraceInterceptor, n as LOGIXIA_EXCEPTION_FILTER_OPTIONS, o as generateRequestId, p as LogixiaLoggerModule, r as LogMethod, s as generateTraceId, t as InjectLogger, u as LOGIXIA_LOGGER_CONFIG, v as LogixiaLogger, w as resetShutdownHandlers, x as deregisterFromShutdown, y as createLogger$1, z as usePlugin } from "./nestjs-extras-ImbuDhs1.mjs";
8
+ import { t as safeToString } from "./coerce.utils-Cu6IUTgX.mjs";
9
+ import { u as stripControlChars } from "./transport.manager-CpdVHEGP.mjs";
10
+ import { a as BasicSearchEngine, i as CorrelationEngine, n as PatternRecognitionEngine, o as BasicLogIndexer, r as NLPSearchEngine, t as SearchManager } from "./search-DjXSn6v5.mjs";
9
11
  import { AsyncLocalStorage } from "node:async_hooks";
10
- import { Catch, Inject, Optional } from "@nestjs/common";
11
12
 
12
- //#region src/exceptions/exception.ts
13
- var LogixiaException = class extends Error {
14
- constructor(options) {
15
- super(options.message, { cause: options.cause });
16
- this.name = "LogixiaException";
17
- this.errorCode = options.code;
18
- this.errorType = options.type;
19
- this.httpStatus = options.httpStatus;
20
- this.param = options.param;
21
- this.details = options.details;
22
- this.docUrl = options.docUrl;
23
- this.metadata = options.metadata;
24
- Object.setPrototypeOf(this, new.target.prototype);
25
- }
26
- };
27
- /**
28
- * Returns `true` when `value` is a `LogixiaException` instance.
29
- *
30
- * Useful in exception filters or middleware that need to distinguish a
31
- * `LogixiaException` from a plain `Error` or a framework `HttpException`.
32
- *
33
- * @example
34
- * ```ts
35
- * if (isLogixiaException(err)) {
36
- * console.log(err.errorCode, err.httpStatus);
37
- * }
38
- * ```
39
- */
40
- function isLogixiaException(value) {
41
- return value instanceof LogixiaException;
42
- }
43
-
44
- //#endregion
45
- //#region src/exceptions/builder.ts
46
- /**
47
- * Generates a trace ID via the shared {@link TraceContext} generator.
48
- *
49
- * Delegates to `TraceContext.instance.generate()` so any custom generator
50
- * configured on `TraceIdConfig.generator` is respected — avoids the silent
51
- * "builder has its own UUID source" divergence this module had previously.
52
- *
53
- * @example `'550e8400-e29b-41d4-a716-446655440000'`
54
- */
55
- function generateTraceId() {
56
- return TraceContext.instance.generate();
57
- }
58
- /** @deprecated Use `generateTraceId` instead. */
59
- const generateRequestId = generateTraceId;
60
- /**
61
- * Maps an HTTP status code to a human-friendly error type string.
62
- * Used as a fallback when the exception is a generic `HttpException`.
63
- */
64
- function httpStatusToType(status) {
65
- if (status === 400) return "api_error";
66
- if (status === 401) return "authentication_error";
67
- if (status === 402) return "payment_error";
68
- if (status === 403) return "authorization_error";
69
- if (status === 404) return "not_found_error";
70
- if (status === 408) return "timeout_error";
71
- if (status === 409) return "conflict_error";
72
- if (status === 422) return "validation_error";
73
- if (status === 429) return "rate_limit_error";
74
- if (status >= 500) return "server_error";
75
- if (status >= 400) return "api_error";
76
- return "server_error";
77
- }
78
- /**
79
- * Duck-type check for NestJS `HttpException`.
80
- * Avoids a hard import on `@nestjs/common` so the builder is usable outside NestJS.
81
- */
82
- function isHttpException(value) {
83
- return typeof value === "object" && value !== null && typeof value["getStatus"] === "function" && typeof value["getResponse"] === "function";
84
- }
85
- /**
86
- * Builds the optional `debug` block from an error.
87
- * Returns `undefined` when there is nothing useful to include.
88
- */
89
- function buildDebug(error, service, durationMs) {
90
- const stack = error instanceof Error ? error.stack : void 0;
91
- const causeRaw = error instanceof Error ? error.cause : void 0;
92
- let cause;
93
- if (causeRaw instanceof Error) cause = causeRaw.message;
94
- else if (causeRaw !== void 0 && causeRaw !== null) cause = String(causeRaw);
95
- if (!stack && !cause && !service && durationMs === void 0) return void 0;
96
- return {
97
- ...stack !== void 0 ? { stack } : {},
98
- ...cause !== void 0 ? { cause } : {},
99
- ...service !== void 0 ? { service } : {},
100
- ...durationMs !== void 0 ? { duration_ms: durationMs } : {}
101
- };
102
- }
103
- var ErrorResponseBuilder = class {
104
- /**
105
- * Build a `LogixiaErrorResponse` from any thrown value.
106
- *
107
- * @param params - See `BuildParams`.
108
- * @returns The unified error response and the HTTP status code to send.
109
- *
110
- * @remarks
111
- * `traceId` does not need to be supplied by the caller in most cases — the
112
- * builder reads `TraceContext.instance.getCurrentTraceId()` internally and
113
- * falls back to the explicit `traceId` argument only when AsyncLocalStorage
114
- * is empty. If neither source yields a value, `meta.trace_id` is omitted.
115
- *
116
- * @example In a NestJS exception filter
117
- * ```ts
118
- * const { response, httpStatus } = ErrorResponseBuilder.build<AppCode, AppType>({
119
- * exception,
120
- * // Omit traceId — it will be picked up from ALS automatically.
121
- * path: request.url,
122
- * service: process.env.SERVICE_NAME,
123
- * startTime: request.startTime,
124
- * });
125
- *
126
- * if (process.env.NODE_ENV === 'production') delete response.debug;
127
- * // Echo the resolved traceId back on whatever header your TraceIdConfig says —
128
- * // do NOT hardcode 'X-Trace-Id', use `resolveResponseHeader(config)` instead.
129
- * if (response.meta.trace_id) {
130
- * response.setHeader(resolveResponseHeader(config) ?? 'X-Trace-Id', response.meta.trace_id);
131
- * }
132
- * response.status(httpStatus).json(response);
133
- * ```
134
- */
135
- static build(params) {
136
- const { exception, path, service, startTime, traceId: rawTraceId } = params;
137
- const traceId = TraceContext.instance.getCurrentTraceId() ?? rawTraceId;
138
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
139
- const durationMs = startTime !== void 0 ? Date.now() - startTime : void 0;
140
- if (isLogixiaException(exception)) {
141
- const debug$1 = buildDebug(exception, service, durationMs);
142
- const errorBlock = {
143
- type: exception.errorType,
144
- code: exception.errorCode,
145
- message: exception.message
146
- };
147
- if (exception.param !== void 0) errorBlock.param = exception.param;
148
- if (exception.details !== void 0 && exception.details.length > 0) errorBlock.details = exception.details;
149
- if (exception.docUrl !== void 0) errorBlock.doc_url = exception.docUrl;
150
- return {
151
- response: {
152
- success: false,
153
- error: errorBlock,
154
- meta: {
155
- ...traceId !== void 0 ? { trace_id: traceId } : {},
156
- timestamp,
157
- path,
158
- status: exception.httpStatus
159
- },
160
- ...debug$1 !== void 0 ? { debug: debug$1 } : {}
161
- },
162
- httpStatus: exception.httpStatus
163
- };
164
- }
165
- if (isHttpException(exception)) {
166
- const status = exception.getStatus();
167
- const exResponse = exception.getResponse();
168
- let message;
169
- if (typeof exResponse === "string") message = exResponse;
170
- else if (typeof exResponse === "object" && exResponse !== null && "message" in exResponse) {
171
- const raw = exResponse.message;
172
- message = Array.isArray(raw) ? raw.join(", ") : String(raw);
173
- } else message = exception.message;
174
- const type = httpStatusToType(status);
175
- const code = `HTTP_${status}`;
176
- const debug$1 = buildDebug(exception, service, durationMs);
177
- return {
178
- response: {
179
- success: false,
180
- error: {
181
- type,
182
- code,
183
- message
184
- },
185
- meta: {
186
- ...traceId !== void 0 ? { trace_id: traceId } : {},
187
- timestamp,
188
- path,
189
- status
190
- },
191
- ...debug$1 !== void 0 ? { debug: debug$1 } : {}
192
- },
193
- httpStatus: status
194
- };
195
- }
196
- const debug = buildDebug(exception instanceof Error ? exception : new Error(String(exception)), service, durationMs);
197
- return {
198
- response: {
199
- success: false,
200
- error: {
201
- type: "server_error",
202
- code: "INTERNAL_SERVER_ERROR",
203
- message: "An unexpected error occurred."
204
- },
205
- meta: {
206
- ...traceId !== void 0 ? { trace_id: traceId } : {},
207
- timestamp,
208
- path,
209
- status: 500
210
- },
211
- ...debug !== void 0 ? { debug } : {}
212
- },
213
- httpStatus: 500
214
- };
215
- }
216
- };
217
-
218
- //#endregion
219
- //#region src/core/nestjs-extras.ts
220
- var _ref;
221
- /**
222
- * Inject the Logixia logger registered in the current NestJS DI container.
223
- *
224
- * Equivalent to `@Inject(LOGIXIA_LOGGER_TOKEN)` but without needing to import
225
- * the internal token constant yourself.
226
- *
227
- * @example
228
- * ```ts
229
- * constructor(@InjectLogger() private readonly logger: LogixiaLoggerService) {}
230
- * ```
231
- */
232
- const InjectLogger = () => Inject(`${LOGIXIA_LOGGER_PREFIX}SERVICE`);
233
- /**
234
- * Method decorator that auto-logs entry, exit, duration, and errors.
235
- *
236
- * Preserves the original method's sync/async contract: a synchronous method
237
- * stays synchronous (returns its value directly, with logs emitted
238
- * fire-and-forget), and an async method is awaited so exit/error logs reflect
239
- * the resolved result. Attaches to the logger found on the class instance via a
240
- * `logger` property (the conventional NestJS name).
241
- *
242
- * @example
243
- * ```ts
244
- * @LogMethod({ level: 'info', logArgs: true })
245
- * async processPayment(orderId: string): Promise<void> { … }
246
- * ```
247
- */
248
- function LogMethod(options = {}) {
249
- const { level = "debug", logArgs = true, logResult = false, logErrors = true } = options;
250
- return function(target, propertyKey, descriptor) {
251
- var _constructor;
252
- const originalMethod = descriptor.value;
253
- if (typeof originalMethod !== "function") return descriptor;
254
- const methodName = String(propertyKey);
255
- const className = ((_constructor = target.constructor) === null || _constructor === void 0 ? void 0 : _constructor.name) ?? "Unknown";
256
- const label = options.label ?? `${className}.${methodName}`;
257
- let _warnedNoLogger = false;
258
- const reportLogFailure = (phase, err) => {
259
- internalError(`@LogMethod(${label}) ${phase} log failed: ${String(err)}`);
260
- };
261
- const emit$1 = (logger$1, phase, message, data) => {
262
- const logFnRaw = logger$1[level];
263
- const p = (typeof logFnRaw === "function" ? logFnRaw : logger$1.debug).bind(logger$1)(message, data);
264
- if (p && typeof p.catch === "function") p.catch((e) => reportLogFailure(phase, e));
265
- };
266
- const emitError = (logger$1, error, start) => {
267
- const err = error instanceof Error ? error : new Error(String(error));
268
- const errLog = logger$1.error(err, {
269
- method: label,
270
- durationMs: Date.now() - start
271
- });
272
- if (errLog && typeof errLog.catch === "function") errLog.catch((e) => reportLogFailure("error", e));
273
- };
274
- descriptor.value = function(...args) {
275
- const logger$1 = this.logger ?? LogixiaLoggerModule._globalLogger ?? void 0;
276
- if (!logger$1 && !_warnedNoLogger) {
277
- _warnedNoLogger = true;
278
- internalWarn(`@LogMethod on ${label}: no logger available. Either inject LogixiaLoggerService as this.logger or ensure LogixiaLoggerModule is initialised.`);
279
- }
280
- const start = Date.now();
281
- const entry = { method: label };
282
- if (logArgs && args.length > 0) entry["args"] = args;
283
- if (logger$1) emit$1(logger$1, "entry", `→ ${label}`, entry);
284
- const buildExit = (result$1) => {
285
- const exit = {
286
- method: label,
287
- durationMs: Date.now() - start
288
- };
289
- if (logResult) exit["result"] = result$1;
290
- return exit;
291
- };
292
- let result;
293
- try {
294
- result = originalMethod.apply(this, args);
295
- } catch (error) {
296
- if (logger$1 && logErrors) emitError(logger$1, error, start);
297
- throw error;
298
- }
299
- if (result && typeof result.then === "function") return result.then((resolved) => {
300
- if (logger$1) emit$1(logger$1, "exit", `← ${label}`, buildExit(resolved));
301
- return resolved;
302
- }, (error) => {
303
- if (logger$1 && logErrors) emitError(logger$1, error, start);
304
- throw error;
305
- });
306
- if (logger$1) emit$1(logger$1, "exit", `← ${label}`, buildExit(result));
307
- return result;
308
- };
309
- return descriptor;
310
- };
311
- }
312
- let LogixiaExceptionFilter = class LogixiaExceptionFilter$1 {
313
- constructor(logger$1, loggerConfig) {
314
- this._logger = logger$1 ?? LogixiaLoggerModule._globalLogger ?? void 0;
315
- this._traceConfig = typeof (loggerConfig === null || loggerConfig === void 0 ? void 0 : loggerConfig.traceId) === "object" ? loggerConfig.traceId : void 0;
316
- }
317
- catch(exception, host) {
318
- var _request$headers;
319
- const ctx = host.switchToHttp();
320
- const request = ctx.getRequest();
321
- const response = ctx.getResponse();
322
- const traceId = TraceContext.instance.getCurrentTraceId() ?? ((_request$headers = request.headers) === null || _request$headers === void 0 ? void 0 : _request$headers["x-trace-id"]) ?? request.id ?? void 0;
323
- const { response: errorResponse, httpStatus } = ErrorResponseBuilder.build({
324
- exception,
325
- traceId,
326
- path: request.url ?? "/",
327
- startTime: request.startTime
328
- });
329
- if (this._logger) {
330
- const requestMeta = {
331
- method: request.method ?? "",
332
- url: request.url ?? "",
333
- status: httpStatus,
334
- ...errorResponse.meta.trace_id !== void 0 ? { trace_id: errorResponse.meta.trace_id } : {}
335
- };
336
- const onLogFailure = (err) => {
337
- internalError(`ExceptionFilter failed to write log entry: ${String(err)}`);
338
- };
339
- let logPromise;
340
- if (httpStatus >= 500) {
341
- const err = exception instanceof Error ? exception : new Error(String(exception));
342
- logPromise = this._logger.error(err, requestMeta);
343
- } else if (isLogixiaException(exception)) logPromise = this._logger.warn(`[${errorResponse.error.code}] ${errorResponse.error.message}`, requestMeta);
344
- else logPromise = this._logger.warn(`[${httpStatus}] ${errorResponse.error.message}`, requestMeta);
345
- if (logPromise && typeof logPromise.catch === "function") logPromise.catch(onLogFailure);
346
- }
347
- if (process.env["NODE_ENV"] === "production") delete errorResponse.debug;
348
- if (errorResponse.meta.trace_id) {
349
- const traceHeader = resolveResponseHeader(this._traceConfig);
350
- if (traceHeader) response.setHeader(traceHeader, errorResponse.meta.trace_id);
351
- }
352
- if (httpStatus === 429) response.setHeader("Retry-After", "60");
353
- response.status(httpStatus).json(errorResponse);
354
- }
355
- };
356
- LogixiaExceptionFilter = __decorate([
357
- Catch(),
358
- __decorateParam(0, Optional()),
359
- __decorateParam(0, Inject(`${LOGIXIA_LOGGER_PREFIX}SERVICE`)),
360
- __decorateParam(1, Optional()),
361
- __decorateParam(1, Inject(LOGIXIA_LOGGER_CONFIG)),
362
- __decorateMetadata("design:paramtypes", [Object, typeof (_ref = typeof Partial !== "undefined" && Partial) === "function" ? _ref : Object])
363
- ], LogixiaExceptionFilter);
364
-
365
- //#endregion
366
13
  //#region src/formatters/json.formatter.ts
367
14
  /**
368
15
  * Build a JSON.stringify replacer that replaces circular references with the
@@ -430,8 +77,7 @@ var JsonFormatter = class {
430
77
 
431
78
  //#endregion
432
79
  //#region src/formatters/text.formatter.ts
433
- const CONTROL_CHARS_RE = /[\x00-\x08\x0B-\x1F\x7F-\x9F]/g;
434
- const stripControls = (value) => safeToString(value).replace(CONTROL_CHARS_RE, "");
80
+ const stripControls = (value) => stripControlChars(safeToString(value));
435
81
  var TextFormatter = class TextFormatter {
436
82
  constructor(options = {}) {
437
83
  this.colorize = options.colorize ?? true;
@@ -583,6 +229,15 @@ function registerLevelSignal(logger$1, options = {}) {
583
229
  process.removeListener(signal, handler);
584
230
  };
585
231
  }
232
+ /** Maximum accepted request body size for the level control handler. */
233
+ const MAX_BODY_BYTES = 16 * 1024;
234
+ function isJsonContentType(req) {
235
+ var _req$headers;
236
+ const raw = (_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers["content-type"];
237
+ const value = Array.isArray(raw) ? raw[0] : raw;
238
+ if (typeof value !== "string") return false;
239
+ return value.split(";")[0].trim().toLowerCase() === "application/json";
240
+ }
586
241
  const VALID_LEVELS = new Set([
587
242
  "error",
588
243
  "warn",
@@ -601,7 +256,16 @@ const VALID_LEVELS = new Set([
601
256
  *
602
257
  * Custom levels are accepted too: any level the logger already knows passes
603
258
  * through. Unknown levels are rejected with 400 so a typo can't silently mute
604
- * logging. Mount behind your own auth — this intentionally has none.
259
+ * logging.
260
+ *
261
+ * **SECURITY: this handler has NO authentication or authorization.** Anyone who
262
+ * can reach it can silence logging or turn on verbose output. Always mount it
263
+ * behind your own auth (and on an internal-only route/port), never on a public
264
+ * listener.
265
+ *
266
+ * Mutating requests must send `Content-Type: application/json` (otherwise 415,
267
+ * which also keeps cross-site form posts out) and a body of at most 16 KB
268
+ * (otherwise 413).
605
269
  */
606
270
  function createLevelControlHandler(logger$1, options = {}) {
607
271
  const allowed = options.allowedLevels && options.allowedLevels.length > 0 ? new Set(options.allowedLevels.map((l) => l.toLowerCase())) : VALID_LEVELS;
@@ -648,8 +312,7 @@ function createLevelControlHandler(logger$1, options = {}) {
648
312
  return;
649
313
  }
650
314
  if (logger$1.setNamespaceLevels) {
651
- const coerced = {};
652
- for (const [pat, lvl] of Object.entries(nl)) coerced[pat] = String(lvl).toLowerCase();
315
+ const coerced = Object.fromEntries(Object.entries(nl).map(([pat, lvl]) => [pat, String(lvl).toLowerCase()]));
653
316
  logger$1.setNamespaceLevels(coerced);
654
317
  } else internalWarn("level control: logger does not support setNamespaceLevels — ignored");
655
318
  }
@@ -662,17 +325,48 @@ function createLevelControlHandler(logger$1, options = {}) {
662
325
  return;
663
326
  }
664
327
  if (method === "POST" || method === "PUT" || method === "PATCH") {
328
+ var _req$headers2;
329
+ if (!isJsonContentType(req)) {
330
+ send(res, 415, { error: "Content-Type must be application/json" });
331
+ return;
332
+ }
333
+ const declared = Number((_req$headers2 = req.headers) === null || _req$headers2 === void 0 ? void 0 : _req$headers2["content-length"]);
334
+ if (Number.isFinite(declared) && declared > MAX_BODY_BYTES) {
335
+ send(res, 413, { error: "request body too large" });
336
+ return;
337
+ }
665
338
  const maybeBody = req.body;
666
- if (maybeBody !== void 0 && typeof req.on !== "function") {
667
- applyBody(res, typeof maybeBody === "string" ? maybeBody : JSON.stringify(maybeBody));
339
+ if (maybeBody !== void 0) {
340
+ let text;
341
+ if (typeof maybeBody === "string") text = maybeBody;
342
+ else if (Buffer.isBuffer(maybeBody)) text = maybeBody.toString("utf8");
343
+ else text = JSON.stringify(maybeBody);
344
+ if (Buffer.byteLength(text) > MAX_BODY_BYTES) {
345
+ send(res, 413, { error: "request body too large" });
346
+ return;
347
+ }
348
+ applyBody(res, text);
668
349
  return;
669
350
  }
670
351
  if (typeof req.on === "function") {
671
352
  let raw = "";
353
+ let size = 0;
354
+ let rejected = false;
672
355
  req.on("data", (chunk) => {
673
- raw += String(chunk ?? "");
356
+ if (rejected) return;
357
+ const piece = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk ?? "");
358
+ size += Buffer.byteLength(piece);
359
+ if (size > MAX_BODY_BYTES) {
360
+ rejected = true;
361
+ raw = "";
362
+ send(res, 413, { error: "request body too large" });
363
+ return;
364
+ }
365
+ raw += piece;
366
+ });
367
+ req.on("end", () => {
368
+ if (!rejected) applyBody(res, raw);
674
369
  });
675
- req.on("end", () => applyBody(res, raw));
676
370
  return;
677
371
  }
678
372
  applyBody(res, "");
@@ -1037,6 +731,10 @@ const DEFAULT_BUCKETS = [
1037
731
  5e3,
1038
732
  1e4
1039
733
  ];
734
+ const MAX_LABEL_VALUE_LENGTH = 256;
735
+ const DEFAULT_MAX_LABEL_SETS = 1e3;
736
+ /** Label value used for the series that absorbs label sets beyond the cardinality cap. */
737
+ const OVERFLOW_LABEL_VALUE = "__overflow__";
1040
738
  function buildLabelKey(config, entry) {
1041
739
  const labelNames = config.labels ?? [];
1042
740
  if (labelNames.length === 0) return "{}";
@@ -1044,10 +742,16 @@ function buildLabelKey(config, entry) {
1044
742
  const payload = entry.payload ?? {};
1045
743
  for (const name of labelNames) {
1046
744
  const raw = name === "level" ? entry.level : payload[name];
1047
- pairs[sanitizePromName(name)] = raw !== void 0 && raw !== null ? String(raw) : "";
745
+ pairs[sanitizePromName(name)] = raw !== void 0 && raw !== null ? String(raw).slice(0, MAX_LABEL_VALUE_LENGTH) : "";
1048
746
  }
1049
747
  return JSON.stringify(pairs);
1050
748
  }
749
+ /** Label key of the shared overflow series for a metric (all label values `__overflow__`). */
750
+ function buildOverflowKey(config) {
751
+ const names = config.labels ?? [];
752
+ if (names.length === 0) return "{}";
753
+ return JSON.stringify(Object.fromEntries(names.map((n) => [sanitizePromName(n), OVERFLOW_LABEL_VALUE])));
754
+ }
1051
755
  function renderLabels(labelKey) {
1052
756
  if (labelKey === "{}") return "";
1053
757
  const obj = JSON.parse(labelKey);
@@ -1084,10 +788,13 @@ function sanitizePromName(name) {
1084
788
  * ```
1085
789
  */
1086
790
  var MetricsPlugin = class {
1087
- constructor(map) {
791
+ constructor(map, options = {}) {
1088
792
  this.name = "logixia-metrics";
1089
793
  this.metricState = /* @__PURE__ */ new Map();
794
+ this.overflowKeys = /* @__PURE__ */ new Map();
1090
795
  this.map = map;
796
+ const max = options.maxLabelSets;
797
+ this.maxLabelSets = typeof max === "number" && Number.isFinite(max) && max >= 1 ? Math.floor(max) : DEFAULT_MAX_LABEL_SETS;
1091
798
  this.initAllState();
1092
799
  }
1093
800
  onInit() {}
@@ -1096,16 +803,19 @@ var MetricsPlugin = class {
1096
803
  for (const [rawName, config] of Object.entries(this.map)) {
1097
804
  const state = this.metricState.get(rawName);
1098
805
  if (!state) continue;
1099
- const labelKey = buildLabelKey(config, entry);
806
+ const rawLabelKey = buildLabelKey(config, entry);
807
+ const overflowKey = this.overflowKeys.get(rawName) ?? "{}";
1100
808
  if (config.type === "counter" && state.type === "counter") {
1101
809
  if (config.levelFilter && entry.level !== config.levelFilter) continue;
1102
810
  if (config.field !== void 0 && payload[config.field] !== config.value) continue;
811
+ const labelKey = this.capLabelKey(state.values, rawLabelKey, overflowKey);
1103
812
  state.values.set(labelKey, (state.values.get(labelKey) ?? 0) + 1);
1104
813
  } else if (config.type === "histogram" && state.type === "histogram") {
1105
814
  const raw = payload[config.field];
1106
815
  if (raw === void 0 || raw === null) continue;
1107
816
  const val = Number(raw);
1108
817
  if (Number.isNaN(val)) continue;
818
+ const labelKey = this.capLabelKey(state.counts, rawLabelKey, overflowKey);
1109
819
  if (!state.counts.has(labelKey)) {
1110
820
  state.counts.set(labelKey, Array.from({ length: state.buckets.length + 1 }).fill(0));
1111
821
  state.sums.set(labelKey, 0);
@@ -1121,7 +831,7 @@ var MetricsPlugin = class {
1121
831
  if (raw === void 0 || raw === null) continue;
1122
832
  const val = Number(raw);
1123
833
  if (Number.isNaN(val)) continue;
1124
- state.values.set(labelKey, val);
834
+ state.values.set(this.capLabelKey(state.values, rawLabelKey, overflowKey), val);
1125
835
  }
1126
836
  }
1127
837
  return entry;
@@ -1222,10 +932,19 @@ var MetricsPlugin = class {
1222
932
  res.end(body);
1223
933
  };
1224
934
  }
935
+ /**
936
+ * Return `labelKey` when it is already tracked or there is room for it;
937
+ * otherwise the shared overflow series key.
938
+ */
939
+ capLabelKey(series, labelKey, overflowKey) {
940
+ if (series.has(labelKey) || series.size < this.maxLabelSets) return labelKey;
941
+ return overflowKey;
942
+ }
1225
943
  initAllState() {
1226
944
  for (const [rawName, config] of Object.entries(this.map)) this.initSingleState(rawName, config);
1227
945
  }
1228
946
  initSingleState(rawName, config) {
947
+ this.overflowKeys.set(rawName, buildOverflowKey(config));
1229
948
  if (config.type === "counter") this.metricState.set(rawName, {
1230
949
  type: "counter",
1231
950
  values: /* @__PURE__ */ new Map()
@@ -1271,9 +990,11 @@ var MetricsPlugin = class {
1271
990
  * logger.use(metrics);
1272
991
  * app.get('/metrics', metrics.expressHandler());
1273
992
  * ```
993
+ *
994
+ * Pass `{ maxLabelSets }` to change the per-metric label cardinality cap (default 1000).
1274
995
  */
1275
- function createMetricsPlugin(map) {
1276
- return new MetricsPlugin(map);
996
+ function createMetricsPlugin(map, options) {
997
+ return new MetricsPlugin(map, options);
1277
998
  }
1278
999
 
1279
1000
  //#endregion
@@ -1347,5 +1068,5 @@ const logger = new LogixiaLogger(DEFAULT_CONFIG);
1347
1068
  */
1348
1069
 
1349
1070
  //#endregion
1350
- export { BasicLogIndexer, BasicSearchEngine, CorrelationEngine, DEFAULT_CONFIG, DEFAULT_LOG_COLORS, DEFAULT_LOG_LEVELS, DEFAULT_TRACE_HEADERS, ErrorResponseBuilder, InjectLogger, JsonFormatter, KafkaTraceInterceptor, LOGIXIA_LOGGER_CONFIG, LOGIXIA_LOGGER_PREFIX, LOGIXIA_TRACE_CONFIG, LogLevel, LogMethod, LogixiaContext, LogixiaException, LogixiaExceptionFilter, LogixiaLogger, LogixiaLoggerModule, LogixiaLoggerService, MetricsPlugin, NLPSearchEngine, OtlpLogTransport, PatternRecognitionEngine, PluginRegistry, SearchManager, TRACE_CONTEXT_KEY, TextFormatter, TraceContext, WebSocketTraceInterceptor, _setActiveContextKey, _shutdownRegistrySize, addEventFields, applyRedaction, createExpressContextMiddleware, createFastifyContextHook, createLevelControlHandler, createLogger, createLoggerService, createMetricsPlugin, createTraceMiddleware, createTypedLogger, decycleValue, defineLogSchema, deregisterFromShutdown, disableOtelBridge, extractTraceId, flushOnExit, generateRequestId, generateTraceId, getActiveOtelContext, getCurrentTraceId, getEventFields, getOtelMetaFields, getTraceContextKey, globalPluginRegistry, initOtelBridge, isError, isLogixiaException, logger, normalizeError, redactObject, registerForShutdown, registerLevelSignal, resetShutdownHandlers, retrocycle, runWithTraceId, safeStringify, serializeError, setEventField, setTraceId, stringifyForLog, toOtelSeverity, traceStorage, usePlugin, wideEventMiddleware, withWideEvent };
1071
+ export { BasicLogIndexer, BasicSearchEngine, CorrelationEngine, DEFAULT_CONFIG, DEFAULT_LOG_COLORS, DEFAULT_LOG_LEVELS, DEFAULT_TRACE_HEADERS, ErrorResponseBuilder, InjectLogger, JsonFormatter, KafkaTraceInterceptor, LOGIXIA_EXCEPTION_FILTER_OPTIONS, LOGIXIA_LOGGER_CONFIG, LOGIXIA_LOGGER_PREFIX, LOGIXIA_TRACE_CONFIG, LogLevel, LogMethod, LogixiaContext, LogixiaException, LogixiaExceptionFilter, LogixiaLogger, LogixiaLoggerModule, LogixiaLoggerService, MAX_INCOMING_ID_LENGTH, MetricsPlugin, NLPSearchEngine, OVERFLOW_LABEL_VALUE, OtlpLogTransport, PatternRecognitionEngine, PluginRegistry, SearchManager, TRACE_CONTEXT_KEY, TextFormatter, TraceContext, WebSocketTraceInterceptor, _setActiveContextKey, _shutdownRegistrySize, addEventFields, applyRedaction, createExpressContextMiddleware, createFastifyContextHook, createLevelControlHandler, createLogger, createLoggerService, createMetricsPlugin, createTraceMiddleware, createTypedLogger, decycleValue, defineLogSchema, deregisterFromShutdown, disableOtelBridge, extractTraceId, flushOnExit, generateRequestId, generateTraceId, getActiveOtelContext, getCurrentTraceId, getEventFields, getOtelMetaFields, getTraceContextKey, globalPluginRegistry, initOtelBridge, isError, isLogixiaException, logger, normalizeError, redactObject, registerForShutdown, registerLevelSignal, resetShutdownHandlers, retrocycle, runWithTraceId, safeStringify, sanitizeIncomingId, serializeError, setEventField, setTraceId, stringifyForLog, toOtelSeverity, traceStorage, usePlugin, wideEventMiddleware, withWideEvent };
1351
1072
  //# sourceMappingURL=index.mjs.map