diff --git a/plugins/node/instrumentation-undici/README.md b/plugins/node/instrumentation-undici/README.md index e0d9f8d158..22763ad27e 100644 --- a/plugins/node/instrumentation-undici/README.md +++ b/plugins/node/instrumentation-undici/README.md @@ -57,6 +57,7 @@ Undici instrumentation has few options available to choose from. You can set the | [`startSpanHook`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/instrumentation-undici/src/types.ts#L79) | `StartSpanHookFunction` | Function for adding custom attributes before a span is started. | | [`requireParentforSpans`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/instrumentation-undici/src/types.ts#L81) | `Boolean` | Require a parent span is present to create new span for outgoing requests. | | [`headersToSpanAttributes`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/instrumentation-undici/src/types.ts#L83) | `Object` | List of case insensitive HTTP headers to convert to span attributes. Headers will be converted to span attributes in the form of `http.{request\|response}.header.header-name` where the name is only lowercased, e.g. `http.response.header.content-length` | +| [`requestMetricAttributesHook`](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/instrumentation-undici/src/types.ts#L85) | `RequestMetricAttributesHookFunction` | Function for adding custom attributes to metrics based on request. | ### Observations diff --git a/plugins/node/instrumentation-undici/src/types.ts b/plugins/node/instrumentation-undici/src/types.ts index 0b56998e6b..fc5105ea82 100644 --- a/plugins/node/instrumentation-undici/src/types.ts +++ b/plugins/node/instrumentation-undici/src/types.ts @@ -63,6 +63,12 @@ export interface StartSpanHookFunction { (request: T): Attributes; } +export interface RequestMetricAttributesHookFunction< + RequestType = UndiciRequest +> { + (request: RequestType): Attributes; +} + // This package will instrument HTTP requests made through `undici` or `fetch` global API // so it seems logical to have similar options than the HTTP instrumentation export interface UndiciInstrumentationConfig< @@ -84,4 +90,6 @@ export interface UndiciInstrumentationConfig< requestHeaders?: string[]; responseHeaders?: string[]; }; + /** Function for adding custom attributes to metrics based on request */ + requestMetricAttributesHook?: RequestMetricAttributesHookFunction; } diff --git a/plugins/node/instrumentation-undici/src/undici.ts b/plugins/node/instrumentation-undici/src/undici.ts index 949b1e11c7..82a4ae71cf 100644 --- a/plugins/node/instrumentation-undici/src/undici.ts +++ b/plugins/node/instrumentation-undici/src/undici.ts @@ -430,7 +430,7 @@ export class UndiciInstrumentation extends InstrumentationBase config.requestMetricAttributesHook?.(request), + e => e && this._diag.error('caught requestMetricAttributesHook error: ', e), + true + ); + if (customAttributes) { + Object.entries(customAttributes).forEach(([key, val]) => { + metricsAttributes[key] = val; + }); + } + // Take the duration and record it const durationSeconds = hrTimeToMilliseconds(hrTimeDuration(startTime, hrTime())) / 1000;