# OpenTelemetry for Cloudflare Workers

Instrument your Cloudflare Worker applications with OpenTelemetry using the the otel-cf-workers SDK.

# Instrumentation

# Step 1: Install the SDK

Install @microlabs/otel-cf-workers in your project.

npm i @microlabs/otel-cf-workers 

# Step 2: Add Node.js Compatibility Flags

OpenTelemetry requires the Node.js Compatibility flag is enabled at the top level of your wrangler.toml

compatibility_flags = [ "nodejs_compat" ]

# Step 3: Configure the tracer

In your Cloudflare worker file, add the following configuration code to configure OpenTelemetry.

import { instrument, ResolveConfigFn } from '@microlabs/otel-cf-workers'

export interface Env {
    SERVICE_NAME: string

const handler = {
	async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
		// your cloudflare worker code

const config: ResolveConfigFn = (env: Env, _trigger) => {
	return {
		exporter: {
			url: 'https://otel.baselime.io/v1',
			headers: { 'x-api-key': env.BASELIME_API_KEY },
		service: { name: env.SERVICE_NAME },

export default instrument(handler, config)

# Step 4: Set the Baselime environment variables

In your Cloudflare Workers Secret Configuration add the BASELIME_API_KEY.

To enable tracing for local dev add your BASELIME_API_KEY to your .dev.vars file


In your wrangler.toml file set the SERVICE_NAME variable

SERVICE_NAME = "my-service-name"

Once these steps are completed, distributed traces from your Cloudflare workers application should be available in Baselime to query via the console or the Baselime CLI.

Example Cloudflare Worker Trace
Example Cloudflare Worker Trace

# Adding custom OpenTelemetry spans

To add custom spans to your OpenTelemetry traces, install the @opentelemetry/api package.

npm i @opentelemetry/api

And manually add spans to your traces.

import { trace } from "@opentelemetry/api";
const tracer = trace.getTracer('your-custom-traces');

const handler = {
    async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
        const span = trace.getActiveSpan();

        span.setAttribute('search', search)

        const result = await tracer.startActiveSpan(`business-logic`, async (span) => {
            // your business logic
            const input = { search }
            const result = await yourBusinessLogic(input)
            return result

# Special Thanks

This is powered by otel-cf-workers developed by Erwin van der Koogh. It's a fantastic vendor agnostic OpenTelemetry SDK for Cloudflare Workers and you should check it out.