Skip to content

Commit 7565bf5

Browse files
authored
chore(bff): filter noisy GraphQL parse/validate spans (#3777)
1 parent 0d76c07 commit 7565bf5

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

packages/bff/src/instrumentation.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { IncomingMessage } from 'node:http';
22
import { logger } from '@altinn/dialogporten-node-logger';
33
import { FastifyOtelInstrumentation } from '@fastify/otel';
4+
import type { Context } from '@opentelemetry/api';
45
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
56
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
67
import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql';
@@ -10,11 +11,28 @@ import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
1011
import { resourceFromAttributes } from '@opentelemetry/resources';
1112
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
1213
import { NodeSDK } from '@opentelemetry/sdk-node';
13-
import { ParentBasedSampler, TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-base';
14+
import {
15+
BatchSpanProcessor,
16+
ParentBasedSampler,
17+
type ReadableSpan,
18+
type Span,
19+
type SpanProcessor,
20+
TraceIdRatioBasedSampler,
21+
} from '@opentelemetry/sdk-trace-base';
1422
import { ATTR_SERVICE_NAME, SEMRESATTRS_SERVICE_INSTANCE_ID } from '@opentelemetry/semantic-conventions';
1523
import config from './config.ts';
1624

1725
const { openTelemetry } = config;
26+
const spansExcludedFromExport = new Set([
27+
'graphql.parse',
28+
'graphql.validate',
29+
'graphql.parseSchema',
30+
'graphql.validateSchema',
31+
]);
32+
33+
const shouldDropSpanByName = (spanName: string): boolean => {
34+
return spansExcludedFromExport.has(spanName);
35+
};
1836

1937
// Configure HTTP instrumentation with filtering
2038
const httpInstrumentationConfig: HttpInstrumentationConfig = {
@@ -58,6 +76,29 @@ const resource = resourceFromAttributes({
5876
[SEMRESATTRS_SERVICE_INSTANCE_ID]: config.info.instanceId || 'local-dev',
5977
});
6078

79+
class SpanNameFilteringProcessor implements SpanProcessor {
80+
constructor(private readonly delegate: SpanProcessor) {}
81+
82+
onStart(span: Span, parentContext: Context): void {
83+
this.delegate.onStart(span, parentContext);
84+
}
85+
86+
onEnd(span: ReadableSpan): void {
87+
if (shouldDropSpanByName(span.name)) {
88+
return;
89+
}
90+
this.delegate.onEnd(span);
91+
}
92+
93+
forceFlush(): Promise<void> {
94+
return this.delegate.forceFlush();
95+
}
96+
97+
shutdown(): Promise<void> {
98+
return this.delegate.shutdown();
99+
}
100+
}
101+
61102
const initializeOpenTelemetry = () => {
62103
try {
63104
if (!config.openTelemetry.enabled) {
@@ -78,6 +119,7 @@ const initializeOpenTelemetry = () => {
78119
const sampler = new ParentBasedSampler({
79120
root: new TraceIdRatioBasedSampler(openTelemetry.sampleRate),
80121
});
122+
const spanProcessor: SpanProcessor = new SpanNameFilteringProcessor(new BatchSpanProcessor(traceExporter));
81123

82124
logger.info(
83125
{
@@ -93,7 +135,7 @@ const initializeOpenTelemetry = () => {
93135
// Initialize NodeSDK
94136
const sdk = new NodeSDK({
95137
resource,
96-
traceExporter,
138+
spanProcessors: [spanProcessor],
97139
metricReaders: [metricReader],
98140
instrumentations,
99141
sampler,

0 commit comments

Comments
 (0)