diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts index 15ca92a45e..0f50b9fb86 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/http.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/http.ts @@ -512,8 +512,15 @@ export class HttpInstrumentation extends InstrumentationBase { }; const startTime = hrTime(); - const metricAttributes = - utils.getIncomingRequestMetricAttributes(spanAttributes); + const metricAttributes = utils.getIncomingRequestMetricAttributes( + spanAttributes, + request, + { + ignoreHostMetricAttribute: + instrumentation._getConfig() + .ignoreIncomingRequestHostMetricAttribute, + } + ); const ctx = propagation.extract(ROOT_CONTEXT, headers); const span = instrumentation._startHttpSpan(method, spanOptions, ctx); diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/types.ts b/experimental/packages/opentelemetry-instrumentation-http/src/types.ts index 5cc09341d4..3de2ffb924 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/types.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/types.ts @@ -60,6 +60,10 @@ export interface IgnoreIncomingRequestFunction { (request: IncomingMessage): boolean; } +export interface IgnoreIncomingRequestHostFunction { + (request: IncomingMessage, host: string): boolean; +} + export interface IgnoreOutgoingRequestFunction { (request: RequestOptions): boolean; } @@ -119,6 +123,8 @@ export interface HttpInstrumentationConfig extends InstrumentationConfig { client?: { requestHeaders?: string[]; responseHeaders?: string[] }; server?: { requestHeaders?: string[]; responseHeaders?: string[] }; }; + /** Function for adding filtering for incoming requests' host name which may have unbounded cardinality */ + ignoreIncomingRequestHostMetricAttribute?: IgnoreIncomingRequestHostFunction; } export interface Err extends Error { diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts index a563e29471..1ade18af8a 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts @@ -35,7 +35,12 @@ import { import { getRPCMetadata, RPCType } from '@opentelemetry/core'; import * as url from 'url'; import { AttributeNames } from './enums/AttributeNames'; -import { Err, IgnoreMatcher, ParsedRequestOptions } from './types'; +import { + Err, + IgnoreIncomingRequestHostFunction, + IgnoreMatcher, + ParsedRequestOptions, +} from './types'; /** * Get an absolute url @@ -499,21 +504,35 @@ export const getIncomingRequestAttributes = ( /** * Returns incoming request Metric attributes scoped to the request data * @param {SpanAttributes} spanAttributes the span attributes - * @param {{ component: string }} options used to pass data needed to create attributes + * @param {IncomingMessage} request the request object + * @param {{ ignoreHostMetricAttribute?: IgnoreIncomingRequestHostFunction }} options used to pass data needed to create attributes */ export const getIncomingRequestMetricAttributes = ( - spanAttributes: SpanAttributes + spanAttributes: SpanAttributes, + request: IncomingMessage, + options: { ignoreHostMetricAttribute?: IgnoreIncomingRequestHostFunction } ): MetricAttributes => { const metricAttributes: MetricAttributes = {}; metricAttributes[SemanticAttributes.HTTP_SCHEME] = spanAttributes[SemanticAttributes.HTTP_SCHEME]; metricAttributes[SemanticAttributes.HTTP_METHOD] = spanAttributes[SemanticAttributes.HTTP_METHOD]; - metricAttributes[SemanticAttributes.NET_HOST_NAME] = - spanAttributes[SemanticAttributes.NET_HOST_NAME]; metricAttributes[SemanticAttributes.HTTP_FLAVOR] = spanAttributes[SemanticAttributes.HTTP_FLAVOR]; - //TODO: http.target attribute, it should susbtitute any parameters to avoid high cardinality. + + // The span attributes set this from the request URL or the Host header which does not have bounded cardinality + const netHostNameAttributeValue = + spanAttributes[SemanticAttributes.NET_HOST_NAME]; + if ( + typeof options.ignoreHostMetricAttribute !== 'function' || + (typeof netHostNameAttributeValue === 'string' && + !options.ignoreHostMetricAttribute(request, netHostNameAttributeValue)) + ) { + metricAttributes[SemanticAttributes.NET_HOST_NAME] = + netHostNameAttributeValue; + } + + //TODO: http.target attribute, it should substitute any parameters to avoid high cardinality. return metricAttributes; }; diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts index 35b3c1ab5b..4001335355 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/utils.test.ts @@ -311,7 +311,7 @@ describe('Utility', () => { ); }); - it('should succesfully process without middleware stack', () => { + it('should successfully process without middleware stack', () => { const request = { socket: {}, } as IncomingMessage;