opentelemetry-js
opentelemetry-js copied to clipboard
http instrumentation does not work when running jest
What happened?
Steps to Reproduce
The following script correctly sets traceparent when run using ts-node (it will not work with plain node because of module hoisting) but the http request is not instrumented if run by just
import { NodeSDK } from '@opentelemetry/sdk-node'
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'
const traceExporter = new OTLPTraceExporter()
const sdk = new NodeSDK({
traceExporter,
instrumentations: [new HttpInstrumentation()],
})
sdk.start()
import * as http from 'http'
http.get('http://localhost:8080')
Expected Result
traceparent is added to the outgoing http headers when running using jest
Actual Result
traceparent is not added
Additional Details
I'm not sure if this is intended to work, but it's a nice use case to be able to trace from integration tests to the services tested. I pushed a small repro to https://github.com/karlbohlmark/otel-jest
OpenTelemetry Setup Code
import { NodeSDK } from '@opentelemetry/sdk-node'
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'
const traceExporter = new OTLPTraceExporter()
const sdk = new NodeSDK({
traceExporter,
instrumentations: [new HttpInstrumentation()],
})
sdk.start()
package.json
{
"scripts": {
"ts-node": "ts-node src/otel.test.ts",
"jest": "jest otel"
},
"dependencies": {
"@opentelemetry/exporter-trace-otlp-proto": "^0.38.0",
"@opentelemetry/instrumentation-http": "^0.38.0",
"@opentelemetry/sdk-node": "^0.38.0",
"@types/jest": "^29.5.0",
"@types/node": "^18.15.11",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
}
}
Relevant log output
No response
After digging a little bit, this seems to be because of https://github.com/elastic/require-in-the-middle/issues/50
Maybe the solution is just to note this in the docs and recommend using another testing framework
Thank you for reporting this.
I think the bug label here is valid. Assigning p2 as it causes telemetry to be incorrectly exported.
Relevant issue on the jest repo: https://github.com/facebook/jest/issues/11295
Maybe it would be possible to get someone on the jest team to take an interest here. I think it could make sense for jest to have tracing built in.
I have now put the necessary workarounds in place for my use case, but I still have some minor issues like
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down. From src/tests/global-settings.test.ts.
at Immediate._onImmediate (node_modules/@opentelemetry/otlp-proto-exporter-base/src/platform/node/OTLPProtoExporterNodeBase.ts:78:26)
Also I'm not sure if all tracing data is properly exported before jest shuts down. If tracing was a first class citizen of jest this would be taken care of.
@karlbohlmark Could you elaborate a bit on the workarounds you used?
I am actually able to get http traces with quite easy setup, my problem is with instrumentation-pg that is missing, probably due to require-in-the-middle issue.
Here is my setup with auto-instrumentation:
# package.json
...
"scripts": {
...
"test": "OTEL_SERVICE_NAME=jest-tests NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" jest'"
},
"dependencies": {
"@opentelemetry/auto-instrumentations-node": "^0.40.2",
"@opentelemetry/instrumentation": "^0.36.0",
...
}
# test.spec
# test are straight forward
endpoints.map(url => it(`${url} (GET)`, async function() {
await request(app)
.get(url)
.expect(200);
Make sure to wait a bit after the tests to make sure all spans were sent. I am running collector available on default path localhost:4318.
Hope that helps