I’m encountering an error related to OpenTelemetry while running a simple Jest test. The error suggests that a file is being imported after the Jest environment has been torn down. Below are the details of my code and the error.
I’m trying to set up OpenTelemetry in my Node.js application to monitor and collect telemetry data. The setup seems to work fine during normal execution, but when I run my Jest tests, I encounter a problem. It appears that the OpenTelemetry exporter is trying to execute a function after the Jest environment has been torn down, causing a ReferenceError.
/* eslint-disable no-console */
import { NodeTracerProvider } from '@opentelemetry/node';
import { SimpleSpanProcessor } from '@opentelemetry/tracing';
import { CollectorTraceExporter } from '@opentelemetry/exporter-collector-grpc';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core';
import { RedisInstrumentation } from '@opentelemetry/instrumentation-redis';
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics-base';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
import * as grpc from '@grpc/grpc-js';
import { Meter } from '@opentelemetry/api';
import { Counter } from '@opentelemetry/api-metrics';
const provider: NodeTracerProvider = new NodeTracerProvider();
const exporter: CollectorTraceExporter = new CollectorTraceExporter({
url: 'grpc://localhost:4317',
credentials: grpc.credentials.createInsecure(),
});
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();
const metricExporter: OTLPMetricExporter = new OTLPMetricExporter({
url: 'grpc://localhost:4317',
credentials: grpc.credentials.createInsecure(),
});
const meterProvider: MeterProvider = new MeterProvider();
meterProvider.addMetricReader(
new PeriodicExportingMetricReader({
exporter: metricExporter,
exportIntervalMillis: 6000,
}),
);
const meter: Meter = meterProvider.getMeter('meter-meter');
const requestCounter: Counter = meter.createCounter('requests', {
description: 'Count all incoming requests',
});
requestCounter.add(1);
export function setupTelemetry(): () => void {
const unregister: () => void = registerInstrumentations({
tracerProvider: provider,
meterProvider: meterProvider,
instrumentations: [
new HttpInstrumentation(),
new PgInstrumentation(),
new RedisInstrumentation(),
new NestInstrumentation(),
],
});
return unregister;
}
export function shutdownTelemetry(): void {
provider
.shutdown()
.then(() => {
console.log('Tracer provider shutdown successfully.');
})
.catch((err: string) => console.error('Tracer provider shutdown failed:', err));
meterProvider
.shutdown()
.then(() => {
console.log('Meter provider shutdown successfully.');
})
.catch((err: string) => console.error('Meter provider shutdown failed:', err));
}
export function flushTelemetry(): void {
provider
.forceFlush()
.then(() => {
console.log('Telemetry data flushed successfully.');
})
.catch((err: string) => console.error('Telemetry data flush failed:', err));
}
this is the test from jest
import { setupTelemetry, shutdownTelemetry, flushTelemetry } from './telemetry.js';
describe('setupTelemetry', () => {
beforeAll(() => {
setupTelemetry();
});
afterAll(() => {
shutdownTelemetry();
flushTelemetry();
});
it('should execute setupTelemetry without throwing an error', () => {
expect(() => setupTelemetry()).not.toThrow();
});
});
and this is the console error I get
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From core/telemtry/telemtry.module.spec.ts.
at Immediate._onImmediate (../node_modules/@opentelemetry/exporter-collector-grpc/src/CollectorExporterNodeBase.ts:83:26)
/Users/naelalshowaikh/Desktop/Fucking work/dbildungs-iam-server/node_modules/@opentelemetry/exporter-collector-grpc/build/src/CollectorExporterNodeBase.js:59
onInit(this, config);
^
TypeError: onInit is not a function
at Immediate.<anonymous> (/Users/naelalshowaikh/Desktop/Fucking work/dbildungs-iam-server/node_modules/@opentelemetry/exporter-collector-grpc/src/CollectorExporterNodeBase.ts:84:7)
at processImmediate (node:internal/timers:478:21)
Node.js v21.7.3
I added the shutdown and flush methods because I thought that might solve the problem, but the error persists. Any advice on how to resolve this issue would be greatly appreciated.
user25276531 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.