Skip to main content

Configuring Instrumentation

There are several things worth mentioning about SDK configuration.

Instrumentation​

We need to understand what instrumentation is, where we define it, and how we can modify or configure it if necessary.

Instrumentation is the part of the code in OpenTelemetry that will generate spans (intervals) and metrics for us. We've already seen that when we receive an HTTP call, a span is created automatically, which means there's a part of the OpenTelemetry code that connects to the HTTP module and observes when it receives and responds to a request and based on that creates its own span.

This happened exactly at this moment in our project.

  const instrumentations = [
getNodeAutoInstrumentations({
"@opentelemetry/instrumentation-express": {},
"@opentelemetry/instrumentation-ioredis": {},
"@opentelemetry/instrumentation-http": {},
"@opentelemetry/instrumentation-dns": {},
"@opentelemetry/instrumentation-net": {},
"@opentelemetry/instrumentation-fs": {},
}),
];

const sdk = new NodeSDK({
resource,
traceExporter,
instrumentations,
});

To keep it simple, in the new NodeSDK part we instantiate all the instrumentation before and below we just use it, but it could have been simplified, as in the code below, using the @opentelemetry/auto-instrumentations-node library in its standard way.

  const sdk = new NodeSDK({
resource,
traceExporter,
instrumentations: [getNodeAutoInstrumentations()]
});

Actually, getNodeAutoInstrumentations already brings all this below by default and much more, and since we didn't make any modification, we wouldn't even need to have passed any of this.

      "@opentelemetry/instrumentation-express": {},
"@opentelemetry/instrumentation-ioredis": {},
"@opentelemetry/instrumentation-http": {},
"@opentelemetry/instrumentation-dns": {},
"@opentelemetry/instrumentation-net": {},
"@opentelemetry/instrumentation-fs": {},

We only need to interfere with these instrumentations if we want to modify the behavior or disable something, and since we didn't do anything, it ended up being redundant.

Looking at getNodeAutoInstrumentations we have this by default.

declare const InstrumentationMap: {
'@opentelemetry/instrumentation-amqplib': typeof AmqplibInstrumentation;
'@opentelemetry/instrumentation-aws-lambda': typeof AwsLambdaInstrumentation;
'@opentelemetry/instrumentation-aws-sdk': typeof AwsInstrumentation;
'@opentelemetry/instrumentation-bunyan': typeof BunyanInstrumentation;
'@opentelemetry/instrumentation-cassandra-driver': typeof CassandraDriverInstrumentation;
'@opentelemetry/instrumentation-connect': typeof ConnectInstrumentation;
'@opentelemetry/instrumentation-cucumber': typeof CucumberInstrumentation;
'@opentelemetry/instrumentation-dataloader': typeof DataloaderInstrumentation;
'@opentelemetry/instrumentation-dns': typeof DnsInstrumentation;
'@opentelemetry/instrumentation-express': typeof ExpressInstrumentation;
'@opentelemetry/instrumentation-fastify': typeof FastifyInstrumentation;
'@opentelemetry/instrumentation-fs': typeof FsInstrumentation;
'@opentelemetry/instrumentation-generic-pool': typeof GenericPoolInstrumentation;
'@opentelemetry/instrumentation-graphql': typeof GraphQLInstrumentation;
'@opentelemetry/instrumentation-grpc': typeof GrpcInstrumentation;
'@opentelemetry/instrumentation-hapi': typeof HapiInstrumentation;
'@opentelemetry/instrumentation-http': typeof HttpInstrumentation;
'@opentelemetry/instrumentation-ioredis': typeof IORedisInstrumentation;
'@opentelemetry/instrumentation-kafkajs': typeof KafkaJsInstrumentation;
'@opentelemetry/instrumentation-knex': typeof KnexInstrumentation;
'@opentelemetry/instrumentation-koa': typeof KoaInstrumentation;
'@opentelemetry/instrumentation-lru-memoizer': typeof LruMemoizerInstrumentation;
'@opentelemetry/instrumentation-memcached': typeof MemcachedInstrumentation;
'@opentelemetry/instrumentation-mongodb': typeof MongoDBInstrumentation;
'@opentelemetry/instrumentation-mongoose': typeof MongooseInstrumentation;
'@opentelemetry/instrumentation-mysql2': typeof MySQL2Instrumentation;
'@opentelemetry/instrumentation-mysql': typeof MySQLInstrumentation;
'@opentelemetry/instrumentation-nestjs-core': typeof NestInstrumentation;
'@opentelemetry/instrumentation-net': typeof NetInstrumentation;
'@opentelemetry/instrumentation-pg': typeof PgInstrumentation;
'@opentelemetry/instrumentation-pino': typeof PinoInstrumentation;
'@opentelemetry/instrumentation-redis': typeof RedisInstrumentationV2;
'@opentelemetry/instrumentation-redis-4': typeof RedisInstrumentationV4;
'@opentelemetry/instrumentation-restify': typeof RestifyInstrumentation;
'@opentelemetry/instrumentation-router': typeof RouterInstrumentation;
'@opentelemetry/instrumentation-socket.io': typeof SocketIoInstrumentation;
'@opentelemetry/instrumentation-tedious': typeof TediousInstrumentation;
'@opentelemetry/instrumentation-undici': typeof UndiciInstrumentation;
'@opentelemetry/instrumentation-winston': typeof WinstonInstrumentation;
};

In other words, if we were using grpc, kafka, graphql, etc., it would already be ready, but sometimes we end up polluting things too much and we can disable or modify some of them.

The Opentelemetry Registry is the place where we can find all the different OpenTelemetry components.

Filtering by JavaScript + Instrumentation we can see everything we have available.

In the presented list we have the repository of each of the libraries, for example for HTTP. Inside each of these repositories we have how to install, how to use, and most importantly the configurations we can make.

If we observe the previous traces we saw that we have a bunch of spans that appeared about filesystem and dns, things for which we didn't write any code and apparently won't help us solve any problem. In order to declutter the trace a bit we can disable this.

  const instrumentations = [
getNodeAutoInstrumentations({
"@opentelemetry/instrumentation-dns": {
enabled: false
},
"@opentelemetry/instrumentation-fs": {
enabled: false
},
}),
];

See how it was before.

alt text

And how it looks now without that span.

alt text

We disabled them, but we could only change the behavior if we wanted to. In each of these libraries there are options that we can adjust.