Skip to content

Commit

Permalink
Pass graphql information to native SDKs
Browse files Browse the repository at this point in the history
  • Loading branch information
louiszawadzki committed Sep 21, 2023
1 parent b45680a commit f08502c
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,29 @@ export class ResourceReporter {
}

const formatResourceStartContext = (
tracingAttributes: RUMResource['tracingAttributes']
): Record<string, string | number> | undefined => {
return tracingAttributes.samplingPriorityHeader === '0'
? undefined
: {
'_dd.span_id': tracingAttributes.spanId.toString(10),
'_dd.trace_id': tracingAttributes.traceId.toString(10),
'_dd.rule_psr': tracingAttributes.rulePsr
};
tracingAttributes: RUMResource['tracingAttributes'],
graphqlAttributes: RUMResource['graphqlAttributes']
): Record<string, string | number> => {
const attributes: Record<string, string | number> = {};
if (tracingAttributes.samplingPriorityHeader !== '0') {
attributes['_dd.span_id'] = tracingAttributes.spanId.toString(10);
attributes['_dd.trace_id'] = tracingAttributes.traceId.toString(10);
attributes['_dd.rule_psr'] = tracingAttributes.rulePsr;
}

if (graphqlAttributes?.operationType) {
attributes['_dd.graphql.operation_type'] =
graphqlAttributes.operationType;
if (graphqlAttributes.operationName) {
attributes['_dd.graphql.operation_name'] =
graphqlAttributes.operationName;
}
if (graphqlAttributes.variables) {
attributes['_dd.graphql.variables'] = graphqlAttributes.variables;
}
}

return attributes;
};

const formatResourceStopContext = (
Expand All @@ -64,7 +78,10 @@ const reportResource = async (resource: RUMResource) => {
resource.key,
resource.request.method,
resource.request.url,
formatResourceStartContext(resource.tracingAttributes),
formatResourceStartContext(
resource.tracingAttributes,
resource.graphqlAttributes
),
resource.timings.startTime
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ interface DdRumXhr extends XMLHttpRequest {
}

interface DdRumXhrContext {
graphql: {
operationType?: string;
operationName?: string;
variables?: string;
};
method: string;
url: string;
reported: boolean;
Expand Down Expand Up @@ -99,6 +104,7 @@ const proxyOpen = (
url,
reported: false,
timer: new Timer(),
graphql: {},
tracingAttributes: getTracingAttributes({
hostname,
firstPartyHostsRegexMap,
Expand Down Expand Up @@ -177,6 +183,7 @@ const reportXhr = async (
url: context.url,
kind: 'xhr'
},
graphqlAttributes: context.graphql,
tracingAttributes: context.tracingAttributes,
response: {
statusCode: xhrProxy.status,
Expand Down Expand Up @@ -204,15 +211,15 @@ const proxySetRequestHeader = (providers: XHRProxyProviders): void => {
) {
if (isDatadogCustomHeader(header)) {
if (header === DATADOG_GRAPH_QL_OPERATION_NAME_HEADER) {
// TODO: add information to request
this._datadog_xhr.graphql.operationName = value;
return;
}
if (header === DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER) {
// TODO: add information to request
this._datadog_xhr.graphql.operationType = value;
return;
}
if (header === DATADOG_GRAPH_QL_VARIABLES_HEADER) {
// TODO: add information to request
this._datadog_xhr.graphql.variables = value;
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ import {
ORIGIN_HEADER_KEY
} from '../../../distributedTracing/distributedTracingHeaders';
import { firstPartyHostsRegexMapBuilder } from '../../../distributedTracing/firstPartyHosts';
import {
DATADOG_GRAPH_QL_OPERATION_NAME_HEADER,
DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER,
DATADOG_GRAPH_QL_VARIABLES_HEADER
} from '../../../graphql/graphqlHeaders';
import { ResourceReporter } from '../DatadogRumResource/ResourceReporter';
import { XHRProxy } from '../XHRProxy';
import {
Expand Down Expand Up @@ -77,7 +82,7 @@ afterEach(() => {
DdRum.unregisterResourceEventMapper();
});

describe('XHRPr', () => {
describe('XHRProxy', () => {
describe('resource interception', () => {
it('intercepts XHR request when startTracking() + XHR.open() + XHR.send()', async () => {
// GIVEN
Expand Down Expand Up @@ -1045,4 +1050,126 @@ describe('XHRPr', () => {
expect(size).toEqual(-1);
});
});

describe('setRequestHeader', () => {
it('sets graphql attributes and drops corresponding headers', async () => {
// GIVEN
const method = 'POST';
const url = 'https://api.example.com/graphql';
xhrProxy.onTrackingStart({
tracingSamplingRate: 100,
firstPartyHostsRegexMap: firstPartyHostsRegexMapBuilder([])
});

// WHEN
const xhr = new XMLHttpRequestMock();
xhr.open(method, url);
xhr.setRequestHeader(
DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER,
'query'
);
xhr.setRequestHeader(
DATADOG_GRAPH_QL_OPERATION_NAME_HEADER,
'cats'
);
xhr.setRequestHeader(DATADOG_GRAPH_QL_VARIABLES_HEADER, '{}');
xhr.send();
xhr.abort();
xhr.complete(0, undefined);
await flushPromises();

// THEN
const attributes = DdNativeRum.startResource.mock.calls[0][3];
expect(attributes['_dd.graphql.operation_type']).toEqual('query');
expect(attributes['_dd.graphql.operation_name']).toEqual('cats');
expect(attributes['_dd.graphql.variables']).toEqual('{}');

expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER]
).not.toBeDefined();
expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_OPERATION_NAME_HEADER]
).not.toBeDefined();
expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_VARIABLES_HEADER]
).not.toBeDefined();
});

it('sets graphql attributes and drops corresponding headers when operation name and variables are missing', async () => {
// GIVEN
const method = 'POST';
const url = 'https://api.example.com/graphql';
xhrProxy.onTrackingStart({
tracingSamplingRate: 100,
firstPartyHostsRegexMap: firstPartyHostsRegexMapBuilder([])
});

// WHEN
const xhr = new XMLHttpRequestMock();
xhr.open(method, url);
xhr.setRequestHeader(
DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER,
'query'
);
xhr.send();
xhr.abort();
xhr.complete(0, undefined);
await flushPromises();

// THEN
const attributes = DdNativeRum.startResource.mock.calls[0][3];
expect(attributes['_dd.graphql.operation_type']).toEqual('query');
expect(attributes['_dd.graphql.operation_name']).not.toBeDefined();
expect(attributes['_dd.graphql.variables']).not.toBeDefined();

expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER]
).not.toBeDefined();
expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_OPERATION_NAME_HEADER]
).not.toBeDefined();
expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_VARIABLES_HEADER]
).not.toBeDefined();
});

it('does not set graphql attributes but drops corresponding headers when operation type is missing', async () => {
// GIVEN
const method = 'POST';
const url = 'https://api.example.com/graphql';
xhrProxy.onTrackingStart({
tracingSamplingRate: 100,
firstPartyHostsRegexMap: firstPartyHostsRegexMapBuilder([])
});

// WHEN
const xhr = new XMLHttpRequestMock();
xhr.open(method, url);
xhr.setRequestHeader(
DATADOG_GRAPH_QL_OPERATION_NAME_HEADER,
'cats'
);
xhr.setRequestHeader(DATADOG_GRAPH_QL_VARIABLES_HEADER, '{}');
xhr.send();
xhr.abort();
xhr.complete(0, undefined);
await flushPromises();

// THEN
const attributes = DdNativeRum.startResource.mock.calls[0][3];
expect(attributes['_dd.graphql.operation_type']).not.toBeDefined();
expect(attributes['_dd.graphql.operation_name']).not.toBeDefined();
expect(attributes['_dd.graphql.variables']).not.toBeDefined();

expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_OPERATION_TYPE_HEADER]
).not.toBeDefined();
expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_OPERATION_NAME_HEADER]
).not.toBeDefined();
expect(
xhr.requestHeaders[DATADOG_GRAPH_QL_VARIABLES_HEADER]
).not.toBeDefined();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface RUMResource {
kind: ResourceKind;
};
tracingAttributes: DdRumResourceTracingAttributes;
graphqlAttributes?: DdRumResourceGraphqlAttributes;
response: {
statusCode: number;
size: number;
Expand All @@ -26,3 +27,9 @@ export interface RUMResource {
};
resourceContext?: XMLHttpRequest;
}

export type DdRumResourceGraphqlAttributes = {
operationType?: string;
operationName?: string;
variables?: string;
};

0 comments on commit f08502c

Please sign in to comment.