table of contents Table of contents

Next.js

Next.js is now shipping with an experimental OpenTelemetry integration. This guide will help you instrument your Next.js application(s) with OpenTelemetry and send traces to Checkly.

Step 1: Install the @vercel/otel package

For Next.js, Vercel has created a wrapper that should get you going very quickly. We’re just adding some extra packages so we can filter out the Checkly traces.

npm install --save \
    @vercel/otel \
    @opentelemetry/api \
    @opentelemetry/sdk-trace-base \
    @opentelemetry/exporter-trace-otlp-http    

Step 2: Initialize the instrumentation

Set the instrumentationHook flag to true in your Next.js configuration file. This will enable the OpenTelemetry instrumentation.

/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental: {
      instrumentationHook: true
    }
  }

module.exports = nextConfig

Create a file called instrumentation.js at the root of your project and add the following code:

// instrumentation.js

import { registerOTel } from '@vercel/otel'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { ConsoleSpanExporter, SimpleSpanProcessor, SamplingDecision } from '@opentelemetry/sdk-trace-base'
import { trace } from '@opentelemetry/api'

const checklyExporter = new OTLPTraceExporter({
    timeoutMillis: 2000,
    url: process.env.CHECKLY_OTEL_ENDPOINT,
    headers: {
        Authorization: `Bearer ${process.env.CHECKLY_OTEL_API_KEY}`
    },
})

// export spans to console (useful for debugging)
const consoleProcessor = new SimpleSpanProcessor(new ConsoleSpanExporter())
const spanProcessors = new SimpleSpanProcessor(checklyExporter)

export function register() {
    registerOTel({
        serviceName: 'acme-next-app',
        traceExporter: checklyExporter,
        spanProcessors: [consoleProcessor, spanProcessors],
        sampler: {
            shouldSample: (context, traceId, spanName, spanKind, attributes, links) => {
                const isChecklySpan = trace.getSpan(context)?.spanContext()?.traceState?.get('checkly')
                if (isChecklySpan) {
                    return { decision: SamplingDecision.RECORD_AND_SAMPLED }
                } else {
                    return { decision: SamplingDecision.NOT_RECORD }
                }
            },
        },
    })
}

Note the sampler configuration. This is a custom, head-based sampler that will only sample spans that are generated by Checkly by inspecting the trace state. This way you only pay for the egress traffic generated by Checkly and not for any other traffic.

Step 3: Start your app with the instrumentation

Grab your OTel API key in the Send traces section of the Open Telemetry Integration page in the Checkly app.
Now, export your API key in your shell by setting the CHECKLY_OTEL_API_KEY environment variable.

export CHECKLY_OTEL_API_KEY="<your-api-key>"

Next, export the endpoint for the region you want to use and give your service a name.

export CHECKLY_OTEL_ENDPOINT="https://otel.eu-west-1.checklyhq.com/v1/traces"   
# export CHECKLY_OTEL_ENDPOINT="https://otel.us-east-1.checklyhq.com/v1/traces"

If you are using Vercel for hosting your Next.js app, add the above environment variables to your Vercel project settings, e.g. 👇

Vercel project OTEL variables

Further reading

Have a look at the official Next.js docs on how to enable the experimental OpenTelemetry integration.


Last updated on May 1, 2024. You can contribute to this documentation by editing this page on Github