Skip to content

@nodalite/otel

OpenTelemetry integration for Nodalite: built-in tracing, metrics, and context propagation for production observability.

npm install @nodalite/otel

Depends on @nodalite/core and @opentelemetry/api. You must also install an OTel SDK (e.g. @opentelemetry/sdk-trace-node) to export spans and metrics.

otel()

Middleware that creates HTTP server spans and records metrics for every request. Extracts incoming trace context from headers for distributed tracing.

ts
import { otel } from '@nodalite/otel';

app.use('*', otel({ serviceName: 'my-api' }));

Options

OptionTypeDefaultDescription
serviceNamestring"nodalite-app"Service name for OTel resource
tracingbooleantrueEnable span creation
metricsbooleantrueEnable metric instruments
recordHeadersbooleanfalseRecord request headers as span attributes
recordResponseHeadersbooleanfalseRecord response headers as span attributes
ignoredPathsstring[][]Paths to skip (e.g. ['/health'])
getSpanName(c) => stringHTTP methodCustom span naming function

Metrics recorded

The middleware automatically records these OTel instruments:

InstrumentTypeDescription
http.server.request.durationHistogram (ms)Request duration
http.server.active_requestsUpDownCounterCurrently active requests
http.server.request.countCounterTotal request count
http.server.request.body.sizeHistogram (By)Request body size
http.server.response.body.sizeHistogram (By)Response body size

All instruments include attributes: http.request.method, http.response.status_code, http.route.

Span attributes

AttributeDescription
http.request.methodHTTP method
url.fullFull request URL
url.pathRequest path
url.schemeProtocol (http or https)
server.addressHostname
server.portPort
http.response.status_codeResponse status code
http.request.header.*Request headers (when recordHeaders: true)
http.response.header.*Response headers (when recordResponseHeaders: true)

Setup example

ts
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

// Initialize OTel SDK (once, at startup)
const provider = new NodeTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter()));
provider.register();

// Use in your app
import { App } from '@nodalite/core';
import { otel } from '@nodalite/otel';

const app = new App();
app.use('*', otel({ serviceName: 'my-api' }));

getSpan()

Retrieve the current OTel span from the Nodalite context. Returns undefined if no otel() middleware is active.

ts
import { getSpan } from '@nodalite/otel';

app.get('/api/data', async (c) => {
  const span = getSpan(c);
  span?.setAttribute('custom.key', 'value');
  return c.json({ ok: true });
});

Parameters

ParameterTypeDescription
cContextThe Nodalite request context

Returns

Span | undefined — the current OTel span, or undefined if not available.

withSpan()

Execute a function within a new child span. The span is automatically ended when the function completes, and exceptions are recorded.

ts
import { withSpan } from '@nodalite/otel';

app.get('/api/users/:id', async (c) => {
  return withSpan('db-query', async (span) => {
    const user = await db.findUser(c.req.param('id'));
    span.setAttribute('db.system', 'postgresql');
    return c.json(user);
  });
});

Parameters

ParameterTypeDescription
namestringSpan name
fn(span: Span) => Promise<T> | TFunction to execute within the span
optsWithSpanOptionsOptional: { attributes } to set on the span

Returns

The return value of fn. The span is ended automatically (including on error).

createMetrics()

Factory for custom OTel metric instruments beyond the built-in HTTP metrics.

ts
import { createMetrics } from '@nodalite/otel';

const metrics = createMetrics({ serviceName: 'my-api' });

app.get('/api/jobs', async (c) => {
  metrics.jobsProcessed.add(1, { status: 'success' });
  return c.json({ ok: true });
});

Options

OptionTypeDefaultDescription
serviceNamestring"nodalite-app"Service name for the OTel Meter

Returns

An OtelMetrics object containing:

FieldTypeDescription
meterMeterThe underlying OTel Meter for creating custom instruments
requestDurationHistogramHTTP request duration histogram
activeRequestsUpDownCounterActive request counter
requestCountCounterTotal request counter
requestBodySizeHistogramRequest body size histogram
responseBodySizeHistogramResponse body size histogram

Use the meter field to create your own instruments:

ts
const metrics = createMetrics({ serviceName: 'my-api' });
const jobsProcessed = metrics.meter.createCounter('jobs.processed');
const queueDepth = metrics.meter.createUpDownCounter('jobs.queue_depth');

SPAN_KEY

The context key used to store the current span. For advanced use cases where you need direct access to the context map.

ts
import { SPAN_KEY } from '@nodalite/otel';
const span = c.get(SPAN_KEY);

Released under the MIT License.