Write once, observe everywhere.
Instrument your Node.js code a single time, keep the DX you love, and stream traces, metrics, logs, and product events to any observability stack without vendor lock-in.
One init(), wrap functions with trace(), and get automatic traces, metrics, and events:
import { init, trace, track } from 'autotel';
import { PostHogSubscriber, SlackSubscriber } from 'autotel-subscribers';
// Initialize once at startup
init({
service: 'checkout-api',
devtools: true, // Local traces + metrics + logs in autotel-devtools
subscribers: [
new PostHogSubscriber({ apiKey: process.env.POSTHOG_KEY! }),
new SlackSubscriber({ webhookUrl: process.env.SLACK_WEBHOOK! }),
],
});
// Wrap any function - automatic spans, error tracking, and context
export const processOrder = trace(async function processOrder(
orderId: string,
amount: number,
) {
const user = await db.users.findById(orderId);
const payment = await chargeCard(user.cardId, amount);
// Product events automatically enriched with trace context
// Sent to: OTLP + PostHog + Slack (all in one call!)
track('order.completed', { orderId, amount, userId: user.id });
return payment;
});That's it. Every call to processOrder() now:
- ✅ Creates a span with automatic error handling
- ✅ Tracks metrics (duration, success rate)
- ✅ Sends events with
traceIdandspanIdto all adapters - ✅ Works with any OTLP-compatible backend (Grafana, Datadog, New Relic, Tempo, etc.)
→ See complete examples and API docs
autotel ships 35 Agent Skills for AI assistants (Claude Code, Cursor, Windsurf, Continue, …) — one per package plus a flagship "review-otel-patterns" skill that surveys 13+ frameworks. Skills are auto-discovered by compatible agents.
npx skills add https://github.com/jagreehal/autotelOr browse the skills/ directory directly. Highlights:
review-otel-patterns— audit a codebase for OTel anti-patterns; covers Next.js, Nuxt, Nitro, TanStack Start, Hono, Express, Fastify, Elysia, NestJS, Cloudflare Workers, AWS Lambda, edge runtimes, and standalone Node.analyze-traces— read OTLP traces from any backend, local dump, or in-memory exporter to debug failures, latency, and cardinality issues.migrate-to-autotel— safe cutover from raw OTel SDK / Sentry / Datadog APM / New Relic / Honeycomb Beelines / OpenTracing.tune-sampling— head + tail sampling strategies, AI-aware, Cloudflare-aware.build-audit-trails— tamper-aware audit logs on top of OTel spans.debug-missing-spans— top-to-bottom troubleshooting walkthrough.create-autotel-adapter/create-autotel-instrumentation/create-autotel-exporter— author new packages following autotel conventions, with templates included.
See skills/README.md for the full index.
This monorepo contains the following packages:
Core library providing ergonomic OpenTelemetry instrumentation with:
- Drop-in DX with
trace(),span(), and decorators - Adaptive sampling (10% baseline, 100% errors/slow paths)
- Production hardening (rate limiting, circuit breakers, redaction)
- Auto trace context enrichment
- LLM observability via OpenLLMetry integration
- AI workflow patterns (multi-agent, RAG, evaluation loops)
Product events subscribers for:
- PostHog
- Mixpanel
- Amplitude
- Slack webhooks
- Custom webhooks
→ View subscribers documentation
Edge runtime support for:
- Cloudflare Workers
- Vercel Edge Functions
- Other edge environments
Composable framework DX adapters on top of autotel core:
useLogger(...)style ergonomics for framework handlerswithAutotel(...)wrappers for Next/Nitro-style handler DXparseError()and drain pipeline composition- Extensible toolkit for custom framework adapters
Audit-focused helpers for compliance logging with automatic tail-sampling bypass:
withAudit(...)— Structured audit metadata with automatic outcome taggingforceKeepAuditEvent(...)— Ensure critical audit trails bypass tail-drop samplingsetAuditAttributes(...)— Normalizedaudit.*span attributes- Type-safe metadata schemas and backend integration
Migration Guide - Migrate from vanilla OpenTelemetry to autotel:
- Quick start with copy-paste code examples
- Pattern-by-pattern transformations (environment variables, manual SDK setup, manual spans, logger integration, sampling)
- Side-by-side before/after comparisons
- 9-phase migration checklist
- Edge cases and when not to migrate
Typical migration: Replace NODE_OPTIONS and 30+ lines of SDK boilerplate with init(), wrap functions with trace() instead of manual span.start()/span.end().
npm install autotel
# Optional: Add event subscribers (PostHog, Slack, Mixpanel, etc.)
npm install autotel-subscribers
# Optional but recommended for local DX
npm install -D autotel-devtools
# or
pnpm add autotel
pnpm add autotel-subscribers # Optional
pnpm add -D autotel-devtools # Optional but recommendedFor the fastest feedback loop, run local devtools and point autotel at it:
import { init, trace } from 'autotel';
init({
service: 'my-app',
devtools: true,
});
const result = await trace(async () => 'success')();That gives you:
- traces, metrics, and logs in one local UI
- no manual OTLP URL wiring for day-to-day development
- the same
init()surface you can later point at Grafana, Datadog, or any OTLP backend
If you want autotel to boot the local devtools server for you:
init({
service: 'my-app',
devtools: { embedded: true },
});This requires autotel-devtools to be installed. If it is not installed, autotel falls back to http://127.0.0.1:4318.
See traces instantly during development - perfect for progressive development:
import { init, trace } from 'autotel';
// Start with console-only (no backend needed)
init({
service: 'my-app',
debug: true // Outputs spans to console
});
// Your traced functions work as normal
const result = await trace(async () => {
// Your code here
return 'success';
})();
// Span printed to console automatically!How it works:
debug: true- Print spans to console AND send to backend (if endpoint configured)- No endpoint = console-only (perfect for local development)
- With endpoint = console + backend (verify before choosing provider)
- No debug flag - Send to backend only (default production behavior)
Or use environment variable:
AUTOTEL_DEBUG=true node server.jsConfigure autotel using standard OpenTelemetry environment variables:
export OTEL_SERVICE_NAME=my-app
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_EXPORTER_OTLP_HEADERS=x-honeycomb-team=YOUR_API_KEY
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=productionFor local development, devtools: true is usually a better default than setting OTEL_EXPORTER_OTLP_ENDPOINT manually.
Then call init() without any config - it picks up env vars automatically:
init({ service: 'my-app' }); // Minimal config, env vars fill the rest→ See complete environment variable documentation
- Node.js 22+
- pnpm 8+
# Clone and install dependencies
git clone https://github.com/jagreehal/autotel.git
cd autotel
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Run example apps
pnpm --filter @jagreehal/example-basic start
pnpm --filter @jagreehal/example-http startautotel/
├── packages/
│ ├── autotel/ # Core library
│ ├── autotel-subscribers/ # Event subscribers
│ └── autotel-edge/ # Edge runtime support
├── apps/
│ ├── example-basic/ # Basic usage example
│ ├── example-http/ # Express server example
│ └── cloudflare-example/ # Cloudflare Workers example
└── turbo.json # Turborepo configuration
# Development
pnpm dev # Watch mode for all packages
pnpm build # Build all packages
pnpm test # Run all tests
pnpm test:integration # Run integration tests
# Code quality
pnpm lint # Lint all packages
pnpm format # Format code with Prettier
pnpm type-check # TypeScript type checking
# Releases
pnpm changeset # Create a changeset
pnpm version-packages # Version packages
pnpm release # Publish to npmpnpm --filter @jagreehal/example-basic startpnpm --filter @jagreehal/example-http startpnpm --filter cloudflare-example devWe welcome contributions! Please see our contributing guidelines for details.
- Fork and clone the repository
- Create a branch for your feature:
git checkout -b feature/my-feature - Make your changes and add tests
- Run tests:
pnpm test - Create a changeset:
pnpm changeset - Commit your changes:
git commit -am "Add new feature" - Push to your fork:
git push origin feature/my-feature - Open a pull request
We use changesets for version management:
pnpm changesetFollow the prompts to:
- Select which packages changed
- Choose semver bump (major/minor/patch)
- Write a summary of your changes
Autotel is built on top of OpenTelemetry and provides:
- Ergonomic API layer - Wraps verbose OpenTelemetry APIs
- Smart defaults - Production-ready configuration out of the box
- Platform agnostic - Works with any OTLP-compatible backend
- Type-safe - Full TypeScript support with strict types
- Modular design - Use only what you need
| Challenge | With autotel |
|---|---|
| Raw OpenTelemetry is verbose | One-line trace() wrapper with automatic lifecycle |
| Vendor SDKs create lock-in | OTLP-native, works with any backend |
| Need both observability & events | Unified API for traces, metrics, logs, and events |
| Production safety concerns | Built-in sampling, rate limiting, redaction |
Having issues seeing your traces? Use ConsoleSpanExporter for visual debugging or InMemorySpanExporter for testing. See the full troubleshooting guide in the detailed docs.
- Core tracing API
- Metrics support
- Log correlation
- Product events subscribers
- Edge runtime support
- LLM observability (OpenLLMetry)
MIT - See LICENSE for details.