@blaxel/telemetry 0.2.17-dev.130 → 0.2.17-dev.132
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/telemetry.d.ts +0 -4
- package/dist/telemetry.js +0 -117
- package/dist/telemetry_provider.d.ts +2 -0
- package/dist/telemetry_provider.js +17 -54
- package/package.json +2 -2
package/dist/telemetry.d.ts
CHANGED
|
@@ -42,10 +42,6 @@ declare class TelemetryManager {
|
|
|
42
42
|
flush(): Promise<void>;
|
|
43
43
|
getLogger(): Promise<Logger>;
|
|
44
44
|
setupSignalHandler(): void;
|
|
45
|
-
/**
|
|
46
|
-
* Check if telemetry is properly initialized and active
|
|
47
|
-
*/
|
|
48
|
-
get isActive(): boolean;
|
|
49
45
|
/**
|
|
50
46
|
* Get resource attributes for OpenTelemetry.
|
|
51
47
|
*/
|
package/dist/telemetry.js
CHANGED
|
@@ -142,22 +142,6 @@ class TelemetryManager {
|
|
|
142
142
|
});
|
|
143
143
|
});
|
|
144
144
|
}
|
|
145
|
-
// Handle uncaughtException differently - log but don't shutdown telemetry
|
|
146
|
-
process.on("uncaughtException", (error) => {
|
|
147
|
-
core_1.logger.error("Uncaught exception:", error);
|
|
148
|
-
// Don't shutdown telemetry for uncaught exceptions
|
|
149
|
-
});
|
|
150
|
-
// Don't listen to 'exit' event as it can be triggered by various things
|
|
151
|
-
// and we don't want to shutdown telemetry unless explicitly requested
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Check if telemetry is properly initialized and active
|
|
155
|
-
*/
|
|
156
|
-
get isActive() {
|
|
157
|
-
return (this.initialized &&
|
|
158
|
-
this.configured &&
|
|
159
|
-
this.nodeTracerProvider !== null &&
|
|
160
|
-
this.meterProvider !== null);
|
|
161
145
|
}
|
|
162
146
|
/**
|
|
163
147
|
* Get resource attributes for OpenTelemetry.
|
|
@@ -208,114 +192,15 @@ class TelemetryManager {
|
|
|
208
192
|
});
|
|
209
193
|
}
|
|
210
194
|
instrumentApp() {
|
|
211
|
-
core_1.logger.debug("Available propagation fields before setup:", api_1.propagation.fields());
|
|
212
195
|
core_1.telemetryRegistry.registerProvider(new telemetry_provider_1.OtelTelemetryProvider());
|
|
213
196
|
const httpInstrumentation = new instrumentation_http_1.HttpInstrumentation({
|
|
214
197
|
requireParentforOutgoingSpans: true,
|
|
215
|
-
requireParentforIncomingSpans: false, // Allow root spans for incoming requests
|
|
216
|
-
ignoreIncomingRequestHook: () => false, // Don't ignore any requests
|
|
217
|
-
ignoreOutgoingRequestHook: () => false, // Don't ignore any requests
|
|
218
|
-
requestHook: (span, request) => {
|
|
219
|
-
core_1.logger.debug("Available propagation fields before setup:", api_1.propagation.fields());
|
|
220
|
-
// Log incoming headers for debugging
|
|
221
|
-
if ("headers" in request && request.headers) {
|
|
222
|
-
// Specifically log trace context headers
|
|
223
|
-
const headers = request.headers;
|
|
224
|
-
const traceHeaders = {
|
|
225
|
-
traceparent: headers.traceparent,
|
|
226
|
-
tracestate: headers.tracestate,
|
|
227
|
-
"x-blaxel-authorization": headers["x-blaxel-authorization"],
|
|
228
|
-
"x-blaxel-workspace": headers["x-blaxel-workspace"],
|
|
229
|
-
};
|
|
230
|
-
core_1.logger.debug("Trace context headers:", JSON.stringify(traceHeaders));
|
|
231
|
-
// Manual trace context extraction for debugging
|
|
232
|
-
if (headers.traceparent) {
|
|
233
|
-
const extractedContext = api_1.propagation.extract(api_1.context.active(), headers);
|
|
234
|
-
core_1.logger.debug("Active context:", JSON.stringify(api_1.context.active()));
|
|
235
|
-
core_1.logger.debug("Extracted context:", JSON.stringify(extractedContext));
|
|
236
|
-
// const extractedSpan = trace.getSpan(extractedContext);
|
|
237
|
-
// if (extractedSpan) {
|
|
238
|
-
// // Force set the extracted span as active
|
|
239
|
-
// context.with(
|
|
240
|
-
// trace.setSpan(context.active(), extractedSpan),
|
|
241
|
-
// () => {
|
|
242
|
-
// logger.debug("Forced context activation from traceparent");
|
|
243
|
-
// }
|
|
244
|
-
// );
|
|
245
|
-
// }
|
|
246
|
-
try {
|
|
247
|
-
const traceparentValue = Array.isArray(headers.traceparent)
|
|
248
|
-
? headers.traceparent[0]
|
|
249
|
-
: headers.traceparent;
|
|
250
|
-
core_1.logger.debug("Manual traceparent parsing:", traceparentValue);
|
|
251
|
-
// Try to manually parse the traceparent header
|
|
252
|
-
const parts = traceparentValue.split("-");
|
|
253
|
-
if (parts.length === 4) {
|
|
254
|
-
core_1.logger.debug("Traceparent parts:", JSON.stringify({
|
|
255
|
-
version: parts[0],
|
|
256
|
-
traceId: parts[1],
|
|
257
|
-
spanId: parts[2],
|
|
258
|
-
flags: parts[3],
|
|
259
|
-
}));
|
|
260
|
-
// Check if this looks like a valid traceparent
|
|
261
|
-
if (parts[1] !== "00000000000000000000000000000000" &&
|
|
262
|
-
parts[2] !== "0000000000000000") {
|
|
263
|
-
core_1.logger.debug("Traceparent appears valid - extraction should work");
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
core_1.logger.debug("Traceparent contains invalid IDs");
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
// // Extract trace context manually to see what should be extracted
|
|
270
|
-
// const extractedContext = propagation.extract(
|
|
271
|
-
// context.active(),
|
|
272
|
-
// headers
|
|
273
|
-
// );
|
|
274
|
-
const extractedSpan = api_1.trace.getSpan(extractedContext);
|
|
275
|
-
if (extractedSpan) {
|
|
276
|
-
const extractedSpanContext = extractedSpan.spanContext();
|
|
277
|
-
core_1.logger.debug("Manual context extraction result:", JSON.stringify({
|
|
278
|
-
traceId: extractedSpanContext.traceId,
|
|
279
|
-
spanId: extractedSpanContext.spanId,
|
|
280
|
-
traceFlags: extractedSpanContext.traceFlags,
|
|
281
|
-
}));
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
core_1.logger.debug("Manual context extraction failed - no span found");
|
|
285
|
-
core_1.logger.debug("Available propagation fields:", api_1.propagation.fields());
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
core_1.logger.debug("Manual context extraction error:", error);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
core_1.logger.debug("Span:", JSON.stringify(span));
|
|
293
|
-
core_1.logger.debug("Span context:", JSON.stringify(span.spanContext()));
|
|
294
|
-
// Log the span context that was created from the incoming request
|
|
295
|
-
const spanContext = span.spanContext();
|
|
296
|
-
core_1.logger.debug("HTTP span context:", JSON.stringify({
|
|
297
|
-
traceId: spanContext.traceId,
|
|
298
|
-
spanId: spanContext.spanId,
|
|
299
|
-
traceFlags: spanContext.traceFlags,
|
|
300
|
-
}));
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
responseHook: (span) => {
|
|
304
|
-
const spanContext = span.spanContext();
|
|
305
|
-
core_1.logger.debug("HTTP response span context:", JSON.stringify({
|
|
306
|
-
traceId: spanContext.traceId,
|
|
307
|
-
spanId: spanContext.spanId,
|
|
308
|
-
traceFlags: spanContext.traceFlags,
|
|
309
|
-
}));
|
|
310
|
-
},
|
|
311
198
|
});
|
|
312
199
|
(0, instrumentation_1.registerInstrumentations)({
|
|
313
200
|
instrumentations: [httpInstrumentation],
|
|
314
201
|
});
|
|
315
202
|
}
|
|
316
203
|
setExporters() {
|
|
317
|
-
// Log current propagators for debugging
|
|
318
|
-
core_1.logger.debug("Current propagators:", api_1.propagation.fields());
|
|
319
204
|
const resource = new BlaxelResource(this.resourceAttributes);
|
|
320
205
|
const logExporter = this.getLogExporter();
|
|
321
206
|
this.loggerProvider = new sdk_logs_1.LoggerProvider({
|
|
@@ -338,8 +223,6 @@ class TelemetryManager {
|
|
|
338
223
|
],
|
|
339
224
|
});
|
|
340
225
|
this.nodeTracerProvider.register();
|
|
341
|
-
// Ensure W3C trace context propagation is working
|
|
342
|
-
core_1.logger.debug("Propagation fields after tracer registration:", api_1.propagation.fields());
|
|
343
226
|
const metricExporter = this.getMetricExporter();
|
|
344
227
|
this.meterProvider = new sdk_metrics_1.MeterProvider({
|
|
345
228
|
resource,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { BlaxelSpan, BlaxelSpanOptions, BlaxelTelemetryProvider } from "@blaxel/core";
|
|
2
2
|
export declare class OtelTelemetryProvider implements BlaxelTelemetryProvider {
|
|
3
|
+
private spans;
|
|
4
|
+
retrieveActiveSpanContext(): import("@opentelemetry/api").Context;
|
|
3
5
|
startSpan(name: string, options?: BlaxelSpanOptions): BlaxelSpan;
|
|
4
6
|
flush(): Promise<void>;
|
|
5
7
|
}
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OtelTelemetryProvider = void 0;
|
|
4
4
|
const api_1 = require("@opentelemetry/api");
|
|
5
5
|
const telemetry_1 = require("./telemetry");
|
|
6
|
-
const core_1 = require("@blaxel/core");
|
|
7
6
|
class OtelSpan {
|
|
8
7
|
span;
|
|
8
|
+
closed = false;
|
|
9
9
|
constructor(span) {
|
|
10
10
|
this.span = span;
|
|
11
11
|
}
|
|
@@ -21,11 +21,12 @@ class OtelSpan {
|
|
|
21
21
|
}
|
|
22
22
|
setStatus(status, message) {
|
|
23
23
|
this.span.setStatus({
|
|
24
|
-
code: status ===
|
|
24
|
+
code: status === 'ok' ? api_1.SpanStatusCode.OK : api_1.SpanStatusCode.ERROR,
|
|
25
25
|
message,
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
end() {
|
|
29
|
+
this.closed = true;
|
|
29
30
|
this.span.end();
|
|
30
31
|
}
|
|
31
32
|
getContext() {
|
|
@@ -33,64 +34,26 @@ class OtelSpan {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
class OtelTelemetryProvider {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
spans = [];
|
|
38
|
+
retrieveActiveSpanContext() {
|
|
39
|
+
for (let i = this.spans.length - 1; i >= 0; i--) {
|
|
40
|
+
const span = this.spans[i];
|
|
41
|
+
if (!span.closed) {
|
|
42
|
+
return api_1.trace.setSpanContext(api_1.ROOT_CONTEXT, span.getContext());
|
|
43
|
+
}
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
return api_1.context.active();
|
|
46
|
+
}
|
|
47
|
+
startSpan(name, options) {
|
|
45
48
|
const tracer = api_1.trace.getTracer("blaxel");
|
|
46
|
-
// Prepare OpenTelemetry span options
|
|
47
49
|
const otelOptions = {
|
|
48
50
|
attributes: options?.attributes,
|
|
49
51
|
root: options?.isRoot,
|
|
50
52
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const activeSpan = api_1.trace.getActiveSpan();
|
|
56
|
-
core_1.logger.debug("Active context:", JSON.stringify(ctx));
|
|
57
|
-
core_1.logger.debug("Active span:", JSON.stringify(activeSpan));
|
|
58
|
-
core_1.logger.debug("Active span context:", JSON.stringify(activeSpan?.spanContext()));
|
|
59
|
-
// Debug logging for context issues
|
|
60
|
-
core_1.logger.info(`Creating span "${name}":`, JSON.stringify({
|
|
61
|
-
hasActiveSpan: !!activeSpan,
|
|
62
|
-
activeSpanId: activeSpan?.spanContext().spanId,
|
|
63
|
-
isRoot: options?.isRoot,
|
|
64
|
-
hasParentContext: !!options?.parentContext,
|
|
65
|
-
parentContext: JSON.stringify(options?.parentContext),
|
|
66
|
-
activeContext: JSON.stringify(ctx),
|
|
67
|
-
otelOptions: JSON.stringify(otelOptions),
|
|
68
|
-
activeTraceId: activeSpan?.spanContext().traceId,
|
|
69
|
-
contextKeys: Object.keys(ctx),
|
|
70
|
-
telemetryActive: telemetry_1.blaxelTelemetry.isActive,
|
|
71
|
-
}));
|
|
72
|
-
if (options?.parentContext) {
|
|
73
|
-
// If explicit parent context is provided, use it
|
|
74
|
-
ctx = api_1.trace.setSpanContext(api_1.ROOT_CONTEXT, options.parentContext);
|
|
75
|
-
}
|
|
76
|
-
else if (options?.isRoot) {
|
|
77
|
-
// If explicitly marked as root, use ROOT_CONTEXT
|
|
78
|
-
ctx = api_1.ROOT_CONTEXT;
|
|
79
|
-
}
|
|
80
|
-
// Otherwise, use the active context (default behavior)
|
|
81
|
-
// Start the span with proper context
|
|
82
|
-
const span = tracer.startSpan(name, otelOptions, ctx);
|
|
83
|
-
const otelSpan = new OtelSpan(span);
|
|
84
|
-
core_1.logger.debug("Span:", JSON.stringify(span));
|
|
85
|
-
core_1.logger.debug("Span context:", JSON.stringify(span.spanContext()));
|
|
86
|
-
// Additional debugging
|
|
87
|
-
const spanContext = span.spanContext();
|
|
88
|
-
core_1.logger.info(`Created span "${name}":`, JSON.stringify({
|
|
89
|
-
spanId: spanContext.spanId,
|
|
90
|
-
traceId: spanContext.traceId,
|
|
91
|
-
parentSpanId: activeSpan?.spanContext().spanId || "none",
|
|
92
|
-
}));
|
|
93
|
-
return otelSpan;
|
|
53
|
+
const ctx = this.retrieveActiveSpanContext();
|
|
54
|
+
const span = new OtelSpan(tracer.startSpan(name, otelOptions, ctx));
|
|
55
|
+
this.spans.push(span);
|
|
56
|
+
return span;
|
|
94
57
|
}
|
|
95
58
|
async flush() {
|
|
96
59
|
await telemetry_1.blaxelTelemetry.flush();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blaxel/telemetry",
|
|
3
|
-
"version": "0.2.17-dev.
|
|
3
|
+
"version": "0.2.17-dev.132",
|
|
4
4
|
"description": "Blaxel SDK for TypeScript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Blaxel, INC (https://blaxel.ai)",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@opentelemetry/sdk-trace-base": "^2.0.0",
|
|
72
72
|
"@opentelemetry/sdk-trace-node": "^2.0.0",
|
|
73
73
|
"ai": "^4.3.13",
|
|
74
|
-
"@blaxel/core": "0.2.17-dev.
|
|
74
|
+
"@blaxel/core": "0.2.17-dev.132"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@eslint/js": "^9.26.0",
|