npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jahands/workers-observability-utils

v0.3.1

Published

A collection of Utilities for Capturing Logs and Metrics from Cloudflare Workers

Readme

Workers Observability Utils

A lightweight, zero-dependency package for capturing and exporting metrics from Cloudflare Workers.

Features

  • Collect and track COUNT, GAUGE, and HISTOGRAM metrics
  • Auto-aggregation of metrics based on type
  • Tag support for all metrics
  • Export metrics to multiple sinks (Datadog, Workers Analytics Engine)
  • Separate Tail Worker architecture for efficient metrics exporting

Basic Usage

Setting Up Metrics in Your Worker

The main worker will capture metrics and publish them through a diagnostics channel. The metrics object provides methods for recording different types of metrics:

import * as metrics from 'workers-observability-utils/metrics';

export default {
  async fetch(request, env, ctx) {
    // Record count metric with tags
    metrics.count('worker.request', 1, {
      method: request.method,
    });

    // Record gauge metric
    metrics.gauge('worker.connections.active', 42);

    // Record histogram metric for response time.
    // Note: Timers are not totally accurate in cloudflare worker environments
    // but this can give an indication of relative performance
    const startTime = Date.now();
    const response = await processRequest();
    const responseTime = Date.now() - startTime;
    metrics.histogram('worker.response_time', responseTime, {
      percentiles: [0.5, 0.95, 0.99],
      aggregates: ['avg', 'max']
    });

    return response;
  },
};

Metric Types

This library supports three types of metrics:

  1. COUNT - Represents the total number of occurrences. It can be incremented or decremented. (e.g., request count, error count)

    metrics.count('worker.request', 1, { status: '200' });
  2. GAUGE - Point-in-time measurement (e.g., memory usage, connection count)

    metrics.gauge('worker.memory_usage', memoryUsage, { region: 'earth' });
  3. HISTOGRAM - Distribution of values over time with statistical aggregations

    metrics.histogram('worker.response_time', responseTimeMs, {
      percentiles: [0.5, 0.95, 0.99],  // p50, p95, and p99 percentiles
      aggregates: ['avg', 'max', 'min', 'sum', 'count']
    }, { endpoint: '/api' });

    Histogram metrics automatically generate multiple derived metrics:

    • Percentiles (as gauges): worker.cpu_time.p50, worker.cpu_time.p95, etc.
    • Aggregates: worker.cpu_time.avg, worker.cpu_time.max, etc.

Tags

All metrics support tags, which are key-value pairs that help categorize and filter metrics:

metrics.count('worker.request', 1, {
  method: 'GET',
  path: '/api',
  status: '200'
});

Setting Up the Tail Worker

To efficiently export metrics to external providers, you should set up a dedicated Tail Worker. This architecture allows your main worker to focus on handling requests, while the Tail Worker handles metric collection and export. For more information, see the Cloudflare Tail Workers documentation.

Multiple Sinks

With this library, you can send metrics to multiple destinations simultaneously. The TailExporter supports an array of metric sinks, and each sink receives the same metrics data. Currently supported sinks include:

  • Datadog - Export metrics to Datadog for visualization and alerting
  • Workers Analytics Engine - Store metrics in Cloudflare's Analytics Engine for custom queries and analysis

When using multiple sinks, metrics will be sent to all configured sinks in parallel. If one sink fails, the others will still receive the metrics.

Tail Worker Configuration

  1. Create a new Worker for handling tail events:
// tail-worker/src/index.ts
import { TailExporter, DatadogMetricSink, WorkersAnalyticsEngineSink } from 'workers-observability-utils/tail';

export default new TailExporter({
  metrics: {
    sinks: [
      new DatadogMetricSink({
        site: 'us3.datadoghq.com',
        // API key can be provided here or via environment variables
        // apiKey: 'your-datadog-api-key'
      }),
      new WorkersAnalyticsEngineSink({
        datasetBinding: env.ANALYTICS_ENGINE_DATASET
      })
    ],
    // Optional default metrics to collect automatically
    defaultMetrics: {
      cpuTime: true,           // default: true - collects worker.cpu_time as a GAUGE
      wallTime: true,          // default: true - collects worker.wall_time as a GAUGE
      workersInvocation: true, // default: true - collects worker.invocation as a COUNT
    },
    // When using Workers Analytics Engine, a value of 20 or less is recommended due to soft limits
    maxBufferSize: 20,
    // Maximum duration in seconds to buffer before flushing (default: 5, max: 30)
    maxBufferDuration: 5
  }
});
  1. Set up Datadog API key:
# Using wrangler secrets
wrangler secret put DD_API_KEY
# Or DATADOG_API_KEY is also supported
  1. Configure your Worker:
// wrangler.jsonc for the Emitting Worker
{
  "name": "my-worker",
  // Required: Enable the tail_consumers configuration
  "tail_consumers": [
    {
      "service": "name-of-tail-worker",
    }
  ]
}

Environment Variables and Bindings

The Tail Worker supports the following environment variables and bindings:

For Datadog

  • DD_API_KEY or DATADOG_API_KEY: Your Datadog API key

For Workers Analytics Engine

  • Requires an Analytics Engine dataset binding in your wrangler.jsonc:
{
  "analytics_engine_datasets": [
    {
      "binding": "ANALYTICS_ENGINE_DATASET",
      "dataset": "your-dataset-name"
    }
  ]
}

Note: Workers Analytics Engine has a soft limit of 25 writes per invocation, so it's recommended to keep your maxBufferSize at 20 or lower when using this sink.

Default Metrics

The Tail Worker can automatically collect the following metrics without any instrumentation in your main worker:

  1. CPU Time (worker.cpu_time) - A GAUGE metric measuring the CPU time used by the worker in milliseconds
  2. Wall Time (worker.wall_time) - A GAUGE metric measuring the total execution time of the worker in milliseconds
  3. Workers Invocation (worker.invocation) - A COUNT metric that increases by 1 for each worker invocation

These metrics are collected with the same global tags that are applied to your custom metrics (scriptName, executionModel, outcome, versionId).

You can enable or disable these default metrics in the TailExporter configuration:

export default new TailExporter({
  metrics: {
    sinks: [...],
    defaultMetrics: {
      cpuTime: true,           // default: true
      wallTime: true,          // default: true
      workersInvocation: true, // default: true
    }
  }
});