@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.
- package/LICENSE.txt +87 -0
- package/README.md +155 -0
- package/dist/browser/index.d.ts +8 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +19 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/init.d.ts +75 -0
- package/dist/browser/init.d.ts.map +1 -0
- package/dist/browser/init.js +169 -0
- package/dist/browser/init.js.map +1 -0
- package/dist/browser/resilient-exporter.d.ts +43 -0
- package/dist/browser/resilient-exporter.d.ts.map +1 -0
- package/dist/browser/resilient-exporter.js +88 -0
- package/dist/browser/resilient-exporter.js.map +1 -0
- package/dist/common/contracts/tier2-traces.d.ts +75 -0
- package/dist/common/contracts/tier2-traces.d.ts.map +1 -0
- package/dist/common/contracts/tier2-traces.js +186 -0
- package/dist/common/contracts/tier2-traces.js.map +1 -0
- package/dist/common/deployment-type.d.ts +18 -0
- package/dist/common/deployment-type.d.ts.map +1 -0
- package/dist/common/deployment-type.js +30 -0
- package/dist/common/deployment-type.js.map +1 -0
- package/dist/common/guardrails.d.ts +116 -0
- package/dist/common/guardrails.d.ts.map +1 -0
- package/dist/common/guardrails.js +189 -0
- package/dist/common/guardrails.js.map +1 -0
- package/dist/common/index.d.ts +16 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +32 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/log-sanitizer.d.ts +78 -0
- package/dist/common/log-sanitizer.d.ts.map +1 -0
- package/dist/common/log-sanitizer.js +340 -0
- package/dist/common/log-sanitizer.js.map +1 -0
- package/dist/common/policy-evaluator.d.ts +103 -0
- package/dist/common/policy-evaluator.d.ts.map +1 -0
- package/dist/common/policy-evaluator.js +200 -0
- package/dist/common/policy-evaluator.js.map +1 -0
- package/dist/common/resource.d.ts +62 -0
- package/dist/common/resource.d.ts.map +1 -0
- package/dist/common/resource.js +106 -0
- package/dist/common/resource.js.map +1 -0
- package/dist/common/tier-hints.d.ts +182 -0
- package/dist/common/tier-hints.d.ts.map +1 -0
- package/dist/common/tier-hints.js +209 -0
- package/dist/common/tier-hints.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/forbidden-attributes.d.ts +149 -0
- package/dist/lint/forbidden-attributes.d.ts.map +1 -0
- package/dist/lint/forbidden-attributes.js +214 -0
- package/dist/lint/forbidden-attributes.js.map +1 -0
- package/dist/lint/index.d.ts +9 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +16 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/llmobs/index.d.ts +22 -0
- package/dist/llmobs/index.d.ts.map +1 -0
- package/dist/llmobs/index.js +29 -0
- package/dist/llmobs/index.js.map +1 -0
- package/dist/llmobs/tier1-exporter.d.ts +146 -0
- package/dist/llmobs/tier1-exporter.d.ts.map +1 -0
- package/dist/llmobs/tier1-exporter.js +196 -0
- package/dist/llmobs/tier1-exporter.js.map +1 -0
- package/dist/llmobs/tier2-summarizer.d.ts +268 -0
- package/dist/llmobs/tier2-summarizer.d.ts.map +1 -0
- package/dist/llmobs/tier2-summarizer.js +650 -0
- package/dist/llmobs/tier2-summarizer.js.map +1 -0
- package/dist/node/exporters/resilient-exporter.d.ts +77 -0
- package/dist/node/exporters/resilient-exporter.d.ts.map +1 -0
- package/dist/node/exporters/resilient-exporter.js +129 -0
- package/dist/node/exporters/resilient-exporter.js.map +1 -0
- package/dist/node/index.d.ts +11 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +24 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/init.d.ts +75 -0
- package/dist/node/init.d.ts.map +1 -0
- package/dist/node/init.js +245 -0
- package/dist/node/init.js.map +1 -0
- package/dist/node/log-processor.d.ts +83 -0
- package/dist/node/log-processor.d.ts.map +1 -0
- package/dist/node/log-processor.js +266 -0
- package/dist/node/log-processor.js.map +1 -0
- package/dist/node/metrics-client.d.ts +66 -0
- package/dist/node/metrics-client.d.ts.map +1 -0
- package/dist/node/metrics-client.js +193 -0
- package/dist/node/metrics-client.js.map +1 -0
- package/dist/node/traced-socket.d.ts +76 -0
- package/dist/node/traced-socket.d.ts.map +1 -0
- package/dist/node/traced-socket.js +261 -0
- package/dist/node/traced-socket.js.map +1 -0
- package/dist/testing/in-memory-exporter.d.ts +179 -0
- package/dist/testing/in-memory-exporter.d.ts.map +1 -0
- package/dist/testing/in-memory-exporter.js +254 -0
- package/dist/testing/in-memory-exporter.js.map +1 -0
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +19 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/test-init.d.ts +80 -0
- package/dist/testing/test-init.d.ts.map +1 -0
- package/dist/testing/test-init.js +144 -0
- package/dist/testing/test-init.js.map +1 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/policy.d.ts +92 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/policy.js +125 -0
- package/dist/types/policy.js.map +1 -0
- package/dist-esm/browser/index.d.ts +8 -0
- package/dist-esm/browser/index.d.ts.map +1 -0
- package/dist-esm/browser/index.js +9 -0
- package/dist-esm/browser/index.js.map +1 -0
- package/dist-esm/browser/init.d.ts +75 -0
- package/dist-esm/browser/init.d.ts.map +1 -0
- package/dist-esm/browser/init.js +162 -0
- package/dist-esm/browser/init.js.map +1 -0
- package/dist-esm/browser/resilient-exporter.d.ts +43 -0
- package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
- package/dist-esm/browser/resilient-exporter.js +84 -0
- package/dist-esm/browser/resilient-exporter.js.map +1 -0
- package/dist-esm/common/contracts/tier2-traces.d.ts +75 -0
- package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
- package/dist-esm/common/contracts/tier2-traces.js +178 -0
- package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
- package/dist-esm/common/deployment-type.d.ts +18 -0
- package/dist-esm/common/deployment-type.d.ts.map +1 -0
- package/dist-esm/common/deployment-type.js +27 -0
- package/dist-esm/common/deployment-type.js.map +1 -0
- package/dist-esm/common/guardrails.d.ts +116 -0
- package/dist-esm/common/guardrails.d.ts.map +1 -0
- package/dist-esm/common/guardrails.js +179 -0
- package/dist-esm/common/guardrails.js.map +1 -0
- package/dist-esm/common/index.d.ts +16 -0
- package/dist-esm/common/index.d.ts.map +1 -0
- package/dist-esm/common/index.js +16 -0
- package/dist-esm/common/index.js.map +1 -0
- package/dist-esm/common/log-sanitizer.d.ts +78 -0
- package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
- package/dist-esm/common/log-sanitizer.js +331 -0
- package/dist-esm/common/log-sanitizer.js.map +1 -0
- package/dist-esm/common/policy-evaluator.d.ts +103 -0
- package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
- package/dist-esm/common/policy-evaluator.js +196 -0
- package/dist-esm/common/policy-evaluator.js.map +1 -0
- package/dist-esm/common/resource.d.ts +62 -0
- package/dist-esm/common/resource.d.ts.map +1 -0
- package/dist-esm/common/resource.js +100 -0
- package/dist-esm/common/resource.js.map +1 -0
- package/dist-esm/common/tier-hints.d.ts +182 -0
- package/dist-esm/common/tier-hints.d.ts.map +1 -0
- package/dist-esm/common/tier-hints.js +199 -0
- package/dist-esm/common/tier-hints.js.map +1 -0
- package/dist-esm/index.d.ts +43 -0
- package/dist-esm/index.d.ts.map +1 -0
- package/dist-esm/index.js +53 -0
- package/dist-esm/index.js.map +1 -0
- package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
- package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
- package/dist-esm/lint/forbidden-attributes.js +209 -0
- package/dist-esm/lint/forbidden-attributes.js.map +1 -0
- package/dist-esm/lint/index.d.ts +9 -0
- package/dist-esm/lint/index.d.ts.map +1 -0
- package/dist-esm/lint/index.js +9 -0
- package/dist-esm/lint/index.js.map +1 -0
- package/dist-esm/llmobs/index.d.ts +22 -0
- package/dist-esm/llmobs/index.d.ts.map +1 -0
- package/dist-esm/llmobs/index.js +22 -0
- package/dist-esm/llmobs/index.js.map +1 -0
- package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
- package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
- package/dist-esm/llmobs/tier1-exporter.js +190 -0
- package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
- package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
- package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
- package/dist-esm/llmobs/tier2-summarizer.js +646 -0
- package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts +77 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
- package/dist-esm/node/exporters/resilient-exporter.js +125 -0
- package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
- package/dist-esm/node/index.d.ts +11 -0
- package/dist-esm/node/index.d.ts.map +1 -0
- package/dist-esm/node/index.js +11 -0
- package/dist-esm/node/index.js.map +1 -0
- package/dist-esm/node/init.d.ts +75 -0
- package/dist-esm/node/init.d.ts.map +1 -0
- package/dist-esm/node/init.js +239 -0
- package/dist-esm/node/init.js.map +1 -0
- package/dist-esm/node/log-processor.d.ts +83 -0
- package/dist-esm/node/log-processor.d.ts.map +1 -0
- package/dist-esm/node/log-processor.js +261 -0
- package/dist-esm/node/log-processor.js.map +1 -0
- package/dist-esm/node/metrics-client.d.ts +66 -0
- package/dist-esm/node/metrics-client.d.ts.map +1 -0
- package/dist-esm/node/metrics-client.js +189 -0
- package/dist-esm/node/metrics-client.js.map +1 -0
- package/dist-esm/node/traced-socket.d.ts +76 -0
- package/dist-esm/node/traced-socket.d.ts.map +1 -0
- package/dist-esm/node/traced-socket.js +257 -0
- package/dist-esm/node/traced-socket.js.map +1 -0
- package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
- package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
- package/dist-esm/testing/in-memory-exporter.js +248 -0
- package/dist-esm/testing/in-memory-exporter.js.map +1 -0
- package/dist-esm/testing/index.d.ts +8 -0
- package/dist-esm/testing/index.d.ts.map +1 -0
- package/dist-esm/testing/index.js +8 -0
- package/dist-esm/testing/index.js.map +1 -0
- package/dist-esm/testing/test-init.d.ts +80 -0
- package/dist-esm/testing/test-init.d.ts.map +1 -0
- package/dist-esm/testing/test-init.js +137 -0
- package/dist-esm/testing/test-init.js.map +1 -0
- package/dist-esm/types/index.d.ts +40 -0
- package/dist-esm/types/index.d.ts.map +1 -0
- package/dist-esm/types/index.js +7 -0
- package/dist-esm/types/index.js.map +1 -0
- package/dist-esm/types/policy.d.ts +92 -0
- package/dist-esm/types/policy.d.ts.map +1 -0
- package/dist-esm/types/policy.js +122 -0
- package/dist-esm/types/policy.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1,261 @@
|
|
|
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 { TelemetryTier } from "../types/policy.js";
|
|
12
|
+
import { TelemetryPolicyEvaluator } from "../common/policy-evaluator.js";
|
|
13
|
+
import { isSecretField, sanitizeLogMessage, sanitizeLogObject, redactStackTrace, TIER1_FORBIDDEN_LOG_FIELDS, } from "../common/log-sanitizer.js";
|
|
14
|
+
import { DeploymentTypeEnum } from "@superblocksteam/shared";
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Log Export Mode
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Controls what logs are exported via OTEL.
|
|
20
|
+
*/
|
|
21
|
+
export var LogExportMode;
|
|
22
|
+
(function (LogExportMode) {
|
|
23
|
+
/** No log export - local stdout/stderr only */
|
|
24
|
+
LogExportMode["LOCAL_ONLY"] = "local_only";
|
|
25
|
+
/** Export WARN/ERROR/FATAL only (default for cloud-prem) */
|
|
26
|
+
LogExportMode["ERRORS_ONLY"] = "errors_only";
|
|
27
|
+
/** Export INFO and above (not recommended for cloud-prem) */
|
|
28
|
+
LogExportMode["INFO_AND_ABOVE"] = "info_and_above";
|
|
29
|
+
})(LogExportMode || (LogExportMode = {}));
|
|
30
|
+
/**
|
|
31
|
+
* Get logging policy based on telemetry policy.
|
|
32
|
+
*
|
|
33
|
+
* @param policy - Telemetry policy
|
|
34
|
+
* @returns Logging policy configuration
|
|
35
|
+
*/
|
|
36
|
+
export function getLoggingPolicy(policy) {
|
|
37
|
+
const evaluator = new TelemetryPolicyEvaluator(policy);
|
|
38
|
+
// Check if Tier 2 export is allowed
|
|
39
|
+
const canExportTier2 = evaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL);
|
|
40
|
+
if (!canExportTier2) {
|
|
41
|
+
return {
|
|
42
|
+
exportMode: LogExportMode.LOCAL_ONLY,
|
|
43
|
+
localMaxLevel: "debug",
|
|
44
|
+
redactPatterns: [],
|
|
45
|
+
forbiddenFields: TIER1_FORBIDDEN_LOG_FIELDS,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Cloud-prem: export errors only, with full sanitization
|
|
49
|
+
if (policy.deploymentType === DeploymentTypeEnum.CLOUD_PREM) {
|
|
50
|
+
return {
|
|
51
|
+
exportMode: LogExportMode.ERRORS_ONLY,
|
|
52
|
+
localMaxLevel: "debug",
|
|
53
|
+
redactPatterns: [
|
|
54
|
+
// JWTs
|
|
55
|
+
/\b[A-Za-z0-9-_]{20,}\.[A-Za-z0-9-_]{20,}\.[A-Za-z0-9-_]{20,}\b/g,
|
|
56
|
+
// Bearer tokens
|
|
57
|
+
/(\bbearer\s+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
58
|
+
// API keys
|
|
59
|
+
/(\bapi[_\s]?key[:\s=]+)[a-zA-Z0-9\-._~+/]+=*/gi,
|
|
60
|
+
],
|
|
61
|
+
forbiddenFields: TIER1_FORBIDDEN_LOG_FIELDS,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Cloud: more permissive (INFO and above)
|
|
65
|
+
return {
|
|
66
|
+
exportMode: LogExportMode.INFO_AND_ABOVE,
|
|
67
|
+
localMaxLevel: "debug",
|
|
68
|
+
redactPatterns: [],
|
|
69
|
+
forbiddenFields: new Set(), // Cloud can export more
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Severity Level Utilities
|
|
74
|
+
// ============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* OTEL severity numbers:
|
|
77
|
+
* 1-4: TRACE
|
|
78
|
+
* 5-8: DEBUG
|
|
79
|
+
* 9-12: INFO
|
|
80
|
+
* 13-16: WARN
|
|
81
|
+
* 17-20: ERROR
|
|
82
|
+
* 21-24: FATAL
|
|
83
|
+
*/
|
|
84
|
+
function getSeverityName(severityNumber) {
|
|
85
|
+
if (!severityNumber)
|
|
86
|
+
return "info";
|
|
87
|
+
if (severityNumber <= 4)
|
|
88
|
+
return "trace";
|
|
89
|
+
if (severityNumber <= 8)
|
|
90
|
+
return "debug";
|
|
91
|
+
if (severityNumber <= 12)
|
|
92
|
+
return "info";
|
|
93
|
+
if (severityNumber <= 16)
|
|
94
|
+
return "warn";
|
|
95
|
+
if (severityNumber <= 20)
|
|
96
|
+
return "error";
|
|
97
|
+
return "fatal";
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if a severity level should be exported based on export mode.
|
|
101
|
+
*/
|
|
102
|
+
function shouldExportSeverity(severityNumber, mode) {
|
|
103
|
+
if (mode === LogExportMode.LOCAL_ONLY) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const severity = getSeverityName(severityNumber);
|
|
107
|
+
if (mode === LogExportMode.ERRORS_ONLY) {
|
|
108
|
+
return severity === "warn" || severity === "error" || severity === "fatal";
|
|
109
|
+
}
|
|
110
|
+
// INFO_AND_ABOVE
|
|
111
|
+
return (severity === "info" ||
|
|
112
|
+
severity === "warn" ||
|
|
113
|
+
severity === "error" ||
|
|
114
|
+
severity === "fatal");
|
|
115
|
+
}
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Policy-Aware Log Processor
|
|
118
|
+
// ============================================================================
|
|
119
|
+
/**
|
|
120
|
+
* Log processor that filters and sanitizes logs based on policy.
|
|
121
|
+
*
|
|
122
|
+
* This processor:
|
|
123
|
+
* 1. Blocks all logs if exportMode is LOCAL_ONLY
|
|
124
|
+
* 2. Filters by severity level based on exportMode
|
|
125
|
+
* 3. Sanitizes log body and attributes before forwarding
|
|
126
|
+
*/
|
|
127
|
+
export class PolicyAwareLogProcessor {
|
|
128
|
+
policy;
|
|
129
|
+
delegate;
|
|
130
|
+
constructor(policy, delegate) {
|
|
131
|
+
this.policy = policy;
|
|
132
|
+
this.delegate = delegate;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Called when a log record is emitted.
|
|
136
|
+
*/
|
|
137
|
+
onEmit(logRecord, context) {
|
|
138
|
+
// Check if export mode allows this log
|
|
139
|
+
if (this.policy.exportMode === LogExportMode.LOCAL_ONLY) {
|
|
140
|
+
return; // Don't export anything
|
|
141
|
+
}
|
|
142
|
+
// Check if severity level should be exported
|
|
143
|
+
if (!shouldExportSeverity(logRecord.severityNumber, this.policy.exportMode)) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Sanitize the log record in place before forwarding
|
|
147
|
+
// The logRecord is actually an SdkLogRecord at runtime, we mutate it directly
|
|
148
|
+
this.sanitizeLogRecord(logRecord);
|
|
149
|
+
// Forward to delegate - cast is safe because logRecord is SdkLogRecord at runtime
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
151
|
+
this.delegate.onEmit(logRecord, context);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Sanitize a log record for export.
|
|
155
|
+
* Mutates the log record in place to preserve OTEL SDK internal state.
|
|
156
|
+
*/
|
|
157
|
+
sanitizeLogRecord(logRecord) {
|
|
158
|
+
// Sanitize body - mutate in place
|
|
159
|
+
if (typeof logRecord.body === "string") {
|
|
160
|
+
// Apply policy-specific redact patterns first
|
|
161
|
+
let sanitizedBody = logRecord.body;
|
|
162
|
+
for (const pattern of this.policy.redactPatterns) {
|
|
163
|
+
pattern.lastIndex = 0; // Reset regex state
|
|
164
|
+
sanitizedBody = sanitizedBody.replace(pattern, "[REDACTED]");
|
|
165
|
+
}
|
|
166
|
+
// Check for stack traces
|
|
167
|
+
if (this.containsStackTrace(sanitizedBody)) {
|
|
168
|
+
// Use setAttribute pattern for LogRecord mutation
|
|
169
|
+
logRecord.body =
|
|
170
|
+
redactStackTrace(sanitizedBody);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
logRecord.body =
|
|
174
|
+
sanitizeLogMessage(sanitizedBody);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else if (logRecord.body && typeof logRecord.body === "object") {
|
|
178
|
+
logRecord.body = sanitizeLogObject(logRecord.body);
|
|
179
|
+
}
|
|
180
|
+
// Sanitize attributes - mutate in place
|
|
181
|
+
const attrs = logRecord.attributes;
|
|
182
|
+
if (attrs) {
|
|
183
|
+
const sanitizedAttributes = this.sanitizeAttributes(attrs);
|
|
184
|
+
// Clear and repopulate attributes
|
|
185
|
+
for (const key of Object.keys(attrs)) {
|
|
186
|
+
delete attrs[key];
|
|
187
|
+
}
|
|
188
|
+
for (const [key, value] of Object.entries(sanitizedAttributes)) {
|
|
189
|
+
attrs[key] = value;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if a string contains a stack trace.
|
|
195
|
+
*/
|
|
196
|
+
containsStackTrace(text) {
|
|
197
|
+
// Node.js stack traces
|
|
198
|
+
if (/at .+\(.+:\d+:\d+\)/.test(text))
|
|
199
|
+
return true;
|
|
200
|
+
// Go stack traces
|
|
201
|
+
if (/goroutine \d+ \[.+\]:/.test(text))
|
|
202
|
+
return true;
|
|
203
|
+
// Python stack traces
|
|
204
|
+
if (/File ".+", line \d+/.test(text))
|
|
205
|
+
return true;
|
|
206
|
+
// Java stack traces
|
|
207
|
+
if (/at \w+\.\w+\(.+\.java:\d+\)/.test(text))
|
|
208
|
+
return true;
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Sanitize log attributes.
|
|
213
|
+
*/
|
|
214
|
+
sanitizeAttributes(attributes) {
|
|
215
|
+
if (!attributes) {
|
|
216
|
+
return {};
|
|
217
|
+
}
|
|
218
|
+
const sanitized = {};
|
|
219
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
220
|
+
const lowerKey = key.toLowerCase();
|
|
221
|
+
// Skip forbidden fields (exact match from policy)
|
|
222
|
+
if (this.policy.forbiddenFields.has(lowerKey)) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
// Skip fields matching secret field patterns (word-boundary aware)
|
|
226
|
+
if (isSecretField(key)) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
// Sanitize string values
|
|
230
|
+
if (typeof value === "string") {
|
|
231
|
+
// Apply policy-specific redact patterns
|
|
232
|
+
let sanitizedValue = value;
|
|
233
|
+
for (const pattern of this.policy.redactPatterns) {
|
|
234
|
+
pattern.lastIndex = 0;
|
|
235
|
+
sanitizedValue = sanitizedValue.replace(pattern, "[REDACTED]");
|
|
236
|
+
}
|
|
237
|
+
sanitized[key] = sanitizeLogMessage(sanitizedValue);
|
|
238
|
+
}
|
|
239
|
+
else if (value && typeof value === "object") {
|
|
240
|
+
sanitized[key] = sanitizeLogObject(value);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
sanitized[key] = value;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return sanitized;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Shutdown the processor.
|
|
250
|
+
*/
|
|
251
|
+
async shutdown() {
|
|
252
|
+
return this.delegate.shutdown();
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Force flush pending logs.
|
|
256
|
+
*/
|
|
257
|
+
async forceFlush() {
|
|
258
|
+
return this.delegate.forceFlush();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=log-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-processor.js","sourceRoot":"","sources":["../../src/node/log-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Client for Node.js Telemetry
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple interface for recording metrics via OpenTelemetry.
|
|
5
|
+
* This is the recommended way to record metrics in services using the telemetry package.
|
|
6
|
+
*/
|
|
7
|
+
import type { Meter } from "@opentelemetry/api";
|
|
8
|
+
/**
|
|
9
|
+
* Labels for metrics (key-value pairs).
|
|
10
|
+
*/
|
|
11
|
+
export type Labels = Record<string, string | number>;
|
|
12
|
+
/**
|
|
13
|
+
* Handle for a counter metric.
|
|
14
|
+
*/
|
|
15
|
+
export interface CounterHandle {
|
|
16
|
+
inc(labels?: Labels, value?: number): void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Handle for a gauge metric.
|
|
20
|
+
*/
|
|
21
|
+
export interface GaugeHandle {
|
|
22
|
+
set(labels: Labels, value: number): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Handle for a histogram metric.
|
|
26
|
+
*/
|
|
27
|
+
export interface HistogramHandle {
|
|
28
|
+
observe(labels: Labels, value: number): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Metrics client that provides a unified interface for recording OTEL metrics.
|
|
32
|
+
*/
|
|
33
|
+
export declare class MetricsClient {
|
|
34
|
+
private readonly meter;
|
|
35
|
+
private counters;
|
|
36
|
+
private histograms;
|
|
37
|
+
private gaugeValues;
|
|
38
|
+
constructor(meter: Meter);
|
|
39
|
+
/**
|
|
40
|
+
* Creates or retrieves a counter and returns a handle.
|
|
41
|
+
*/
|
|
42
|
+
counter(name: string): CounterHandle;
|
|
43
|
+
/**
|
|
44
|
+
* Creates or retrieves a gauge and returns a handle.
|
|
45
|
+
* Note: OTEL gauges are async/observable, so we store the value and emit via callback.
|
|
46
|
+
* Values are automatically expired after 5 minutes to prevent unbounded memory growth.
|
|
47
|
+
*/
|
|
48
|
+
gauge(name: string): GaugeHandle;
|
|
49
|
+
/**
|
|
50
|
+
* Creates or retrieves a histogram and returns a handle.
|
|
51
|
+
*/
|
|
52
|
+
histogram(name: string): HistogramHandle;
|
|
53
|
+
/**
|
|
54
|
+
* Increments a counter by name (creates if not exists).
|
|
55
|
+
*/
|
|
56
|
+
incCounter(name: string, labels?: Labels, value?: number): void;
|
|
57
|
+
/**
|
|
58
|
+
* Sets a gauge value by name (creates if not exists).
|
|
59
|
+
*/
|
|
60
|
+
setGauge(name: string, labels: Labels, value: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Observes a histogram value by name (creates if not exists).
|
|
63
|
+
*/
|
|
64
|
+
observeHistogram(name: string, labels: Labels, value: number): void;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=metrics-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-client.d.ts","sourceRoot":"","sources":["../../src/node/metrics-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAkC,MAAM,oBAAoB,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAoHrD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9C;AAED;;GAEG;AACH,qBAAa,aAAa;IAMZ,OAAO,CAAC,QAAQ,CAAC,KAAK;IALlC,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,UAAU,CAAgC;IAElD,OAAO,CAAC,WAAW,CAAkC;gBAExB,KAAK,EAAE,KAAK;IAEzC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IAapC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IA2BhC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAaxC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,IAAI;IAIlE;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3D;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAGpE"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Client for Node.js Telemetry
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple interface for recording metrics via OpenTelemetry.
|
|
5
|
+
* This is the recommended way to record metrics in services using the telemetry package.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Converts Labels to OTEL Attributes.
|
|
9
|
+
*/
|
|
10
|
+
function labelsToAttributes(labels) {
|
|
11
|
+
if (!labels)
|
|
12
|
+
return {};
|
|
13
|
+
const attributes = {};
|
|
14
|
+
for (const [key, value] of Object.entries(labels)) {
|
|
15
|
+
attributes[key] = String(value);
|
|
16
|
+
}
|
|
17
|
+
return attributes;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* TTL configuration for gauge values.
|
|
21
|
+
*/
|
|
22
|
+
const GAUGE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
23
|
+
const GAUGE_MAX_ENTRIES = 10_000; // Max entries per gauge to prevent unbounded growth
|
|
24
|
+
const GAUGE_CLEANUP_INTERVAL_MS = 60 * 1000; // Cleanup every minute
|
|
25
|
+
/**
|
|
26
|
+
* TTL-based map for gauge values with automatic cleanup.
|
|
27
|
+
*/
|
|
28
|
+
class TTLGaugeMap {
|
|
29
|
+
ttlMs;
|
|
30
|
+
maxEntries;
|
|
31
|
+
entries = new Map();
|
|
32
|
+
cleanupTimer = null;
|
|
33
|
+
constructor(ttlMs = GAUGE_TTL_MS, maxEntries = GAUGE_MAX_ENTRIES) {
|
|
34
|
+
this.ttlMs = ttlMs;
|
|
35
|
+
this.maxEntries = maxEntries;
|
|
36
|
+
// Start periodic cleanup
|
|
37
|
+
this.cleanupTimer = setInterval(() => this.cleanup(), GAUGE_CLEANUP_INTERVAL_MS);
|
|
38
|
+
// Don't prevent Node.js from exiting
|
|
39
|
+
this.cleanupTimer.unref();
|
|
40
|
+
}
|
|
41
|
+
set(labelsKey, value) {
|
|
42
|
+
// If at max capacity, remove oldest entry
|
|
43
|
+
if (this.entries.size >= this.maxEntries && !this.entries.has(labelsKey)) {
|
|
44
|
+
this.evictOldest();
|
|
45
|
+
}
|
|
46
|
+
this.entries.set(labelsKey, {
|
|
47
|
+
value,
|
|
48
|
+
updatedAt: Date.now(),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Gets all non-expired entries.
|
|
53
|
+
*/
|
|
54
|
+
getAll() {
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const result = new Map();
|
|
57
|
+
for (const [key, entry] of this.entries) {
|
|
58
|
+
if (now - entry.updatedAt <= this.ttlMs) {
|
|
59
|
+
result.set(key, entry.value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Removes expired entries.
|
|
66
|
+
*/
|
|
67
|
+
cleanup() {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
for (const [key, entry] of this.entries) {
|
|
70
|
+
if (now - entry.updatedAt > this.ttlMs) {
|
|
71
|
+
this.entries.delete(key);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Evicts the oldest entry when at max capacity.
|
|
77
|
+
*/
|
|
78
|
+
evictOldest() {
|
|
79
|
+
let oldestKey = null;
|
|
80
|
+
let oldestTime = Infinity;
|
|
81
|
+
for (const [key, entry] of this.entries) {
|
|
82
|
+
if (entry.updatedAt < oldestTime) {
|
|
83
|
+
oldestTime = entry.updatedAt;
|
|
84
|
+
oldestKey = key;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (oldestKey) {
|
|
88
|
+
this.entries.delete(oldestKey);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Stops the cleanup timer.
|
|
93
|
+
*/
|
|
94
|
+
destroy() {
|
|
95
|
+
if (this.cleanupTimer) {
|
|
96
|
+
clearInterval(this.cleanupTimer);
|
|
97
|
+
this.cleanupTimer = null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Metrics client that provides a unified interface for recording OTEL metrics.
|
|
103
|
+
*/
|
|
104
|
+
export class MetricsClient {
|
|
105
|
+
meter;
|
|
106
|
+
counters = new Map();
|
|
107
|
+
histograms = new Map();
|
|
108
|
+
// Gauges use TTL-based maps to prevent unbounded memory growth
|
|
109
|
+
gaugeValues = new Map();
|
|
110
|
+
constructor(meter) {
|
|
111
|
+
this.meter = meter;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Creates or retrieves a counter and returns a handle.
|
|
115
|
+
*/
|
|
116
|
+
counter(name) {
|
|
117
|
+
if (!this.counters.has(name)) {
|
|
118
|
+
this.counters.set(name, this.meter.createCounter(name));
|
|
119
|
+
}
|
|
120
|
+
const counter = this.counters.get(name);
|
|
121
|
+
return {
|
|
122
|
+
inc: (labels, value = 1) => {
|
|
123
|
+
counter.add(value, labelsToAttributes(labels));
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Creates or retrieves a gauge and returns a handle.
|
|
129
|
+
* Note: OTEL gauges are async/observable, so we store the value and emit via callback.
|
|
130
|
+
* Values are automatically expired after 5 minutes to prevent unbounded memory growth.
|
|
131
|
+
*/
|
|
132
|
+
gauge(name) {
|
|
133
|
+
if (!this.gaugeValues.has(name)) {
|
|
134
|
+
const ttlMap = new TTLGaugeMap();
|
|
135
|
+
this.gaugeValues.set(name, ttlMap);
|
|
136
|
+
// Create an observable gauge that reads from the TTL map
|
|
137
|
+
this.meter.createObservableGauge(name, {}).addCallback((result) => {
|
|
138
|
+
const ttlMapRef = this.gaugeValues.get(name);
|
|
139
|
+
if (ttlMapRef) {
|
|
140
|
+
// getAll() only returns non-expired entries
|
|
141
|
+
for (const [labelsKey, value] of ttlMapRef.getAll()) {
|
|
142
|
+
const labels = JSON.parse(labelsKey);
|
|
143
|
+
result.observe(value, labelsToAttributes(labels));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
set: (labels, value) => {
|
|
150
|
+
const ttlMap = this.gaugeValues.get(name);
|
|
151
|
+
const labelsKey = JSON.stringify(labels);
|
|
152
|
+
ttlMap.set(labelsKey, value);
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Creates or retrieves a histogram and returns a handle.
|
|
158
|
+
*/
|
|
159
|
+
histogram(name) {
|
|
160
|
+
if (!this.histograms.has(name)) {
|
|
161
|
+
this.histograms.set(name, this.meter.createHistogram(name));
|
|
162
|
+
}
|
|
163
|
+
const histogram = this.histograms.get(name);
|
|
164
|
+
return {
|
|
165
|
+
observe: (labels, value) => {
|
|
166
|
+
histogram.record(value, labelsToAttributes(labels));
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Increments a counter by name (creates if not exists).
|
|
172
|
+
*/
|
|
173
|
+
incCounter(name, labels, value = 1) {
|
|
174
|
+
this.counter(name).inc(labels, value);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Sets a gauge value by name (creates if not exists).
|
|
178
|
+
*/
|
|
179
|
+
setGauge(name, labels, value) {
|
|
180
|
+
this.gauge(name).set(labels, value);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Observes a histogram value by name (creates if not exists).
|
|
184
|
+
*/
|
|
185
|
+
observeHistogram(name, labels, value) {
|
|
186
|
+
this.histogram(name).observe(labels, value);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=metrics-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-client.js","sourceRoot":"","sources":["../../src/node/metrics-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TracedSocket for WebSocket connections with OpenTelemetry tracing.
|
|
3
|
+
*
|
|
4
|
+
* This is a generic implementation that can be used across services.
|
|
5
|
+
* Server-specific behavior (like error handling) is injected via callbacks.
|
|
6
|
+
*/
|
|
7
|
+
import { IncomingHttpHeaders } from "http";
|
|
8
|
+
import { ISocket, ISocketClient, MethodHandler, RequestContextBase, SocketMessage, SocketError, MethodHandlers, GenericMiddleware, SocketTimeouts } from "@superblocksteam/shared";
|
|
9
|
+
/**
|
|
10
|
+
* PinoLogger interface compatible with pino.
|
|
11
|
+
*/
|
|
12
|
+
interface PinoLogger {
|
|
13
|
+
error: (obj: object, msg?: string) => void;
|
|
14
|
+
info: (obj: object, msg?: string) => void;
|
|
15
|
+
warn: (obj: object, msg?: string) => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* WebSocket interface (subset of isomorphic-ws).
|
|
19
|
+
*/
|
|
20
|
+
interface WebSocketLike {
|
|
21
|
+
readonly readyState: number;
|
|
22
|
+
close(code?: number, reason?: string): void;
|
|
23
|
+
send(data: string | ArrayBuffer): void;
|
|
24
|
+
addEventListener(type: string, listener: (event: unknown) => void): void;
|
|
25
|
+
removeEventListener(type: string, listener: (event: unknown) => void): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Configuration options for TracedSocket.
|
|
29
|
+
*/
|
|
30
|
+
export interface TracedSocketConfig {
|
|
31
|
+
/** Request headers from the WebSocket upgrade request */
|
|
32
|
+
requestHeaders: IncomingHttpHeaders;
|
|
33
|
+
/** Optional error handler to get HTTP status from errors */
|
|
34
|
+
getResponseMetaByError?: (error: Error, logger: PinoLogger) => {
|
|
35
|
+
status: number;
|
|
36
|
+
message: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Socket options passed to ISocket.
|
|
41
|
+
*/
|
|
42
|
+
export interface TracedSocketOptions {
|
|
43
|
+
onClose: (event: {
|
|
44
|
+
code: number;
|
|
45
|
+
reason: string;
|
|
46
|
+
}) => void;
|
|
47
|
+
timeouts?: SocketTimeouts;
|
|
48
|
+
logger?: {
|
|
49
|
+
error: (message?: string) => void;
|
|
50
|
+
info: (message?: string) => void;
|
|
51
|
+
warn: (message?: string) => void;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* TracedSocket extends ISocket to add OpenTelemetry tracing capabilities.
|
|
56
|
+
*
|
|
57
|
+
* It manages spans for WebSocket handler calls to provide detailed tracing information.
|
|
58
|
+
*/
|
|
59
|
+
export declare class TracedSocket<ImplementedMethods, CallableMethods, RequestContext extends RequestContextBase> extends ISocket<ImplementedMethods, CallableMethods, RequestContext> {
|
|
60
|
+
private activeSpanByRequestId;
|
|
61
|
+
private middlewareSpanByReqId;
|
|
62
|
+
private lastActiveSpan;
|
|
63
|
+
private readonly requestHeaders;
|
|
64
|
+
private readonly tracer;
|
|
65
|
+
private readonly setHttpStatusFromError;
|
|
66
|
+
constructor(ws: WebSocketLike, requestHandlers: MethodHandlers<ImplementedMethods, CallableMethods, RequestContext>, globalMiddlewares: GenericMiddleware<CallableMethods, RequestContext>[], config: TracedSocketConfig, options: TracedSocketOptions);
|
|
67
|
+
protected callHandler<Params, Result, CallableMethodsInner, RequestContextInner extends RequestContextBase>(handler: MethodHandler<Params, Result, CallableMethodsInner, RequestContextInner>, params: Params, ctx: RequestContextInner, client: ISocketClient<CallableMethodsInner>, next: () => Promise<Result>): Promise<Result>;
|
|
68
|
+
protected handleMessage(message: SocketMessage): Promise<void>;
|
|
69
|
+
request<Params, Result>(method: string, params: Params, authorization?: string): Promise<Result>;
|
|
70
|
+
protected respond<Result>(requestId: number, result: Result): void;
|
|
71
|
+
protected respondError(requestId: number, error: SocketError, exception?: Error): void;
|
|
72
|
+
private addEvent;
|
|
73
|
+
close(reason?: string): void;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=traced-socket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traced-socket.d.ts","sourceRoot":"","sources":["../../src/node/traced-socket.ts"],"names":[],"mappings":"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"}
|