opentelemetry-js
opentelemetry-js copied to clipboard
Provide working TypeScript / ESM examples
- [ ] This only affects the JavaScript OpenTelemetry library
- [ ] This may affect other libraries, but I would like to get opinions here first
Please provide an example for "type": "module"
NodeJS projects. Currently all of the examples are using old CommonJS syntax and node --require
flag. ~~Why instrumentation.ts
is not imported in the main file directly?~~ ( I guess it allows to use auto instrumentation without code modification, but we are willing to modify our code if it's not supported ).
Also example provided in https://opentelemetry.io/docs/instrumentation/js/getting-started/nodejs/ is not working.
❯ npx ts-node --require ./instrumentation.ts app.ts
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:
...
I guess it assumes some kind of tsconfig.json and other settings available.
Edit: Example is only working when package.json
is configured with "type": "commonjs"
& tsconfig.json
is configured with "module": "Node16", "moduleResolution": "Node16"
Hmm I think it depends which version of node you're using. The defaults changed with node 20 so the examples likely need to be updated
We're using latest LTS NodeJS 20.x by default and few apps running on NodeJS 18.x, 16.x.
I read through the https://github.com/open-telemetry/opentelemetry-js/issues/1946 and looks like it is now supported. But it's unclear how to use it. We're currently blocked as we're using some ESM only packages and our apps already setup with "type": "module"
.
Actually @JamieDanielson is currently working on or at least thinking about working on this. Right now the ESM support is in a format that is only compatible with some bundlers.
There is one example I had added when working on instrumentation for ESM-imported libraries, in the examples directory called esm-http-ts. That particular example builds to JS first and then runs with node --experimental-loader=@opentelemetry/instrumentation/hook.mjs ./build/index.js
.
We're still sorting through some things trying to figure out what specific setups make things work or not work, as there are many nuances between TS and JS, loaders, Node versions, bundlers, specific package exports, etc.
I believe this to be related https://github.com/open-telemetry/opentelemetry-js/issues/4437
🎉 I found a working solution here! My project is using esm and I switched my runtime from node
to jiti
and NOW EVERYTHING JUST WORKS!!!!!! I'm using http, express and pg instrumentations. Works on node18 and node20
If we are living in a simulation then this is a complete cheat code 🥷🏼
@tobiasmuehl thanks for sharing, that's nice thing to try out. However I wouldn't call it a solution
🎉 I found a working solution here! My project is using esm and I switched my runtime from
node
tojiti
and NOW EVERYTHING JUST WORKS!!!!!! I'm using http, express and pg instrumentations. Works on node18 and node20If we are living in a simulation then this is a complete cheat code 🥷🏼
can you provide sample or demo? I tried a lot but all in vain,
i am running server using "node --require ./tracer.cjs index.js here is code of my tracer.cjs file:
const jiti =require('jiti')(__filename);
jiti.register()
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node');
const {
PeriodicExportingMetricReader,
ConsoleMetricExporter,
} = require('@opentelemetry/sdk-metrics');
const { GrpcInstrumentation } = require('@opentelemetry/instrumentation-grpc');
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
const sdk = new NodeSDK({
traceExporter: new ConsoleSpanExporter(),
metricReader: new PeriodicExportingMetricReader({
exporter: new ConsoleMetricExporter(),
}),
instrumentations: [new GrpcInstrumentation()],
});
sdk.start();
@Mahmaddz
tracer.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
// your config
})
});
sdk.start();
index.ts
import './tracer.js' // this needs to be the very first import
import 'dotenv/config'
import express from 'express'
const port = Number(process.env.PORT)
const app = express()
// init express, etc
Run with jiti:
npx jiti index.ts
This might be useful to anyone who is trying to figure out all the gotchas https://gajus.com/blog/how-to-add-sentry-tracing-to-your-node-js-app
@JamieDanielson if I get it right, based on https://github.com/nodejs/node/issues/51196#issuecomment-1998216742 the correct way would now be
// register.mjs
import { register } from 'node:module';
register('@opentelemetry/instrumentation/hook.mjs', new URL('./', import.meta.url));
and then
node --import=./register.mjs ./main.mjs
This does not only stop throwing a deprecation warning, that's actually quite handy, because it is now possible to drop all relevant opentelemetry config in. That's how a minimal version of this could look like:
// register.mjs
import { register } from 'node:module';
import { context, propagation, trace } from '@opentelemetry/api';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
register('@opentelemetry/instrumentation/hook.mjs', new URL('./', import.meta.url));
const sdk = new NodeSDK({
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
process.on('SIGTERM', () => {
sdk
.shutdown()
.then(() => console.log('tracing terminated'))
.catch((error) => console.error(error, 'error terminating tracing'))
.finally(() => process.exit(0));
});
Playing with it for like a day, it works. There are issues however. Probably not all instrumentations are ESM compatible yet (and https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1942 kinda confirms that), e.g.
- dns instrumentation doesn't work
- http outgoing requests are not handled, incoming however do work
- undici works well
Please correct me if I'm wrong.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.
This issue was closed because it has been stale for 14 days with no activity.