@superblocksteam/telemetry 2.0.83-next.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.
Files changed (227) hide show
  1. package/LICENSE.txt +87 -0
  2. package/README.md +155 -0
  3. package/dist/browser/index.d.ts +8 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/browser/index.js +19 -0
  6. package/dist/browser/index.js.map +1 -0
  7. package/dist/browser/init.d.ts +75 -0
  8. package/dist/browser/init.d.ts.map +1 -0
  9. package/dist/browser/init.js +169 -0
  10. package/dist/browser/init.js.map +1 -0
  11. package/dist/browser/resilient-exporter.d.ts +43 -0
  12. package/dist/browser/resilient-exporter.d.ts.map +1 -0
  13. package/dist/browser/resilient-exporter.js +88 -0
  14. package/dist/browser/resilient-exporter.js.map +1 -0
  15. package/dist/common/contracts/tier2-traces.d.ts +75 -0
  16. package/dist/common/contracts/tier2-traces.d.ts.map +1 -0
  17. package/dist/common/contracts/tier2-traces.js +186 -0
  18. package/dist/common/contracts/tier2-traces.js.map +1 -0
  19. package/dist/common/deployment-type.d.ts +18 -0
  20. package/dist/common/deployment-type.d.ts.map +1 -0
  21. package/dist/common/deployment-type.js +30 -0
  22. package/dist/common/deployment-type.js.map +1 -0
  23. package/dist/common/guardrails.d.ts +116 -0
  24. package/dist/common/guardrails.d.ts.map +1 -0
  25. package/dist/common/guardrails.js +189 -0
  26. package/dist/common/guardrails.js.map +1 -0
  27. package/dist/common/index.d.ts +16 -0
  28. package/dist/common/index.d.ts.map +1 -0
  29. package/dist/common/index.js +32 -0
  30. package/dist/common/index.js.map +1 -0
  31. package/dist/common/log-sanitizer.d.ts +78 -0
  32. package/dist/common/log-sanitizer.d.ts.map +1 -0
  33. package/dist/common/log-sanitizer.js +340 -0
  34. package/dist/common/log-sanitizer.js.map +1 -0
  35. package/dist/common/policy-evaluator.d.ts +103 -0
  36. package/dist/common/policy-evaluator.d.ts.map +1 -0
  37. package/dist/common/policy-evaluator.js +200 -0
  38. package/dist/common/policy-evaluator.js.map +1 -0
  39. package/dist/common/resource.d.ts +62 -0
  40. package/dist/common/resource.d.ts.map +1 -0
  41. package/dist/common/resource.js +106 -0
  42. package/dist/common/resource.js.map +1 -0
  43. package/dist/common/tier-hints.d.ts +182 -0
  44. package/dist/common/tier-hints.d.ts.map +1 -0
  45. package/dist/common/tier-hints.js +209 -0
  46. package/dist/common/tier-hints.js.map +1 -0
  47. package/dist/index.d.ts +43 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +76 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/lint/forbidden-attributes.d.ts +149 -0
  52. package/dist/lint/forbidden-attributes.d.ts.map +1 -0
  53. package/dist/lint/forbidden-attributes.js +214 -0
  54. package/dist/lint/forbidden-attributes.js.map +1 -0
  55. package/dist/lint/index.d.ts +9 -0
  56. package/dist/lint/index.d.ts.map +1 -0
  57. package/dist/lint/index.js +16 -0
  58. package/dist/lint/index.js.map +1 -0
  59. package/dist/llmobs/index.d.ts +22 -0
  60. package/dist/llmobs/index.d.ts.map +1 -0
  61. package/dist/llmobs/index.js +29 -0
  62. package/dist/llmobs/index.js.map +1 -0
  63. package/dist/llmobs/tier1-exporter.d.ts +146 -0
  64. package/dist/llmobs/tier1-exporter.d.ts.map +1 -0
  65. package/dist/llmobs/tier1-exporter.js +196 -0
  66. package/dist/llmobs/tier1-exporter.js.map +1 -0
  67. package/dist/llmobs/tier2-summarizer.d.ts +268 -0
  68. package/dist/llmobs/tier2-summarizer.d.ts.map +1 -0
  69. package/dist/llmobs/tier2-summarizer.js +650 -0
  70. package/dist/llmobs/tier2-summarizer.js.map +1 -0
  71. package/dist/node/exporters/resilient-exporter.d.ts +77 -0
  72. package/dist/node/exporters/resilient-exporter.d.ts.map +1 -0
  73. package/dist/node/exporters/resilient-exporter.js +129 -0
  74. package/dist/node/exporters/resilient-exporter.js.map +1 -0
  75. package/dist/node/index.d.ts +11 -0
  76. package/dist/node/index.d.ts.map +1 -0
  77. package/dist/node/index.js +24 -0
  78. package/dist/node/index.js.map +1 -0
  79. package/dist/node/init.d.ts +75 -0
  80. package/dist/node/init.d.ts.map +1 -0
  81. package/dist/node/init.js +245 -0
  82. package/dist/node/init.js.map +1 -0
  83. package/dist/node/log-processor.d.ts +83 -0
  84. package/dist/node/log-processor.d.ts.map +1 -0
  85. package/dist/node/log-processor.js +266 -0
  86. package/dist/node/log-processor.js.map +1 -0
  87. package/dist/node/metrics-client.d.ts +66 -0
  88. package/dist/node/metrics-client.d.ts.map +1 -0
  89. package/dist/node/metrics-client.js +193 -0
  90. package/dist/node/metrics-client.js.map +1 -0
  91. package/dist/node/traced-socket.d.ts +76 -0
  92. package/dist/node/traced-socket.d.ts.map +1 -0
  93. package/dist/node/traced-socket.js +261 -0
  94. package/dist/node/traced-socket.js.map +1 -0
  95. package/dist/testing/in-memory-exporter.d.ts +179 -0
  96. package/dist/testing/in-memory-exporter.d.ts.map +1 -0
  97. package/dist/testing/in-memory-exporter.js +254 -0
  98. package/dist/testing/in-memory-exporter.js.map +1 -0
  99. package/dist/testing/index.d.ts +8 -0
  100. package/dist/testing/index.d.ts.map +1 -0
  101. package/dist/testing/index.js +19 -0
  102. package/dist/testing/index.js.map +1 -0
  103. package/dist/testing/test-init.d.ts +80 -0
  104. package/dist/testing/test-init.d.ts.map +1 -0
  105. package/dist/testing/test-init.js +144 -0
  106. package/dist/testing/test-init.js.map +1 -0
  107. package/dist/types/index.d.ts +40 -0
  108. package/dist/types/index.d.ts.map +1 -0
  109. package/dist/types/index.js +23 -0
  110. package/dist/types/index.js.map +1 -0
  111. package/dist/types/policy.d.ts +92 -0
  112. package/dist/types/policy.d.ts.map +1 -0
  113. package/dist/types/policy.js +125 -0
  114. package/dist/types/policy.js.map +1 -0
  115. package/dist-esm/browser/index.d.ts +8 -0
  116. package/dist-esm/browser/index.d.ts.map +1 -0
  117. package/dist-esm/browser/index.js +9 -0
  118. package/dist-esm/browser/index.js.map +1 -0
  119. package/dist-esm/browser/init.d.ts +75 -0
  120. package/dist-esm/browser/init.d.ts.map +1 -0
  121. package/dist-esm/browser/init.js +162 -0
  122. package/dist-esm/browser/init.js.map +1 -0
  123. package/dist-esm/browser/resilient-exporter.d.ts +43 -0
  124. package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
  125. package/dist-esm/browser/resilient-exporter.js +84 -0
  126. package/dist-esm/browser/resilient-exporter.js.map +1 -0
  127. package/dist-esm/common/contracts/tier2-traces.d.ts +75 -0
  128. package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
  129. package/dist-esm/common/contracts/tier2-traces.js +178 -0
  130. package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
  131. package/dist-esm/common/deployment-type.d.ts +18 -0
  132. package/dist-esm/common/deployment-type.d.ts.map +1 -0
  133. package/dist-esm/common/deployment-type.js +27 -0
  134. package/dist-esm/common/deployment-type.js.map +1 -0
  135. package/dist-esm/common/guardrails.d.ts +116 -0
  136. package/dist-esm/common/guardrails.d.ts.map +1 -0
  137. package/dist-esm/common/guardrails.js +179 -0
  138. package/dist-esm/common/guardrails.js.map +1 -0
  139. package/dist-esm/common/index.d.ts +16 -0
  140. package/dist-esm/common/index.d.ts.map +1 -0
  141. package/dist-esm/common/index.js +16 -0
  142. package/dist-esm/common/index.js.map +1 -0
  143. package/dist-esm/common/log-sanitizer.d.ts +78 -0
  144. package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
  145. package/dist-esm/common/log-sanitizer.js +331 -0
  146. package/dist-esm/common/log-sanitizer.js.map +1 -0
  147. package/dist-esm/common/policy-evaluator.d.ts +103 -0
  148. package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
  149. package/dist-esm/common/policy-evaluator.js +196 -0
  150. package/dist-esm/common/policy-evaluator.js.map +1 -0
  151. package/dist-esm/common/resource.d.ts +62 -0
  152. package/dist-esm/common/resource.d.ts.map +1 -0
  153. package/dist-esm/common/resource.js +100 -0
  154. package/dist-esm/common/resource.js.map +1 -0
  155. package/dist-esm/common/tier-hints.d.ts +182 -0
  156. package/dist-esm/common/tier-hints.d.ts.map +1 -0
  157. package/dist-esm/common/tier-hints.js +199 -0
  158. package/dist-esm/common/tier-hints.js.map +1 -0
  159. package/dist-esm/index.d.ts +43 -0
  160. package/dist-esm/index.d.ts.map +1 -0
  161. package/dist-esm/index.js +53 -0
  162. package/dist-esm/index.js.map +1 -0
  163. package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
  164. package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
  165. package/dist-esm/lint/forbidden-attributes.js +209 -0
  166. package/dist-esm/lint/forbidden-attributes.js.map +1 -0
  167. package/dist-esm/lint/index.d.ts +9 -0
  168. package/dist-esm/lint/index.d.ts.map +1 -0
  169. package/dist-esm/lint/index.js +9 -0
  170. package/dist-esm/lint/index.js.map +1 -0
  171. package/dist-esm/llmobs/index.d.ts +22 -0
  172. package/dist-esm/llmobs/index.d.ts.map +1 -0
  173. package/dist-esm/llmobs/index.js +22 -0
  174. package/dist-esm/llmobs/index.js.map +1 -0
  175. package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
  176. package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
  177. package/dist-esm/llmobs/tier1-exporter.js +190 -0
  178. package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
  179. package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
  180. package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
  181. package/dist-esm/llmobs/tier2-summarizer.js +646 -0
  182. package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
  183. package/dist-esm/node/exporters/resilient-exporter.d.ts +77 -0
  184. package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
  185. package/dist-esm/node/exporters/resilient-exporter.js +125 -0
  186. package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
  187. package/dist-esm/node/index.d.ts +11 -0
  188. package/dist-esm/node/index.d.ts.map +1 -0
  189. package/dist-esm/node/index.js +11 -0
  190. package/dist-esm/node/index.js.map +1 -0
  191. package/dist-esm/node/init.d.ts +75 -0
  192. package/dist-esm/node/init.d.ts.map +1 -0
  193. package/dist-esm/node/init.js +239 -0
  194. package/dist-esm/node/init.js.map +1 -0
  195. package/dist-esm/node/log-processor.d.ts +83 -0
  196. package/dist-esm/node/log-processor.d.ts.map +1 -0
  197. package/dist-esm/node/log-processor.js +261 -0
  198. package/dist-esm/node/log-processor.js.map +1 -0
  199. package/dist-esm/node/metrics-client.d.ts +66 -0
  200. package/dist-esm/node/metrics-client.d.ts.map +1 -0
  201. package/dist-esm/node/metrics-client.js +189 -0
  202. package/dist-esm/node/metrics-client.js.map +1 -0
  203. package/dist-esm/node/traced-socket.d.ts +76 -0
  204. package/dist-esm/node/traced-socket.d.ts.map +1 -0
  205. package/dist-esm/node/traced-socket.js +257 -0
  206. package/dist-esm/node/traced-socket.js.map +1 -0
  207. package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
  208. package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
  209. package/dist-esm/testing/in-memory-exporter.js +248 -0
  210. package/dist-esm/testing/in-memory-exporter.js.map +1 -0
  211. package/dist-esm/testing/index.d.ts +8 -0
  212. package/dist-esm/testing/index.d.ts.map +1 -0
  213. package/dist-esm/testing/index.js +8 -0
  214. package/dist-esm/testing/index.js.map +1 -0
  215. package/dist-esm/testing/test-init.d.ts +80 -0
  216. package/dist-esm/testing/test-init.d.ts.map +1 -0
  217. package/dist-esm/testing/test-init.js +137 -0
  218. package/dist-esm/testing/test-init.js.map +1 -0
  219. package/dist-esm/types/index.d.ts +40 -0
  220. package/dist-esm/types/index.d.ts.map +1 -0
  221. package/dist-esm/types/index.js +7 -0
  222. package/dist-esm/types/index.js.map +1 -0
  223. package/dist-esm/types/policy.d.ts +92 -0
  224. package/dist-esm/types/policy.d.ts.map +1 -0
  225. package/dist-esm/types/policy.js +122 -0
  226. package/dist-esm/types/policy.js.map +1 -0
  227. package/package.json +101 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Resilient Exporter
3
+ *
4
+ * Wrapper that ensures Tier 2/3 export failures never block core request paths.
5
+ * Export failures are observable via metrics, not via blocking or exceptions.
6
+ */
7
+ import type { SpanExporter, ReadableSpan } from "@opentelemetry/sdk-trace-base";
8
+ import { ExportResult } from "@opentelemetry/core";
9
+ /**
10
+ * Configuration for the resilient exporter.
11
+ */
12
+ export interface ResilientExporterConfig {
13
+ /** Underlying exporter to wrap */
14
+ delegate: SpanExporter;
15
+ /** Max items to buffer before dropping (default: 2048) */
16
+ maxQueueSize?: number;
17
+ /** Export timeout in ms (default: 30000) */
18
+ exportTimeoutMs?: number;
19
+ /** Callback when items are dropped due to backpressure */
20
+ onDrop?: (count: number, reason: "queue_full" | "export_failed" | "timeout") => void;
21
+ }
22
+ /**
23
+ * Metrics exposed by the resilient exporter.
24
+ */
25
+ export interface ResilientExporterMetrics {
26
+ /** Total spans dropped due to backpressure or failure */
27
+ dropped: number;
28
+ /** Current queue size */
29
+ queued: number;
30
+ /** Total export failures */
31
+ failures: number;
32
+ }
33
+ /**
34
+ * Resilient exporter wrapper that:
35
+ * - Drops spans when queue is full (never blocks)
36
+ * - Catches export failures and emits metrics
37
+ * - Times out stalled exports
38
+ *
39
+ * CRITICAL: Telemetry export must be fire-and-forget from the application's perspective.
40
+ * Export failures should be observable via metrics, not via blocking or exceptions.
41
+ */
42
+ export declare class ResilientExporter implements SpanExporter {
43
+ private readonly delegate;
44
+ private readonly maxQueueSize;
45
+ private readonly exportTimeoutMs;
46
+ private readonly onDrop;
47
+ private queuedCount;
48
+ private droppedCount;
49
+ private exportFailures;
50
+ private shuttingDown;
51
+ constructor(config: ResilientExporterConfig);
52
+ /**
53
+ * Export spans with resilient error handling.
54
+ *
55
+ * IMPORTANT: Always returns SUCCESS to caller - export failures are
56
+ * observable via metrics, not via the result callback.
57
+ */
58
+ export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
59
+ /**
60
+ * Shutdown the underlying exporter.
61
+ * Marks exporter as shutting down to reject new exports.
62
+ */
63
+ shutdown(): Promise<void>;
64
+ /**
65
+ * Force flush the underlying exporter.
66
+ */
67
+ forceFlush(): Promise<void>;
68
+ /**
69
+ * Get current metrics for observability.
70
+ */
71
+ getMetrics(): ResilientExporterMetrics;
72
+ /**
73
+ * Reset metrics (for testing).
74
+ */
75
+ resetMetrics(): void;
76
+ }
77
+ //# sourceMappingURL=resilient-exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilient-exporter.d.ts","sourceRoot":"","sources":["../../../src/node/exporters/resilient-exporter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,QAAQ,EAAE,YAAY,CAAC;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,CACP,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,YAAY,GAAG,eAAe,GAAG,SAAS,KAC/C,IAAI,CAAC;CACX;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGb;IAEV,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,uBAAuB;IAO3C;;;;;OAKG;IACH,MAAM,CACJ,KAAK,EAAE,YAAY,EAAE,EACrB,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC7C,IAAI;IA0DP;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACH,UAAU,IAAI,wBAAwB;IAQtC;;OAEG;IACH,YAAY,IAAI,IAAI;CAIrB"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Resilient Exporter
3
+ *
4
+ * Wrapper that ensures Tier 2/3 export failures never block core request paths.
5
+ * Export failures are observable via metrics, not via blocking or exceptions.
6
+ */
7
+ import { ExportResultCode } from "@opentelemetry/core";
8
+ /**
9
+ * Resilient exporter wrapper that:
10
+ * - Drops spans when queue is full (never blocks)
11
+ * - Catches export failures and emits metrics
12
+ * - Times out stalled exports
13
+ *
14
+ * CRITICAL: Telemetry export must be fire-and-forget from the application's perspective.
15
+ * Export failures should be observable via metrics, not via blocking or exceptions.
16
+ */
17
+ export class ResilientExporter {
18
+ delegate;
19
+ maxQueueSize;
20
+ exportTimeoutMs;
21
+ onDrop;
22
+ queuedCount = 0;
23
+ droppedCount = 0;
24
+ exportFailures = 0;
25
+ shuttingDown = false;
26
+ constructor(config) {
27
+ this.delegate = config.delegate;
28
+ this.maxQueueSize = config.maxQueueSize ?? 2048;
29
+ this.exportTimeoutMs = config.exportTimeoutMs ?? 30000;
30
+ this.onDrop = config.onDrop ?? (() => { });
31
+ }
32
+ /**
33
+ * Export spans with resilient error handling.
34
+ *
35
+ * IMPORTANT: Always returns SUCCESS to caller - export failures are
36
+ * observable via metrics, not via the result callback.
37
+ */
38
+ export(spans, resultCallback) {
39
+ // Don't accept new exports during shutdown
40
+ if (this.shuttingDown) {
41
+ resultCallback({ code: ExportResultCode.SUCCESS });
42
+ return;
43
+ }
44
+ // Check backpressure - drop if queue is full
45
+ if (this.queuedCount + spans.length > this.maxQueueSize) {
46
+ this.droppedCount += spans.length;
47
+ this.onDrop(spans.length, "queue_full");
48
+ // Still return success - don't block the caller
49
+ resultCallback({ code: ExportResultCode.SUCCESS });
50
+ return;
51
+ }
52
+ this.queuedCount += spans.length;
53
+ let completed = false;
54
+ // Wrap with timeout
55
+ const timeoutId = setTimeout(() => {
56
+ if (completed)
57
+ return;
58
+ completed = true;
59
+ this.queuedCount -= spans.length;
60
+ this.droppedCount += spans.length;
61
+ this.onDrop(spans.length, "timeout");
62
+ resultCallback({ code: ExportResultCode.SUCCESS }); // Don't propagate failure
63
+ }, this.exportTimeoutMs);
64
+ try {
65
+ this.delegate.export(spans, (result) => {
66
+ if (completed)
67
+ return;
68
+ completed = true;
69
+ clearTimeout(timeoutId);
70
+ this.queuedCount -= spans.length;
71
+ if (result.code !== ExportResultCode.SUCCESS) {
72
+ this.exportFailures++;
73
+ this.droppedCount += spans.length;
74
+ this.onDrop(spans.length, "export_failed");
75
+ }
76
+ // Always return success to caller - export failures are observable via metrics
77
+ resultCallback({ code: ExportResultCode.SUCCESS });
78
+ });
79
+ }
80
+ catch (error) {
81
+ if (completed)
82
+ return;
83
+ completed = true;
84
+ clearTimeout(timeoutId);
85
+ this.queuedCount -= spans.length;
86
+ this.exportFailures++;
87
+ this.droppedCount += spans.length;
88
+ this.onDrop(spans.length, "export_failed");
89
+ console.warn("[Telemetry] Span export threw:", error);
90
+ resultCallback({ code: ExportResultCode.SUCCESS }); // Don't propagate failure
91
+ }
92
+ }
93
+ /**
94
+ * Shutdown the underlying exporter.
95
+ * Marks exporter as shutting down to reject new exports.
96
+ */
97
+ async shutdown() {
98
+ this.shuttingDown = true;
99
+ return this.delegate.shutdown();
100
+ }
101
+ /**
102
+ * Force flush the underlying exporter.
103
+ */
104
+ async forceFlush() {
105
+ return this.delegate.forceFlush?.() ?? Promise.resolve();
106
+ }
107
+ /**
108
+ * Get current metrics for observability.
109
+ */
110
+ getMetrics() {
111
+ return {
112
+ dropped: this.droppedCount,
113
+ queued: this.queuedCount,
114
+ failures: this.exportFailures,
115
+ };
116
+ }
117
+ /**
118
+ * Reset metrics (for testing).
119
+ */
120
+ resetMetrics() {
121
+ this.droppedCount = 0;
122
+ this.exportFailures = 0;
123
+ }
124
+ }
125
+ //# sourceMappingURL=resilient-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilient-exporter.js","sourceRoot":"","sources":["../../../src/node/exporters/resilient-exporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Node.js Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in Node.js services.
5
+ */
6
+ export { initNodeTelemetry, getTelemetryInstance, isTelemetryInitialized, resetTelemetry, type NodeTelemetryInstance, } from "./init.js";
7
+ export { MetricsClient, type Labels, type CounterHandle, type GaugeHandle, type HistogramHandle, } from "./metrics-client.js";
8
+ export { TracedSocket, type TracedSocketConfig, type TracedSocketOptions, } from "./traced-socket.js";
9
+ export { ResilientExporter, type ResilientExporterConfig, type ResilientExporterMetrics, } from "./exporters/resilient-exporter.js";
10
+ export { PolicyAwareLogProcessor, LogExportMode, getLoggingPolicy, type LoggingPolicyConfig, } from "./log-processor.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,cAAc,EACd,KAAK,qBAAqB,GAC3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,aAAa,EACb,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,GAC9B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Node.js Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in Node.js services.
5
+ */
6
+ export { initNodeTelemetry, getTelemetryInstance, isTelemetryInitialized, resetTelemetry, } from "./init.js";
7
+ export { MetricsClient, } from "./metrics-client.js";
8
+ export { TracedSocket, } from "./traced-socket.js";
9
+ export { ResilientExporter, } from "./exporters/resilient-exporter.js";
10
+ export { PolicyAwareLogProcessor, LogExportMode, getLoggingPolicy, } from "./log-processor.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,cAAc,GAEf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,aAAa,GAKd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,YAAY,GAGb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,iBAAiB,GAGlB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Node.js Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in Node.js services.
5
+ * Direct NodeSDK usage outside this package is prohibited.
6
+ */
7
+ import { Tracer, Meter } from "@opentelemetry/api";
8
+ import { Logger } from "@opentelemetry/api-logs";
9
+ import { NodeSDK } from "@opentelemetry/sdk-node";
10
+ import { TelemetryPolicyEvaluator } from "../common/policy-evaluator.js";
11
+ import type { NodeTelemetryConfig } from "../types/index.js";
12
+ import { TelemetryPolicy } from "../types/policy.js";
13
+ import { MetricsClient } from "./metrics-client.js";
14
+ /**
15
+ * Telemetry instance returned by initNodeTelemetry.
16
+ */
17
+ export interface NodeTelemetryInstance {
18
+ /** The underlying NodeSDK instance (undefined in CI/no-op mode) */
19
+ sdk?: NodeSDK;
20
+ /** Policy evaluator for runtime decisions */
21
+ policyEvaluator: TelemetryPolicyEvaluator;
22
+ /** Get a tracer for the service */
23
+ getTracer: (name?: string) => Tracer;
24
+ /** Get a meter for the service */
25
+ getMeter: (name?: string) => Meter;
26
+ /** Get a logger for the service */
27
+ getLogger: (name?: string) => Logger;
28
+ /** Metrics client for recording counters, gauges, and histograms */
29
+ metricsClient: MetricsClient;
30
+ /** Graceful shutdown */
31
+ shutdown: () => Promise<void>;
32
+ }
33
+ /**
34
+ * Initialize Node.js telemetry with policy enforcement.
35
+ *
36
+ * This is the ONLY approved way to initialize telemetry in Node.js services.
37
+ * Direct NodeSDK usage outside this package is prohibited.
38
+ *
39
+ * @param config - Service configuration
40
+ * @param policy - Telemetry policy (REQUIRED)
41
+ * @returns Telemetry instance with SDK and utilities
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * import { initNodeTelemetry } from '@superblocksteam/telemetry/node';
46
+ * import { getDefaultPolicy, DeploymentType } from '@superblocksteam/shared';
47
+ *
48
+ * const policy = getDefaultPolicy(DeploymentType.CLOUD_PREM);
49
+ * const telemetry = initNodeTelemetry({
50
+ * serviceName: 'my-service',
51
+ * serviceVersion: '1.0.0',
52
+ * environment: 'production',
53
+ * otlpUrl: 'http://localhost:4318',
54
+ * }, policy);
55
+ *
56
+ * const tracer = telemetry.getTracer();
57
+ * ```
58
+ */
59
+ export declare function initNodeTelemetry(config: NodeTelemetryConfig, policy: TelemetryPolicy): NodeTelemetryInstance;
60
+ /**
61
+ * Get the current telemetry instance.
62
+ *
63
+ * @throws Error if not initialized
64
+ */
65
+ export declare function getTelemetryInstance(): NodeTelemetryInstance;
66
+ /**
67
+ * Check if telemetry is initialized.
68
+ */
69
+ export declare function isTelemetryInitialized(): boolean;
70
+ /**
71
+ * Reset telemetry (for testing only).
72
+ * @internal
73
+ */
74
+ export declare function resetTelemetry(): void;
75
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/node/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAS,MAAM,EAAW,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAQ,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAWvD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAIlD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AAOpE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6CAA6C;IAC7C,eAAe,EAAE,wBAAwB,CAAC;IAC1C,mCAAmC;IACnC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,kCAAkC;IAClC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC,mCAAmC;IACnC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,oEAAoE;IACpE,aAAa,EAAE,aAAa,CAAC;IAC7B,wBAAwB;IACxB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AA0ED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,eAAe,GACtB,qBAAqB,CAkJvB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,qBAAqB,CAO5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Node.js Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in Node.js services.
5
+ * Direct NodeSDK usage outside this package is prohibited.
6
+ */
7
+ import { trace, metrics } from "@opentelemetry/api";
8
+ import { logs } from "@opentelemetry/api-logs";
9
+ import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
10
+ import { W3CTraceContextPropagator } from "@opentelemetry/core";
11
+ import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
12
+ import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
13
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
14
+ import { BatchLogRecordProcessor } from "@opentelemetry/sdk-logs";
15
+ import { AggregationTemporality, PeriodicExportingMetricReader, } from "@opentelemetry/sdk-metrics";
16
+ import { NodeSDK } from "@opentelemetry/sdk-node";
17
+ import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
18
+ import { buildResource, validateResource } from "../common/resource.js";
19
+ import { TelemetryPolicyEvaluator } from "../common/policy-evaluator.js";
20
+ import { TelemetryTier } from "../types/policy.js";
21
+ import { ResilientExporter } from "./exporters/resilient-exporter.js";
22
+ import { PolicyAwareLogProcessor, getLoggingPolicy, LogExportMode, } from "./log-processor.js";
23
+ import { MetricsClient } from "./metrics-client.js";
24
+ // Singleton instance
25
+ let instance;
26
+ /**
27
+ * Create a no-op telemetry instance for CI environments.
28
+ *
29
+ * IMPORTANT: We intentionally do NOT use NodeSDK here. NodeSDK.start()
30
+ * auto-configures OTLP exporters for traces, metrics, and logs from
31
+ * environment defaults (localhost:4318). During shutdown, these exporters
32
+ * try to flush to the non-existent collector, causing ECONNREFUSED errors
33
+ * that fail test suites even when all tests pass.
34
+ *
35
+ * Instead, we return a lightweight instance that uses the global OTel API
36
+ * (which returns no-op tracers/meters/loggers when no provider is registered).
37
+ */
38
+ function createNoOpInstance(config, policy) {
39
+ const policyEvaluator = new TelemetryPolicyEvaluator(policy);
40
+ // Use a no-op meter for the metrics client
41
+ const defaultMeter = metrics.getMeter(config.serviceName, config.serviceVersion);
42
+ return {
43
+ sdk: undefined,
44
+ policyEvaluator,
45
+ getTracer: (name) => trace.getTracer(name ?? config.serviceName, config.serviceVersion),
46
+ getMeter: (name) => metrics.getMeter(name ?? config.serviceName, config.serviceVersion),
47
+ getLogger: (name) => logs.getLogger(name ?? config.serviceName, config.serviceVersion),
48
+ metricsClient: new MetricsClient(defaultMeter),
49
+ shutdown: async () => {
50
+ // No-op: nothing to flush or shut down
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * Validate telemetry configuration.
56
+ *
57
+ * @param config - Configuration to validate
58
+ * @throws Error if configuration is invalid
59
+ */
60
+ function validateNodeTelemetryConfig(config) {
61
+ if (!config.serviceName?.trim()) {
62
+ throw new Error("[Telemetry] serviceName is required and cannot be empty");
63
+ }
64
+ if (!config.serviceVersion?.trim()) {
65
+ throw new Error("[Telemetry] serviceVersion is required and cannot be empty");
66
+ }
67
+ if (!config.environment?.trim()) {
68
+ throw new Error("[Telemetry] environment is required and cannot be empty");
69
+ }
70
+ if (config.otlpUrl) {
71
+ try {
72
+ new URL(config.otlpUrl);
73
+ }
74
+ catch (error) {
75
+ throw new Error(`[Telemetry] Invalid otlpUrl: ${config.otlpUrl} (${error.message})`);
76
+ }
77
+ }
78
+ }
79
+ /**
80
+ * Initialize Node.js telemetry with policy enforcement.
81
+ *
82
+ * This is the ONLY approved way to initialize telemetry in Node.js services.
83
+ * Direct NodeSDK usage outside this package is prohibited.
84
+ *
85
+ * @param config - Service configuration
86
+ * @param policy - Telemetry policy (REQUIRED)
87
+ * @returns Telemetry instance with SDK and utilities
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * import { initNodeTelemetry } from '@superblocksteam/telemetry/node';
92
+ * import { getDefaultPolicy, DeploymentType } from '@superblocksteam/shared';
93
+ *
94
+ * const policy = getDefaultPolicy(DeploymentType.CLOUD_PREM);
95
+ * const telemetry = initNodeTelemetry({
96
+ * serviceName: 'my-service',
97
+ * serviceVersion: '1.0.0',
98
+ * environment: 'production',
99
+ * otlpUrl: 'http://localhost:4318',
100
+ * }, policy);
101
+ *
102
+ * const tracer = telemetry.getTracer();
103
+ * ```
104
+ */
105
+ export function initNodeTelemetry(config, policy) {
106
+ // Policy is required
107
+ if (!policy) {
108
+ throw new Error("[Telemetry] Policy is required. Cannot initialize telemetry without a policy.");
109
+ }
110
+ // Validate config
111
+ validateNodeTelemetryConfig(config);
112
+ // Return existing instance if already initialized
113
+ if (instance) {
114
+ // Warn if config differs from existing
115
+ const existingPolicy = instance.policyEvaluator.getPolicy();
116
+ if (existingPolicy.deploymentType !== policy.deploymentType) {
117
+ console.warn(`[Telemetry] Already initialized with different deployment type ` +
118
+ `(existing: ${existingPolicy.deploymentType}, requested: ${policy.deploymentType}). ` +
119
+ `Returning existing instance.`);
120
+ }
121
+ return instance;
122
+ }
123
+ // CI environment detection - use no-op telemetry
124
+ if (process.env.CI === "true") {
125
+ console.debug("[Telemetry] CI environment detected, using no-op telemetry");
126
+ instance = createNoOpInstance(config, policy);
127
+ return instance;
128
+ }
129
+ const policyEvaluator = new TelemetryPolicyEvaluator(policy);
130
+ const resource = buildResource(config);
131
+ // Validate resource has required attributes
132
+ validateResource(resource);
133
+ // Track dropped spans for observability
134
+ let droppedSpans = 0;
135
+ const onDrop = (count, reason) => {
136
+ droppedSpans += count;
137
+ console.warn(`[Telemetry] Dropped ${count} spans (${reason}). Total dropped: ${droppedSpans}`);
138
+ };
139
+ // Create trace exporter if URL provided and Tier 2 export is enabled
140
+ // Use isExportEnabled (not canExport) - sampling applies at runtime, not initialization
141
+ let traceExporter;
142
+ if (config.otlpUrl &&
143
+ policyEvaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL)) {
144
+ traceExporter = new ResilientExporter({
145
+ delegate: new OTLPTraceExporter({ url: `${config.otlpUrl}/v1/traces` }),
146
+ onDrop,
147
+ });
148
+ }
149
+ // Create metric exporter if enabled
150
+ // Use isExportEnabled (not canExport) - sampling applies at runtime, not initialization
151
+ let metricReader;
152
+ if (config.otlpUrl &&
153
+ config.metricsEnabled !== false &&
154
+ policyEvaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL)) {
155
+ metricReader = new PeriodicExportingMetricReader({
156
+ exporter: new OTLPMetricExporter({
157
+ url: `${config.otlpUrl}/v1/metrics`,
158
+ temporalityPreference: AggregationTemporality.DELTA,
159
+ }),
160
+ exportIntervalMillis: 10000, // every 10 seconds
161
+ });
162
+ }
163
+ // Create log processor with policy-aware filtering and sanitization
164
+ // The PolicyAwareLogProcessor wraps the batch processor to:
165
+ // 1. Filter logs by severity level based on export mode (LOCAL_ONLY, ERRORS_ONLY, INFO_AND_ABOVE)
166
+ // 2. Sanitize log bodies and attributes to remove PII, file paths, stack traces
167
+ // 3. Remove forbidden fields that should never be exported
168
+ let logProcessor;
169
+ const loggingPolicy = getLoggingPolicy(policy);
170
+ if (config.otlpUrl &&
171
+ config.logsEnabled !== false &&
172
+ policyEvaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL) &&
173
+ loggingPolicy.exportMode !== LogExportMode.LOCAL_ONLY) {
174
+ const batchProcessor = new BatchLogRecordProcessor(new OTLPLogExporter({ url: `${config.otlpUrl}/v1/logs` }));
175
+ logProcessor = new PolicyAwareLogProcessor(loggingPolicy, batchProcessor);
176
+ }
177
+ // Create the SDK
178
+ // Note: instrumentations typed as unknown[] for flexibility with various OTEL instrumentation packages
179
+ const sdk = new NodeSDK({
180
+ resource,
181
+ spanProcessor: traceExporter
182
+ ? new BatchSpanProcessor(traceExporter)
183
+ : undefined,
184
+ metricReader,
185
+ logRecordProcessor: logProcessor,
186
+ contextManager: new AsyncLocalStorageContextManager(),
187
+ textMapPropagator: new W3CTraceContextPropagator(),
188
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- OTEL instrumentation types vary
189
+ instrumentations: (config.instrumentations ?? []),
190
+ });
191
+ sdk.start();
192
+ console.info(`[Telemetry] Initialized for ${config.serviceName} (${policy.deploymentType})` +
193
+ ` | Traces: ${traceExporter ? "enabled" : "disabled"}` +
194
+ ` | Metrics: ${metricReader ? "enabled" : "disabled"}` +
195
+ ` | Logs: ${logProcessor ? "enabled" : "disabled"}`);
196
+ const defaultMeter = metrics.getMeter(config.serviceName, config.serviceVersion);
197
+ instance = {
198
+ sdk,
199
+ policyEvaluator,
200
+ getTracer: (name) => trace.getTracer(name ?? config.serviceName, config.serviceVersion),
201
+ getMeter: (name) => metrics.getMeter(name ?? config.serviceName, config.serviceVersion),
202
+ getLogger: (name) => logs.getLogger(name ?? config.serviceName, config.serviceVersion),
203
+ metricsClient: new MetricsClient(defaultMeter),
204
+ shutdown: async () => {
205
+ try {
206
+ await sdk.shutdown();
207
+ }
208
+ finally {
209
+ instance = undefined;
210
+ }
211
+ },
212
+ };
213
+ return instance;
214
+ }
215
+ /**
216
+ * Get the current telemetry instance.
217
+ *
218
+ * @throws Error if not initialized
219
+ */
220
+ export function getTelemetryInstance() {
221
+ if (!instance) {
222
+ throw new Error("[Telemetry] Not initialized. Call initNodeTelemetry() first.");
223
+ }
224
+ return instance;
225
+ }
226
+ /**
227
+ * Check if telemetry is initialized.
228
+ */
229
+ export function isTelemetryInitialized() {
230
+ return instance !== undefined;
231
+ }
232
+ /**
233
+ * Reset telemetry (for testing only).
234
+ * @internal
235
+ */
236
+ export function resetTelemetry() {
237
+ instance = undefined;
238
+ }
239
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/node/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Policy-Aware Log Processor
3
+ *
4
+ * Wraps a delegate LogRecordProcessor to provide:
5
+ * 1. Export mode filtering (LOCAL_ONLY, ERRORS_ONLY, INFO_AND_ABOVE)
6
+ * 2. Severity level filtering
7
+ * 3. Log body and attribute sanitization
8
+ *
9
+ * @see https://github.com/superblocksteam/engineering/blob/main/projects/o11y-refactor/epics/epic-c4-logging-strategy.md
10
+ */
11
+ import type { LogRecordProcessor, ReadableLogRecord } from "@opentelemetry/sdk-logs";
12
+ import type { Context } from "@opentelemetry/api";
13
+ import { TelemetryPolicy } from "../types/policy.js";
14
+ /**
15
+ * Controls what logs are exported via OTEL.
16
+ */
17
+ export declare enum LogExportMode {
18
+ /** No log export - local stdout/stderr only */
19
+ LOCAL_ONLY = "local_only",
20
+ /** Export WARN/ERROR/FATAL only (default for cloud-prem) */
21
+ ERRORS_ONLY = "errors_only",
22
+ /** Export INFO and above (not recommended for cloud-prem) */
23
+ INFO_AND_ABOVE = "info_and_above"
24
+ }
25
+ /**
26
+ * Logging-specific policy configuration.
27
+ */
28
+ export interface LoggingPolicyConfig {
29
+ /** What logs to export */
30
+ exportMode: LogExportMode;
31
+ /** Maximum log level for local retention */
32
+ localMaxLevel: "trace" | "debug" | "info" | "warn" | "error" | "fatal";
33
+ /** Regex patterns to redact from log content */
34
+ redactPatterns: RegExp[];
35
+ /** Fields to never include in exported logs */
36
+ forbiddenFields: Set<string>;
37
+ }
38
+ /**
39
+ * Get logging policy based on telemetry policy.
40
+ *
41
+ * @param policy - Telemetry policy
42
+ * @returns Logging policy configuration
43
+ */
44
+ export declare function getLoggingPolicy(policy: TelemetryPolicy): LoggingPolicyConfig;
45
+ /**
46
+ * Log processor that filters and sanitizes logs based on policy.
47
+ *
48
+ * This processor:
49
+ * 1. Blocks all logs if exportMode is LOCAL_ONLY
50
+ * 2. Filters by severity level based on exportMode
51
+ * 3. Sanitizes log body and attributes before forwarding
52
+ */
53
+ export declare class PolicyAwareLogProcessor implements LogRecordProcessor {
54
+ private readonly policy;
55
+ private readonly delegate;
56
+ constructor(policy: LoggingPolicyConfig, delegate: LogRecordProcessor);
57
+ /**
58
+ * Called when a log record is emitted.
59
+ */
60
+ onEmit(logRecord: ReadableLogRecord, context?: Context): void;
61
+ /**
62
+ * Sanitize a log record for export.
63
+ * Mutates the log record in place to preserve OTEL SDK internal state.
64
+ */
65
+ private sanitizeLogRecord;
66
+ /**
67
+ * Check if a string contains a stack trace.
68
+ */
69
+ private containsStackTrace;
70
+ /**
71
+ * Sanitize log attributes.
72
+ */
73
+ private sanitizeAttributes;
74
+ /**
75
+ * Shutdown the processor.
76
+ */
77
+ shutdown(): Promise<void>;
78
+ /**
79
+ * Force flush pending logs.
80
+ */
81
+ forceFlush(): Promise<void>;
82
+ }
83
+ //# sourceMappingURL=log-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-processor.d.ts","sourceRoot":"","sources":["../../src/node/log-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AAepE;;GAEG;AACH,oBAAY,aAAa;IACvB,+CAA+C;IAC/C,UAAU,eAAe;IACzB,4DAA4D;IAC5D,WAAW,gBAAgB;IAC3B,6DAA6D;IAC7D,cAAc,mBAAmB;CAClC;AAMD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,0BAA0B;IAC1B,UAAU,EAAE,aAAa,CAAC;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACvE,gDAAgD;IAChD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,+CAA+C;IAC/C,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,mBAAmB,CAyC7E;AAuDD;;;;;;;GAOG;AACH,qBAAa,uBAAwB,YAAW,kBAAkB;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;gBAElC,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,kBAAkB;IAKrE;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI;IAsB7D;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAuCzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyC1B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGlC"}