Skip to content

Commit

Permalink
feat(core): Add OpenTelemetry-specific getTraceData version
Browse files Browse the repository at this point in the history
  • Loading branch information
Lms24 committed Aug 8, 2024
1 parent 21830b1 commit 9729ece
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 3 deletions.
4 changes: 4 additions & 0 deletions packages/core/src/asyncContext/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Scope } from '@sentry/types';
import { getTraceData } from '../utils/traceData';
import type {
startInactiveSpan,
startSpan,
Expand Down Expand Up @@ -64,4 +65,7 @@ export interface AsyncContextStrategy {

/** Suppress tracing in the given callback, ensuring no spans are generated inside of it. */
suppressTracing?: typeof suppressTracing;

/** get trace data as serialized string values for propagation via `sentry-trace` and `baggage` */
getTraceData?: typeof getTraceData;
}
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type { OfflineStore, OfflineTransportOptions } from './transports/offline
export type { ServerRuntimeClientOptions } from './server-runtime-client';
export type { RequestDataIntegrationOptions } from './integrations/requestdata';
export type { IntegrationIndex } from './integration';
export type { TraceData } from './utils/traceData';

export * from './tracing';
export * from './semanticAttributes';
Expand Down
10 changes: 9 additions & 1 deletion packages/core/src/utils/traceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {
generateSentryTraceHeader,
logger,
} from '@sentry/utils';
import { getAsyncContextStrategy } from '../asyncContext';
import { getMainCarrier } from '../carrier';
import { getClient, getCurrentScope } from '../currentScopes';
import { getDynamicSamplingContextFromClient, getDynamicSamplingContextFromSpan } from '../tracing';
import { getActiveSpan, getRootSpan, spanToTraceHeader } from './spanUtils';

type TraceData = {
export type TraceData = {
'sentry-trace'?: string;
baggage?: string;
};
Expand All @@ -30,6 +32,12 @@ type TraceData = {
* or meta tag name.
*/
export function getTraceData(span?: Span, scope?: Scope, client?: Client): TraceData {
const carrier = getMainCarrier();
const acs = getAsyncContextStrategy(carrier);
if (acs.getTraceData) {
return acs.getTraceData(span, scope, client);
}

const clientToUse = client || getClient();
const scopeToUse = scope || getCurrentScope();
const spanToUse = span || getActiveSpan();
Expand Down
6 changes: 4 additions & 2 deletions packages/opentelemetry/src/asyncContextStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as api from '@opentelemetry/api';
import { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core';
import type { withActiveSpan as defaultWithActiveSpan } from '@sentry/core';
import type { getTraceData as defaultGetTraceData, withActiveSpan as defaultWithActiveSpan } from '@sentry/core';
import type { Scope } from '@sentry/types';

import {
Expand All @@ -12,6 +12,7 @@ import { startInactiveSpan, startSpan, startSpanManual, withActiveSpan } from '.
import type { CurrentScopes } from './types';
import { getScopesFromContext } from './utils/contextData';
import { getActiveSpan } from './utils/getActiveSpan';
import { getTraceData } from './utils/getTraceData';
import { suppressTracing } from './utils/suppressTracing';

/**
Expand Down Expand Up @@ -102,9 +103,10 @@ export function setOpenTelemetryContextAsyncContextStrategy(): void {
startSpanManual,
startInactiveSpan,
getActiveSpan,
suppressTracing,
// The types here don't fully align, because our own `Span` type is narrower
// than the OTEL one - but this is OK for here, as we now we'll only have OTEL spans passed around
withActiveSpan: withActiveSpan as typeof defaultWithActiveSpan,
suppressTracing: suppressTracing,
getTraceData: getTraceData as typeof defaultGetTraceData,
});
}
40 changes: 40 additions & 0 deletions packages/opentelemetry/src/utils/getTraceData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as api from '@opentelemetry/api';
import type { Span } from '@opentelemetry/api';
import type { TraceData } from '@sentry/core';
import { getCurrentScope } from '@sentry/core';
import { getPropagationContextFromSpan } from '../propagator';
import { generateSpanContextForPropagationContext } from './generateSpanContextForPropagationContext';

/**
* Otel-specific implementation of `getTraceData`.
* @see `@sentry/core` version of `getTraceData` for more information
*/
export function getTraceData(span?: Span): TraceData {
const ctx = api.context.active();
const spanToUse = span || api.trace.getSpan(ctx);

// This should never happen, given we always create an ambient non-recording span if there's no active span.
if (!spanToUse) {
return {};
}
const headersObject: Record<string, string> = {};

const propagationContext = spanToUse
? getPropagationContextFromSpan(spanToUse)
: getCurrentScope().getPropagationContext();

const spanContext = generateSpanContextForPropagationContext(propagationContext);

const context = api.trace.setSpanContext(ctx, spanContext);

api.propagation.inject(context, headersObject);

if (!headersObject['sentry-trace']) {
return {};
}

return {
'sentry-trace': headersObject['sentry-trace'],
baggage: headersObject['baggage'],
};
}

0 comments on commit 9729ece

Please sign in to comment.