vercel / otel

OTEL tracing for Vercel
https://vercel.com/docs/observability/otel-overview
28 stars 8 forks source link

onError [TypeError: fetch failed] { cause: [Error: AggregateError] } #122

Closed SandervanL closed 1 week ago

SandervanL commented 2 weeks ago

When using @vercel/otel locally (using next dev), on startup, I get the following error. Am I doing something wrong?

Error: fetch failed
    at context.fetch (C:\Users\myuser\myproject\node_modules\.pnpm\next@14.2.5_@opentelemetry+api@1.9.0_react-dom@18.3.1_react@18.3.1__react@18.3.1\node_modules\next\dist\server\web\sandbox\context.js:292:38)
    at U (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:29:28952)
    at Jn.send (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:29:21880)
    at eval (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:53323)
    at new Promise (<anonymous>)
    at Jn._export (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:53258)
    at Jn.export (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:53122)
    at Be.export (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:29:27027)
    at s (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:88728)
    at eval (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:89002)
    at AsyncLocalStorage.run (node:async_hooks:346:14)
    at Ln.with (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:46510)
    at ContextAPI.with (webpack-internal:///(instrument)/./node_modules/.pnpm/@opentelemetry+api@1.9.0/node_modules/@opentelemetry/api/build/esm/api/context.js:95:54)
    at eval (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:88581)
    at new Promise (<anonymous>)
    at t._flushOneBatch (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:88464)
    at r (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:89286)
    at Timeout.eval (webpack-internal:///(instrument)/./node_modules/.pnpm/@vercel+otel@1.10.0_@opentelemetry+api-logs@0.53.0_@opentelemetry+api@1.9.0_@opentelemetry+in_6ezolcja6otbzhrjaauejhhk4i/node_modules/@vercel/otel/dist/edge/index.js:17:89603)
    at listOnTimeout (node:internal/timers:573:17)
    at process.processTimers (node:internal/timers:514:7)

Then for each request, I get the following:

@vercel/otel/otlp: onError TypeError: fetch failed
    at C:\Users\myuser\myproject\lib\internal\deps\undici\undici.js:12344:11
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {cause: AggregateError
    at internalConnectMultiple …t:1114:18)
    at afterConnectMultiple (node:…, stack: 'TypeError: fetch failed
    at node:internal/…ions (node:internal/process/task_queues:95:5)', message: 'fetch failed'}

With as a cause:

Error: connect ECONNREFUSED ::1:4318
    at createConnectionError (node:net:1634:14)
    at afterConnectMultiple (node:net:1664:40)
    at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)

This is my instrumentation.ts:

import { env } from "~/env";
import type { SpanExporter } from "@opentelemetry/sdk-trace-base";
import { registerOTel } from "@vercel/otel";

export async function register() {
    let traceExporter: SpanExporter | undefined;

    if (
        process.env.NEXT_RUNTIME === "nodejs" &&
        env.APPLICATIONINSIGHTS_CONNECTION_STRING != null
    ) {
        const { AzureMonitorTraceExporter } = await import(
            "@azure/monitor-opentelemetry-exporter"
        );
        traceExporter = new AzureMonitorTraceExporter({
            connectionString: env.APPLICATIONINSIGHTS_CONNECTION_STRING,
        });
    }

    registerOTel({
        serviceName: env.APPLICATIONINSIGHTS_SERVICE_NAME,
        traceExporter,
    });
}

My package.json:

{
    "name": "myproject",
    "version": "0.1.0",
    "private": true,
    "type": "module",
    "scripts": {
        "build": "cross-env NODE_ENV=production next build",
        "db:push": "prisma db push",
        "db:studio": "prisma studio",
        "dev": "next dev",
        "postinstall": "prisma generate",
        "lint": "next lint",
        "start": "next start"
    },
    "dependencies": {
        "@auth/prisma-adapter": "^1.6.0",
        "@azure/monitor-opentelemetry-exporter": "1.0.0-beta.26",
        "@opentelemetry/api": "^1.9.0",
        "@opentelemetry/api-logs": ">=0.46.0 && <1.0.0",
        "@opentelemetry/instrumentation": ">=0.46.0 && <1.0.0",
        "@opentelemetry/sdk-logs": ">=0.46.0 && <1.0.0",
        "@opentelemetry/sdk-trace-base": "^1.26.0",
        "@t3-oss/env-nextjs": "^0.10.1",
        "@tanstack/react-query": "^5.50.0",
        "@trpc/client": "^11.0.0-rc.446",
        "@trpc/react-query": "^11.0.0-rc.446",
        "@trpc/server": "^11.0.0-rc.446",
        "@vercel/otel": "^1.10.0",
        "@vertx/core": "^4.5.1",
        "async-mutex": "^0.5.0",
        "clsx": "^2.1.1",
        "geist": "^1.3.0",
        "next": "^14.2.4",
        "next-auth": "^4.24.7",
        "react": "^18.3.1",
        "react-dom": "^18.3.1",
        "server-only": "^0.0.1",
        "superjson": "^2.2.1",
        "tailwind-merge": "^2.5.2",
        "vertx": "0.0.1-security",
        "winston": "^3.14.1",
        "ws": "^8.18.0",
        "zod": "^3.23.3"
    },
    "devDependencies": {
        "@types/eslint": "^8.56.10",
        "@types/node": "^20.14.10",
        "@types/react": "^18.3.3",
        "@types/react-dom": "^18.3.0",
        "@types/ws": "^8.5.12",
        "@typescript-eslint/eslint-plugin": "^7.1.1",
        "@typescript-eslint/parser": "^7.1.1",
        "concurrently": "^8.2.2",
        "cross-env": "^7.0.3",
        "dotenv": "^16.4.5",
        "eslint": "^8.57.0",
        "eslint-config-next": "^14.2.4",
        "postcss": "^8.4.39",
        "prettier": "^3.3.2",
        "prettier-plugin-tailwindcss": "^0.6.5",
        "prisma": "^5.19.1",
        "tailwindcss": "^3.4.3",
        "tsc-alias": "^1.8.10",
        "tsx": "^4.17.0",
        "typescript": "^5.5.3"
    },
    "ct3aMetadata": {
        "initVersion": "7.36.2"
    },
    "packageManager": "pnpm@9.10.0"
}
SandervanL commented 1 week ago

This issue was being caused by registerOtel being initialized without a traceExporter, which defaulted sending the logs to http://localhost:4318/v1/traces, but I did not setup an Otel Collector to be running there. That means a fetch error. It would be great if in the future a more verbose error could be setup.

I solved it as follows (no instrumentation when no Azure Application Insights connection string is configured.

import { env } from "~/env";
import type { SpanExporter } from "@opentelemetry/sdk-trace-base";
import { registerOTel } from "@vercel/otel";

export async function register() {
    let traceExporter: SpanExporter | undefined;

    if (
        typeof "window" === "undefined" &&
        env.APPLICATIONINSIGHTS_CONNECTION_STRING != null
    ) {
        const { AzureMonitorTraceExporter } = await import(
            "@azure/monitor-opentelemetry-exporter"
        );
        traceExporter = new AzureMonitorTraceExporter({
            connectionString: env.APPLICATIONINSIGHTS_CONNECTION_STRING,
        });

        registerOTel({
            serviceName: env.APPLICATIONINSIGHTS_SERVICE_NAME,
            traceExporter,
        });
    }
}