instrumentation.ts

It's easy to add observability to your indexer using our native instrumentation powered by OpenTelemetry.

Convention

To add instrumentation to your project, create a instrumentation.ts file at the root (next to apibara.config.ts).

This file should export a register function, this function is called once by the runtime before the production indexer is started.

instrumentation.ts
import type { RegisterFn } from "apibara/types";

export const register: RegisterFn = async () => {
  // Setup OpenTelemetry SDK exporter
};

Logger

You can also replace the default logger by exporting a logger function from instrumentation.ts. This function should return a console-like object with the same methods as console.

instrumentation.ts
import type { LoggerFactoryFn } from "apibara/types";

export const logger: LoggerFactoryFn = ({ indexer, indexers, preset }) => {
  // Build console here.
};

Examples

OpenTelemetry with OpenTelemetry Collector

The OpenTelemetry Collector offers a vendor-agnostic implementation for receiving, processing, and exporting telemetry data. Using the collector with Apibara allows you to collect and send both metrics and traces to your preferred observability backend.

1. Install required dependencies

First, install the required OpenTelemetry packages:

Terminal
pnpm install @opentelemetry/api @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-metrics-otlp-grpc @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/resources @opentelemetry/sdk-node @opentelemetry/sdk-metrics @opentelemetry/sdk-trace-node @opentelemetry/semantic-conventions

2. Update instrumentation.ts to use the OpenTelemetry Collector

Create or update the instrumentation.ts file at the root of your project:

instrumentation.ts
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-grpc";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
import {
  defaultResource,
  resourceFromAttributes,
} from "@opentelemetry/resources";
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-node";
import {
  ATTR_SERVICE_NAME,
  ATTR_SERVICE_VERSION,
} from "@opentelemetry/semantic-conventions";
import type { RegisterFn } from "apibara/types";

export const register: RegisterFn = async () => {
  // Create a resource that identifies your service
  const resource = defaultResource().merge(
    resourceFromAttributes({
      [ATTR_SERVICE_NAME]: "apibara",
      [ATTR_SERVICE_VERSION]: "1.0.0",
    })
  );
  const collectorOptions = {
    // configure the grpc endpoint of the opentelemetry-collector
    url: "http://localhost:4317",
  };

  // Configure the OTLP exporter for metrics using grpc protocol,
  const metricExporter = new OTLPMetricExporter(collectorOptions);
  const metricReader = new PeriodicExportingMetricReader({
    exporter: metricExporter,
    exportIntervalMillis: 1000,
  });

  // Configure the OTLP exporter for traces using grpc protocol,
  const traceExporter = new OTLPTraceExporter(collectorOptions);
  const spanProcessors = [new SimpleSpanProcessor(traceExporter)];

  // Configure the SDK
  const sdk = new NodeSDK({
    resource,
    spanProcessors,
    metricReader,
    instrumentations: [getNodeAutoInstrumentations()],
  });

  // Start the SDK
  sdk.start();
};

3. Build and run your indexer to see the metrics and traces on the configured OpenTelemetry Collector.

Terminal
pnpm build
pnpm start --indexer=your-indexer

The following metrics are available out of the box:

  • current_block: The latest block number being processed by the indexer
  • processed_blocks_total: Total number of blocks that have been processed
  • reorgs_total: Number of chain reorganizations detected and handled

Additionally, you can observe detailed traces showing:

  • Block processing lifecycle and duration
  • Individual transform function execution time
  • Chain reorganization handling

Prometheus

Collecting metrics with Prometheus and visualizing them is a powerful way to monitor your indexers. This section shows how to set up OpenTelemetry with Prometheus.

1. Install required dependencies

First, install the required OpenTelemetry packages:

Terminal
pnpm install @opentelemetry/api @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-prometheus @opentelemetry/resources @opentelemetry/sdk-node @opentelemetry/semantic-conventions

2. Update instrumentation.ts to use the OpenTelemetry SDK

Update the instrumentation.ts file at the root of your project:

instrumentation.ts
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { PrometheusExporter } from "@opentelemetry/exporter-prometheus";
import {
  defaultResource,
  resourceFromAttributes,
} from "@opentelemetry/resources";
import { NodeSDK } from "@opentelemetry/sdk-node";
import {
  ATTR_SERVICE_NAME,
  ATTR_SERVICE_VERSION,
} from "@opentelemetry/semantic-conventions";
import type { RegisterFn } from "apibara/types";

export const register: RegisterFn = async () => {
  // Create a resource that identifies your service
  const resource = defaultResource().merge(
    resourceFromAttributes({
      [ATTR_SERVICE_NAME]: "apibara",
      [ATTR_SERVICE_VERSION]: "1.0.0",
    })
  );

  // By default port 9464 will be exposed on the apibara app
  const prometheusExporter = new PrometheusExporter();

  // Configure the SDK
  const sdk = new NodeSDK({
    resource,
    metricReader: prometheusExporter,
    instrumentations: [getNodeAutoInstrumentations()],
  });

  sdk.start();
};

3. Build and run your indexer to see the metrics and traces on your configured observability platform.

Terminal
pnpm build
pnpm start --indexer=your-indexer

Sentry

1. Install required dependencies

First, install the required Sentry package:

Terminal
pnpm install @sentry/node

2. Update instrumentation.ts to use Sentry

Update the instrumentation.ts file at the root of your project:

instrumentation.ts
import * as Sentry from "@sentry/node";
import type { RegisterFn } from "apibara/types";

export const register: RegisterFn = async () => {
  Sentry.init({
    dsn: "__YOUR_DSN__",
    tracesSampleRate: 1.0,
  });
};

3. Build and run your indexer with Sentry error tracking enabled

Terminal
pnpm build
pnpm start --indexer=your-indexer

The Sentry SDK uses OpenTelemetry under the hood, which means any OpenTelemetry instrumentation that emits spans will automatically be picked up by Sentry without additional configuration.

For more information on how to use Sentry with OpenTelemetry, refer to the Sentry documentation.

Last modified
Apibara

Apibara is the fastest platform to build production-grade indexers that connect onchain data to web2 services.

© 2025 GNC Labs Limited. All rights reserved.

Cookie Notice

We use cookies to enhance your browsing experience.