Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(instrumentation-http): Add API for adding custom metric attributes #4108

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Http instrumentation has few options available to choose from. You can set the f
| [`startOutgoingSpanHook`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-http/src/types.ts#L99) | `StartOutgoingSpanCustomAttributeFunction` | Function for adding custom attributes before a span is started in outgoingRequest |
| `ignoreIncomingRequestHook` | `IgnoreIncomingRequestFunction` | Http instrumentation will not trace all incoming requests that matched with custom function |
| `ignoreOutgoingRequestHook` | `IgnoreOutgoingRequestFunction` | Http instrumentation will not trace all outgoing requests that matched with custom function |
| `customMetricAttributes` | `CustomMetricAttributeFunction` | Function for adding custom metric attributes on all recorded metrics |
| [`serverName`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-http/src/types.ts#L101) | `string` | The primary server name of the matched virtual host. |
| [`requireParentforOutgoingSpans`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-http/src/types.ts#L103) | Boolean | Require that is a parent span to create new span for outgoing requests. |
| [`requireParentforIncomingSpans`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-http/src/types.ts#L105) | Boolean | Require that is a parent span to create new span for incoming requests. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
SpanStatusCode,
trace,
Histogram,
MetricAttributes,
Attributes,
ValueType,
} from '@opentelemetry/api';
import {
Expand Down Expand Up @@ -310,7 +310,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
request: http.ClientRequest,
span: Span,
startTime: HrTime,
metricAttributes: MetricAttributes
metricAttributes: Attributes
): http.ClientRequest {
if (this._getConfig().requestHook) {
this._callRequestHook(span, request);
Expand Down Expand Up @@ -376,7 +376,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
if (this._getConfig().applyCustomAttributesOnSpan) {
safeExecuteInTheMiddle(
() =>
this._getConfig().applyCustomAttributesOnSpan!(
this._getConfig().applyCustomAttributesOnSpan?.(
span,
request,
response
Expand Down Expand Up @@ -512,8 +512,15 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
};

const startTime = hrTime();
const metricAttributes =
utils.getIncomingRequestMetricAttributes(spanAttributes);
const customMetricAttributes = safeExecuteInTheMiddle(
() => instrumentation._getConfig().customMetricAttributes?.(),
() => {},
true
);
const metricAttributes: Attributes = Object.assign(
utils.getIncomingRequestMetricAttributes(spanAttributes),
customMetricAttributes
);

const ctx = propagation.extract(ROOT_CONTEXT, headers);
const span = instrumentation._startHttpSpan(method, spanOptions, ctx);
Expand Down Expand Up @@ -658,8 +665,15 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
});

const startTime = hrTime();
const metricAttributes: MetricAttributes =
utils.getOutgoingRequestMetricAttributes(attributes);
const customMetricAttributes = safeExecuteInTheMiddle(
() => instrumentation._getConfig().customMetricAttributes?.(),
() => {},
true
);
const metricAttributes: Attributes = Object.assign(
utils.getOutgoingRequestMetricAttributes(attributes),
customMetricAttributes
);

const spanOptions: SpanOptions = {
kind: SpanKind.CLIENT,
Expand Down Expand Up @@ -719,7 +733,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
request: http.IncomingMessage,
response: http.ServerResponse,
span: Span,
metricAttributes: MetricAttributes,
metricAttributes: Attributes,
startTime: HrTime
) {
const attributes = utils.getIncomingRequestAttributesOnResponse(
Expand Down Expand Up @@ -747,7 +761,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
if (this._getConfig().applyCustomAttributesOnSpan) {
safeExecuteInTheMiddle(
() =>
this._getConfig().applyCustomAttributesOnSpan!(
this._getConfig().applyCustomAttributesOnSpan?.(
span,
request,
response
Expand All @@ -762,7 +776,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {

private _onServerResponseError(
span: Span,
metricAttributes: MetricAttributes,
metricAttributes: Attributes,
startTime: HrTime,
error: Err
) {
Expand Down Expand Up @@ -802,7 +816,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
span: Span,
spanKind: SpanKind,
startTime: HrTime,
metricAttributes: MetricAttributes
metricAttributes: Attributes
) {
if (!this._spanNotEnded.has(span)) {
return;
Expand All @@ -825,7 +839,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
response: http.IncomingMessage | http.ServerResponse
) {
safeExecuteInTheMiddle(
() => this._getConfig().responseHook!(span, response),
() => this._getConfig().responseHook?.(span, response),
() => {},
true
);
Expand All @@ -836,7 +850,7 @@ export class HttpInstrumentation extends InstrumentationBase<Http> {
request: http.ClientRequest | http.IncomingMessage
) {
safeExecuteInTheMiddle(
() => this._getConfig().requestHook!(span, request),
() => this._getConfig().requestHook?.(span, request),
() => {},
true
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Span, SpanAttributes } from '@opentelemetry/api';
import { Attributes, Span } from '@opentelemetry/api';
import type * as http from 'http';
import type * as https from 'https';
import {
Expand Down Expand Up @@ -73,11 +73,15 @@ export interface HttpResponseCustomAttributeFunction {
}

export interface StartIncomingSpanCustomAttributeFunction {
(request: IncomingMessage): SpanAttributes;
(request: IncomingMessage): Attributes;
}

export interface StartOutgoingSpanCustomAttributeFunction {
(request: RequestOptions): SpanAttributes;
(request: RequestOptions): Attributes;
}

export interface CustomMetricAttributeFunction {
(): Attributes;
}

/**
Expand Down Expand Up @@ -108,6 +112,8 @@ export interface HttpInstrumentationConfig extends InstrumentationConfig {
startIncomingSpanHook?: StartIncomingSpanCustomAttributeFunction;
/** Function for adding custom attributes before a span is started in outgoingRequest */
startOutgoingSpanHook?: StartOutgoingSpanCustomAttributeFunction;
/** Function for adding custom metric attributes on all recorded metrics */
customMetricAttributes?: CustomMetricAttributeFunction;
/** The primary server name of the matched virtual host. */
serverName?: string;
/** Require parent to create span for outgoing requests */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ import { HttpInstrumentation } from '../../src/http';
import { httpRequest } from '../utils/httpRequest';
import { TestMetricReader } from '../utils/TestMetricReader';

const instrumentation = new HttpInstrumentation();
const instrumentation = new HttpInstrumentation({
customMetricAttributes: () => {
return {
foo: 'bar',
};
},
});

instrumentation.enable();
instrumentation.disable();

Expand Down Expand Up @@ -115,6 +122,8 @@ describe('metrics', () => {
metrics[0].dataPoints[0].attributes[SemanticAttributes.NET_HOST_PORT],
22346
);
// Custom attributes
assert.strictEqual(metrics[0].dataPoints[0].attributes['foo'], 'bar');

assert.strictEqual(metrics[1].dataPointType, DataPointType.HISTOGRAM);
assert.strictEqual(
Expand Down Expand Up @@ -148,5 +157,7 @@ describe('metrics', () => {
metrics[1].dataPoints[0].attributes[SemanticAttributes.HTTP_FLAVOR],
'1.1'
);
// Custom attributes
assert.strictEqual(metrics[1].dataPoints[0].attributes['foo'], 'bar');
});
});