Skip to content

Commit

Permalink
feat(add-option-to-disable-instrumentation-http-metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
AkselAllas committed Oct 1, 2024
1 parent 3007d3e commit d918ac6
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 2 deletions.
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ All notable changes to experimental packages in this project will be documented
* Applies to both client and server spans
* Generate spans compliant with Semantic Conventions 1.27+ when `OTEL_SEMCONV_STABILITY_OPT_IN` contains `http` or `http/dup`
* Generate spans backwards compatible with previous attributes when `OTEL_SEMCONV_STABILITY_OPT_IN` contains `http/dup` or DOES NOT contain `http`
* feat(add-option-to-disable-instrumentation-http-metrics): Add option to disable instrumentation-http metrics such as incoming or outgoing HTTP request duration [#4409](https://github.com/open-telemetry/opentelemetry-js/pull/5029) @AkselAllas

### :bug: (Bug Fix)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Http instrumentation has few options available to choose from. You can set the f
| `ignoreOutgoingRequestHook` | `IgnoreOutgoingRequestFunction` | Http instrumentation will not trace all outgoing requests that matched with custom function |
| `disableOutgoingRequestInstrumentation` | `boolean` | Set to true to avoid instrumenting outgoing requests at all. This can be helpful when another instrumentation handles outgoing requests. |
| `disableIncomingRequestInstrumentation` | `boolean` | Set to true to avoid instrumenting incoming requests at all. This can be helpful when another instrumentation handles incoming requests. |
| `disableMetrics` | `boolean` | Set to true in order to disable instrumentation-http from emitting any metrics such as duration of inbound/outbound HTTP requests. |
| [`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 @@ -88,6 +88,7 @@ export class HttpInstrumentation extends InstrumentationBase<HttpInstrumentation
/** keep track on spans not ended */
private readonly _spanNotEnded: WeakSet<Span> = new WeakSet<Span>();
private _headerCapture;
private _disableMetrics: boolean;
private _httpServerDurationHistogram!: Histogram;
private _httpClientDurationHistogram!: Histogram;

Expand All @@ -96,6 +97,7 @@ export class HttpInstrumentation extends InstrumentationBase<HttpInstrumentation
constructor(config: HttpInstrumentationConfig = {}) {
super('@opentelemetry/instrumentation-http', VERSION, config);
this._headerCapture = this._createHeaderCapture();
this._disableMetrics = this.getConfig().disableMetrics || false;

for (const entry in getEnv().OTEL_SEMCONV_STABILITY_OPT_IN) {
if (entry.toLowerCase() === 'http/dup') {
Expand Down Expand Up @@ -851,9 +853,9 @@ export class HttpInstrumentation extends InstrumentationBase<HttpInstrumentation

// Record metrics
const duration = hrTimeToMilliseconds(hrTimeDuration(startTime, hrTime()));
if (spanKind === SpanKind.SERVER) {
if (spanKind === SpanKind.SERVER && !this._disableMetrics) {
this._httpServerDurationHistogram.record(duration, metricAttributes);
} else if (spanKind === SpanKind.CLIENT) {
} else if (spanKind === SpanKind.CLIENT && !this._disableMetrics) {
this._httpClientDurationHistogram.record(duration, metricAttributes);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ export interface HttpInstrumentationConfig extends InstrumentationConfig {
disableIncomingRequestInstrumentation?: boolean;
/** If set to true, outgoing requests will not be instrumented at all. */
disableOutgoingRequestInstrumentation?: boolean;
/** If set to true, no metrics will be emitted */
disableMetrics?: boolean;
/** Function for adding custom attributes after response is handled */
applyCustomAttributesOnSpan?: HttpCustomAttributeFunction;
/** Function for adding custom attributes before request is handled */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
AggregationTemporality,
InMemoryMetricExporter,
MeterProvider,
} from '@opentelemetry/sdk-metrics';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import * as assert from 'assert';
import { HttpInstrumentation } from '../../src/http';
import { httpRequest } from '../utils/httpRequest';
import { TestMetricReader } from '../utils/TestMetricReader';

const instrumentation = new HttpInstrumentation({ disableMetrics: true });
instrumentation.enable();
instrumentation.disable();

import * as http from 'http';

let server: http.Server;
const serverPort = 22346;
const protocol = 'http';
const hostname = 'localhost';
const pathname = '/test';
const tracerProvider = new NodeTracerProvider();
const metricsMemoryExporter = new InMemoryMetricExporter(
AggregationTemporality.DELTA
);
const metricReader = new TestMetricReader(metricsMemoryExporter);
const meterProvider = new MeterProvider({ readers: [metricReader] });

instrumentation.setTracerProvider(tracerProvider);
instrumentation.setMeterProvider(meterProvider);

describe('metrics can be disabled', () => {
beforeEach(() => {
metricsMemoryExporter.reset();
});

before(() => {
instrumentation.enable();
server = http.createServer((request, response) => {
response.end('Test Server Response');
});
server.listen(serverPort);
});

after(() => {
server.close();
instrumentation.disable();
});

it('should not create server/client duration metrics', async () => {
const requestCount = 3;
for (let i = 0; i < requestCount; i++) {
await httpRequest.get(
`${protocol}://${hostname}:${serverPort}${pathname}`
);
}
await metricReader.collectAndExport();
const resourceMetrics = metricsMemoryExporter.getMetrics();
const scopeMetrics = resourceMetrics[0].scopeMetrics;
assert.strictEqual(scopeMetrics.length, 0, 'scopeMetrics count');
});
});

0 comments on commit d918ac6

Please sign in to comment.