Skip to content

Commit

Permalink
lib: add tracing support for fetch(undici)
Browse files Browse the repository at this point in the history
  • Loading branch information
santigimeno committed Nov 13, 2024
1 parent 8696d0a commit 62e2f6f
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 2 deletions.
95 changes: 93 additions & 2 deletions lib/internal/nsolid_diag.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,114 @@ const {
} = nsolidApi;

const { now } = require('internal/perf/utils');
const { contextManager } = require('internal/otel/context');
const {
getApi,
} = require('internal/otel/core');

const {
generateSpan,
nsolidTracer,
} = require('internal/nsolid_trace');

const dc = require('diagnostics_channel');

const {
kHttpClientAbortCount,
kHttpClientCount,
kSpanHttpClient,
kSpanHttpMethod,
kSpanHttpReqUrl,
kSpanHttpStatusCode,
} = nsolid_consts;

const undiciFetch = dc.tracingChannel('undici:fetch');

let tracingEnabled = false;

const fetchSubscribeListener = (message, name) => {};

function disableTracing() {
undiciFetch.start.unbindStore();
dc.unsubscribe('tracing:undici:fetch:start', fetchSubscribeListener);
}

function enableTracing() {
undiciFetch.start.bindStore(contextManager._getALS(), (data) => {
const { req } = data;
const api = getApi();
const tracer = api.trace.getTracer('http');
const span = tracer.startSpan(`HTTP ${req.method}`,
{ internal: true,
kind: api.SpanKind.CLIENT,
type: kSpanHttpClient });
span._pushSpanDataString(kSpanHttpMethod, req.method);
span._pushSpanDataString(kSpanHttpReqUrl, req.url);
const { spanId, traceId } = span.spanContext();
if (span._isSampled()) {
req.headers.append('traceparent', `00-${traceId}-${spanId}-01`);
} else {
req.headers.append('traceparent', `00-${traceId}-${spanId}-00`);
}

return api.trace.setSpan(api.context.active(), span);
});

dc.subscribe('tracing:undici:fetch:start', fetchSubscribeListener);
}

nsolidTracer.on('flagsUpdated', () => {
const next = generateSpan(kSpanHttpClient);
if (next && !tracingEnabled) {
enableTracing();
tracingEnabled = true;
} else if (!next && tracingEnabled) {
disableTracing();
tracingEnabled = false;
}
});

dc.subscribe('undici:request:create', ({ request }) => {
request[nsolid_tracer_s] = now();
});

dc.subscribe('undici:request:headers', ({ request }) => {
dc.subscribe('undici:request:headers', ({ request, response }) => {
nsolid_counts[kHttpClientCount]++;
nsolidApi.pushClientBucket(now() - request[nsolid_tracer_s]);
if (generateSpan(kSpanHttpClient)) {
const api = getApi();
const span = api.trace.getSpan(api.context.active());
if (span) {
span._pushSpanDataUint64(kSpanHttpStatusCode, response.statusCode);
if (response.statusCode >= 400) {
span.setStatus({ code: getApi().SpanStatusCode.ERROR });
}
}
}
});

dc.subscribe('undici:request:trailers', ({ request }) => {
if (generateSpan(kSpanHttpClient)) {
const api = getApi();
const span = api.trace.getSpan(api.context.active());
if (span) {
span.end();
}
}
});

dc.subscribe('undici:request:error', () => {
dc.subscribe('undici:request:error', ({ request, error }) => {
nsolid_counts[kHttpClientAbortCount]++;
if (generateSpan(kSpanHttpClient)) {
const api = getApi();
const span = api.trace.getSpan(api.context.active());
if (span) {
span.recordException(error);
span.setStatus({
code: getApi().SpanStatusCode.ERROR,
message: error.message,
});
span.end();
}
}
});
4 changes: 4 additions & 0 deletions lib/internal/otel/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ class AsyncLocalStorageContextManager extends AbstractAsyncHooksContextManager {
this._asyncLocalStorage.disable();
return this;
}

_getALS() {
return this._asyncLocalStorage;
}
}

const contextManager = new AsyncLocalStorageContextManager();
Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ expected.atRunTime = new Set([
'NativeModule internal/nsolid_loader',
'NativeModule internal/nsolid_promise_tracking',
'NativeModule internal/nsolid_diag',
'NativeModule internal/nsolid_trace',
'NativeModule internal/otel/api',
'NativeModule internal/otel/context',
'NativeModule internal/otel/core',
]);

if (common.isMainThread) {
Expand Down

0 comments on commit 62e2f6f

Please sign in to comment.