Configurando la Instrumentación
Hay varias cosas que vale la pena mencionar sobre la configuración del SDK.
Instrumentación
Necesitamos entender qué es la instrumentación, dónde la definimos y cómo podemos modificarla o configurarla si es necesario.
La instrumentación es la parte del código en OpenTelemetry que generará los spans (intervalos) y métricas para nosotros. Ya hemos visto que cuando recibimos una llamada HTTP se crea un intervalo automáticamente, lo que significa que hay una parte del código de OpenTelemetry que se conecta al módulo HTTP y observa cuándo recibe y responde una solicitud y en base a eso crea su propio span.
Esto sucedió exactamente en este momento de nuestro proyecto.
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,
});
Para mantenerlo simple, en la parte de new NodeSDK instanciamos toda la instrumentación antes y abajo solo la usamos, pero podría haberse simplificado, como en el código a continuación, usando la biblioteca @opentelemetry/auto-instrumentations-node de forma estándar.
const sdk = new NodeSDK({
resource,
traceExporter,
instrumentations: [getNodeAutoInstrumentations()]
});
En realidad getNodeAutoInstrumentations ya trae todo esto abajo por defecto y mucho más, y como no hicimos ninguna modificación, ni siquiera necesitaríamos haber pasado nada de esto.
"@opentelemetry/instrumentation-express": {},
"@opentelemetry/instrumentation-ioredis": {},
"@opentelemetry/instrumentation-http": {},
"@opentelemetry/instrumentation-dns": {},
"@opentelemetry/instrumentation-net": {},
"@opentelemetry/instrumentation-fs": {},
Solo necesitamos interferir con estas instrumentaciones si queremos modificar el comportamiento o desactivar algo, y como no hicimos nada, terminó siendo redundante.
Mirando getNodeAutoInstrumentations tenemos esto por defecto.
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;
};
En otras palabras, si estuviéramos usando grpc, kafka, graphql, etc., ya estaría listo, pero a veces terminamos contaminando demasiado las cosas y podemos desactivar o modificar algunas de ellas.
El Opentelemetry Registry es el lugar donde podemos encontrar todos los diferentes componentes de OpenTelemetry.
Filtrando por JavaScript + Instrumentation podemos ver todo lo que tenemos disponible.
En la lista presentada tenemos el repositorio de cada una de las bibliotecas, por ejemplo para HTTP. Dentro de cada uno de estos repositorios tenemos cómo instalar, cómo usar y lo más importante las configuraciones que podemos hacer.
Si observamos las trazas anteriores vimos que tenemos un montón de spans que aparecieron sobre filesystem y dns, cosas para las cuales no escribimos ningún código y aparentemente no nos ayudarán a resolver ningún problema. Para limpiar un poco la traza podemos desactivar esto.
const instrumentations = [
getNodeAutoInstrumentations({
"@opentelemetry/instrumentation-dns": {
enabled: false
},
"@opentelemetry/instrumentation-fs": {
enabled: false
},
}),
];
Vea cómo era antes.

Y cómo queda ahora sin ese span.

Los desactivamos, pero podríamos solo cambiar el comportamiento si quisiéramos. En cada una de estas bibliotecas hay opciones que podemos ajustar.