https://github.com/jagreehal/autotel
Write once, observe everywhere
https://github.com/jagreehal/autotel
mcp observability otel pino posthog slack
Last synced: 9 days ago
JSON representation
Write once, observe everywhere
- Host: GitHub
- URL: https://github.com/jagreehal/autotel
- Owner: jagreehal
- License: mit
- Created: 2025-11-26T06:43:32.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-05-29T19:54:02.000Z (14 days ago)
- Last Synced: 2026-05-29T21:22:37.361Z (14 days ago)
- Topics: mcp, observability, otel, pino, posthog, slack
- Language: TypeScript
- Homepage: https://jagreehal.github.io/autotel/
- Size: 10.3 MB
- Stars: 4
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# 🔠autotel
[](https://www.npmjs.com/package/autotel)
[](https://www.npmjs.com/package/autotel-subscribers)
[](LICENSE)
**Write once, observe everywhere.**
Instrument your Node.js code once and stream traces, metrics, logs, and product events to **any** OTLP-compatible backend. No vendor lock-in.
**One `init()`, wrap functions with `trace()`, and get automatic traces, metrics, and events:**
```typescript
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 `traceId` and `spanId` to **all** adapters
- ✅ Works with **any** OTLP-compatible backend (Grafana, Datadog, New Relic, Tempo, etc.)
Wrap a handler and autotel emits one canonical wide event per request (full context in a single log line) on top of real distributed traces and metrics. You get the debuggability of one event per operation and the call graph of OpenTelemetry from the same instrumentation.
**[→ See complete examples and API docs](./packages/autotel/README.md#quick-start)**
## Agent Skills
autotel ships **35 Agent Skills** for AI assistants (Claude Code, Cursor, Windsurf, Continue, …): one per package, plus a `review-otel-patterns` skill that surveys 13+ frameworks. Compatible agents discover them automatically.
```bash
npx skills add https://github.com/jagreehal/autotel
```
Or browse the [`skills/`](./skills) directory directly. Highlights:
- **[`review-otel-patterns`](./packages/autotel/skills/review-otel-patterns/SKILL.md)**: 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`](./packages/autotel/skills/analyze-traces/SKILL.md)**: read OTLP traces from any backend, local dump, or in-memory exporter to debug failures, latency, and cardinality issues.
- **[`migrate-to-autotel`](./packages/autotel/skills/migrate-to-autotel/SKILL.md)**: cut over from raw OTel SDK, Sentry, Datadog APM, New Relic, Honeycomb Beelines, or OpenTracing.
- **[`tune-sampling`](./packages/autotel/skills/tune-sampling/SKILL.md)**: head and tail sampling strategies, AI-aware and Cloudflare-aware.
- **[`build-audit-trails`](./packages/autotel/skills/build-audit-trails/SKILL.md)**: tamper-aware audit logs on top of OTel spans.
- **[`debug-missing-spans`](./packages/autotel/skills/debug-missing-spans/SKILL.md)**: top-to-bottom troubleshooting walkthrough.
- **[`create-autotel-adapter`](./skills/create-autotel-adapter/SKILL.md)** / **[`create-autotel-instrumentation`](./skills/create-autotel-instrumentation/SKILL.md)** / **[`create-autotel-exporter`](./skills/create-autotel-exporter/SKILL.md)**: author new packages following autotel conventions, with templates included.
See [`skills/README.md`](./skills/README.md) for the full index.
## Packages
This monorepo contains the following packages:
### [autotel](./packages/autotel)
[](https://www.npmjs.com/package/autotel)
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
- Typed error and audit catalogs (`defineErrorCatalog`, `defineAuditCatalog`)
- LLM observability via OpenLLMetry, plus per-model cost estimation (`recordLLMCost`)
- AI workflow patterns (multi-agent, RAG, evaluation loops)
**[→ View full documentation](./packages/autotel/README.md)**
### [autotel-subscribers](./packages/autotel-subscribers)
[](https://www.npmjs.com/package/autotel-subscribers)
Product events subscribers for:
- PostHog
- Mixpanel
- Amplitude
- Slack webhooks
- Custom webhooks
- Filesystem NDJSON (for agents, scripts, and evals)
**[→ View subscribers documentation](./packages/autotel-subscribers/README.md)**
### [autotel-edge](./packages/autotel-edge)
[](https://www.npmjs.com/package/autotel-edge)
Edge runtime support for:
- Cloudflare Workers
- Vercel Edge Functions
- Other edge environments
**[→ View edge documentation](./packages/autotel-edge/README.md)**
### [autotel-adapters](./packages/autotel-adapters)
Composable framework DX adapters on top of `autotel` core:
- `useLogger(...)` style ergonomics for framework handlers
- `withAutotel(...)` wrappers for Next, Nitro, Cloudflare, Express, and Fastify
- One canonical wide event per request, emitted automatically (`autoEmit`, default on; opt out per handler)
- `parseError()` and drain pipeline composition
- Extensible toolkit for custom framework adapters
**[→ View adapters documentation](./packages/autotel-adapters/README.md)**
### [autotel-audit](./packages/autotel-audit)
[](https://www.npmjs.com/package/autotel-audit)
Audit-focused helpers for compliance logging with automatic tail-sampling bypass:
- `withAudit(...)`: structured audit metadata with automatic outcome tagging
- `forceKeepAuditEvent(...)`: keep critical audit trails past tail-drop sampling
- `setAuditAttributes(...)`: normalized `audit.*` span attributes
- Type-safe metadata schemas and backend integration
**[→ View audit documentation](./packages/autotel-audit/README.md)**
## Migrating from OpenTelemetry?
**[Migration Guide](./docs/MIGRATION.md)** - 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()`.
## Quick Start
```bash
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 recommended
```
### Quick Local Observability
For the fastest feedback loop, run local devtools and point autotel at it:
```typescript
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:
```typescript
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`.
### Quick Debug Mode
See traces during development without configuring a backend:
```typescript
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 output 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:
```bash
AUTOTEL_DEBUG=true node server.js
```
### Environment Variables
Configure autotel using standard OpenTelemetry environment variables:
```bash
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=production
```
For 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:
```typescript
init({ service: 'my-app' }); // Minimal config, env vars fill the rest
```
**[→ See complete environment variable documentation](./packages/autotel/README.md#configuration-reference)**
**[→ Full API documentation](./packages/autotel/README.md)**
## Development
### Prerequisites
- Node.js 22+
- pnpm 8+
### Setup
```bash
# 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 start
```
### Project Structure
```text
autotel/
├── 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
```
### Available Scripts
```bash
# 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 npm
```
### Running Examples
#### Basic Example
```bash
pnpm --filter @jagreehal/example-basic start
```
#### HTTP Server Example
```bash
pnpm --filter @jagreehal/example-http start
```
#### Cloudflare Workers Example
```bash
pnpm --filter cloudflare-example dev
```
## Contributing
We welcome contributions! Please see our [contributing guidelines](./CONTRIBUTING.md) for details.
### Development Workflow
1. **Fork and clone** the repository
2. **Create a branch** for your feature: `git checkout -b feature/my-feature`
3. **Make your changes** and add tests
4. **Run tests**: `pnpm test`
5. **Create a changeset**: `pnpm changeset`
6. **Commit your changes**: `git commit -am "Add new feature"`
7. **Push to your fork**: `git push origin feature/my-feature`
8. **Open a pull request**
### Adding a Changeset
We use [changesets](https://github.com/changesets/changesets) for version management:
```bash
pnpm changeset
```
Follow the prompts to:
1. Select which packages changed
2. Choose semver bump (major/minor/patch)
3. Write a summary of your changes
## Architecture
Autotel is built on top of OpenTelemetry and provides:
- **Ergonomic API layer** - Wraps verbose OpenTelemetry APIs
- **Smart defaults** - Production-ready configuration without tuning
- **Platform agnostic** - Works with any OTLP-compatible backend
- **Type-safe** - Full TypeScript support with strict types
- **Modular design** - Use only what you need
## Why Autotel?
| 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 |
## Troubleshooting
Having issues seeing your traces? Use `ConsoleSpanExporter` for visual debugging or `InMemorySpanExporter` for testing. See the [full troubleshooting guide](./packages/autotel/README.md#troubleshooting--debugging) in the detailed docs.
## Roadmap
- [x] Core tracing API
- [x] Metrics support
- [x] Log correlation
- [x] Product events subscribers
- [x] Edge runtime support
- [x] LLM observability (OpenLLMetry)
## Community & Support
- [Report bugs](https://github.com/jagreehal/autotel/issues)
- [Request features](https://github.com/jagreehal/autotel/discussions)
- [Join discussions](https://github.com/jagreehal/autotel/discussions)
## License
MIT - See [LICENSE](./LICENSE) for details.