| name | autotel-instrumentation |
| description | trace(), span(), instrument(), init(). Factory vs direct pattern, name inference. Sync init; use node-require for optional deps. Load when wrapping handlers or functions with spans.
|
Autotel — Instrumentation
Wrap functions and handlers with trace(), span(), or instrument(). Call init() once at app startup. Keep init synchronous; use safeRequire/requireModule for optional dependencies.
For new event emission, prefer correlated logs (OTel Logs API path) over adding new direct span-event calls.
Setup
import { init, trace } from 'autotel';
init({ service: 'my-app' });
const handler = trace(async (req: Request) => {
return processRequest(req);
});
With span context (attributes, request logger):
const handler = trace((ctx) => async (req: Request) => {
ctx.setAttribute('http.route', '/api/checkout');
const log = getRequestLogger(ctx);
log.set({ path: req.url });
return processRequest(req);
});
Core Patterns
Explicit span name:
const checkout = trace('checkout', async (body) => {
return processCheckout(body);
});
instrument() with key:
import { instrument } from 'autotel';
const fn = instrument({
key: 'processOrder',
fn: async (id) => db.orders.get(id),
});
span() for a child span:
import { span } from 'autotel';
const result = await span('db.query', async () => db.query(sql));
Init with optional config:
init({
service: 'my-api',
});
Single backend vs multi-backend OTLP:
init({
service: 'my-api',
endpoint: 'https://otlp-gateway-prod.grafana.net/otlp',
});
init({
service: 'my-api',
logs: true,
destinations: [
{
endpoint: 'https://otlp-gateway-prod.grafana.net/otlp',
headers: 'Authorization=Basic ...',
},
{
endpoint: 'https://api.honeycomb.io',
headers: { 'x-honeycomb-team': process.env.HONEYCOMB_API_KEY! },
signals: ['traces'],
},
],
});
Common Mistakes
HIGH Forget to call init() before using trace/span
Wrong:
import { trace } from 'autotel';
export const fn = trace(async () => {});
Correct:
import { init, trace } from 'autotel';
init({ service: 'my-app' });
export const fn = trace(async () => {});
SDK must be initialized; trace() and span() rely on the global tracer.
Source: packages/autotel/CLAUDE.md
MEDIUM Wrong export path for submodules
Wrong:
import { Event } from 'autotel';
import { createTraceCollector } from 'autotel';
Correct:
import { trace, init, getRequestLogger } from 'autotel';
import { Event } from 'autotel/event';
import { createTraceCollector } from 'autotel/testing';
Use the exact export paths from package.json (autotel/event, autotel/testing, autotel/attributes, etc.).
Source: packages/autotel/package.json exports
Version
Targets autotel v2.23.x.
See also: autotel-core/SKILL.md — when to use what. autotel-request-logging/SKILL.md — getRequestLogger requires active span.