From a318bccc75d09f4d990bbbca3bdf58a308970912 Mon Sep 17 00:00:00 2001 From: Purvi Kanal Date: Thu, 16 Jan 2025 11:24:13 -0500 Subject: [PATCH 1/2] instr-fetch: config cleanup and order alphabetically --- .../src/fetch.ts | 27 +++++++++++-------- .../packages/otlp-grpc-exporter-base/protos | 1 + .../packages/otlp-proto-exporter-base/protos | 1 + 3 files changed, 18 insertions(+), 11 deletions(-) create mode 160000 experimental/packages/otlp-grpc-exporter-base/protos create mode 160000 experimental/packages/otlp-proto-exporter-base/protos diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts b/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts index 6a41c5337db..45a084fc529 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts +++ b/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts @@ -58,26 +58,31 @@ export interface FetchCustomAttributeFunction { * FetchPlugin Config */ export interface FetchInstrumentationConfig extends InstrumentationConfig { - // the number of timing resources is limited, after the limit - // (chrome 250, safari 150) the information is not collected anymore - // the only way to prevent that is to regularly clean the resources - // whenever it is possible, this is needed only when PerformanceObserver - // is not available + /** Function for adding custom attributes on the span */ + applyCustomAttributesOnSpan?: FetchCustomAttributeFunction; + + /** the number of timing resources is limited, after the limit + (chrome 250, safari 150) the information is not collected anymore + the only way to prevent that is to regularly clean the resources + whenever it is possible, this is needed only when PerformanceObserver + is not available */ clearTimingResources?: boolean; - // urls which should include trace headers when origin doesn't match - propagateTraceHeaderCorsUrls?: web.PropagateTraceHeaderCorsUrls; + + /** Ignore adding network events as span events */ + ignoreNetworkEvents?: boolean; + /** * URLs that partially match any regex in ignoreUrls will not be traced. * In addition, URLs that are _exact matches_ of strings in ignoreUrls will * also not be traced. */ ignoreUrls?: Array; - /** Function for adding custom attributes on the span */ - applyCustomAttributesOnSpan?: FetchCustomAttributeFunction; - // Ignore adding network events as span events - ignoreNetworkEvents?: boolean; + /** Measure outgoing request size */ measureRequestSize?: boolean; + + /** urls which should include trace headers when origin doesn't match */ + propagateTraceHeaderCorsUrls?: web.PropagateTraceHeaderCorsUrls; } /** diff --git a/experimental/packages/otlp-grpc-exporter-base/protos b/experimental/packages/otlp-grpc-exporter-base/protos new file mode 160000 index 00000000000..1608f92cf08 --- /dev/null +++ b/experimental/packages/otlp-grpc-exporter-base/protos @@ -0,0 +1 @@ +Subproject commit 1608f92cf08119f9aec237c910b200d1317ec696 diff --git a/experimental/packages/otlp-proto-exporter-base/protos b/experimental/packages/otlp-proto-exporter-base/protos new file mode 160000 index 00000000000..1608f92cf08 --- /dev/null +++ b/experimental/packages/otlp-proto-exporter-base/protos @@ -0,0 +1 @@ +Subproject commit 1608f92cf08119f9aec237c910b200d1317ec696 From 6aaf31804c0dee1086b046abe156d191015a0263 Mon Sep 17 00:00:00 2001 From: Purvi Kanal Date: Mon, 20 Jan 2025 14:34:07 -0500 Subject: [PATCH 2/2] add config options for request and response header attributes --- .../src/fetch.ts | 62 +++++++++++++++++++ .../test/fetch.test.ts | 19 ++++++ 2 files changed, 81 insertions(+) diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts b/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts index 45a084fc529..da5822a0360 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts +++ b/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts @@ -32,6 +32,8 @@ import { SEMATTRS_HTTP_URL, SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED, + ATTR_HTTP_REQUEST_HEADER, + ATTR_HTTP_RESPONSE_HEADER, } from '@opentelemetry/semantic-conventions'; import { FetchError, FetchResponse, SpanData } from './types'; import { getFetchBodyLength } from './utils'; @@ -68,6 +70,12 @@ export interface FetchInstrumentationConfig extends InstrumentationConfig { is not available */ clearTimingResources?: boolean; + /** List of request headers to include as attributes on the span. */ + requestHeadersAsAttributes?: string[]; + + /** List of request headers to include as attributes on the span. */ + responseHeadersAsAttributes?: string[]; + /** Ignore adding network events as span events */ ignoreNetworkEvents?: boolean; @@ -348,8 +356,20 @@ export class FetchInstrumentation extends InstrumentationBase= 200 && response.status < 400) { plugin._endSpan(span, spanData, response); } else { @@ -440,6 +476,32 @@ export class FetchInstrumentation extends InstrumentationBase { + const value = requestHeaders.get(header); + if (value) { + span.setAttribute(ATTR_HTTP_REQUEST_HEADER(header), value); + } + }); + } + + private _applyResponseHeadersAsAttributes( + span: api.Span, + headersToInclude: string[], + responseHeaders: Headers + ) { + headersToInclude.forEach(header => { + const value = responseHeaders.get(header); + if (value) { + span.setAttribute(ATTR_HTTP_RESPONSE_HEADER(header), value); + } + }); + } + private _applyAttributesAfterFetch( span: api.Span, request: Request | RequestInit, diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/test/fetch.test.ts b/experimental/packages/opentelemetry-instrumentation-fetch/test/fetch.test.ts index f81336ae4f6..ce21aa077ed 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/test/fetch.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-fetch/test/fetch.test.ts @@ -50,6 +50,7 @@ import { SEMATTRS_HTTP_URL, SEMATTRS_HTTP_USER_AGENT, SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED, + ATTR_HTTP_REQUEST_HEADER, } from '@opentelemetry/semantic-conventions'; class DummySpanExporter implements tracing.SpanExporter { @@ -1222,4 +1223,22 @@ describe('fetch', () => { ); }); }); + + describe('when request headers are applied as attributes', () => { + afterEach(() => { + clearData(); + }); + + it('applies request headers supplied in config', async () => { + await prepareData(url, () => getData(url), { + requestHeadersAsAttributes: ['foo', 'Content-Type'], + }); + const span: tracing.ReadableSpan = exportSpy.args[1][0][0]; + assert.ok(span.attributes[ATTR_HTTP_REQUEST_HEADER('foo')] === 'bar'); + assert.ok( + span.attributes[ATTR_HTTP_REQUEST_HEADER('Content-Type')] === + 'application/json' + ); + }); + }); });