Skip to main content
GreenSlope

Node.js quickstart

Target: first trace in your tenant in about four minutes. Works for Express, Fastify, Hono, and any other Node 18+ HTTP server. If you're on Next.js, use the Next.js quickstart instead — it has a framework-specific entry point.

1. Sign up and grab your tenant key

Create a tenant and copy your tenant ingest key (gs_ing_live_…). Add it to your environment:

# .env
GREENSLOPE_INGEST_KEY="gs_ing_live_…"

2. Install the OTel packages

pnpm add @opentelemetry/api \
  @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-http \
  @opentelemetry/resources \
  @opentelemetry/semantic-conventions

3. Create the OTel bootstrap module

OpenTelemetry needs to start before your app requires any of its dependencies, so auto-instrumentation can patch them. That means a dedicated bootstrap file:

// otel.ts
import { NodeSDK } from "@opentelemetry/sdk-node"
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node"
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"
import { resourceFromAttributes } from "@opentelemetry/resources"
import {
  ATTR_SERVICE_NAME,
  ATTR_SERVICE_VERSION
} from "@opentelemetry/semantic-conventions"
 
const sdk = new NodeSDK({
  resource: resourceFromAttributes({
    [ATTR_SERVICE_NAME]: "api",
    [ATTR_SERVICE_VERSION]: process.env.APP_VERSION ?? "0.0.0",
    "greenslope.release.id": process.env.GIT_SHA ?? "local"
  }),
  traceExporter: new OTLPTraceExporter({
    url: "https://ingest.greenslope.io/v1/otel/v1/traces",
    headers: {
      "x-greenslope-key": process.env.GREENSLOPE_INGEST_KEY ?? ""
    }
  }),
  instrumentations: [getNodeAutoInstrumentations()]
})
 
sdk.start()
 
process.on("SIGTERM", () => {
  sdk.shutdown().finally(() => process.exit(0))
})

All three resource attributes are required — see Release attribution.

4. Require the bootstrap before your app

Add a -r ./otel.js flag (or --import for ESM) so the SDK starts before your server imports its HTTP framework:

node -r ./otel.js server.js

5. Hit an endpoint

curl http://localhost:3000/health

The auto-instrumentation captures the HTTP server span, so no manual tracing is needed for the first trace.

Verify

Open Live traces at app.greenslope.io. You should see a span for GET /health within ten seconds with your service.name, service.version, and greenslope.release.id attached.

Still blank? See Troubleshooting: first trace doesn't arrive.

Related