-
Couldn't load subscription status.
- Fork 942
Description
What happened?
Steps to Reproduce
Create an OTLPMetricsExporter from @opentelemetry/exporter-metrics-otlp-proto. Use this in a PeriodicExportingMetricReader. Add a value to a counter and flush.
This is a small Typescript commonjs jest test case to demonstrate the problem:
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'
import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'
import { diag, DiagLogLevel } from '@opentelemetry/api'
describe('Exporter', () => {
it('runs without errors', async function () {
diag.setLogger(logger, DiagLogLevel.ERROR)
const exporter = new OTLPMetricExporter({
url: 'http://localhost:3000/metrics',
temporalityPreference: AggregationTemporality.CUMULATIVE,
headers: {
Authorization: 'Api-Token my-token',
},
})
const reader = new PeriodicExportingMetricReader({
exporter: exporter,
exportIntervalMillis: 30000,
})
const provider = new MeterProvider({
readers: [reader],
})
const meter = provider.getMeter('my-name-space')
const counter = meter.createCounter('my-counter')
counter.add(100)
await reader.forceFlush()
})
})
const logger = {
error: (message: string, ...args: unknown[]) => {
console.error('OTLP Error:', message, ...args)
},
warn: (message: string, ...args: unknown[]) => {
console.warn(message, ...args)
},
info: (message: string, ...args: unknown[]) => {
console.info(message, ...args)
},
debug: (message: string, ...args: unknown[]) => {
console.debug(message, ...args)
},
verbose: (message: string, ...args: unknown[]) => {
console.log(message, ...args)
},
}
Expected Result
A metric is written to the provided URL
Actual Result
No metric is written. An error is logged:
{"stack":"Error: PeriodicExportingMetricReader: metrics export failed (error TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG]: A dynamic import callback was invoked without --experimental-vm-modules)
at PeriodicExportingMetricReader._doRun (/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:144:13)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at PeriodicExportingMetricReader._runOnce (/node_modules/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:103:7)
at PeriodicExportingMetricReader.onForceFlush (/node_modules/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:160:5)
at PeriodicExportingMetricReader.forceFlush (/node_modules/@opentelemetry/sdk-metrics/src/export/MetricReader.ts:277:7)
at Object. (/test/metrics/Exporter.spec.ts:30:9)","message":"PeriodicExportingMetricReader:
metrics export failed (error TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG]: A dynamic import callback was invoked without --experimental-vm-modules)","name":"Error"}
Additional Details
Passing the --experimental-vm-modules fixes the problem. But this code needs to run in an AWS Lambda so I don't have control over the node runtime. Running in a container is a possibility but I have a lot of lambdas that would need migrating to containers so this would be expensive.
The problem looks like it is in @opentelemetry/otlp-exporter-base/build/src/transport/http-exporter-transport.js. The requestFunctionFactory function has a conditional import:
const module = protocol === 'http:' ? import('http') : import('https')
OpenTelemetry Setup Code
See above examplepackage.json
{
"scripts": {
"test": "npx jest --detectOpenHandles --coverage --reporters=jest-junit --reporters=default"
},
"dependencies": {
"@opentelemetry/api": "1.9.0",
"@opentelemetry/exporter-metrics-otlp-proto": "0.206.0",
"@opentelemetry/resources": "2.1.0",
"@opentelemetry/sdk-metrics": "2.1.0",
"@opentelemetry/sdk-node": "0.206.0",
"@opentelemetry/semantic-conventions": "1.37.0"
},
"devDependencies": {
"@types/jest": "30.0.0",
"jest": "30.2.0",
"jest-junit": "16.0.0",
"jest-junit-reporter": "1.1.0",
"ts-jest": "29.4.5",
"typescript": "5.9.3",
"typescript-eslint": "8.46.0"
},
"jest": {
"testMatch": [
"**/Exporter.spec.ts"
],
"transform": {
".+\\.(ts|tsx)?$": "ts-jest"
},
"verbose": true,
"silent": false,
"detectOpenHandles": true,
"forceExit": true,
"testTimeout": 30000
}
}Relevant log output
{"stack":"Error: PeriodicExportingMetricReader: metrics export failed (error TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG]: A dynamic import callback was invoked without --experimental-vm-modules)
at PeriodicExportingMetricReader._doRun (<redacted>/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:144:13)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at PeriodicExportingMetricReader._runOnce (<redacted>/node_modules/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:103:7)
at PeriodicExportingMetricReader.onForceFlush (<redacted>/node_modules/@opentelemetry/sdk-metrics/src/export/PeriodicExportingMetricReader.ts:160:5)
at PeriodicExportingMetricReader.forceFlush (<redacted>/node_modules/@opentelemetry/sdk-metrics/src/export/MetricReader.ts:277:7)
at Object.<anonymous> (<redacted>/test/metrics/Exporter.spec.ts:30:9)","message":"PeriodicExportingMetricReader:
metrics export failed (error TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING_FLAG]: A dynamic import callback was invoked without --experimental-vm-modules)","name":"Error"}Operating System and Version
No response
Runtime and Version
Node.js 20.18.0
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.