Skip to content

[node-sdk] Missing @opentelemetry/exporter-jaeger raises an error on Next.js app #4297

@jstlaurent

Description

@jstlaurent

What happened?

Steps to Reproduce

Create a basic Next.js app and follow the steps to manually add OpenTelemetry to the application.

Use the OpenTelemetry setup code below. Don't set any environment variables, so that a ConsoleSpanExporter gets configured.

Start the dev server (npm run dev) and launch the app.

Expected Result

I see the default OpenTelemetry spans from my request in the console.

Actual Result

I get an error message from a failed import: Can't resolve '@opentelemetry/exporter-jaeger'. See the full trace below.

Additional Details

It looks like node-sdk imports TracerProviderWithEnvExporters. As a side effect of which, a Map of registered providers is built that assumes Jaeger is available and throws an error if it isn't. Since the dependency was removed in v0.44, the error gets thrown.

Edit:
Note that I'm not using Jaeger. I'll add the dependency to solve the error, but I would rather not have to include it at all. I can't include @opentelemetry/exporter-jaeger in my project because #3759 happens.

OpenTelemetry Setup Code

//instrumentation.ts
import { settings } from '@/config'
import { Span, SpanOptions, SpanStatusCode, trace } from '@opentelemetry/api'

export const tracer = trace.getTracer(settings.SERVICE_NAME)

export async function register() {
  if (settings.DISABLE_OTEL) {
    console.info('OpenTelemetry is disabled')
    return
  }

  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation.node.ts')
  }
}

//instrumentation.node.ts

import { settings } from '@/config'
import * as grpc from '@grpc/grpc-js'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'
import { Resource } from '@opentelemetry/resources'
import { NodeSDK } from '@opentelemetry/sdk-node'
import {
  BatchSpanProcessor,
  ConsoleSpanExporter,
  SimpleSpanProcessor
} from '@opentelemetry/sdk-trace-node'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'

function getProcessor() {
  if (settings.HONEYCOMB_API_KEY) {
    const metadata = new grpc.Metadata()
    metadata.set('x-honeycomb-team', settings.HONEYCOMB_API_KEY)

    const exporter = new OTLPTraceExporter({
      url: 'grpc://api.honeycomb.io:443/',
      credentials: grpc.credentials.createSsl(),
      metadata
    })

    // Values from https://github.com/honeycombio/intro-to-o11y-nodejs/blob/main/src/tracing.js
    return new BatchSpanProcessor(exporter, {
      maxQueueSize: 16000,
      maxExportBatchSize: 1000,
      scheduledDelayMillis: 500
    })
  }

  console.info('Using console exporter')
  return new SimpleSpanProcessor(new ConsoleSpanExporter())
}

const sdk = new NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: settings.SERVICE_NAME,
    [SemanticResourceAttributes.SERVICE_NAMESPACE]: settings.PROJECT_NAME,
    [SemanticResourceAttributes.SERVICE_VERSION]:
      settings.VERCEL_GIT_COMMIT_SHA,
    [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: settings.VERCEL_ENV
  }),
  spanProcessor: getProcessor()
})

sdk.start()

package.json

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "format": "prettier --write ."
  },
  "dependencies": {
    "next": "^14.0.2",
    "react": "^18.2.0",
    "@opentelemetry/api": "^1.7.0",
    "@opentelemetry/exporter-trace-otlp-grpc": "^0.45.1",
    "@opentelemetry/resources": "^1.18.1",
    "@opentelemetry/sdk-node": "^0.45.1",
    "@opentelemetry/sdk-trace-node": "^1.18.1",
    "@opentelemetry/semantic-conventions": "^1.18.1",
    "tailwind-merge": "^2.0.0",
    "tailwindcss": "^3.3.5",
    "tailwindcss-animate": "^1.0.7",
  },
  "devDependencies": {
    "@ianvs/prettier-plugin-sort-imports": "^4.1.1",
    "@tailwindcss/typography": "^0.5.10",
    "@types/node": "^20.9.0",
    "@types/react": "^18.2.37",
    "@types/react-dom": "^18.2.15",
    "@types/ws": "^8.5.9",
    "autoprefixer": "^10.4.16",
    "dotenv": "^16.3.1",
    "dotenv-cli": "^7.3.0",
    "eslint": "^8.53.0",
    "eslint-config-next": "^14.0.2",
    "eslint-config-prettier": "^9.0.0",
    "eslint-plugin-tailwindcss": "^3.13.0",
    "postcss": "^8.4.30",
    "prettier": "^3.1.0",
    "prettier-plugin-tailwindcss": "^0.5.7",
    "ts-node": "^10.9.1",
    "typescript": "^5.2.2"
  },
  "postcss": {
    "plugins": {
      "tailwindcss": {},
      "autoprefixer": {}
    }
  }
}

Relevant log output

./node_modules/@opentelemetry/sdk-node/build/src/TracerProviderWithEnvExporter.js
Module not found: Can't resolve '@opentelemetry/exporter-jaeger' in '/Users/julien/projects/my-app/node_modules/@opentelemetry/sdk-node/build/src'

Import trace for requested module:
./node_modules/@opentelemetry/sdk-node/build/src/TracerProviderWithEnvExporter.js
./node_modules/@opentelemetry/sdk-node/build/src/sdk.js
./node_modules/@opentelemetry/sdk-node/build/src/index.js
./src/instrumentation.node.ts
./src/instrumentation.ts
./src/services/dataset.ts
./src/app/datasets/page.tsx

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpkg:sdk-nodepriority:p1Bugs which cause problems in end-user applications such as crashes, data inconsistencies, etc

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions