@sebspark/otel 4.2.1 → 4.2.2
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/CHANGELOG.md +15 -0
- package/README.md +9 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +72 -54
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @sebspark/otel
|
|
2
2
|
|
|
3
|
+
## 4.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 176ea40: Fix outgoing HTTP span attributes and tracer edge cases:
|
|
8
|
+
|
|
9
|
+
- `requestHook` read `port` and `headers` from the `ClientRequest`, but `ClientRequest` has neither. Every outgoing `http`/`https` span was therefore overwritten with port 80, scheme `http`, a `url.full` without the port, and no captured request headers. The port now comes from the `host` header, the scheme from `protocol`, and headers from `getHeader`.
|
|
10
|
+
- `withTrace` and `withTraceSync` treated span options without `attributes`, `kind` or `startTime` (for example `{ root: true }`) as a parent span and crashed. Spans are now detected by shape and anything else is treated as options.
|
|
11
|
+
- When a value that is not an `Error` is thrown inside `withTrace` or `withTraceSync`, the span's error status now carries its message instead of `undefined`.
|
|
12
|
+
- `GcpJsonLogExporter` ignores `trace_id` and `span_id` attributes that are not strings.
|
|
13
|
+
- The README examples call the instrumentation factories (`instrumentations.http()`), as the current API requires.
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [176ea40]
|
|
16
|
+
- @sebspark/opentelemetry-instrumentation-opensearch@0.4.2
|
|
17
|
+
|
|
3
18
|
## 4.2.1
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -24,10 +24,10 @@ pnpm add @sebspark/otel
|
|
|
24
24
|
import { initialize, instrumentations, dispose } from '@sebspark/otel'
|
|
25
25
|
|
|
26
26
|
await initialize(
|
|
27
|
-
instrumentations.undici,
|
|
28
|
-
instrumentations.http,
|
|
29
|
-
instrumentations.express,
|
|
30
|
-
instrumentations.redis,
|
|
27
|
+
instrumentations.undici(),
|
|
28
|
+
instrumentations.http(),
|
|
29
|
+
instrumentations.express(),
|
|
30
|
+
instrumentations.redis(),
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
// start your application
|
|
@@ -78,11 +78,11 @@ process.env.OTEL_SERVICE_NAME ??= pkg.name
|
|
|
78
78
|
process.env.OTEL_SERVICE_VERSION ??= pkg.version
|
|
79
79
|
|
|
80
80
|
await initialize(
|
|
81
|
-
instrumentations.http,
|
|
82
|
-
instrumentations.express,
|
|
83
|
-
instrumentations.grpc,
|
|
84
|
-
instrumentations.redis,
|
|
85
|
-
instrumentations.undici,
|
|
81
|
+
instrumentations.http(),
|
|
82
|
+
instrumentations.express(),
|
|
83
|
+
instrumentations.grpc(),
|
|
84
|
+
instrumentations.redis(),
|
|
85
|
+
instrumentations.undici(),
|
|
86
86
|
)
|
|
87
87
|
```
|
|
88
88
|
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":["Span","Span"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/types.ts","../src/instrumentations.ts","../src/logger.ts","../src/metrics.ts","../src/otel.ts","../src/tracer.ts"],"mappings":";;;;;;;;;;;cA0Ba;KCtBD,mBAAmB;UASd;EACf;EACA;EACA;;EAEA;EACA,UAAU;;EAEV,UAAU;;UAeK,qCAAqC;;;;;EAKpD;;EAGA;;;;;;EAOA,cAAc,MAAMA,QAAM,SAAS;;;;;EAMnC;;;;;EAMA;;qBCpCW;WACX,OAAI,SAAU,iCAA4B,QAAA,gBAAA;WAe1C,UAAO,SAAU,iCAA4B,QAAA,gBAAA;WAc7C,OAAI,SAAU,8BAAyB,QAAA,gBAAA;WAcvC,QAAK,SAAU,+BAA0B,QAAA,gBAAA;WAczC,MAAG,SAAU,6BAAwB,QAAA,gBAAA;WAcrC,MAAG,SAAU,0BAAqB,QAAA,gBAAA;WAclC,KAAE,SAAU,4BAAuB,QAAA,gBAAA;WAcnC,SAAM,SAAU,iCAA4B,QAAA,gBAAA;WAe5C,WAAQ,SAAU,kCAA6B,QAAA,gBAAA;WAc/C,aAAU,SAAU,oCAA+B,QAAA,gBAAA;;KCtJhD,QAAQ;YAED,SAAS,kBAAkB;wBACvB,UAAU,0BAA0B,aAAY;EAkF5D;KAjBM,aAAM,QAAU;KAChB,aAAM,OAAS,OAAK,QAAU;KAC5B,OAAA,OAAK,QAAU;;EAgBvB;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;;wBC9FY,SAAS,8DAA8B;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":["Span","Span"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/types.ts","../src/instrumentations.ts","../src/logger.ts","../src/metrics.ts","../src/otel.ts","../src/tracer.ts"],"mappings":";;;;;;;;;;;cA0Ba;KCtBD,mBAAmB;UASd;EACf;EACA;EACA;;EAEA;EACA,UAAU;;EAEV,UAAU;;UAeK,qCAAqC;;;;;EAKpD;;EAGA;;;;;;EAOA,cAAc,MAAMA,QAAM,SAAS;;;;;EAMnC;;;;;EAMA;;qBCpCW;WACX,OAAI,SAAU,iCAA4B,QAAA,gBAAA;WAe1C,UAAO,SAAU,iCAA4B,QAAA,gBAAA;WAc7C,OAAI,SAAU,8BAAyB,QAAA,gBAAA;WAcvC,QAAK,SAAU,+BAA0B,QAAA,gBAAA;WAczC,MAAG,SAAU,6BAAwB,QAAA,gBAAA;WAcrC,MAAG,SAAU,0BAAqB,QAAA,gBAAA;WAclC,KAAE,SAAU,4BAAuB,QAAA,gBAAA;WAcnC,SAAM,SAAU,iCAA4B,QAAA,gBAAA;WAe5C,WAAQ,SAAU,kCAA6B,QAAA,gBAAA;WAc/C,aAAU,SAAU,oCAA+B,QAAA,gBAAA;;KCtJhD,QAAQ;YAED,SAAS,kBAAkB;wBACvB,UAAU,0BAA0B,aAAY;EAkF5D;KAjBM,aAAM,QAAU;KAChB,aAAM,OAAS,OAAK,QAAU;KAC5B,OAAA,OAAK,QAAU;;EAgBvB;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;;wBC9FY,SAAS,8DAA8B;wBC2BjC,cACjB,kBAAkB,QAAQ,qBAC5B;wBAea;qBAsCH,eAAO;KC7Ef,aAAa,kBAAkB,MAAM;KACrCC,SAAO,WAAW;KAElB,KAAK,MAAM,MAAMA,WAAS,QAAQ,KAAK;KACvC,SAAS,MAAM,MAAMA,WAAS;KAE9B;GACF,GAAG,cAAc,IAAI,KAAK,KAAK,QAAQ;GACvC,GAAG,cAAc,SAAS,aAAa,IAAI,KAAK,KAAK,QAAQ;GAC7D,GAAG,cAAc,QAAQA,QAAM,IAAI,KAAK,KAAK,QAAQ;GACrD,GAAG,cAAc,SAAS,aAAa,QAAQA,QAAM,IAAI,KAAK,KAAK,QAAQ;;KAEzE;GACF,GAAG,cAAc,IAAI,SAAS,KAAK;GACnC,GAAG,cAAc,SAAS,aAAa,IAAI,SAAS,KAAK;GACzD,GAAG,cAAc,QAAQA,QAAM,IAAI,SAAS,KAAK;GACjD,GAAG,cAAc,SAAS,aAAa,QAAQA,QAAM,IAAI,SAAS,KAAK;;;;;UAMhE,eAAe;EACvB,WAAW;EACX,eAAe;;;;;;;;;wBAUD,UAAU,iCAAiC"}
|
package/dist/index.mjs
CHANGED
|
@@ -88,9 +88,10 @@ const resolve = (opts) => ({
|
|
|
88
88
|
useDescriptiveSpanNames: opts.useDescriptiveSpanNames ?? true,
|
|
89
89
|
ignoreOutgoingPaths: opts.ignoreOutgoingPaths ?? []
|
|
90
90
|
});
|
|
91
|
-
const isClientRequest = (req) => typeof req.getHeader === "function";
|
|
91
|
+
const isClientRequest = (req) => "getHeader" in req && typeof req.getHeader === "function";
|
|
92
92
|
const isIncomingMessage = (res) => res != null && typeof res === "object" && "statusCode" in res && "headers" in res;
|
|
93
93
|
// src/enrichments/outgoing-http/normalize-http.ts
|
|
94
|
+
const isHeaderList = (headers) => Array.isArray(headers);
|
|
94
95
|
const normHttpRequest = (req) => {
|
|
95
96
|
const hostname = String(req.hostname ?? req.host ?? "").split(":")[0];
|
|
96
97
|
const port = Number(req.port ?? req.defaultPort ?? 80);
|
|
@@ -104,11 +105,33 @@ const normHttpRequest = (req) => {
|
|
|
104
105
|
protocol,
|
|
105
106
|
getHeader(name) {
|
|
106
107
|
const headers = req.headers;
|
|
107
|
-
if (!headers ||
|
|
108
|
+
if (!headers || isHeaderList(headers)) return void 0;
|
|
108
109
|
return getHeaderFromObject(headers, name);
|
|
109
110
|
}
|
|
110
111
|
};
|
|
111
112
|
};
|
|
113
|
+
/**
|
|
114
|
+
* Normalises an outgoing `ClientRequest`. Unlike `RequestOptions` it has no
|
|
115
|
+
* `port` or `headers`, so the port comes from the `host` header and the
|
|
116
|
+
* scheme from `protocol`.
|
|
117
|
+
*/
|
|
118
|
+
const normClientRequest = (req) => {
|
|
119
|
+
const protocol = req.protocol === "https:" ? "https" : "http";
|
|
120
|
+
const hostPort = String(req.getHeader("host") ?? "").split(":")[1];
|
|
121
|
+
const port = hostPort ? Number(hostPort) : protocol === "https" ? 443 : 80;
|
|
122
|
+
return {
|
|
123
|
+
method: req.method,
|
|
124
|
+
hostname: req.host,
|
|
125
|
+
port,
|
|
126
|
+
path: req.path,
|
|
127
|
+
protocol,
|
|
128
|
+
getHeader(name) {
|
|
129
|
+
const value = req.getHeader(name);
|
|
130
|
+
if (value === void 0) return void 0;
|
|
131
|
+
return Array.isArray(value) ? value : [String(value)];
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
};
|
|
112
135
|
const normHttpResponse = (res) => {
|
|
113
136
|
const socket = res.socket;
|
|
114
137
|
return {
|
|
@@ -182,7 +205,7 @@ const buildHttpConfig = (opts = {}) => {
|
|
|
182
205
|
/* istanbul ignore next */
|
|
183
206
|
proto === "https:" ? "1.1" : "1.1"
|
|
184
207
|
);
|
|
185
|
-
applyRequestAttributes(span,
|
|
208
|
+
applyRequestAttributes(span, normClientRequest(request), cfg);
|
|
186
209
|
},
|
|
187
210
|
responseHook(span, response) {
|
|
188
211
|
if (!isIncomingMessage(response)) return;
|
|
@@ -193,7 +216,7 @@ const buildHttpConfig = (opts = {}) => {
|
|
|
193
216
|
// src/enrichments/outgoing-http/normalize-undici.ts
|
|
194
217
|
const normUndiciRequest = (req) => {
|
|
195
218
|
const origin = new URL(req.origin);
|
|
196
|
-
const protocol = origin.protocol
|
|
219
|
+
const protocol = origin.protocol === "https:" ? "https" : "http";
|
|
197
220
|
const port = Number(origin.port) || (protocol === "https" ? 443 : 80);
|
|
198
221
|
const headers = parseUndiciRequestHeaders(req.headers);
|
|
199
222
|
return {
|
|
@@ -219,10 +242,8 @@ const parseUndiciResponseHeaders = (headers) => {
|
|
|
219
242
|
const keyBuf = headers[i];
|
|
220
243
|
const valBuf = headers[i + 1];
|
|
221
244
|
if (!keyBuf || !valBuf) continue;
|
|
222
|
-
|
|
223
|
-
const
|
|
224
|
-
/* istanbul ignore next */
|
|
225
|
-
const val = Buffer.isBuffer(valBuf) ? valBuf.toString("utf8").trim() : Buffer.from(valBuf).toString("utf8").trim();
|
|
245
|
+
const key = Buffer.from(keyBuf).toString("utf8").trim().toLowerCase();
|
|
246
|
+
const val = Buffer.from(valBuf).toString("utf8").trim();
|
|
226
247
|
if (!key || !val) continue;
|
|
227
248
|
if (!result[key]) result[key] = [];
|
|
228
249
|
result[key].push(val);
|
|
@@ -342,6 +363,12 @@ const LOG_SEVERITY_MAP = {
|
|
|
342
363
|
ALERT: 22,
|
|
343
364
|
EMERGENCY: 23
|
|
344
365
|
};
|
|
366
|
+
const isLogSeverityName = (level) => Object.hasOwn(LOG_SEVERITY_MAP, level);
|
|
367
|
+
/** Severity threshold from `LOG_LEVEL`, falling back to INFO. */
|
|
368
|
+
const logThresholdFromEnv = () => {
|
|
369
|
+
const level = process.env.LOG_LEVEL?.toUpperCase() ?? "INFO";
|
|
370
|
+
return LOG_SEVERITY_MAP[isLogSeverityName(level) ? level : "INFO"];
|
|
371
|
+
};
|
|
345
372
|
// src/loggers/formatters/style.ts
|
|
346
373
|
const colors = {
|
|
347
374
|
gray: kleur.gray,
|
|
@@ -379,7 +406,7 @@ const statusColorMap = {
|
|
|
379
406
|
};
|
|
380
407
|
colors.white, colors.cyan, colors.yellow, colors.magenta, colors.green;
|
|
381
408
|
// src/loggers/formatters/shared.ts
|
|
382
|
-
const stringify = fss.
|
|
409
|
+
const stringify = fss.stableStringify;
|
|
383
410
|
function formatTimestamp(time) {
|
|
384
411
|
const date = new Date(hrTimeToMillis(time));
|
|
385
412
|
return colors.dim(date.toISOString().slice(11, 23));
|
|
@@ -601,9 +628,7 @@ function globToRegex(glob) {
|
|
|
601
628
|
var ConsoleLogPrettyExporter = class {
|
|
602
629
|
logThreshold;
|
|
603
630
|
constructor() {
|
|
604
|
-
|
|
605
|
-
const env = process.env.LOG_LEVEL?.toUpperCase() ?? defaultLogLevel;
|
|
606
|
-
this.logThreshold = LOG_SEVERITY_MAP[env] ?? LOG_SEVERITY_MAP[defaultLogLevel];
|
|
631
|
+
this.logThreshold = logThresholdFromEnv();
|
|
607
632
|
}
|
|
608
633
|
export(logs, resultCallback) {
|
|
609
634
|
this._sendLogRecords(logs, resultCallback);
|
|
@@ -792,14 +817,14 @@ function getGlobal() {
|
|
|
792
817
|
}
|
|
793
818
|
async function initialize(...instrumentations) {
|
|
794
819
|
const g = getGlobal();
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
return
|
|
820
|
+
const existing = g[OTEL_INIT_PROMISE_KEY];
|
|
821
|
+
if (existing instanceof Promise) return existing;
|
|
822
|
+
const promise = _initialize(await Promise.all(instrumentations)).catch((err) => {
|
|
823
|
+
g[OTEL_INIT_PROMISE_KEY] = void 0;
|
|
824
|
+
throw err;
|
|
825
|
+
});
|
|
826
|
+
g[OTEL_INIT_PROMISE_KEY] = promise;
|
|
827
|
+
return promise;
|
|
803
828
|
}
|
|
804
829
|
function isInitialized() {
|
|
805
830
|
return getGlobal()[OTEL_INIT_KEY] === true;
|
|
@@ -942,12 +967,7 @@ function getTracer(componentNameOverride) {
|
|
|
942
967
|
span.setStatus({ code: SpanStatusCode$1.OK });
|
|
943
968
|
return result;
|
|
944
969
|
} catch (err) {
|
|
945
|
-
|
|
946
|
-
span.setStatus({
|
|
947
|
-
code: SpanStatusCode$1.ERROR,
|
|
948
|
-
message: error.message
|
|
949
|
-
});
|
|
950
|
-
span.recordException?.(error);
|
|
970
|
+
recordError(span, err);
|
|
951
971
|
throw err;
|
|
952
972
|
} finally {
|
|
953
973
|
endOnce();
|
|
@@ -977,47 +997,45 @@ function getTracer(componentNameOverride) {
|
|
|
977
997
|
span.setStatus({ code: SpanStatusCode$1.OK });
|
|
978
998
|
return result;
|
|
979
999
|
} catch (err) {
|
|
980
|
-
|
|
981
|
-
span.setStatus({
|
|
982
|
-
code: SpanStatusCode$1.ERROR,
|
|
983
|
-
message: error.message
|
|
984
|
-
});
|
|
985
|
-
span.recordException?.(error);
|
|
1000
|
+
recordError(span, err);
|
|
986
1001
|
throw err;
|
|
987
1002
|
} finally {
|
|
988
1003
|
endOnce();
|
|
989
1004
|
}
|
|
990
1005
|
});
|
|
991
1006
|
};
|
|
992
|
-
tracer
|
|
993
|
-
|
|
994
|
-
|
|
1007
|
+
return Object.assign(tracer, {
|
|
1008
|
+
withTrace,
|
|
1009
|
+
withTraceSync
|
|
1010
|
+
});
|
|
995
1011
|
}
|
|
1012
|
+
const recordError = (span, err) => {
|
|
1013
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1014
|
+
span.setStatus({
|
|
1015
|
+
code: SpanStatusCode$1.ERROR,
|
|
1016
|
+
message
|
|
1017
|
+
});
|
|
1018
|
+
span.recordException?.(err instanceof Error ? err : message);
|
|
1019
|
+
};
|
|
996
1020
|
function extractArgs(spanOptionsSpanOrFunc, spanOrFunc, func) {
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
fn
|
|
1006
|
-
}
|
|
1007
|
-
options = spanOptionsSpanOrFunc;
|
|
1008
|
-
parent = spanOrFunc;
|
|
1009
|
-
fn = func;
|
|
1010
|
-
}
|
|
1021
|
+
if (isFunction(spanOptionsSpanOrFunc)) return {
|
|
1022
|
+
options: {},
|
|
1023
|
+
fn: spanOptionsSpanOrFunc
|
|
1024
|
+
};
|
|
1025
|
+
const options = spanOptionsSpanOrFunc && !isSpan(spanOptionsSpanOrFunc) ? spanOptionsSpanOrFunc : {};
|
|
1026
|
+
if (isFunction(spanOrFunc)) return {
|
|
1027
|
+
options,
|
|
1028
|
+
parent: isSpan(spanOptionsSpanOrFunc) ? spanOptionsSpanOrFunc : void 0,
|
|
1029
|
+
fn: spanOrFunc
|
|
1030
|
+
};
|
|
1011
1031
|
return {
|
|
1012
1032
|
options,
|
|
1013
|
-
parent,
|
|
1014
|
-
fn
|
|
1033
|
+
parent: spanOrFunc,
|
|
1034
|
+
fn: func
|
|
1015
1035
|
};
|
|
1016
1036
|
}
|
|
1017
1037
|
const isFunction = (value) => typeof value === "function";
|
|
1018
|
-
const isSpan = (value) => value
|
|
1019
|
-
/* istanbul ignore next */
|
|
1020
|
-
const isSpanOptions = (value) => value !== null && value !== void 0 && (!!value.startTime || !!value.attributes || !!value.kind) && !isSpan(value);
|
|
1038
|
+
const isSpan = (value) => typeof value === "object" && value !== null && "spanContext" in value && isFunction(value.spanContext) && "end" in value && isFunction(value.end);
|
|
1021
1039
|
// src/index.ts
|
|
1022
1040
|
/* istanbul ignore file */
|
|
1023
1041
|
export { SpanStatusCode, context, dispose, getLogger, getMeter, getTracer, initialize, instrumentations, isInitialized };
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["SpanStatusCode","SpanStatusCode","SpanStatusCode","context","context","SpanStatusCode"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/apply-attributes.ts","../src/enrichments/outgoing-http/helpers.ts","../src/enrichments/outgoing-http/normalize-http.ts","../src/enrichments/outgoing-http/build-http-config.ts","../src/enrichments/outgoing-http/normalize-undici.ts","../src/enrichments/outgoing-http/build-undici-config.ts","../src/enrichments/outgoing-http/index.ts","../src/instrumentations.ts","../src/consts.ts","../src/loggers/formatters/style.ts","../src/loggers/formatters/shared.ts","../src/loggers/formatters/log-record.ts","../src/loggers/formatters/metrics.ts","../src/loggers/formatters/span.ts","../src/loggers/formatters/index.ts","../src/loggers/console-metric-pretty-exporter.ts","../src/loggers/console-log-pretty-exporter.ts","../src/loggers/console-span-pretty-exporter.ts","../src/loggers/index.ts","../src/loggers/tree-span-processor.ts","../src/providers.ts","../src/otel-context.ts","../src/resource.ts","../src/otel.ts","../src/logger.ts","../src/metrics.ts","../src/tracer.ts","../src/index.ts"],"sourcesContent":["// Incubating attrs — copied as string literals per OTel JS team recommendation:\n// importing from /incubating at runtime is explicitly discouraged because that\n// entry-point is NOT subject to semver and may break in minor releases.\n// https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-semantic-conventions#unstable-semconv\nexport const ATTR_HTTP_REQUEST_BODY_SIZE = 'http.request.body.size'\nexport const ATTR_HTTP_RESPONSE_BODY_SIZE = 'http.response.body.size'\n\nexport const DEFAULT_REQUEST_HEADERS: string[] = [\n 'content-type',\n 'accept',\n 'x-request-id',\n 'x-correlation-id',\n 'traceparent',\n 'tracestate',\n] as const\n\nexport const DEFAULT_RESPONSE_HEADERS: string[] = [\n 'content-type',\n 'x-request-id',\n 'x-correlation-id',\n 'x-ratelimit-limit',\n 'x-ratelimit-remaining',\n 'x-ratelimit-reset',\n 'retry-after',\n] as const\n\nexport const PROTOCOLS = ['https', 'http'] as const\n","import { type Span, SpanStatusCode } from '@opentelemetry/api'\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_QUERY,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n ATTR_HTTP_REQUEST_BODY_SIZE,\n ATTR_HTTP_RESPONSE_BODY_SIZE,\n} from './consts'\nimport type {\n NormalisedRequest,\n NormalisedResponse,\n ResolvedConfig,\n} from './types'\n\nconst requestHeaderAttr = (h: string) =>\n `http.request.header.${h.toLowerCase().replace(/-/g, '_')}`\nconst responseHeaderAttr = (h: string) =>\n `http.response.header.${h.toLowerCase().replace(/-/g, '_')}`\n\nexport const applyRequestAttributes = (\n span: Span,\n req: NormalisedRequest,\n cfg: ResolvedConfig\n): void => {\n const { method, hostname, port, path, protocol } = req\n const [urlPath, urlQuery] = path.split('?')\n /* istanbul ignore next */\n const defaultPort = protocol === 'https' ? 443 : 80\n /* istanbul ignore next */\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n // Stable semconv v1.23+ attributes\n span.setAttributes({\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n })\n\n if (urlQuery) {\n span.setAttribute(ATTR_URL_QUERY, urlQuery)\n }\n\n if (cfg.useDescriptiveSpanNames) {\n span.updateName(`${method.toUpperCase()} ${hostname}${resolvedUrlPath}`)\n }\n\n for (const header of cfg.captureRequestHeaders) {\n const value = req.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(requestHeaderAttr(header), value)\n }\n }\n\n const contentLength = req.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_REQUEST_BODY_SIZE, Number(contentLength))\n }\n\n cfg.enrichSpan(span, req)\n}\n\nexport const applyResponseAttributes = (\n span: Span,\n res: NormalisedResponse,\n cfg: ResolvedConfig\n): void => {\n const { statusCode } = res\n\n span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, statusCode)\n\n // OTel spec for CLIENT spans: 5xx = SDK error; 4xx is not (it's the\n // server's fault). We still record error.type for both so they're filterable.\n if (statusCode >= 500) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n })\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n } else if (statusCode >= 400) {\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n }\n\n for (const header of cfg.captureResponseHeaders) {\n const value = res.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(responseHeaderAttr(header), value)\n }\n }\n\n const contentLength = res.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_RESPONSE_BODY_SIZE, Number(contentLength))\n }\n\n // Resolved wire address (post-proxy) — separate from the original hostname\n // so you can see both in the span and spot mesh rewrites.\n if (res.remoteAddress) {\n span.setAttribute(ATTR_NETWORK_PEER_ADDRESS, res.remoteAddress)\n }\n if (res.remotePort) {\n span.setAttribute(ATTR_NETWORK_PEER_PORT, res.remotePort)\n }\n}\n","import type { ClientRequest, IncomingMessage } from 'node:http'\nimport { DEFAULT_REQUEST_HEADERS, DEFAULT_RESPONSE_HEADERS } from './consts'\nimport type { OutgoingHttpEnrichmentConfig, ResolvedConfig } from './types'\n\nexport const resolve = (\n opts: OutgoingHttpEnrichmentConfig\n): ResolvedConfig => ({\n captureRequestHeaders: opts.captureRequestHeaders ?? DEFAULT_REQUEST_HEADERS,\n captureResponseHeaders:\n opts.captureResponseHeaders ?? DEFAULT_RESPONSE_HEADERS,\n enrichSpan: opts.enrichSpan ?? (() => {}),\n useDescriptiveSpanNames: opts.useDescriptiveSpanNames ?? true,\n ignoreOutgoingPaths: opts.ignoreOutgoingPaths ?? [],\n})\n\nexport const isClientRequest = (\n req: ClientRequest | IncomingMessage\n): req is ClientRequest =>\n typeof (req as ClientRequest).getHeader === 'function'\n\nexport const isIncomingMessage = (res: unknown): res is IncomingMessage =>\n res != null &&\n typeof res === 'object' &&\n 'statusCode' in res &&\n 'headers' in res\n","import type { IncomingMessage, RequestOptions } from 'node:http'\nimport type { NormalisedRequest, NormalisedResponse, Protocol } from './types'\n\nexport const normHttpRequest = (req: RequestOptions): NormalisedRequest => {\n const hostname = String(req.hostname ?? req.host ?? '').split(':')[0]\n const port = Number(req.port ?? req.defaultPort ?? 80)\n const path = String(req.path ?? '/')\n const protocol: Protocol = port === 443 ? 'https' : 'http'\n\n return {\n method: req.method ?? 'GET',\n hostname,\n port,\n path,\n protocol,\n getHeader(name) {\n const headers = req.headers\n if (!headers || Array.isArray(headers)) return undefined\n return getHeaderFromObject(headers as Record<string, unknown>, name)\n },\n }\n}\n\nexport const normHttpResponse = (res: IncomingMessage): NormalisedResponse => {\n const socket = res.socket\n return {\n statusCode: res.statusCode ?? 0,\n statusMessage: res.statusMessage ?? '',\n getHeader(name) {\n return getHeaderFromObject(res.headers, name)\n },\n remoteAddress: socket?.remoteAddress,\n remotePort: socket?.remotePort,\n }\n}\n\nexport const getHeaderFromObject = (\n headers: Record<string, unknown> | undefined,\n name: string\n): string[] | undefined => {\n if (!headers) return undefined\n\n const target = name.toLowerCase()\n\n // Iterate over all keys to find case-insensitive match\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === target) {\n const value = headers[key]\n if (Array.isArray(value)) return value\n /* istanbul ignore next */\n if (typeof value === 'string') return [value]\n /* istanbul ignore next */\n return undefined\n }\n }\n\n return undefined\n}\n","import type { Attributes } from '@opentelemetry/api'\nimport type { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'\nimport {\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { isClientRequest, isIncomingMessage, resolve } from './helpers'\nimport { normHttpRequest, normHttpResponse } from './normalize-http'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an HttpInstrumentationConfig that applies shared enrichment logic.\n *\n * The returned config can be spread with your own additional options:\n * new HttpInstrumentation({ ...buildHttpConfig(opts), requireParentforOutgoingSpans: true })\n */\nexport const buildHttpConfig = (\n opts: OutgoingHttpEnrichmentConfig = {}\n): HttpInstrumentationConfig => {\n const cfg = resolve(opts)\n\n const config: HttpInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreOutgoingRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // startOutgoingSpanHook fires at span creation time — before any proxy or\n // service-mesh sidecar can rewrite the destination socket. The returned\n // attributes are the \"ground truth\" hostname we captured off the wire.\n startOutgoingSpanHook(req) {\n const { method, hostname, port, path, protocol } = normHttpRequest(req)\n const [urlPath] = path.split('?')\n const defaultPort = protocol === 'https' ? 443 : 80\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n const attrs: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n [ATTR_NETWORK_PEER_ADDRESS]: hostname,\n [ATTR_NETWORK_PEER_PORT]: port,\n }\n /* istanbul ignore next */\n for (const [key, val] of Object.entries(req.headers || {})) {\n if (!val) continue\n\n const name = key.toLowerCase().replace(/-/g, '_')\n const value = Array.isArray(val) ? val.join(',') : val\n attrs[`http.request.header.${name}`] = value\n }\n return attrs\n },\n\n requestHook(span, request) {\n // requestHook fires for both incoming (IncomingMessage) and outgoing\n // (ClientRequest) spans — skip the incoming side.\n if (!isClientRequest(request)) return\n\n // HTTP version isn't always accessible here, but try to read it.\n const proto = request.protocol\n if (proto) {\n span.setAttribute(\n ATTR_NETWORK_PROTOCOL_VERSION,\n /* istanbul ignore next */\n proto === 'https:' ? '1.1' : '1.1'\n )\n }\n\n applyRequestAttributes(span, normHttpRequest(request), cfg)\n },\n\n responseHook(span, response) {\n if (!isIncomingMessage(response)) return\n applyResponseAttributes(span, normHttpResponse(response), cfg)\n },\n }\n\n return config\n}\n","import type {\n UndiciRequest,\n UndiciResponse,\n} from '@opentelemetry/instrumentation-undici'\nimport type { NormalisedRequest, NormalisedResponse } from './types'\n\nexport const normUndiciRequest = (req: UndiciRequest): NormalisedRequest => {\n const origin = new URL(req.origin)\n const protocol = origin.protocol.replace(':', '') as 'http' | 'https'\n const port = Number(origin.port) || (protocol === 'https' ? 443 : 80)\n\n // Parse \"Key: Value\\r\\nKey2: Value2\\r\\n\" → Map\n const headers = parseUndiciRequestHeaders(req.headers)\n\n return {\n method: req.method,\n hostname: origin.hostname,\n port,\n path: req.path,\n protocol,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const normUndiciResponse = (res: UndiciResponse): NormalisedResponse => {\n const headers = parseUndiciResponseHeaders(res.headers)\n\n return {\n statusCode: res.statusCode,\n statusMessage: res.statusText,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const parseUndiciResponseHeaders = (\n headers: Buffer<ArrayBufferLike>[]\n): Record<string, string[]> => {\n const result: Record<string, string[]> = {}\n\n for (let i = 0; i < headers.length; i += 2) {\n const keyBuf = headers[i]\n const valBuf = headers[i + 1]\n\n if (!keyBuf || !valBuf) continue\n\n /* istanbul ignore next */\n const key = (\n Buffer.isBuffer(keyBuf)\n ? keyBuf.toString('utf8').trim()\n : Buffer.from(keyBuf as ArrayBuffer)\n .toString('utf8')\n .trim()\n ).toLowerCase()\n\n /* istanbul ignore next */\n const val = Buffer.isBuffer(valBuf)\n ? valBuf.toString('utf8').trim()\n : Buffer.from(valBuf as ArrayBuffer)\n .toString('utf8')\n .trim()\n\n if (!key || !val) continue\n\n if (!result[key]) result[key] = []\n result[key].push(val)\n }\n\n return result\n}\n\nexport const parseUndiciRequestHeaders = (\n headers: string | (string | string[])[]\n) => {\n const result: Record<string, string[]> = {}\n\n if (typeof headers === 'string') {\n // Single string format: \"key: value\"\n const [key, ...rest] = headers.split(':')\n if (key && rest.length > 0) {\n result[key.trim().toLowerCase()] = [rest.join(':').trim()]\n }\n } else {\n // The type union guarantees headers is string | array[]; the else-if is always true\n /* istanbul ignore else */\n if (Array.isArray(headers)) {\n // Array format: [key, value] or [key, [value1, value2]]\n for (let i = 0; i < headers.length; i += 2) {\n const key = headers[i]\n const val = headers[i + 1]\n if (typeof key !== 'string' || val == null) continue\n\n if (Array.isArray(val)) {\n result[key.toLowerCase()] = val.map((v) => String(v))\n } else {\n result[key.toLowerCase()] = [String(val)]\n }\n }\n }\n }\n\n return result\n}\n","import type { UndiciInstrumentationConfig } from '@opentelemetry/instrumentation-undici'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { resolve } from './helpers'\nimport { normUndiciRequest, normUndiciResponse } from './normalize-undici'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an UndiciInstrumentationConfig that applies shared enrichment logic.\n *\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\nexport function buildUndiciConfig(\n opts: OutgoingHttpEnrichmentConfig = {}\n): UndiciInstrumentationConfig {\n const cfg = resolve(opts)\n\n const config: UndiciInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // undici collapses startSpanHook + requestHook into a single requestHook\n // because diagnostics_channel gives us everything at once.\n requestHook(span, request) {\n applyRequestAttributes(span, normUndiciRequest(request), cfg)\n },\n\n responseHook(span, { response }) {\n applyResponseAttributes(span, normUndiciResponse(response), cfg)\n },\n }\n\n return config\n}\n","/* istanbul ignore file */\n/**\n * Shared enrichment logic for outgoing HTTP spans, normalised across\n * @opentelemetry/instrumentation-http (node:http / node:https)\n * @opentelemetry/instrumentation-undici (undici / global fetch)\n *\n * Usage:\n *\n * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n * import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'\n * import { buildHttpConfig, buildUndiciConfig } from './instrumentation/outgoing-http'\n * import type { OutgoingHttpEnrichmentConfig } from './instrumentation/outgoing-http'\n *\n * const opts: OutgoingHttpEnrichmentConfig = {\n * captureRequestHeaders: ['x-tenant-id', 'x-request-id'],\n * captureResponseHeaders: ['x-ratelimit-remaining'],\n * enrichSpan: (span, req) =>\n * span.setAttribute('app.tenant.id', req.getHeader('x-tenant-id') ?? ''),\n * ignoreOutgoingPaths: ['/health', '/ready'],\n * }\n *\n * new HttpInstrumentation(buildHttpConfig(opts))\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\n\nexport { buildHttpConfig } from './build-http-config'\nexport { buildUndiciConfig } from './build-undici-config'\nexport type { OutgoingHttpEnrichmentConfig } from './types'\n","import type {\n Instrumentation,\n InstrumentationConfig,\n} from '@opentelemetry/instrumentation'\nimport type { DnsInstrumentationConfig } from '@opentelemetry/instrumentation-dns'\nimport type { ExpressInstrumentationConfig } from '@opentelemetry/instrumentation-express'\nimport type { FsInstrumentationConfig } from '@opentelemetry/instrumentation-fs'\nimport type { GrpcInstrumentationConfig } from '@opentelemetry/instrumentation-grpc'\nimport type { RedisInstrumentationConfig } from '@opentelemetry/instrumentation-redis'\nimport type { SocketIoInstrumentationConfig } from '@opentelemetry/instrumentation-socket.io'\nimport type { OpenSearchInstrumentationConfig } from '@sebspark/opentelemetry-instrumentation-opensearch'\nimport {\n buildHttpConfig,\n buildUndiciConfig,\n type OutgoingHttpEnrichmentConfig,\n} from './enrichments/outgoing-http'\n\nconst cache = new Map<string, Promise<Instrumentation>>()\nconst cacheKey = (\n instrumentationName: string,\n config?: InstrumentationConfig\n) => {\n return config\n ? `${instrumentationName}:${JSON.stringify(config)}`\n : instrumentationName\n}\n\nexport const instrumentations = {\n http(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('http', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-http').then(\n ({ HttpInstrumentation }) =>\n new HttpInstrumentation(buildHttpConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n express(config?: ExpressInstrumentationConfig) {\n const key = cacheKey('express', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-express').then(\n ({ ExpressInstrumentation }) => new ExpressInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n grpc(config?: GrpcInstrumentationConfig) {\n const key = cacheKey('grpc', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-grpc').then(\n ({ GrpcInstrumentation }) => new GrpcInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n redis(config?: RedisInstrumentationConfig) {\n const key = cacheKey('redis', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-redis').then(\n ({ RedisInstrumentation }) => new RedisInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n dns(config?: DnsInstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-dns').then(\n ({ DnsInstrumentation }) => new DnsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n net(config?: InstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-net').then(\n ({ NetInstrumentation }) => new NetInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n fs(config?: FsInstrumentationConfig) {\n const key = cacheKey('fs', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-fs').then(\n ({ FsInstrumentation }) => new FsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n undici(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('undici', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-undici').then(\n ({ UndiciInstrumentation }) =>\n new UndiciInstrumentation(buildUndiciConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n socketIo(config?: SocketIoInstrumentationConfig) {\n const key = cacheKey('socket-io', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-socket.io').then(\n ({ SocketIoInstrumentation }) => new SocketIoInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n opensearch(config?: OpenSearchInstrumentationConfig) {\n const key = cacheKey('opensearch', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@sebspark/opentelemetry-instrumentation-opensearch').then(\n ({ OpenSearchInstrumentation }) =>\n new OpenSearchInstrumentation({\n suppressInternalInstrumentation: true,\n ...(config || {}),\n })\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n} as const\n","export const LOG_SEVERITY_MAP = {\n TRACE: 1,\n DEBUG: 5,\n INFO: 9,\n NOTICE: 10,\n WARNING: 13,\n WARN: 13,\n ERROR: 17,\n FATAL: 21,\n CRITICAL: 21,\n ALERT: 22,\n EMERGENCY: 23,\n} as const\n\nexport type LOG_SEVERITY_NAME = keyof typeof LOG_SEVERITY_MAP\n","import kleur from 'kleur'\n\nexport const colors = {\n gray: kleur.gray,\n dim: kleur.dim,\n cyan: kleur.cyan,\n white: kleur.white,\n green: kleur.green,\n yellow: kleur.yellow,\n red: kleur.red,\n magenta: kleur.magenta,\n}\n\nexport const levelColorMap: Record<string, (s: string) => string> = {\n DEBUG: kleur.magenta,\n INFO: kleur.green,\n WARN: kleur.yellow,\n ERROR: kleur.red,\n FATAL: kleur.red,\n}\n\nexport const levelIconMap: Record<string, string> = {\n DEBUG: '🐛',\n INFO: 'ℹ️ ',\n WARN: '⚠️ ',\n ERROR: '❌',\n FATAL: '💀',\n}\n\n// --- Span status codes (per OpenTelemetry spec) ---\nexport const statusLabelMap: Record<number, string> = {\n 0: 'UNSET',\n 1: 'OK',\n 2: 'ERROR',\n}\n\nexport const statusColorMap: Record<number, (s: string) => string> = {\n 0: colors.gray, // UNSET\n 1: colors.green, // OK\n 2: colors.red, // ERROR\n}\n\n// --- Span kinds (for visual context: client/server etc.) ---\nexport const kindLabelMap: Record<number, string> = {\n 0: 'INTERNAL',\n 1: 'SERVER',\n 2: 'CLIENT',\n 3: 'PRODUCER',\n 4: 'CONSUMER',\n}\n\nexport const kindColorMap: Record<number, (s: string) => string> = {\n 0: colors.white, // INTERNAL\n 1: colors.cyan, // SERVER\n 2: colors.yellow, // CLIENT\n 3: colors.magenta, // PRODUCER\n 4: colors.green, // CONSUMER\n}\n","import type { Attributes, HrTime } from '@opentelemetry/api'\nimport type { Resource } from '@opentelemetry/resources'\nimport type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace'\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\nimport fss from 'fast-safe-stringify'\nimport { colors, levelColorMap, levelIconMap } from './style'\n\nconst stringify = fss.default.stableStringify\n\ntype IResource = Pick<Resource, 'attributes'>\ntype IInstrumentation = ReadableLogRecord['instrumentationScope']\n\nexport function formatTimestamp(time: HrTime): string {\n const date = new Date(hrTimeToMillis(time))\n return colors.dim(date.toISOString().slice(11, 23)) // HH:mm:ss.sss\n}\n\nexport function formatService(resource: IResource): string {\n const name = resource.attributes[ATTR_SERVICE_NAME] ?? 'unknown-service'\n const version = resource.attributes[ATTR_SERVICE_VERSION] ?? '1.0.0'\n return colors.gray(`[${name}@${version}]`)\n}\n\nexport function formatLevel(record: ReadableLogRecord): string {\n const text = (record.severityText ?? 'INFO').toUpperCase()\n const colorFn = levelColorMap[text] ?? colors.white\n const icon = levelIconMap[text] ?? '•'\n return `${icon} ${colorFn(text.padEnd(5))}`\n}\n\nexport function formatScope(\n resource: IResource,\n instrumentationScope: IInstrumentation\n): string {\n const component = resource.attributes['component.name']\n const { name } = instrumentationScope\n const scopeLabel =\n component || (name && name !== 'unknown' ? name : undefined)\n\n if (!scopeLabel) return ''\n\n return colors.cyan(`${scopeLabel} `)\n}\n\nexport function formatMessage(record: ReadableLogRecord): string {\n return typeof record.body === 'string' ? record.body : stringify(record.body)\n}\n\nexport function formatAttributes(attrs: Attributes): string {\n const keys = Object.keys(attrs).filter(\n (k) =>\n !k.startsWith('service.') &&\n !k.startsWith('serviceContext.') &&\n k !== 'cloud.orchestrator' &&\n k !== 'component.name'\n )\n if (keys.length === 0) return ''\n const formatted = keys.map((k) => {\n const val = attrs[k]\n return `${k}=${typeof val === 'object' ? stringify(val) : val}`\n })\n return ` ${colors.gray(formatted.join(' '))}`\n}\n\nexport function hrTimeToMillis(hrTime: [number, number]): number {\n return hrTime[0] * 1000 + Math.floor(hrTime[1] / 1_000_000)\n}\n\nexport function calculateDuration(span: ReadableSpan): number {\n const start = hrTimeToMillis(span.startTime)\n const end = hrTimeToMillis(span.endTime)\n return Math.max(0, Math.round(end - start))\n}\n","import type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport {\n formatAttributes,\n formatLevel,\n formatMessage,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\n\nexport function formatLogRecord(record: ReadableLogRecord): string {\n const timestamp = formatTimestamp(record.hrTime)\n const service = formatService(record.resource)\n const level = formatLevel(record)\n const scope = formatScope(record.resource, record.instrumentationScope)\n const message = formatMessage(record)\n const attrs = formatAttributes(record.attributes)\n\n return `${service} ${timestamp} ${level} ${scope}${message}${attrs}`\n}\n","import type { Resource } from '@opentelemetry/resources'\nimport type {\n DataPoint,\n MetricData,\n ResourceMetrics,\n ScopeMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport {\n formatAttributes,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\nimport { colors } from './style'\n\nexport function formatMetrics(resourceMetrics: ResourceMetrics): string {\n const { resource, scopeMetrics } = resourceMetrics\n\n return scopeMetrics\n .map((scopeMetric) => formatScopeMetric(scopeMetric, resource))\n .join('\\n')\n}\n\nfunction formatScopeMetric(\n scopeMetric: ScopeMetrics,\n resource: Resource\n): string {\n return scopeMetric.metrics\n .map((metric: MetricData) =>\n formatMetricData(metric, resource, scopeMetric.scope)\n )\n .join('\\n')\n}\n\nfunction formatMetricData(\n metric: MetricData,\n resource: Resource,\n scope: ScopeMetrics['scope']\n): string {\n const scopeStr = formatScope(resource, scope)\n const serviceStr = formatService(resource)\n\n const lines: string[] = []\n\n for (const dp of metric.dataPoints) {\n const ts = formatTimestamp(dp.startTime)\n const value = extractMetricValue(dp)\n const attrs = formatAttributes(dp.attributes ?? {})\n\n lines.push(\n `${serviceStr} ${ts} 📊 ${scopeStr}${colors.white(metric.descriptor.name)} ${colors.dim(value)}${attrs}`\n )\n }\n\n return lines.join('\\n')\n}\n\nfunction extractMetricValue(dp: DataPoint<unknown>): string {\n const value = dp.value\n\n if (typeof value === 'number') {\n return value.toString()\n }\n\n if (isHistogramLike(value)) {\n return value.sum.toString()\n }\n\n return '[complex]'\n}\n\nfunction isHistogramLike(val: unknown): val is { sum: number } {\n return (\n typeof val === 'object' &&\n val !== null &&\n 'sum' in val &&\n typeof (val as { sum: number }).sum === 'number'\n )\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace'\nimport {\n calculateDuration,\n formatService,\n formatTimestamp,\n hrTimeToMillis,\n} from './shared'\nimport { colors, statusColorMap, statusLabelMap } from './style'\n\nconst LABEL_WIDTH = 20\nconst DESCRIPTION_MAX_WIDTH = 16\nconst BAR_MIN_WIDTH = 1\nconst BAR_MAX_WIDTH = 20\n\nexport function formatSpans(spans: ReadableSpan[]) {\n const rootSpan = spans[0]\n const rootStart = hrTimeToMillis(rootSpan.startTime)\n const rootEnd = hrTimeToMillis(rootSpan.endTime)\n const totalDuration = rootEnd - rootStart\n\n const service = formatService(rootSpan.resource)\n const timestamp = formatTimestamp(rootSpan.startTime)\n const traceId = colors.gray(`[${rootSpan.spanContext().traceId}]`)\n\n const lines = [`${service} ${timestamp} ${traceId}`]\n\n for (const span of spans) {\n const offset = hrTimeToMillis(span.startTime) - rootStart\n const depth = computeDepth(span, spans) // optional\n lines.push(\n formatSpan(span, {\n offsetMs: offset,\n totalDurationMs: totalDuration,\n depth,\n })\n )\n }\n\n return lines.join('\\n')\n}\n\nexport function formatSpan(\n span: ReadableSpan,\n opts: {\n offsetMs: number // relative start time in ms (0 for root)\n totalDurationMs: number // total duration in ms (root span duration)\n depth: number // nesting level for indent\n }\n): string {\n const label = formatLabel(span, opts.depth)\n const bar = buildBar(span, opts?.offsetMs, opts?.totalDurationMs)\n const barColor =\n span.status.code === SpanStatusCode.OK\n ? colors.green\n : span.status.code === SpanStatusCode.ERROR\n ? colors.red\n : colors.gray\n const desc = formatDescription(span)\n const status = formatStatus(span)\n const duration = formatDuration(span, opts?.offsetMs)\n const spanId = colors.gray(`[${span.spanContext().spanId}]`)\n\n return `${label} ${barColor(bar)} ${desc} ${status} ${duration} ${spanId}`\n}\n\nfunction formatLabel(span: ReadableSpan, depth: number) {\n const indent = ' '.repeat(depth) // 2 spaces per depth level\n const label = `${indent}└─ ${span.name}`\n return label.padEnd(LABEL_WIDTH)\n}\n\nfunction buildBar(\n span: ReadableSpan,\n offsetMs: number | undefined,\n totalDurationMs: number | undefined\n) {\n const duration = calculateDuration(span)\n\n if (\n typeof offsetMs !== 'number' ||\n typeof totalDurationMs !== 'number' ||\n totalDurationMs === 0\n ) {\n // fallback: show duration-only bar\n const capped = Math.min(duration, 1000)\n const barLength = Math.max(\n BAR_MIN_WIDTH,\n Math.round((capped / 1000) * BAR_MAX_WIDTH)\n )\n return '█'.repeat(barLength).padEnd(BAR_MAX_WIDTH + 2)\n }\n\n // Relative position and size\n const offsetRatio = Math.max(0, Math.min(offsetMs / totalDurationMs, 1))\n const durationRatio = Math.max(0, Math.min(duration / totalDurationMs, 1))\n\n const offsetChars = Math.floor(offsetRatio * BAR_MAX_WIDTH)\n const barChars = Math.max(\n BAR_MIN_WIDTH,\n Math.round(durationRatio * BAR_MAX_WIDTH)\n )\n\n const empty = ' '.repeat(offsetChars)\n const bar = '█'.repeat(barChars)\n\n return (empty + bar).padEnd(BAR_MAX_WIDTH + 2)\n}\n\nfunction formatDescription(span: ReadableSpan): string {\n const keyPriority = [\n // HTTP\n ['http.method', 'http.target'], // → GET /users/123\n ['http.route'], // → /users/:id\n ['http.url'], // → https://...\n\n // GraphQL\n ['graphql.operation.name'], // → getUsers\n ['graphql.operation.type'], // → query\n ['graphql.document'], // → full query text (maybe too long)\n\n // WebSocket\n ['ws.event'], // → connection, message, disconnect\n ['ws.message_type'], // → ping/pong/text/binary\n ['ws.url'], // → wss://...\n\n // Redis\n ['db.system', 'db.statement'], // → redis, \"SET foo bar\"\n ['db.operation'], // → GET, SET\n\n // Spanner\n ['db.statement'], // → SELECT * FROM...\n ['db.operation'], // → SELECT, INSERT\n ['db.name'], // → projects/.../instances/.../databases/...\n\n // OpenSearch\n ['db.operation'], // → search, index, bulk\n ['db.statement'], // → { query DSL... }\n\n // Pub/Sub (GCP)\n ['messaging.operation'], // → publish, receive\n ['messaging.destination'], // → topic-a\n ['messaging.gcp_pubsub.topic'], // → projects/x/topics/y\n\n // General FaaS\n ['faas.invoked_name'], // → myFunction\n ['faas.trigger'], // → http, pubsub, etc.\n\n // Custom or fallback\n ['otel.description'],\n ]\n\n for (const keys of keyPriority) {\n const parts = keys\n .map((k) => span.attributes[k])\n .filter((v) => v !== undefined && v !== null)\n .map((v) => String(v)) // 👈 FIX — guarantees string\n if (parts.length > 0) {\n return truncate(parts.join(' '), DESCRIPTION_MAX_WIDTH - 1).padEnd(\n DESCRIPTION_MAX_WIDTH\n )\n }\n }\n\n return ''.padEnd(DESCRIPTION_MAX_WIDTH)\n}\n\nfunction formatStatus(span: ReadableSpan): string {\n const code = span.status.code\n const label = statusLabelMap[code] ?? 'UNSET'\n const colorFn = statusColorMap[code] ?? colors.gray\n return colorFn(label).padEnd(6)\n}\n\nfunction formatDuration(\n span: ReadableSpan,\n offsetMs: number | undefined\n): string {\n const duration = calculateDuration(span)\n\n const format = (ms: number): string =>\n ms >= 1000 ? `${(ms / 1000).toFixed(2)} s` : `${ms} ms`\n\n return `(${format(offsetMs || 0)}–${format(duration)})`.padEnd(16)\n}\n\nfunction truncate(input: unknown, maxLength: number): string {\n // In practice, input is always a string — the String() cast is a defensive fallback.\n const str = String(input)\n return str.length > maxLength ? `${str.slice(0, maxLength - 1)}…` : str\n}\n\nfunction computeDepth(span: ReadableSpan, allSpans: ReadableSpan[]): number {\n let depth = 0\n let currentParentId = span.parentSpanContext?.spanId\n\n while (currentParentId) {\n const parentSpan = allSpans.find(\n (s) => s.spanContext().spanId === currentParentId\n )\n if (!parentSpan) break\n\n depth += 1\n currentParentId = parentSpan.parentSpanContext?.spanId\n }\n\n return depth\n}\n","/* istanbul ignore file */\nexport * from './log-record'\nexport * from './metrics'\nexport * from './span'\n","import { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n PushMetricExporter,\n ResourceMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport { formatMetrics } from './formatters/index'\n\nexport class ConsoleMetricPrettyExporter implements PushMetricExporter {\n private readonly patterns: RegExp[]\n\n constructor() {\n const raw = process.env.METRIC_FILTER ?? ''\n const entries = raw\n .split(',')\n .map((e) => e.trim())\n .filter(Boolean)\n\n this.patterns = entries.map(globToRegex)\n }\n\n private filterMetrics(\n resourceMetrics: ResourceMetrics\n ): ResourceMetrics | undefined {\n // No filter = block all metrics\n if (this.patterns.length === 0) return undefined\n\n const filteredScopes = resourceMetrics.scopeMetrics\n .map((scopeMetric) => {\n const filteredMetrics = scopeMetric.metrics.filter((metric) =>\n this.patterns.some((pattern) => pattern.test(metric.descriptor.name))\n )\n\n if (filteredMetrics.length === 0) return undefined\n\n return {\n ...scopeMetric,\n metrics: filteredMetrics,\n }\n })\n .filter((s): s is NonNullable<typeof s> => s !== undefined)\n\n if (filteredScopes.length === 0) return undefined\n\n return {\n ...resourceMetrics,\n scopeMetrics: filteredScopes,\n }\n }\n\n export(\n metrics: ResourceMetrics,\n resultCallback: (result: ExportResult) => void\n ): void {\n const filtered = this.filterMetrics(metrics)\n if (filtered) {\n console.log(formatMetrics(filtered))\n }\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n}\n\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n const regex = `^${escaped.replace(/\\*/g, '.*')}$`\n return new RegExp(regex)\n}\n","import { SeverityNumber } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n LogRecordExporter,\n ReadableLogRecord,\n} from '@opentelemetry/sdk-logs'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from '../consts'\nimport { formatLogRecord } from './formatters/index'\n\nexport class ConsoleLogPrettyExporter implements LogRecordExporter {\n private readonly logThreshold: number\n constructor() {\n const defaultLogLevel = 'INFO'\n const env = (process.env.LOG_LEVEL?.toUpperCase() ??\n defaultLogLevel) as LOG_SEVERITY_NAME\n this.logThreshold =\n LOG_SEVERITY_MAP[env] ?? LOG_SEVERITY_MAP[defaultLogLevel]\n }\n export(\n logs: ReadableLogRecord[],\n resultCallback: (result: ExportResult) => void\n ): void {\n this._sendLogRecords(logs, resultCallback)\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n\n private _sendLogRecords(\n logRecords: ReadableLogRecord[],\n done: (result: ExportResult) => void\n ): void {\n for (const record of logRecords) {\n if ((record.severityNumber ?? 0) >= this.logThreshold) {\n const formatted = formatLogRecord(record)\n /* istanbul ignore next */\n const severity = record.severityNumber || SeverityNumber.UNSPECIFIED\n\n if (severity >= SeverityNumber.ERROR) {\n console.error(formatted)\n } else if (severity >= SeverityNumber.WARN) {\n console.log(formatted)\n } else if (severity >= SeverityNumber.INFO) {\n console.info(formatted)\n } else if (severity >= SeverityNumber.DEBUG) {\n console.debug(formatted)\n } else {\n console.trace(formatted)\n }\n }\n }\n\n done?.({ code: ExportResultCode.SUCCESS })\n }\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace'\nimport { formatSpans } from './formatters/index'\n\nexport class ConsoleSpanPrettyExporter implements SpanExporter {\n private readonly allowedStatuses: Set<number>\n\n constructor() {\n const env = process.env.SPAN_LEVEL?.toUpperCase()\n if (!env) {\n this.allowedStatuses = new Set([\n SpanStatusCode.UNSET,\n SpanStatusCode.OK,\n SpanStatusCode.ERROR,\n ])\n } else {\n const map: Record<string, number> = {\n UNSET: SpanStatusCode.UNSET,\n OK: SpanStatusCode.OK,\n ERROR: SpanStatusCode.ERROR,\n }\n\n this.allowedStatuses = new Set(\n env\n .split(',')\n .map((s) => s.trim())\n .map((s) => map[s])\n .filter((v): v is number => typeof v === 'number')\n )\n }\n }\n\n private shouldExport(spans: ReadableSpan[]) {\n // print all spans\n if (this.allowedStatuses.size === 3) {\n return true\n }\n // print only certain levels\n return spans.some((span) => this.allowedStatuses.has(span.status.code))\n }\n\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void {\n if (this.shouldExport(spans)) {\n console.log(formatSpans(spans))\n }\n\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n}\n","/* istanbul ignore file */\nexport * from './console-log-pretty-exporter'\nexport * from './console-span-pretty-exporter'\nexport * from './gcp-json-log-exporter'\n","import type {\n ReadableSpan,\n SpanExporter,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace'\n\nexport class TreeSpanProcessor implements SpanProcessor {\n private exporter: SpanExporter\n private orphans: Map<string, ReadableSpan[]> = new Map()\n\n constructor(exporter: SpanExporter) {\n this.exporter = exporter\n }\n\n onStart(): void {\n // no-op\n }\n\n onEnd(span: ReadableSpan): void {\n const parentId = span.parentSpanContext?.spanId\n\n if (parentId) {\n const siblings = this.orphans.get(parentId) || []\n this.orphans.set(parentId, [...siblings, span])\n\n return\n }\n\n const children = this.getChildrenRecursively(span)\n const sorted = [span, ...children].sort((s1, s2) => {\n const [sec1, nano1] = s1.startTime\n const [sec2, nano2] = s2.startTime\n\n if (sec1 !== sec2) return sec1 - sec2\n return nano1 - nano2\n })\n this.exporter.export(sorted, () => {})\n }\n\n private getChildrenRecursively(span: ReadableSpan) {\n const spanId = span.spanContext().spanId\n const children = this.orphans.get(spanId) || []\n this.orphans.delete(spanId)\n\n const result = [...children]\n for (const child of children) {\n result.push(...this.getChildrenRecursively(child))\n }\n\n return result\n }\n\n shutdown(): Promise<void> {\n return this.exporter.shutdown()\n }\n\n async forceFlush(): Promise<void> {\n await this.exporter.forceFlush?.()\n }\n}\n","import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport type { Resource } from '@opentelemetry/resources'\nimport {\n BatchLogRecordProcessor,\n LoggerProvider,\n type LogRecordProcessor,\n SimpleLogRecordProcessor,\n} from '@opentelemetry/sdk-logs'\nimport { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport {\n BatchSpanProcessor,\n SimpleSpanProcessor,\n type SpanProcessor,\n} from '@opentelemetry/sdk-trace'\nimport { ConsoleMetricPrettyExporter } from './loggers/console-metric-pretty-exporter'\nimport {\n ConsoleLogPrettyExporter,\n ConsoleSpanPrettyExporter,\n} from './loggers/index'\nimport { TreeSpanProcessor } from './loggers/tree-span-processor'\n\nexport const getLogProvider = (\n resource: Resource,\n otlpEndpoint: string | undefined\n) => {\n // With collector\n if (otlpEndpoint) {\n const otlpExporter = new OTLPLogExporter({ url: `${otlpEndpoint}/v1/logs` })\n const processors: LogRecordProcessor[] = [\n new BatchLogRecordProcessor({ exporter: otlpExporter }),\n ]\n\n // Console logging for cluster\n if (process.env.LOG_LEVEL) {\n const consoleExporter = new ConsoleLogPrettyExporter()\n processors.push(\n new SimpleLogRecordProcessor({ exporter: consoleExporter })\n )\n }\n\n return new LoggerProvider({\n resource,\n processors,\n })\n }\n\n // Local dev\n const consoleExporter = new ConsoleLogPrettyExporter()\n const processor = new SimpleLogRecordProcessor({ exporter: consoleExporter })\n return new LoggerProvider({\n resource,\n processors: [processor],\n })\n}\n\nexport const getSpanProcessor = (\n otlpEndpoint: string | undefined\n): SpanProcessor => {\n const exporter = otlpEndpoint\n ? new OTLPTraceExporter({\n url: `${otlpEndpoint}/v1/traces`,\n })\n : new ConsoleSpanPrettyExporter()\n\n if (!otlpEndpoint) {\n return new TreeSpanProcessor(exporter)\n }\n\n if (process.env.OTEL_SIMPLE_SPAN_PROCESSOR === 'true') {\n console.log(\n '[otel] Using SimpleSpanProcessor (OTEL_SIMPLE_SPAN_PROCESSOR=true)'\n )\n return new SimpleSpanProcessor({ exporter })\n }\n\n return new BatchSpanProcessor({ exporter })\n}\n\nexport const getMetricReader = (otlpEndpoint: string | undefined) => {\n const metricExporter = otlpEndpoint\n ? new OTLPMetricExporter({\n url: `${otlpEndpoint}/v1/metrics`,\n })\n : new ConsoleMetricPrettyExporter()\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricExporter,\n })\n\n return metricReader\n}\n","import {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\n\n/**\n * Extracts telemetry context from environment (cloud/k8s aware),\n * with support for subservice/component override.\n */\nexport function detectTelemetryContext(componentNameOverride?: string) {\n const {\n OTEL_SERVICE_NAME, // e.g. \"UserSystem\"\n OTEL_SERVICE_VERSION, // e.g. \"1.2.3\"\n K_SERVICE,\n K_REVISION,\n K_CONFIGURATION,\n KUBERNETES_SERVICE_HOST,\n POD_NAME,\n POD_NAMESPACE,\n GCP_PROJECT,\n CLOUD_PROVIDER,\n } = process.env\n\n const systemName = OTEL_SERVICE_NAME || 'unknown-service'\n const systemVersion = OTEL_SERVICE_VERSION || '1.0.0'\n\n // Only use component if explicitly provided\n const componentName = componentNameOverride || undefined\n\n const resourceAttributes = {\n [ATTR_SERVICE_NAME]: systemName,\n [ATTR_SERVICE_VERSION]: systemVersion,\n 'serviceContext.service': systemName,\n 'serviceContext.version': systemVersion,\n ...(K_SERVICE && { 'cloud.run.service': K_SERVICE }),\n ...(K_REVISION && { 'cloud.run.revision': K_REVISION }),\n ...(K_CONFIGURATION && { 'cloud.run.configuration': K_CONFIGURATION }),\n ...(POD_NAME && { 'k8s.pod_name': POD_NAME }),\n ...(POD_NAMESPACE && { 'k8s.namespace_name': POD_NAMESPACE }),\n ...(KUBERNETES_SERVICE_HOST && { 'cloud.orchestrator': 'kubernetes' }),\n ...(GCP_PROJECT && { 'cloud.account.id': GCP_PROJECT }),\n ...(CLOUD_PROVIDER && { 'cloud.provider': CLOUD_PROVIDER }),\n ...(componentName && { 'component.name': componentName }),\n }\n\n return {\n systemName,\n systemVersion,\n componentName,\n resourceAttributes,\n }\n}\n","import { containerDetector } from '@opentelemetry/resource-detector-container'\nimport { gcpDetector } from '@opentelemetry/resource-detector-gcp'\nimport {\n detectResources,\n envDetector,\n osDetector,\n processDetector,\n resourceFromAttributes,\n serviceInstanceIdDetector,\n} from '@opentelemetry/resources'\nimport { detectTelemetryContext } from './otel-context'\n\nconst isOnGcp = () =>\n !!(\n process.env.K_SERVICE ||\n process.env.GAE_APPLICATION ||\n process.env.KUBERNETES_SERVICE_HOST\n )\n\nexport const getResource = async () => {\n const baseRes = detectResources({\n detectors: [\n containerDetector,\n envDetector,\n ...(isOnGcp() ? [gcpDetector] : []),\n osDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n })\n\n if (baseRes.waitForAsyncAttributes) {\n await baseRes.waitForAsyncAttributes()\n }\n\n const { resourceAttributes } = detectTelemetryContext()\n const customRes = resourceFromAttributes(resourceAttributes)\n const resource = baseRes.merge(customRes)\n\n if (resource.waitForAsyncAttributes) {\n await resource.waitForAsyncAttributes()\n }\n\n return resource\n}\n","import {\n context,\n DiagConsoleLogger,\n DiagLogLevel,\n diag,\n logs,\n metrics,\n trace,\n} from '@opentelemetry/api'\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs'\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getLogProvider, getMetricReader, getSpanProcessor } from './providers'\nimport { getResource } from './resource'\n\ndiag.disable()\ndiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR)\n\n// Use globalThis with a Symbol key so the flag is shared even when the module\n// is instantiated more than once (e.g. --import preload vs main app graph when\n// using tsx or other loaders that don't share the ESM module cache).\nconst OTEL_INIT_KEY = Symbol.for('@sebspark/otel:initialized')\nconst OTEL_INIT_PROMISE_KEY = Symbol.for('@sebspark/otel:initPromise')\n\nfunction getGlobal(): {\n [key: symbol]: unknown\n} {\n return globalThis as Record<symbol, unknown>\n}\n\nexport async function initialize(\n ...instrumentations: Promise<Instrumentation>[]\n) {\n const g = getGlobal()\n if (!g[OTEL_INIT_PROMISE_KEY]) {\n const resolvedInstrumentations = await Promise.all(instrumentations)\n const promise = _initialize(resolvedInstrumentations).catch((err) => {\n // Allow re-initialization if the first attempt fails\n g[OTEL_INIT_PROMISE_KEY] = undefined\n throw err\n })\n g[OTEL_INIT_PROMISE_KEY] = promise\n }\n return g[OTEL_INIT_PROMISE_KEY] as Promise<void>\n}\n\nexport function isInitialized() {\n return getGlobal()[OTEL_INIT_KEY] === true\n}\n\nlet sdk: NodeSDK | undefined\nlet logProvider: LoggerProvider | undefined\n\nasync function _initialize(instrumentations: Instrumentation[]) {\n const serviceName = process.env.OTEL_SERVICE_NAME ?? 'unknown-service'\n const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT\n\n const resource = await getResource()\n\n // Reset any previous instrumentation\n context.disable()\n logs.disable()\n trace.disable()\n metrics.disable()\n\n // Manual setup for logs\n logProvider = getLogProvider(resource, otlpEndpoint)\n logs.setGlobalLoggerProvider(logProvider)\n\n // NodeSDK setup\n const spanProcessor = getSpanProcessor(otlpEndpoint)\n const metricReader = getMetricReader(otlpEndpoint)\n sdk = new NodeSDK({\n spanProcessors: [spanProcessor],\n metricReaders: [metricReader],\n instrumentations,\n resource,\n })\n\n sdk.start()\n getGlobal()[OTEL_INIT_KEY] = true\n console.log(`[otel] Telemetry initialized for \"${serviceName}\"`)\n}\n\nexport const dispose = async () => {\n const processes: Promise<void>[] = []\n if (sdk) processes.push(sdk.shutdown())\n if (logProvider) processes.push(logProvider.shutdown())\n\n // Only initiate shotdown once\n sdk = undefined\n logProvider = undefined\n\n if (processes.length) {\n console.log('[otel] Shutting down...')\n await Promise.all(processes)\n console.log('[otel] Shutdown complete.')\n }\n}\n","import { context, logs, trace } from '@opentelemetry/api'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from './consts'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\n// biome-ignore lint/suspicious/noExplicitAny: library\ntype Attrs = Record<string, any>\n\nexport type Logger = ReturnType<typeof getLogger>\nexport function getLogger(serviceOverride?: string, extraAttrs: Attrs = {}) {\n const { systemName, systemVersion, resourceAttributes } =\n detectTelemetryContext(serviceOverride)\n\n const defaultAttrs = {\n ...resourceAttributes,\n ...extraAttrs,\n }\n\n let hasWarnedAboutInit = false\n\n function emit(\n severityText: LOG_SEVERITY_NAME,\n body: string,\n attrs: Attrs = {}\n ) {\n // Get the logger at the last second\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n if (!hasWarnedAboutInit) {\n console.warn('OTEL must be initialized before using logger')\n hasWarnedAboutInit = true\n }\n console.log(`[${severityText}] ${body}`)\n return\n }\n const logger = logs.getLogger(systemName, systemVersion)\n\n const span = trace.getSpan(context.active())\n const spanContext = span?.spanContext()\n\n logger.emit({\n severityText,\n severityNumber: LOG_SEVERITY_MAP[severityText],\n body,\n attributes: {\n 'gcp.log_name': systemName.replace(/^@/, '').replace(/\\//g, '-'),\n ...defaultAttrs,\n ...(spanContext && {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n }),\n ...attrs,\n },\n })\n }\n\n function resolveArgs(\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ): { body: string; attrs: Attrs } {\n if (errOrAttrs instanceof Error) {\n /* istanbul ignore next */\n const body = `${msg}: ${errOrAttrs.stack || errOrAttrs.message}`\n return { body, attrs: maybeAttrs }\n }\n\n /* istanbul ignore next */\n const body = msg instanceof Error ? msg.stack || msg.message : msg\n /* istanbul ignore next */\n const attrs = errOrAttrs || {}\n return { body, attrs }\n }\n\n type LogFn = {\n (msg: string, attrs?: Attrs): void\n (msg: string, error: Error, attrs?: Attrs): void\n (error: Error, attrs?: Attrs): void\n }\n\n function createLogFn(severity: LOG_SEVERITY_NAME): LogFn {\n return (\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ) => {\n const { body, attrs } = resolveArgs(msg, errOrAttrs, maybeAttrs)\n emit(severity, body, attrs)\n }\n }\n\n return {\n debug: createLogFn('DEBUG'),\n info: createLogFn('INFO'),\n notice: createLogFn('NOTICE'),\n warn: createLogFn('WARN'),\n error: createLogFn('ERROR'),\n critical: createLogFn('CRITICAL'),\n alert: createLogFn('ALERT'),\n emergency: createLogFn('EMERGENCY'),\n }\n}\n","import { metrics } from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\nexport function getMeter(componentNameOverride?: string) {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before using getMeter()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n return metrics.getMeter(componentName ?? systemName, systemVersion)\n}\n","import {\n context,\n type SpanOptions,\n SpanStatusCode,\n trace,\n} from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\ntype OtelTracer = ReturnType<typeof trace.getTracer>\ntype Span = ReturnType<OtelTracer['startSpan']>\n\ntype Func<T> = (span: Span) => Promise<T> | T\ntype SyncFunc<T> = (span: Span) => T\n\ntype WithTrace = {\n <T>(name: string, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, fn: Func<T>): Promise<T>\n <T>(name: string, parent: Span, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, parent: Span, fn: Func<T>): Promise<T>\n}\ntype WithTraceSync = {\n <T>(name: string, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, fn: SyncFunc<T>): T\n <T>(name: string, parent: Span, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, parent: Span, fn: SyncFunc<T>): T\n}\n\n/**\n * Extended tracer with helper methods for span-wrapped execution\n */\ninterface Tracer extends OtelTracer {\n withTrace: WithTrace\n withTraceSync: WithTraceSync\n}\n\n/**\n * Returns an OpenTelemetry tracer bound to the current service.\n * Includes `withTrace()` and `withTraceSync()` helpers for span-wrapped execution.\n *\n * @param serviceOverride - Optional override for service name\n * @returns Tracer with helpers\n */\nexport function getTracer(componentNameOverride?: string): Tracer {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before calling getTracer()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n const tracer = trace.getTracer(\n componentName ?? systemName,\n systemVersion\n ) as Tracer\n\n /**\n * Runs a function inside a new span (async variant).\n * Automatically handles span status and nesting.\n */\n const withTrace: WithTrace = async <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | Func<T>,\n spanOrFunc?: Span | Func<T>,\n func?: Func<T>\n ): Promise<T> => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return await context.with(trace.setSpan(parentContext, span), async () => {\n try {\n const result = await fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n const error = err as Error\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.recordException?.(error)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n /**\n * Runs a synchronous function inside a new span.\n * Automatically handles span status and nesting.\n */\n const withTraceSync: WithTraceSync = <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | SyncFunc<T>,\n spanOrFunc?: Span | SyncFunc<T>,\n func?: SyncFunc<T>\n ): T => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return context.with(trace.setSpan(parentContext, span), () => {\n try {\n const result = fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n const error = err as Error\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.recordException?.(error)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n tracer.withTrace = withTrace\n tracer.withTraceSync = withTraceSync\n\n return tracer\n}\n\ntype TraceArgs<T> = {\n options: SpanOptions\n parent?: Span\n fn: (span: Span) => T\n}\n\nfunction extractArgs<T>(\n spanOptionsSpanOrFunc?: SpanOptions | Span | ((span: Span) => T),\n spanOrFunc?: Span | ((span: Span) => T),\n func?: (span: Span) => T\n): TraceArgs<T> {\n let options: SpanOptions = {}\n let parent: Span | undefined\n let fn: (span: Span) => T\n\n if (isFunction(spanOptionsSpanOrFunc)) {\n fn = spanOptionsSpanOrFunc\n } else if (isFunction(spanOrFunc)) {\n const spanOrSpanOptions = spanOptionsSpanOrFunc as Span | SpanOptions\n if (isSpanOptions(spanOrSpanOptions)) {\n options = spanOrSpanOptions as SpanOptions\n } else {\n parent = spanOrSpanOptions as Span\n }\n fn = spanOrFunc\n } else {\n options = spanOptionsSpanOrFunc as SpanOptions\n parent = spanOrFunc as Span\n // biome-ignore lint/style/noNonNullAssertion: it IS defined here\n fn = func!\n }\n\n return { options, parent, fn }\n}\n\nconst isFunction = (value: unknown): value is (span: Span) => unknown =>\n typeof value === 'function'\nconst isSpan = (value: unknown): value is Span =>\n value !== null &&\n value !== undefined &&\n isFunction((value as Span).spanContext) &&\n isFunction((value as Span).end)\n/* istanbul ignore next */\nconst isSpanOptions = (value: unknown): value is SpanOptions =>\n value !== null &&\n value !== undefined &&\n (!!(value as SpanOptions).startTime ||\n !!(value as SpanOptions).attributes ||\n !!(value as SpanOptions).kind) &&\n !isSpan(value)\n","/* istanbul ignore file */\nexport {\n type Context,\n type Counter,\n context,\n type Gauge,\n type Histogram,\n type Meter,\n type ObservableCounter,\n type ObservableGauge,\n type ObservableUpDownCounter,\n type Span,\n type SpanStatus,\n SpanStatusCode,\n type UpDownCounter,\n} from '@opentelemetry/api'\nexport * from './instrumentations'\nexport * from './logger'\nexport * from './metrics'\nexport * from './otel'\nexport * from './tracer'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["SpanStatusCode","SpanStatusCode","SpanStatusCode","context","context","SpanStatusCode"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/apply-attributes.ts","../src/enrichments/outgoing-http/helpers.ts","../src/enrichments/outgoing-http/normalize-http.ts","../src/enrichments/outgoing-http/build-http-config.ts","../src/enrichments/outgoing-http/normalize-undici.ts","../src/enrichments/outgoing-http/build-undici-config.ts","../src/enrichments/outgoing-http/index.ts","../src/instrumentations.ts","../src/consts.ts","../src/loggers/formatters/style.ts","../src/loggers/formatters/shared.ts","../src/loggers/formatters/log-record.ts","../src/loggers/formatters/metrics.ts","../src/loggers/formatters/span.ts","../src/loggers/formatters/index.ts","../src/loggers/console-metric-pretty-exporter.ts","../src/loggers/console-log-pretty-exporter.ts","../src/loggers/console-span-pretty-exporter.ts","../src/loggers/index.ts","../src/loggers/tree-span-processor.ts","../src/providers.ts","../src/otel-context.ts","../src/resource.ts","../src/otel.ts","../src/logger.ts","../src/metrics.ts","../src/tracer.ts","../src/index.ts"],"sourcesContent":["// Incubating attrs — copied as string literals per OTel JS team recommendation:\n// importing from /incubating at runtime is explicitly discouraged because that\n// entry-point is NOT subject to semver and may break in minor releases.\n// https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-semantic-conventions#unstable-semconv\nexport const ATTR_HTTP_REQUEST_BODY_SIZE = 'http.request.body.size'\nexport const ATTR_HTTP_RESPONSE_BODY_SIZE = 'http.response.body.size'\n\nexport const DEFAULT_REQUEST_HEADERS: string[] = [\n 'content-type',\n 'accept',\n 'x-request-id',\n 'x-correlation-id',\n 'traceparent',\n 'tracestate',\n] as const\n\nexport const DEFAULT_RESPONSE_HEADERS: string[] = [\n 'content-type',\n 'x-request-id',\n 'x-correlation-id',\n 'x-ratelimit-limit',\n 'x-ratelimit-remaining',\n 'x-ratelimit-reset',\n 'retry-after',\n] as const\n\nexport const PROTOCOLS = ['https', 'http'] as const\n","import { type Span, SpanStatusCode } from '@opentelemetry/api'\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_QUERY,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n ATTR_HTTP_REQUEST_BODY_SIZE,\n ATTR_HTTP_RESPONSE_BODY_SIZE,\n} from './consts'\nimport type {\n NormalisedRequest,\n NormalisedResponse,\n ResolvedConfig,\n} from './types'\n\nconst requestHeaderAttr = (h: string) =>\n `http.request.header.${h.toLowerCase().replace(/-/g, '_')}`\nconst responseHeaderAttr = (h: string) =>\n `http.response.header.${h.toLowerCase().replace(/-/g, '_')}`\n\nexport const applyRequestAttributes = (\n span: Span,\n req: NormalisedRequest,\n cfg: ResolvedConfig\n): void => {\n const { method, hostname, port, path, protocol } = req\n const [urlPath, urlQuery] = path.split('?')\n /* istanbul ignore next */\n const defaultPort = protocol === 'https' ? 443 : 80\n /* istanbul ignore next */\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n // Stable semconv v1.23+ attributes\n span.setAttributes({\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n })\n\n if (urlQuery) {\n span.setAttribute(ATTR_URL_QUERY, urlQuery)\n }\n\n if (cfg.useDescriptiveSpanNames) {\n span.updateName(`${method.toUpperCase()} ${hostname}${resolvedUrlPath}`)\n }\n\n for (const header of cfg.captureRequestHeaders) {\n const value = req.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(requestHeaderAttr(header), value)\n }\n }\n\n const contentLength = req.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_REQUEST_BODY_SIZE, Number(contentLength))\n }\n\n cfg.enrichSpan(span, req)\n}\n\nexport const applyResponseAttributes = (\n span: Span,\n res: NormalisedResponse,\n cfg: ResolvedConfig\n): void => {\n const { statusCode } = res\n\n span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, statusCode)\n\n // OTel spec for CLIENT spans: 5xx = SDK error; 4xx is not (it's the\n // server's fault). We still record error.type for both so they're filterable.\n if (statusCode >= 500) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n })\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n } else if (statusCode >= 400) {\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n }\n\n for (const header of cfg.captureResponseHeaders) {\n const value = res.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(responseHeaderAttr(header), value)\n }\n }\n\n const contentLength = res.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_RESPONSE_BODY_SIZE, Number(contentLength))\n }\n\n // Resolved wire address (post-proxy) — separate from the original hostname\n // so you can see both in the span and spot mesh rewrites.\n if (res.remoteAddress) {\n span.setAttribute(ATTR_NETWORK_PEER_ADDRESS, res.remoteAddress)\n }\n if (res.remotePort) {\n span.setAttribute(ATTR_NETWORK_PEER_PORT, res.remotePort)\n }\n}\n","import type { ClientRequest, IncomingMessage } from 'node:http'\nimport { DEFAULT_REQUEST_HEADERS, DEFAULT_RESPONSE_HEADERS } from './consts'\nimport type { OutgoingHttpEnrichmentConfig, ResolvedConfig } from './types'\n\nexport const resolve = (\n opts: OutgoingHttpEnrichmentConfig\n): ResolvedConfig => ({\n captureRequestHeaders: opts.captureRequestHeaders ?? DEFAULT_REQUEST_HEADERS,\n captureResponseHeaders:\n opts.captureResponseHeaders ?? DEFAULT_RESPONSE_HEADERS,\n enrichSpan: opts.enrichSpan ?? (() => {}),\n useDescriptiveSpanNames: opts.useDescriptiveSpanNames ?? true,\n ignoreOutgoingPaths: opts.ignoreOutgoingPaths ?? [],\n})\n\nexport const isClientRequest = (\n req: ClientRequest | IncomingMessage\n): req is ClientRequest =>\n 'getHeader' in req && typeof req.getHeader === 'function'\n\nexport const isIncomingMessage = (res: unknown): res is IncomingMessage =>\n res != null &&\n typeof res === 'object' &&\n 'statusCode' in res &&\n 'headers' in res\n","import type { ClientRequest, IncomingMessage, RequestOptions } from 'node:http'\nimport type { NormalisedRequest, NormalisedResponse, Protocol } from './types'\n\nconst isHeaderList = (headers: unknown): headers is readonly string[] =>\n Array.isArray(headers)\n\nexport const normHttpRequest = (req: RequestOptions): NormalisedRequest => {\n const hostname = String(req.hostname ?? req.host ?? '').split(':')[0]\n const port = Number(req.port ?? req.defaultPort ?? 80)\n const path = String(req.path ?? '/')\n const protocol: Protocol = port === 443 ? 'https' : 'http'\n\n return {\n method: req.method ?? 'GET',\n hostname,\n port,\n path,\n protocol,\n getHeader(name) {\n const headers = req.headers\n if (!headers || isHeaderList(headers)) return undefined\n return getHeaderFromObject(headers, name)\n },\n }\n}\n\n/**\n * Normalises an outgoing `ClientRequest`. Unlike `RequestOptions` it has no\n * `port` or `headers`, so the port comes from the `host` header and the\n * scheme from `protocol`.\n */\nexport const normClientRequest = (req: ClientRequest): NormalisedRequest => {\n const protocol: Protocol = req.protocol === 'https:' ? 'https' : 'http'\n const hostPort = String(req.getHeader('host') ?? '').split(':')[1]\n const port = hostPort ? Number(hostPort) : protocol === 'https' ? 443 : 80\n\n return {\n method: req.method,\n hostname: req.host,\n port,\n path: req.path,\n protocol,\n getHeader(name) {\n const value = req.getHeader(name)\n if (value === undefined) return undefined\n return Array.isArray(value) ? value : [String(value)]\n },\n }\n}\n\nexport const normHttpResponse = (res: IncomingMessage): NormalisedResponse => {\n const socket = res.socket\n return {\n statusCode: res.statusCode ?? 0,\n statusMessage: res.statusMessage ?? '',\n getHeader(name) {\n return getHeaderFromObject(res.headers, name)\n },\n remoteAddress: socket?.remoteAddress,\n remotePort: socket?.remotePort,\n }\n}\n\nexport const getHeaderFromObject = (\n headers: Record<string, unknown> | undefined,\n name: string\n): string[] | undefined => {\n if (!headers) return undefined\n\n const target = name.toLowerCase()\n\n // Iterate over all keys to find case-insensitive match\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === target) {\n const value = headers[key]\n if (Array.isArray(value)) return value\n /* istanbul ignore next */\n if (typeof value === 'string') return [value]\n /* istanbul ignore next */\n return undefined\n }\n }\n\n return undefined\n}\n","import type { Attributes } from '@opentelemetry/api'\nimport type { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'\nimport {\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { isClientRequest, isIncomingMessage, resolve } from './helpers'\nimport {\n normClientRequest,\n normHttpRequest,\n normHttpResponse,\n} from './normalize-http'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an HttpInstrumentationConfig that applies shared enrichment logic.\n *\n * The returned config can be spread with your own additional options:\n * new HttpInstrumentation({ ...buildHttpConfig(opts), requireParentforOutgoingSpans: true })\n */\nexport const buildHttpConfig = (\n opts: OutgoingHttpEnrichmentConfig = {}\n): HttpInstrumentationConfig => {\n const cfg = resolve(opts)\n\n const config: HttpInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreOutgoingRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // startOutgoingSpanHook fires at span creation time — before any proxy or\n // service-mesh sidecar can rewrite the destination socket. The returned\n // attributes are the \"ground truth\" hostname we captured off the wire.\n startOutgoingSpanHook(req) {\n const { method, hostname, port, path, protocol } = normHttpRequest(req)\n const [urlPath] = path.split('?')\n const defaultPort = protocol === 'https' ? 443 : 80\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n const attrs: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n [ATTR_NETWORK_PEER_ADDRESS]: hostname,\n [ATTR_NETWORK_PEER_PORT]: port,\n }\n /* istanbul ignore next */\n for (const [key, val] of Object.entries(req.headers || {})) {\n if (!val) continue\n\n const name = key.toLowerCase().replace(/-/g, '_')\n const value = Array.isArray(val) ? val.join(',') : val\n attrs[`http.request.header.${name}`] = value\n }\n return attrs\n },\n\n requestHook(span, request) {\n // requestHook fires for both incoming (IncomingMessage) and outgoing\n // (ClientRequest) spans — skip the incoming side.\n if (!isClientRequest(request)) return\n\n // HTTP version isn't always accessible here, but try to read it.\n const proto = request.protocol\n if (proto) {\n span.setAttribute(\n ATTR_NETWORK_PROTOCOL_VERSION,\n /* istanbul ignore next */\n proto === 'https:' ? '1.1' : '1.1'\n )\n }\n\n applyRequestAttributes(span, normClientRequest(request), cfg)\n },\n\n responseHook(span, response) {\n if (!isIncomingMessage(response)) return\n applyResponseAttributes(span, normHttpResponse(response), cfg)\n },\n }\n\n return config\n}\n","import type {\n UndiciRequest,\n UndiciResponse,\n} from '@opentelemetry/instrumentation-undici'\nimport type { NormalisedRequest, NormalisedResponse, Protocol } from './types'\n\nexport const normUndiciRequest = (req: UndiciRequest): NormalisedRequest => {\n const origin = new URL(req.origin)\n const protocol: Protocol = origin.protocol === 'https:' ? 'https' : 'http'\n const port = Number(origin.port) || (protocol === 'https' ? 443 : 80)\n\n // Parse \"Key: Value\\r\\nKey2: Value2\\r\\n\" → Map\n const headers = parseUndiciRequestHeaders(req.headers)\n\n return {\n method: req.method,\n hostname: origin.hostname,\n port,\n path: req.path,\n protocol,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const normUndiciResponse = (res: UndiciResponse): NormalisedResponse => {\n const headers = parseUndiciResponseHeaders(res.headers)\n\n return {\n statusCode: res.statusCode,\n statusMessage: res.statusText,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const parseUndiciResponseHeaders = (\n headers: Buffer<ArrayBufferLike>[]\n): Record<string, string[]> => {\n const result: Record<string, string[]> = {}\n\n for (let i = 0; i < headers.length; i += 2) {\n const keyBuf = headers[i]\n const valBuf = headers[i + 1]\n\n if (!keyBuf || !valBuf) continue\n\n // Buffer.from also decodes plain Uint8Arrays correctly\n const key = Buffer.from(keyBuf).toString('utf8').trim().toLowerCase()\n const val = Buffer.from(valBuf).toString('utf8').trim()\n\n if (!key || !val) continue\n\n if (!result[key]) result[key] = []\n result[key].push(val)\n }\n\n return result\n}\n\nexport const parseUndiciRequestHeaders = (\n headers: string | (string | string[])[]\n) => {\n const result: Record<string, string[]> = {}\n\n if (typeof headers === 'string') {\n // Single string format: \"key: value\"\n const [key, ...rest] = headers.split(':')\n if (key && rest.length > 0) {\n result[key.trim().toLowerCase()] = [rest.join(':').trim()]\n }\n } else {\n // The type union guarantees headers is string | array[]; the else-if is always true\n /* istanbul ignore else */\n if (Array.isArray(headers)) {\n // Array format: [key, value] or [key, [value1, value2]]\n for (let i = 0; i < headers.length; i += 2) {\n const key = headers[i]\n const val = headers[i + 1]\n if (typeof key !== 'string' || val == null) continue\n\n if (Array.isArray(val)) {\n result[key.toLowerCase()] = val.map((v) => String(v))\n } else {\n result[key.toLowerCase()] = [String(val)]\n }\n }\n }\n }\n\n return result\n}\n","import type { UndiciInstrumentationConfig } from '@opentelemetry/instrumentation-undici'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { resolve } from './helpers'\nimport { normUndiciRequest, normUndiciResponse } from './normalize-undici'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an UndiciInstrumentationConfig that applies shared enrichment logic.\n *\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\nexport function buildUndiciConfig(\n opts: OutgoingHttpEnrichmentConfig = {}\n): UndiciInstrumentationConfig {\n const cfg = resolve(opts)\n\n const config: UndiciInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // undici collapses startSpanHook + requestHook into a single requestHook\n // because diagnostics_channel gives us everything at once.\n requestHook(span, request) {\n applyRequestAttributes(span, normUndiciRequest(request), cfg)\n },\n\n responseHook(span, { response }) {\n applyResponseAttributes(span, normUndiciResponse(response), cfg)\n },\n }\n\n return config\n}\n","/* istanbul ignore file */\n/**\n * Shared enrichment logic for outgoing HTTP spans, normalised across\n * @opentelemetry/instrumentation-http (node:http / node:https)\n * @opentelemetry/instrumentation-undici (undici / global fetch)\n *\n * Usage:\n *\n * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n * import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'\n * import { buildHttpConfig, buildUndiciConfig } from './instrumentation/outgoing-http'\n * import type { OutgoingHttpEnrichmentConfig } from './instrumentation/outgoing-http'\n *\n * const opts: OutgoingHttpEnrichmentConfig = {\n * captureRequestHeaders: ['x-tenant-id', 'x-request-id'],\n * captureResponseHeaders: ['x-ratelimit-remaining'],\n * enrichSpan: (span, req) =>\n * span.setAttribute('app.tenant.id', req.getHeader('x-tenant-id') ?? ''),\n * ignoreOutgoingPaths: ['/health', '/ready'],\n * }\n *\n * new HttpInstrumentation(buildHttpConfig(opts))\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\n\nexport { buildHttpConfig } from './build-http-config'\nexport { buildUndiciConfig } from './build-undici-config'\nexport type { OutgoingHttpEnrichmentConfig } from './types'\n","import type {\n Instrumentation,\n InstrumentationConfig,\n} from '@opentelemetry/instrumentation'\nimport type { DnsInstrumentationConfig } from '@opentelemetry/instrumentation-dns'\nimport type { ExpressInstrumentationConfig } from '@opentelemetry/instrumentation-express'\nimport type { FsInstrumentationConfig } from '@opentelemetry/instrumentation-fs'\nimport type { GrpcInstrumentationConfig } from '@opentelemetry/instrumentation-grpc'\nimport type { RedisInstrumentationConfig } from '@opentelemetry/instrumentation-redis'\nimport type { SocketIoInstrumentationConfig } from '@opentelemetry/instrumentation-socket.io'\nimport type { OpenSearchInstrumentationConfig } from '@sebspark/opentelemetry-instrumentation-opensearch'\nimport {\n buildHttpConfig,\n buildUndiciConfig,\n type OutgoingHttpEnrichmentConfig,\n} from './enrichments/outgoing-http'\n\nconst cache = new Map<string, Promise<Instrumentation>>()\nconst cacheKey = (\n instrumentationName: string,\n config?: InstrumentationConfig\n) => {\n return config\n ? `${instrumentationName}:${JSON.stringify(config)}`\n : instrumentationName\n}\n\nexport const instrumentations = {\n http(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('http', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-http').then(\n ({ HttpInstrumentation }) =>\n new HttpInstrumentation(buildHttpConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n express(config?: ExpressInstrumentationConfig) {\n const key = cacheKey('express', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-express').then(\n ({ ExpressInstrumentation }) => new ExpressInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n grpc(config?: GrpcInstrumentationConfig) {\n const key = cacheKey('grpc', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-grpc').then(\n ({ GrpcInstrumentation }) => new GrpcInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n redis(config?: RedisInstrumentationConfig) {\n const key = cacheKey('redis', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-redis').then(\n ({ RedisInstrumentation }) => new RedisInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n dns(config?: DnsInstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-dns').then(\n ({ DnsInstrumentation }) => new DnsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n net(config?: InstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-net').then(\n ({ NetInstrumentation }) => new NetInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n fs(config?: FsInstrumentationConfig) {\n const key = cacheKey('fs', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-fs').then(\n ({ FsInstrumentation }) => new FsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n undici(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('undici', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-undici').then(\n ({ UndiciInstrumentation }) =>\n new UndiciInstrumentation(buildUndiciConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n socketIo(config?: SocketIoInstrumentationConfig) {\n const key = cacheKey('socket-io', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-socket.io').then(\n ({ SocketIoInstrumentation }) => new SocketIoInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n opensearch(config?: OpenSearchInstrumentationConfig) {\n const key = cacheKey('opensearch', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@sebspark/opentelemetry-instrumentation-opensearch').then(\n ({ OpenSearchInstrumentation }) =>\n new OpenSearchInstrumentation({\n suppressInternalInstrumentation: true,\n ...(config || {}),\n })\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n} as const\n","export const LOG_SEVERITY_MAP = {\n TRACE: 1,\n DEBUG: 5,\n INFO: 9,\n NOTICE: 10,\n WARNING: 13,\n WARN: 13,\n ERROR: 17,\n FATAL: 21,\n CRITICAL: 21,\n ALERT: 22,\n EMERGENCY: 23,\n} as const\n\nexport type LOG_SEVERITY_NAME = keyof typeof LOG_SEVERITY_MAP\n\nconst isLogSeverityName = (level: string): level is LOG_SEVERITY_NAME =>\n Object.hasOwn(LOG_SEVERITY_MAP, level)\n\n/** Severity threshold from `LOG_LEVEL`, falling back to INFO. */\nexport const logThresholdFromEnv = (): number => {\n const level = process.env.LOG_LEVEL?.toUpperCase() ?? 'INFO'\n return LOG_SEVERITY_MAP[isLogSeverityName(level) ? level : 'INFO']\n}\n","import kleur from 'kleur'\n\nexport const colors = {\n gray: kleur.gray,\n dim: kleur.dim,\n cyan: kleur.cyan,\n white: kleur.white,\n green: kleur.green,\n yellow: kleur.yellow,\n red: kleur.red,\n magenta: kleur.magenta,\n}\n\nexport const levelColorMap: Record<string, (s: string) => string> = {\n DEBUG: kleur.magenta,\n INFO: kleur.green,\n WARN: kleur.yellow,\n ERROR: kleur.red,\n FATAL: kleur.red,\n}\n\nexport const levelIconMap: Record<string, string> = {\n DEBUG: '🐛',\n INFO: 'ℹ️ ',\n WARN: '⚠️ ',\n ERROR: '❌',\n FATAL: '💀',\n}\n\n// --- Span status codes (per OpenTelemetry spec) ---\nexport const statusLabelMap: Record<number, string> = {\n 0: 'UNSET',\n 1: 'OK',\n 2: 'ERROR',\n}\n\nexport const statusColorMap: Record<number, (s: string) => string> = {\n 0: colors.gray, // UNSET\n 1: colors.green, // OK\n 2: colors.red, // ERROR\n}\n\n// --- Span kinds (for visual context: client/server etc.) ---\nexport const kindLabelMap: Record<number, string> = {\n 0: 'INTERNAL',\n 1: 'SERVER',\n 2: 'CLIENT',\n 3: 'PRODUCER',\n 4: 'CONSUMER',\n}\n\nexport const kindColorMap: Record<number, (s: string) => string> = {\n 0: colors.white, // INTERNAL\n 1: colors.cyan, // SERVER\n 2: colors.yellow, // CLIENT\n 3: colors.magenta, // PRODUCER\n 4: colors.green, // CONSUMER\n}\n","import type { Attributes, HrTime } from '@opentelemetry/api'\nimport type { Resource } from '@opentelemetry/resources'\nimport type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace'\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\nimport fss from 'fast-safe-stringify'\nimport { colors, levelColorMap, levelIconMap } from './style'\n\nconst stringify = fss.stableStringify\n\ntype IResource = Pick<Resource, 'attributes'>\ntype IInstrumentation = ReadableLogRecord['instrumentationScope']\n\nexport function formatTimestamp(time: HrTime): string {\n const date = new Date(hrTimeToMillis(time))\n return colors.dim(date.toISOString().slice(11, 23)) // HH:mm:ss.sss\n}\n\nexport function formatService(resource: IResource): string {\n const name = resource.attributes[ATTR_SERVICE_NAME] ?? 'unknown-service'\n const version = resource.attributes[ATTR_SERVICE_VERSION] ?? '1.0.0'\n return colors.gray(`[${name}@${version}]`)\n}\n\nexport function formatLevel(record: ReadableLogRecord): string {\n const text = (record.severityText ?? 'INFO').toUpperCase()\n const colorFn = levelColorMap[text] ?? colors.white\n const icon = levelIconMap[text] ?? '•'\n return `${icon} ${colorFn(text.padEnd(5))}`\n}\n\nexport function formatScope(\n resource: IResource,\n instrumentationScope: IInstrumentation\n): string {\n const component = resource.attributes['component.name']\n const { name } = instrumentationScope\n const scopeLabel =\n component || (name && name !== 'unknown' ? name : undefined)\n\n if (!scopeLabel) return ''\n\n return colors.cyan(`${scopeLabel} `)\n}\n\nexport function formatMessage(record: ReadableLogRecord): string {\n return typeof record.body === 'string' ? record.body : stringify(record.body)\n}\n\nexport function formatAttributes(attrs: Attributes): string {\n const keys = Object.keys(attrs).filter(\n (k) =>\n !k.startsWith('service.') &&\n !k.startsWith('serviceContext.') &&\n k !== 'cloud.orchestrator' &&\n k !== 'component.name'\n )\n if (keys.length === 0) return ''\n const formatted = keys.map((k) => {\n const val = attrs[k]\n return `${k}=${typeof val === 'object' ? stringify(val) : val}`\n })\n return ` ${colors.gray(formatted.join(' '))}`\n}\n\nexport function hrTimeToMillis(hrTime: [number, number]): number {\n return hrTime[0] * 1000 + Math.floor(hrTime[1] / 1_000_000)\n}\n\nexport function calculateDuration(span: ReadableSpan): number {\n const start = hrTimeToMillis(span.startTime)\n const end = hrTimeToMillis(span.endTime)\n return Math.max(0, Math.round(end - start))\n}\n","import type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport {\n formatAttributes,\n formatLevel,\n formatMessage,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\n\nexport function formatLogRecord(record: ReadableLogRecord): string {\n const timestamp = formatTimestamp(record.hrTime)\n const service = formatService(record.resource)\n const level = formatLevel(record)\n const scope = formatScope(record.resource, record.instrumentationScope)\n const message = formatMessage(record)\n const attrs = formatAttributes(record.attributes)\n\n return `${service} ${timestamp} ${level} ${scope}${message}${attrs}`\n}\n","import type { Resource } from '@opentelemetry/resources'\nimport type {\n DataPoint,\n MetricData,\n ResourceMetrics,\n ScopeMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport {\n formatAttributes,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\nimport { colors } from './style'\n\nexport function formatMetrics(resourceMetrics: ResourceMetrics): string {\n const { resource, scopeMetrics } = resourceMetrics\n\n return scopeMetrics\n .map((scopeMetric) => formatScopeMetric(scopeMetric, resource))\n .join('\\n')\n}\n\nfunction formatScopeMetric(\n scopeMetric: ScopeMetrics,\n resource: Resource\n): string {\n return scopeMetric.metrics\n .map((metric: MetricData) =>\n formatMetricData(metric, resource, scopeMetric.scope)\n )\n .join('\\n')\n}\n\nfunction formatMetricData(\n metric: MetricData,\n resource: Resource,\n scope: ScopeMetrics['scope']\n): string {\n const scopeStr = formatScope(resource, scope)\n const serviceStr = formatService(resource)\n\n const lines: string[] = []\n\n for (const dp of metric.dataPoints) {\n const ts = formatTimestamp(dp.startTime)\n const value = extractMetricValue(dp)\n const attrs = formatAttributes(dp.attributes ?? {})\n\n lines.push(\n `${serviceStr} ${ts} 📊 ${scopeStr}${colors.white(metric.descriptor.name)} ${colors.dim(value)}${attrs}`\n )\n }\n\n return lines.join('\\n')\n}\n\nfunction extractMetricValue(dp: DataPoint<unknown>): string {\n const value = dp.value\n\n if (typeof value === 'number') {\n return value.toString()\n }\n\n if (isHistogramLike(value)) {\n return value.sum.toString()\n }\n\n return '[complex]'\n}\n\nfunction isHistogramLike(val: unknown): val is { sum: number } {\n return (\n typeof val === 'object' &&\n val !== null &&\n 'sum' in val &&\n typeof val.sum === 'number'\n )\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace'\nimport {\n calculateDuration,\n formatService,\n formatTimestamp,\n hrTimeToMillis,\n} from './shared'\nimport { colors, statusColorMap, statusLabelMap } from './style'\n\nconst LABEL_WIDTH = 20\nconst DESCRIPTION_MAX_WIDTH = 16\nconst BAR_MIN_WIDTH = 1\nconst BAR_MAX_WIDTH = 20\n\nexport function formatSpans(spans: ReadableSpan[]) {\n const rootSpan = spans[0]\n const rootStart = hrTimeToMillis(rootSpan.startTime)\n const rootEnd = hrTimeToMillis(rootSpan.endTime)\n const totalDuration = rootEnd - rootStart\n\n const service = formatService(rootSpan.resource)\n const timestamp = formatTimestamp(rootSpan.startTime)\n const traceId = colors.gray(`[${rootSpan.spanContext().traceId}]`)\n\n const lines = [`${service} ${timestamp} ${traceId}`]\n\n for (const span of spans) {\n const offset = hrTimeToMillis(span.startTime) - rootStart\n const depth = computeDepth(span, spans) // optional\n lines.push(\n formatSpan(span, {\n offsetMs: offset,\n totalDurationMs: totalDuration,\n depth,\n })\n )\n }\n\n return lines.join('\\n')\n}\n\nexport function formatSpan(\n span: ReadableSpan,\n opts: {\n offsetMs: number // relative start time in ms (0 for root)\n totalDurationMs: number // total duration in ms (root span duration)\n depth: number // nesting level for indent\n }\n): string {\n const label = formatLabel(span, opts.depth)\n const bar = buildBar(span, opts?.offsetMs, opts?.totalDurationMs)\n const barColor =\n span.status.code === SpanStatusCode.OK\n ? colors.green\n : span.status.code === SpanStatusCode.ERROR\n ? colors.red\n : colors.gray\n const desc = formatDescription(span)\n const status = formatStatus(span)\n const duration = formatDuration(span, opts?.offsetMs)\n const spanId = colors.gray(`[${span.spanContext().spanId}]`)\n\n return `${label} ${barColor(bar)} ${desc} ${status} ${duration} ${spanId}`\n}\n\nfunction formatLabel(span: ReadableSpan, depth: number) {\n const indent = ' '.repeat(depth) // 2 spaces per depth level\n const label = `${indent}└─ ${span.name}`\n return label.padEnd(LABEL_WIDTH)\n}\n\nfunction buildBar(\n span: ReadableSpan,\n offsetMs: number | undefined,\n totalDurationMs: number | undefined\n) {\n const duration = calculateDuration(span)\n\n if (\n typeof offsetMs !== 'number' ||\n typeof totalDurationMs !== 'number' ||\n totalDurationMs === 0\n ) {\n // fallback: show duration-only bar\n const capped = Math.min(duration, 1000)\n const barLength = Math.max(\n BAR_MIN_WIDTH,\n Math.round((capped / 1000) * BAR_MAX_WIDTH)\n )\n return '█'.repeat(barLength).padEnd(BAR_MAX_WIDTH + 2)\n }\n\n // Relative position and size\n const offsetRatio = Math.max(0, Math.min(offsetMs / totalDurationMs, 1))\n const durationRatio = Math.max(0, Math.min(duration / totalDurationMs, 1))\n\n const offsetChars = Math.floor(offsetRatio * BAR_MAX_WIDTH)\n const barChars = Math.max(\n BAR_MIN_WIDTH,\n Math.round(durationRatio * BAR_MAX_WIDTH)\n )\n\n const empty = ' '.repeat(offsetChars)\n const bar = '█'.repeat(barChars)\n\n return (empty + bar).padEnd(BAR_MAX_WIDTH + 2)\n}\n\nfunction formatDescription(span: ReadableSpan): string {\n const keyPriority = [\n // HTTP\n ['http.method', 'http.target'], // → GET /users/123\n ['http.route'], // → /users/:id\n ['http.url'], // → https://...\n\n // GraphQL\n ['graphql.operation.name'], // → getUsers\n ['graphql.operation.type'], // → query\n ['graphql.document'], // → full query text (maybe too long)\n\n // WebSocket\n ['ws.event'], // → connection, message, disconnect\n ['ws.message_type'], // → ping/pong/text/binary\n ['ws.url'], // → wss://...\n\n // Redis\n ['db.system', 'db.statement'], // → redis, \"SET foo bar\"\n ['db.operation'], // → GET, SET\n\n // Spanner\n ['db.statement'], // → SELECT * FROM...\n ['db.operation'], // → SELECT, INSERT\n ['db.name'], // → projects/.../instances/.../databases/...\n\n // OpenSearch\n ['db.operation'], // → search, index, bulk\n ['db.statement'], // → { query DSL... }\n\n // Pub/Sub (GCP)\n ['messaging.operation'], // → publish, receive\n ['messaging.destination'], // → topic-a\n ['messaging.gcp_pubsub.topic'], // → projects/x/topics/y\n\n // General FaaS\n ['faas.invoked_name'], // → myFunction\n ['faas.trigger'], // → http, pubsub, etc.\n\n // Custom or fallback\n ['otel.description'],\n ]\n\n for (const keys of keyPriority) {\n const parts = keys\n .map((k) => span.attributes[k])\n .filter((v) => v !== undefined && v !== null)\n .map((v) => String(v)) // 👈 FIX — guarantees string\n if (parts.length > 0) {\n return truncate(parts.join(' '), DESCRIPTION_MAX_WIDTH - 1).padEnd(\n DESCRIPTION_MAX_WIDTH\n )\n }\n }\n\n return ''.padEnd(DESCRIPTION_MAX_WIDTH)\n}\n\nfunction formatStatus(span: ReadableSpan): string {\n const code = span.status.code\n const label = statusLabelMap[code] ?? 'UNSET'\n const colorFn = statusColorMap[code] ?? colors.gray\n return colorFn(label).padEnd(6)\n}\n\nfunction formatDuration(\n span: ReadableSpan,\n offsetMs: number | undefined\n): string {\n const duration = calculateDuration(span)\n\n const format = (ms: number): string =>\n ms >= 1000 ? `${(ms / 1000).toFixed(2)} s` : `${ms} ms`\n\n return `(${format(offsetMs || 0)}–${format(duration)})`.padEnd(16)\n}\n\nfunction truncate(input: unknown, maxLength: number): string {\n // In practice, input is always a string — the String() cast is a defensive fallback.\n const str = String(input)\n return str.length > maxLength ? `${str.slice(0, maxLength - 1)}…` : str\n}\n\nfunction computeDepth(span: ReadableSpan, allSpans: ReadableSpan[]): number {\n let depth = 0\n let currentParentId = span.parentSpanContext?.spanId\n\n while (currentParentId) {\n const parentSpan = allSpans.find(\n (s) => s.spanContext().spanId === currentParentId\n )\n if (!parentSpan) break\n\n depth += 1\n currentParentId = parentSpan.parentSpanContext?.spanId\n }\n\n return depth\n}\n","/* istanbul ignore file */\nexport * from './log-record'\nexport * from './metrics'\nexport * from './span'\n","import { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n PushMetricExporter,\n ResourceMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport { formatMetrics } from './formatters/index'\n\nexport class ConsoleMetricPrettyExporter implements PushMetricExporter {\n private readonly patterns: RegExp[]\n\n constructor() {\n const raw = process.env.METRIC_FILTER ?? ''\n const entries = raw\n .split(',')\n .map((e) => e.trim())\n .filter(Boolean)\n\n this.patterns = entries.map(globToRegex)\n }\n\n private filterMetrics(\n resourceMetrics: ResourceMetrics\n ): ResourceMetrics | undefined {\n // No filter = block all metrics\n if (this.patterns.length === 0) return undefined\n\n const filteredScopes = resourceMetrics.scopeMetrics\n .map((scopeMetric) => {\n const filteredMetrics = scopeMetric.metrics.filter((metric) =>\n this.patterns.some((pattern) => pattern.test(metric.descriptor.name))\n )\n\n if (filteredMetrics.length === 0) return undefined\n\n return {\n ...scopeMetric,\n metrics: filteredMetrics,\n }\n })\n .filter((s): s is NonNullable<typeof s> => s !== undefined)\n\n if (filteredScopes.length === 0) return undefined\n\n return {\n ...resourceMetrics,\n scopeMetrics: filteredScopes,\n }\n }\n\n export(\n metrics: ResourceMetrics,\n resultCallback: (result: ExportResult) => void\n ): void {\n const filtered = this.filterMetrics(metrics)\n if (filtered) {\n console.log(formatMetrics(filtered))\n }\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n}\n\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n const regex = `^${escaped.replace(/\\*/g, '.*')}$`\n return new RegExp(regex)\n}\n","import { SeverityNumber } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n LogRecordExporter,\n ReadableLogRecord,\n} from '@opentelemetry/sdk-logs'\nimport { logThresholdFromEnv } from '../consts'\nimport { formatLogRecord } from './formatters/index'\n\nexport class ConsoleLogPrettyExporter implements LogRecordExporter {\n private readonly logThreshold: number\n constructor() {\n this.logThreshold = logThresholdFromEnv()\n }\n export(\n logs: ReadableLogRecord[],\n resultCallback: (result: ExportResult) => void\n ): void {\n this._sendLogRecords(logs, resultCallback)\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n\n private _sendLogRecords(\n logRecords: ReadableLogRecord[],\n done: (result: ExportResult) => void\n ): void {\n for (const record of logRecords) {\n if ((record.severityNumber ?? 0) >= this.logThreshold) {\n const formatted = formatLogRecord(record)\n /* istanbul ignore next */\n const severity = record.severityNumber || SeverityNumber.UNSPECIFIED\n\n if (severity >= SeverityNumber.ERROR) {\n console.error(formatted)\n } else if (severity >= SeverityNumber.WARN) {\n console.log(formatted)\n } else if (severity >= SeverityNumber.INFO) {\n console.info(formatted)\n } else if (severity >= SeverityNumber.DEBUG) {\n console.debug(formatted)\n } else {\n console.trace(formatted)\n }\n }\n }\n\n done?.({ code: ExportResultCode.SUCCESS })\n }\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace'\nimport { formatSpans } from './formatters/index'\n\nexport class ConsoleSpanPrettyExporter implements SpanExporter {\n private readonly allowedStatuses: Set<number>\n\n constructor() {\n const env = process.env.SPAN_LEVEL?.toUpperCase()\n if (!env) {\n this.allowedStatuses = new Set([\n SpanStatusCode.UNSET,\n SpanStatusCode.OK,\n SpanStatusCode.ERROR,\n ])\n } else {\n const map: Record<string, number> = {\n UNSET: SpanStatusCode.UNSET,\n OK: SpanStatusCode.OK,\n ERROR: SpanStatusCode.ERROR,\n }\n\n this.allowedStatuses = new Set(\n env\n .split(',')\n .map((s) => s.trim())\n .map((s) => map[s])\n .filter((v): v is number => typeof v === 'number')\n )\n }\n }\n\n private shouldExport(spans: ReadableSpan[]) {\n // print all spans\n if (this.allowedStatuses.size === 3) {\n return true\n }\n // print only certain levels\n return spans.some((span) => this.allowedStatuses.has(span.status.code))\n }\n\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void {\n if (this.shouldExport(spans)) {\n console.log(formatSpans(spans))\n }\n\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n}\n","/* istanbul ignore file */\nexport * from './console-log-pretty-exporter'\nexport * from './console-span-pretty-exporter'\nexport * from './gcp-json-log-exporter'\n","import type {\n ReadableSpan,\n SpanExporter,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace'\n\nexport class TreeSpanProcessor implements SpanProcessor {\n private exporter: SpanExporter\n private orphans: Map<string, ReadableSpan[]> = new Map()\n\n constructor(exporter: SpanExporter) {\n this.exporter = exporter\n }\n\n onStart(): void {\n // no-op\n }\n\n onEnd(span: ReadableSpan): void {\n const parentId = span.parentSpanContext?.spanId\n\n if (parentId) {\n const siblings = this.orphans.get(parentId) || []\n this.orphans.set(parentId, [...siblings, span])\n\n return\n }\n\n const children = this.getChildrenRecursively(span)\n const sorted = [span, ...children].sort((s1, s2) => {\n const [sec1, nano1] = s1.startTime\n const [sec2, nano2] = s2.startTime\n\n if (sec1 !== sec2) return sec1 - sec2\n return nano1 - nano2\n })\n this.exporter.export(sorted, () => {})\n }\n\n private getChildrenRecursively(span: ReadableSpan) {\n const spanId = span.spanContext().spanId\n const children = this.orphans.get(spanId) || []\n this.orphans.delete(spanId)\n\n const result = [...children]\n for (const child of children) {\n result.push(...this.getChildrenRecursively(child))\n }\n\n return result\n }\n\n shutdown(): Promise<void> {\n return this.exporter.shutdown()\n }\n\n async forceFlush(): Promise<void> {\n await this.exporter.forceFlush?.()\n }\n}\n","import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport type { Resource } from '@opentelemetry/resources'\nimport {\n BatchLogRecordProcessor,\n LoggerProvider,\n type LogRecordProcessor,\n SimpleLogRecordProcessor,\n} from '@opentelemetry/sdk-logs'\nimport { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport {\n BatchSpanProcessor,\n SimpleSpanProcessor,\n type SpanProcessor,\n} from '@opentelemetry/sdk-trace'\nimport { ConsoleMetricPrettyExporter } from './loggers/console-metric-pretty-exporter'\nimport {\n ConsoleLogPrettyExporter,\n ConsoleSpanPrettyExporter,\n} from './loggers/index'\nimport { TreeSpanProcessor } from './loggers/tree-span-processor'\n\nexport const getLogProvider = (\n resource: Resource,\n otlpEndpoint: string | undefined\n) => {\n // With collector\n if (otlpEndpoint) {\n const otlpExporter = new OTLPLogExporter({ url: `${otlpEndpoint}/v1/logs` })\n const processors: LogRecordProcessor[] = [\n new BatchLogRecordProcessor({ exporter: otlpExporter }),\n ]\n\n // Console logging for cluster\n if (process.env.LOG_LEVEL) {\n const consoleExporter = new ConsoleLogPrettyExporter()\n processors.push(\n new SimpleLogRecordProcessor({ exporter: consoleExporter })\n )\n }\n\n return new LoggerProvider({\n resource,\n processors,\n })\n }\n\n // Local dev\n const consoleExporter = new ConsoleLogPrettyExporter()\n const processor = new SimpleLogRecordProcessor({ exporter: consoleExporter })\n return new LoggerProvider({\n resource,\n processors: [processor],\n })\n}\n\nexport const getSpanProcessor = (\n otlpEndpoint: string | undefined\n): SpanProcessor => {\n const exporter = otlpEndpoint\n ? new OTLPTraceExporter({\n url: `${otlpEndpoint}/v1/traces`,\n })\n : new ConsoleSpanPrettyExporter()\n\n if (!otlpEndpoint) {\n return new TreeSpanProcessor(exporter)\n }\n\n if (process.env.OTEL_SIMPLE_SPAN_PROCESSOR === 'true') {\n console.log(\n '[otel] Using SimpleSpanProcessor (OTEL_SIMPLE_SPAN_PROCESSOR=true)'\n )\n return new SimpleSpanProcessor({ exporter })\n }\n\n return new BatchSpanProcessor({ exporter })\n}\n\nexport const getMetricReader = (otlpEndpoint: string | undefined) => {\n const metricExporter = otlpEndpoint\n ? new OTLPMetricExporter({\n url: `${otlpEndpoint}/v1/metrics`,\n })\n : new ConsoleMetricPrettyExporter()\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricExporter,\n })\n\n return metricReader\n}\n","import {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\n\n/**\n * Extracts telemetry context from environment (cloud/k8s aware),\n * with support for subservice/component override.\n */\nexport function detectTelemetryContext(componentNameOverride?: string) {\n const {\n OTEL_SERVICE_NAME, // e.g. \"UserSystem\"\n OTEL_SERVICE_VERSION, // e.g. \"1.2.3\"\n K_SERVICE,\n K_REVISION,\n K_CONFIGURATION,\n KUBERNETES_SERVICE_HOST,\n POD_NAME,\n POD_NAMESPACE,\n GCP_PROJECT,\n CLOUD_PROVIDER,\n } = process.env\n\n const systemName = OTEL_SERVICE_NAME || 'unknown-service'\n const systemVersion = OTEL_SERVICE_VERSION || '1.0.0'\n\n // Only use component if explicitly provided\n const componentName = componentNameOverride || undefined\n\n const resourceAttributes = {\n [ATTR_SERVICE_NAME]: systemName,\n [ATTR_SERVICE_VERSION]: systemVersion,\n 'serviceContext.service': systemName,\n 'serviceContext.version': systemVersion,\n ...(K_SERVICE && { 'cloud.run.service': K_SERVICE }),\n ...(K_REVISION && { 'cloud.run.revision': K_REVISION }),\n ...(K_CONFIGURATION && { 'cloud.run.configuration': K_CONFIGURATION }),\n ...(POD_NAME && { 'k8s.pod_name': POD_NAME }),\n ...(POD_NAMESPACE && { 'k8s.namespace_name': POD_NAMESPACE }),\n ...(KUBERNETES_SERVICE_HOST && { 'cloud.orchestrator': 'kubernetes' }),\n ...(GCP_PROJECT && { 'cloud.account.id': GCP_PROJECT }),\n ...(CLOUD_PROVIDER && { 'cloud.provider': CLOUD_PROVIDER }),\n ...(componentName && { 'component.name': componentName }),\n }\n\n return {\n systemName,\n systemVersion,\n componentName,\n resourceAttributes,\n }\n}\n","import { containerDetector } from '@opentelemetry/resource-detector-container'\nimport { gcpDetector } from '@opentelemetry/resource-detector-gcp'\nimport {\n detectResources,\n envDetector,\n osDetector,\n processDetector,\n resourceFromAttributes,\n serviceInstanceIdDetector,\n} from '@opentelemetry/resources'\nimport { detectTelemetryContext } from './otel-context'\n\nconst isOnGcp = () =>\n !!(\n process.env.K_SERVICE ||\n process.env.GAE_APPLICATION ||\n process.env.KUBERNETES_SERVICE_HOST\n )\n\nexport const getResource = async () => {\n const baseRes = detectResources({\n detectors: [\n containerDetector,\n envDetector,\n ...(isOnGcp() ? [gcpDetector] : []),\n osDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n })\n\n if (baseRes.waitForAsyncAttributes) {\n await baseRes.waitForAsyncAttributes()\n }\n\n const { resourceAttributes } = detectTelemetryContext()\n const customRes = resourceFromAttributes(resourceAttributes)\n const resource = baseRes.merge(customRes)\n\n if (resource.waitForAsyncAttributes) {\n await resource.waitForAsyncAttributes()\n }\n\n return resource\n}\n","import {\n context,\n DiagConsoleLogger,\n DiagLogLevel,\n diag,\n logs,\n metrics,\n trace,\n} from '@opentelemetry/api'\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs'\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getLogProvider, getMetricReader, getSpanProcessor } from './providers'\nimport { getResource } from './resource'\n\ndiag.disable()\ndiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR)\n\n// Use globalThis with a Symbol key so the flag is shared even when the module\n// is instantiated more than once (e.g. --import preload vs main app graph when\n// using tsx or other loaders that don't share the ESM module cache).\nconst OTEL_INIT_KEY = Symbol.for('@sebspark/otel:initialized')\nconst OTEL_INIT_PROMISE_KEY = Symbol.for('@sebspark/otel:initPromise')\n\nfunction getGlobal(): {\n [key: symbol]: unknown\n} {\n // biome-ignore lint/plugin/no-type-assertion: globalThis has no symbol index signature\n return globalThis as Record<symbol, unknown>\n}\n\nexport async function initialize(\n ...instrumentations: Promise<Instrumentation>[]\n): Promise<void> {\n const g = getGlobal()\n const existing = g[OTEL_INIT_PROMISE_KEY]\n if (existing instanceof Promise) return existing\n\n const resolvedInstrumentations = await Promise.all(instrumentations)\n const promise = _initialize(resolvedInstrumentations).catch((err) => {\n // Allow re-initialization if the first attempt fails\n g[OTEL_INIT_PROMISE_KEY] = undefined\n throw err\n })\n g[OTEL_INIT_PROMISE_KEY] = promise\n return promise\n}\n\nexport function isInitialized() {\n return getGlobal()[OTEL_INIT_KEY] === true\n}\n\nlet sdk: NodeSDK | undefined\nlet logProvider: LoggerProvider | undefined\n\nasync function _initialize(instrumentations: Instrumentation[]) {\n const serviceName = process.env.OTEL_SERVICE_NAME ?? 'unknown-service'\n const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT\n\n const resource = await getResource()\n\n // Reset any previous instrumentation\n context.disable()\n logs.disable()\n trace.disable()\n metrics.disable()\n\n // Manual setup for logs\n logProvider = getLogProvider(resource, otlpEndpoint)\n logs.setGlobalLoggerProvider(logProvider)\n\n // NodeSDK setup\n const spanProcessor = getSpanProcessor(otlpEndpoint)\n const metricReader = getMetricReader(otlpEndpoint)\n sdk = new NodeSDK({\n spanProcessors: [spanProcessor],\n metricReaders: [metricReader],\n instrumentations,\n resource,\n })\n\n sdk.start()\n getGlobal()[OTEL_INIT_KEY] = true\n console.log(`[otel] Telemetry initialized for \"${serviceName}\"`)\n}\n\nexport const dispose = async () => {\n const processes: Promise<void>[] = []\n if (sdk) processes.push(sdk.shutdown())\n if (logProvider) processes.push(logProvider.shutdown())\n\n // Only initiate shotdown once\n sdk = undefined\n logProvider = undefined\n\n if (processes.length) {\n console.log('[otel] Shutting down...')\n await Promise.all(processes)\n console.log('[otel] Shutdown complete.')\n }\n}\n","import { context, logs, trace } from '@opentelemetry/api'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from './consts'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\n// biome-ignore lint/suspicious/noExplicitAny: library\ntype Attrs = Record<string, any>\n\nexport type Logger = ReturnType<typeof getLogger>\nexport function getLogger(serviceOverride?: string, extraAttrs: Attrs = {}) {\n const { systemName, systemVersion, resourceAttributes } =\n detectTelemetryContext(serviceOverride)\n\n const defaultAttrs = {\n ...resourceAttributes,\n ...extraAttrs,\n }\n\n let hasWarnedAboutInit = false\n\n function emit(\n severityText: LOG_SEVERITY_NAME,\n body: string,\n attrs: Attrs = {}\n ) {\n // Get the logger at the last second\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n if (!hasWarnedAboutInit) {\n console.warn('OTEL must be initialized before using logger')\n hasWarnedAboutInit = true\n }\n console.log(`[${severityText}] ${body}`)\n return\n }\n const logger = logs.getLogger(systemName, systemVersion)\n\n const span = trace.getSpan(context.active())\n const spanContext = span?.spanContext()\n\n logger.emit({\n severityText,\n severityNumber: LOG_SEVERITY_MAP[severityText],\n body,\n attributes: {\n 'gcp.log_name': systemName.replace(/^@/, '').replace(/\\//g, '-'),\n ...defaultAttrs,\n ...(spanContext && {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n }),\n ...attrs,\n },\n })\n }\n\n function resolveArgs(\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ): { body: string; attrs: Attrs } {\n if (errOrAttrs instanceof Error) {\n /* istanbul ignore next */\n const body = `${msg}: ${errOrAttrs.stack || errOrAttrs.message}`\n return { body, attrs: maybeAttrs }\n }\n\n /* istanbul ignore next */\n const body = msg instanceof Error ? msg.stack || msg.message : msg\n /* istanbul ignore next */\n const attrs = errOrAttrs || {}\n return { body, attrs }\n }\n\n type LogFn = {\n (msg: string, attrs?: Attrs): void\n (msg: string, error: Error, attrs?: Attrs): void\n (error: Error, attrs?: Attrs): void\n }\n\n function createLogFn(severity: LOG_SEVERITY_NAME): LogFn {\n return (\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ) => {\n const { body, attrs } = resolveArgs(msg, errOrAttrs, maybeAttrs)\n emit(severity, body, attrs)\n }\n }\n\n return {\n debug: createLogFn('DEBUG'),\n info: createLogFn('INFO'),\n notice: createLogFn('NOTICE'),\n warn: createLogFn('WARN'),\n error: createLogFn('ERROR'),\n critical: createLogFn('CRITICAL'),\n alert: createLogFn('ALERT'),\n emergency: createLogFn('EMERGENCY'),\n }\n}\n","import { metrics } from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\nexport function getMeter(componentNameOverride?: string) {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before using getMeter()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n return metrics.getMeter(componentName ?? systemName, systemVersion)\n}\n","import {\n context,\n type SpanOptions,\n SpanStatusCode,\n trace,\n} from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\ntype OtelTracer = ReturnType<typeof trace.getTracer>\ntype Span = ReturnType<OtelTracer['startSpan']>\n\ntype Func<T> = (span: Span) => Promise<T> | T\ntype SyncFunc<T> = (span: Span) => T\n\ntype WithTrace = {\n <T>(name: string, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, fn: Func<T>): Promise<T>\n <T>(name: string, parent: Span, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, parent: Span, fn: Func<T>): Promise<T>\n}\ntype WithTraceSync = {\n <T>(name: string, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, fn: SyncFunc<T>): T\n <T>(name: string, parent: Span, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, parent: Span, fn: SyncFunc<T>): T\n}\n\n/**\n * Extended tracer with helper methods for span-wrapped execution\n */\ninterface Tracer extends OtelTracer {\n withTrace: WithTrace\n withTraceSync: WithTraceSync\n}\n\n/**\n * Returns an OpenTelemetry tracer bound to the current service.\n * Includes `withTrace()` and `withTraceSync()` helpers for span-wrapped execution.\n *\n * @param serviceOverride - Optional override for service name\n * @returns Tracer with helpers\n */\nexport function getTracer(componentNameOverride?: string): Tracer {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before calling getTracer()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n const tracer = trace.getTracer(componentName ?? systemName, systemVersion)\n\n /**\n * Runs a function inside a new span (async variant).\n * Automatically handles span status and nesting.\n */\n const withTrace: WithTrace = async <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | Func<T>,\n spanOrFunc?: Span | Func<T>,\n func?: Func<T>\n ): Promise<T> => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return await context.with(trace.setSpan(parentContext, span), async () => {\n try {\n const result = await fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n recordError(span, err)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n /**\n * Runs a synchronous function inside a new span.\n * Automatically handles span status and nesting.\n */\n const withTraceSync: WithTraceSync = <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | SyncFunc<T>,\n spanOrFunc?: Span | SyncFunc<T>,\n func?: SyncFunc<T>\n ): T => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return context.with(trace.setSpan(parentContext, span), () => {\n try {\n const result = fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n recordError(span, err)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n return Object.assign(tracer, { withTrace, withTraceSync })\n}\n\nconst recordError = (span: Span, err: unknown) => {\n const message = err instanceof Error ? err.message : String(err)\n span.setStatus({ code: SpanStatusCode.ERROR, message })\n span.recordException?.(err instanceof Error ? err : message)\n}\n\ntype TraceArgs<T> = {\n options: SpanOptions\n parent?: Span\n fn: (span: Span) => T\n}\n\nfunction extractArgs<T>(\n spanOptionsSpanOrFunc?: SpanOptions | Span | ((span: Span) => T),\n spanOrFunc?: Span | ((span: Span) => T),\n func?: (span: Span) => T\n): TraceArgs<T> {\n if (isFunction(spanOptionsSpanOrFunc)) {\n return { options: {}, fn: spanOptionsSpanOrFunc }\n }\n const options =\n spanOptionsSpanOrFunc && !isSpan(spanOptionsSpanOrFunc)\n ? spanOptionsSpanOrFunc\n : {}\n if (isFunction(spanOrFunc)) {\n const parent = isSpan(spanOptionsSpanOrFunc)\n ? spanOptionsSpanOrFunc\n : undefined\n return { options, parent, fn: spanOrFunc }\n }\n // biome-ignore lint/style/noNonNullAssertion: the overloads require fn last\n return { options, parent: spanOrFunc, fn: func! }\n}\n\nconst isFunction = (value: unknown): value is (span: Span) => unknown =>\n typeof value === 'function'\nconst isSpan = (value: unknown): value is Span =>\n typeof value === 'object' &&\n value !== null &&\n 'spanContext' in value &&\n isFunction(value.spanContext) &&\n 'end' in value &&\n isFunction(value.end)\n","/* istanbul ignore file */\nexport {\n type Context,\n type Counter,\n context,\n type Gauge,\n type Histogram,\n type Meter,\n type ObservableCounter,\n type ObservableGauge,\n type ObservableUpDownCounter,\n type Span,\n type SpanStatus,\n SpanStatusCode,\n type UpDownCounter,\n} from '@opentelemetry/api'\nexport * from './instrumentations'\nexport * from './logger'\nexport * from './metrics'\nexport * from './otel'\nexport * from './tracer'\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sebspark/otel",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"lint": "biome check .",
|
|
21
21
|
"test": "vitest run --passWithNoTests --coverage --fsModuleCachePath node_modules/.vitest-cache",
|
|
22
22
|
"test:e2e": "vitest --config vitest.config.e2e.ts --run --fsModuleCachePath node_modules/.vitest-cache",
|
|
23
|
-
"typecheck": "vitest --typecheck.only --passWithNoTests --run"
|
|
23
|
+
"typecheck": "tsc --noEmit -p . && vitest --typecheck.only --passWithNoTests --run"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@opentelemetry/api": "1.10.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@opentelemetry/sdk-node": "0.300.0",
|
|
47
47
|
"@opentelemetry/sdk-trace": "3.0.0",
|
|
48
48
|
"@opentelemetry/semantic-conventions": "1.44.0",
|
|
49
|
-
"@sebspark/opentelemetry-instrumentation-opensearch": "0.4.
|
|
49
|
+
"@sebspark/opentelemetry-instrumentation-opensearch": "0.4.2",
|
|
50
50
|
"fast-safe-stringify": "2.1.1",
|
|
51
51
|
"kleur": "4.1.5",
|
|
52
52
|
"yaml": "2.9.1"
|