Skip to content

Commit

Permalink
remove params
Browse files Browse the repository at this point in the history
  • Loading branch information
Lms24 committed Aug 9, 2024
1 parent b484ad5 commit 3ce020d
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 97 deletions.
9 changes: 4 additions & 5 deletions packages/astro/src/server/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
startSpan,
withIsolationScope,
} from '@sentry/node';
import type { Client, Scope, Span, SpanAttributes } from '@sentry/types';
import type { Scope, SpanAttributes } from '@sentry/types';
import { addNonEnumerableProperty, objectify, stripUrlQueryAndFragment } from '@sentry/utils';
import type { APIContext, MiddlewareResponseHandler } from 'astro';

Expand Down Expand Up @@ -136,7 +136,6 @@ async function instrumentRequest(
setHttpStatus(span, originalResponse.status);
}

const scope = getCurrentScope();
const client = getClient();
const contentType = originalResponse.headers.get('content-type');

Expand All @@ -160,7 +159,7 @@ async function instrumentRequest(
start: async controller => {
for await (const chunk of originalBody) {
const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });
const modifiedHtml = addMetaTagToHead(html, scope, client, span);
const modifiedHtml = addMetaTagToHead(html);
controller.enqueue(new TextEncoder().encode(modifiedHtml));
}
controller.close();
Expand All @@ -184,11 +183,11 @@ async function instrumentRequest(
* This function optimistically assumes that the HTML coming in chunks will not be split
* within the <head> tag. If this still happens, we simply won't replace anything.
*/
function addMetaTagToHead(htmlChunk: string, scope: Scope, client: Client, span?: Span): string {
function addMetaTagToHead(htmlChunk: string): string {
if (typeof htmlChunk !== 'string') {
return htmlChunk;
}
const metaTags = getTraceMetaTags(span, scope, client);
const metaTags = getTraceMetaTags();

if (!metaTags) {
return htmlChunk;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/asyncContext/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ 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` */
/** Get trace data as serialized string values for propagation via `sentry-trace` and `baggage`. */
getTraceData?: typeof getTraceData;
}
3 changes: 1 addition & 2 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
export type { ClientClass } from './sdk';
export type { ClientClass as SentryCoreCurrentScopes } from './sdk';
export type { AsyncContextStrategy } from './asyncContext/types';
export type { Carrier } from './carrier';
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
5 changes: 2 additions & 3 deletions packages/core/src/utils/meta.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { Client, Scope, Span } from '@sentry/types';
import { getTraceData } from './traceData';

/**
Expand All @@ -22,8 +21,8 @@ import { getTraceData } from './traceData';
* ```
*
*/
export function getTraceMetaTags(span?: Span, scope?: Scope, client?: Client): string {
return Object.entries(getTraceData(span, scope, client))
export function getTraceMetaTags(): string {
return Object.entries(getTraceData())
.map(([key, value]) => `<meta name="${key}" content="${value}"/>`)
.join('\n');
}
31 changes: 11 additions & 20 deletions packages/core/src/utils/traceData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Client, Scope, Span } from '@sentry/types';
import type { SerializedTraceData } from '@sentry/types';
import {
TRACEPARENT_REGEXP,
dynamicSamplingContextToSentryBaggageHeader,
Expand All @@ -11,11 +11,6 @@ import { getClient, getCurrentScope } from '../currentScopes';
import { getDynamicSamplingContextFromClient, getDynamicSamplingContextFromSpan } from '../tracing';
import { getActiveSpan, getRootSpan, spanToTraceHeader } from './spanUtils';

export type TraceData = {
'sentry-trace'?: string;
baggage?: string;
};

/**
* Extracts trace propagation data from the current span or from the client's scope (via transaction or propagation
* context) and serializes it to `sentry-trace` and `baggage` values to strings. These values can be used to propagate
Expand All @@ -24,35 +19,31 @@ export type TraceData = {
* This function also applies some validation to the generated sentry-trace and baggage values to ensure that
* only valid strings are returned.
*
* @param span a span to take the trace data from. By default, the currently active span is used.
* @param scope the scope to take trace data from By default, the active current scope is used.
* @param client the SDK's client to take trace data from. By default, the current client is used.
*
* @returns an object with the tracing data values. The object keys are the name of the tracing key to be used as header
* or meta tag name.
*/
export function getTraceData(span?: Span, scope?: Scope, client?: Client): TraceData {
export function getTraceData(): SerializedTraceData {
const carrier = getMainCarrier();
const acs = getAsyncContextStrategy(carrier);
if (acs.getTraceData) {
return acs.getTraceData(span, scope, client);
return acs.getTraceData();
}

const clientToUse = client || getClient();
const scopeToUse = scope || getCurrentScope();
const spanToUse = span || getActiveSpan();
const client = getClient();
const scope = getCurrentScope();
const span = getActiveSpan();

const { dsc, sampled, traceId } = scopeToUse.getPropagationContext();
const rootSpan = spanToUse && getRootSpan(spanToUse);
const { dsc, sampled, traceId } = scope.getPropagationContext();
const rootSpan = span && getRootSpan(span);

const sentryTrace = spanToUse ? spanToTraceHeader(spanToUse) : generateSentryTraceHeader(traceId, undefined, sampled);
const sentryTrace = span ? spanToTraceHeader(span) : generateSentryTraceHeader(traceId, undefined, sampled);

const dynamicSamplingContext = rootSpan
? getDynamicSamplingContextFromSpan(rootSpan)
: dsc
? dsc
: clientToUse
? getDynamicSamplingContextFromClient(traceId, clientToUse)
: client
? getDynamicSamplingContextFromClient(traceId, client)
: undefined;

const baggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
Expand Down
124 changes: 65 additions & 59 deletions packages/core/test/lib/utils/traceData.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { SentrySpan, getTraceData } from '../../../src/';
import * as SentryCoreCurrentScopes from '../../../src/currentScopes';
import * as SentryCoreTracing from '../../../src/tracing';
import * as SentryCoreSpanUtils from '../../../src/utils/spanUtils';

import { isValidBaggageString } from '../../../src/utils/traceData';

Expand All @@ -25,33 +27,38 @@ describe('getTraceData', () => {
jest.spyOn(SentryCoreTracing, 'getDynamicSamplingContextFromSpan').mockReturnValueOnce({
environment: 'production',
});
jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => mockedSpan);
jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(() => mockedScope);

const tags = getTraceData(mockedSpan, mockedScope, mockedClient);
const data = getTraceData();

expect(tags).toEqual({
expect(data).toEqual({
'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
baggage: 'sentry-environment=production',
});
}
});

it('returns propagationContext DSC data if no span is available', () => {
const traceData = getTraceData(
undefined,
{
getPropagationContext: () => ({
traceId: '12345678901234567890123456789012',
sampled: true,
spanId: '1234567890123456',
dsc: {
environment: 'staging',
public_key: 'key',
trace_id: '12345678901234567890123456789012',
},
}),
} as any,
mockedClient,
jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => undefined);
jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(
() =>
({
getPropagationContext: () => ({
traceId: '12345678901234567890123456789012',
sampled: true,
spanId: '1234567890123456',
dsc: {
environment: 'staging',
public_key: 'key',
trace_id: '12345678901234567890123456789012',
},
}),
}) as any,
);
jest.spyOn(SentryCoreCurrentScopes, 'getClient').mockImplementationOnce(() => mockedClient);

const traceData = getTraceData();

expect(traceData).toEqual({
'sentry-trace': expect.stringMatching(/12345678901234567890123456789012-(.{16})-1/),
Expand All @@ -65,21 +72,22 @@ describe('getTraceData', () => {
public_key: undefined,
});

const traceData = getTraceData(
// @ts-expect-error - we don't need to provide all the properties
{
isRecording: () => true,
spanContext: () => {
return {
traceId: '12345678901234567890123456789012',
spanId: '1234567890123456',
traceFlags: TRACE_FLAG_SAMPLED,
};
},
// @ts-expect-error - we don't need to provide all the properties
jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => ({
isRecording: () => true,
spanContext: () => {
return {
traceId: '12345678901234567890123456789012',
spanId: '1234567890123456',
traceFlags: TRACE_FLAG_SAMPLED,
};
},
mockedScope,
mockedClient,
);
}));

jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(() => mockedScope);
jest.spyOn(SentryCoreCurrentScopes, 'getClient').mockImplementationOnce(() => mockedClient);

const traceData = getTraceData();

expect(traceData).toEqual({
'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
Expand All @@ -92,21 +100,21 @@ describe('getTraceData', () => {
public_key: undefined,
});

const traceData = getTraceData(
// @ts-expect-error - we don't need to provide all the properties
{
isRecording: () => true,
spanContext: () => {
return {
traceId: '12345678901234567890123456789012',
spanId: '1234567890123456',
traceFlags: TRACE_FLAG_SAMPLED,
};
},
// @ts-expect-error - we don't need to provide all the properties
jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => ({
isRecording: () => true,
spanContext: () => {
return {
traceId: '12345678901234567890123456789012',
spanId: '1234567890123456',
traceFlags: TRACE_FLAG_SAMPLED,
};
},
mockedScope,
undefined,
);
}));
jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(() => mockedScope);
jest.spyOn(SentryCoreCurrentScopes, 'getClient').mockImplementationOnce(() => undefined);

const traceData = getTraceData();

expect(traceData).toEqual({
'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
Expand All @@ -115,21 +123,19 @@ describe('getTraceData', () => {
});

it('returns an empty object if the `sentry-trace` value is invalid', () => {
const traceData = getTraceData(
// @ts-expect-error - we don't need to provide all the properties
{
isRecording: () => true,
spanContext: () => {
return {
traceId: '1234567890123456789012345678901+',
spanId: '1234567890123456',
traceFlags: TRACE_FLAG_SAMPLED,
};
},
// @ts-expect-error - we don't need to provide all the properties
jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => ({
isRecording: () => true,
spanContext: () => {
return {
traceId: '1234567890123456789012345678901+',
spanId: '1234567890123456',
traceFlags: TRACE_FLAG_SAMPLED,
};
},
mockedScope,
mockedClient,
);
}));

const traceData = getTraceData();

expect(traceData).toEqual({});
});
Expand Down
4 changes: 2 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 { getTraceData as defaultGetTraceData, withActiveSpan as defaultWithActiveSpan } from '@sentry/core';
import type { withActiveSpan as defaultWithActiveSpan } from '@sentry/core';
import type { Scope } from '@sentry/types';

import {
Expand Down Expand Up @@ -104,9 +104,9 @@ export function setOpenTelemetryContextAsyncContextStrategy(): void {
startInactiveSpan,
getActiveSpan,
suppressTracing,
getTraceData,
// 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,
getTraceData: getTraceData as typeof defaultGetTraceData,
});
}
7 changes: 3 additions & 4 deletions packages/opentelemetry/src/utils/getTraceData.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import * as api from '@opentelemetry/api';
import type { Span } from '@opentelemetry/api';
import type { TraceData } from '@sentry/core';
import { getCurrentScope } from '@sentry/core';
import type { SerializedTraceData } from '@sentry/types';
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 {
export function getTraceData(): SerializedTraceData {
const ctx = api.context.active();
const spanToUse = span || api.trace.getSpan(ctx);
const spanToUse = 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) {
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export type { SpanStatus } from './spanStatus';
export type { TimedEvent } from './timedEvent';
export type { StackFrame } from './stackframe';
export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace';
export type { PropagationContext, TracePropagationTargets } from './tracing';
export type { PropagationContext, TracePropagationTargets, SerializedTraceData } from './tracing';
export type { StartSpanOptions } from './startSpanOptions';
export type {
TraceparentData,
Expand Down
9 changes: 9 additions & 0 deletions packages/types/src/tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@ export interface PropagationContext {
*/
dsc?: Partial<DynamicSamplingContext>;
}

/**
* An object holding trace data, like span and trace ids, sampling decision, and dynamic sampling context
* in a serialized form. Both keys are expected to be used as Http headers or Html meta tags.
*/
export interface SerializedTraceData {
'sentry-trace'?: string;
baggage?: string;
}

0 comments on commit 3ce020d

Please sign in to comment.