{"id":33573114,"url":"https://github.com/jagreehal/autotel","last_synced_at":"2026-06-03T23:01:15.798Z","repository":{"id":325918042,"uuid":"1104394297","full_name":"jagreehal/autotel","owner":"jagreehal","description":"Write once, observe everywhere","archived":false,"fork":false,"pushed_at":"2026-05-29T19:54:02.000Z","size":10766,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-29T21:22:37.361Z","etag":null,"topics":["mcp","observability","otel","pino","posthog","slack"],"latest_commit_sha":null,"homepage":"https://jagreehal.github.io/autotel/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jagreehal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-26T06:43:32.000Z","updated_at":"2026-05-29T19:51:51.000Z","dependencies_parsed_at":"2026-04-29T21:02:17.704Z","dependency_job_id":null,"html_url":"https://github.com/jagreehal/autotel","commit_stats":null,"previous_names":["jagreehal/autotel"],"tags_count":597,"template":false,"template_full_name":null,"purl":"pkg:github/jagreehal/autotel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jagreehal%2Fautotel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jagreehal%2Fautotel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jagreehal%2Fautotel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jagreehal%2Fautotel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jagreehal","download_url":"https://codeload.github.com/jagreehal/autotel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jagreehal%2Fautotel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33883102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mcp","observability","otel","pino","posthog","slack"],"created_at":"2025-11-28T12:12:24.659Z","updated_at":"2026-06-03T23:01:15.781Z","avatar_url":"https://github.com/jagreehal.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔭 autotel\n\n[![npm version](https://img.shields.io/npm/v/autotel.svg?label=autotel)](https://www.npmjs.com/package/autotel)\n[![npm subscribers](https://img.shields.io/npm/v/autotel-subscribers.svg?label=adapters)](https://www.npmjs.com/package/autotel-subscribers)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\n**Write once, observe everywhere.**\n\nInstrument your Node.js code once and stream traces, metrics, logs, and product events to **any** OTLP-compatible backend. No vendor lock-in.\n\n**One `init()`, wrap functions with `trace()`, and get automatic traces, metrics, and events:**\n\n```typescript\nimport { init, trace, track } from 'autotel';\nimport { PostHogSubscriber, SlackSubscriber } from 'autotel-subscribers';\n\n// Initialize once at startup\ninit({\n  service: 'checkout-api',\n  devtools: true, // Local traces + metrics + logs in autotel-devtools\n  subscribers: [\n    new PostHogSubscriber({ apiKey: process.env.POSTHOG_KEY! }),\n    new SlackSubscriber({ webhookUrl: process.env.SLACK_WEBHOOK! }),\n  ],\n});\n\n// Wrap any function - automatic spans, error tracking, and context\nexport const processOrder = trace(async function processOrder(\n  orderId: string,\n  amount: number,\n) {\n  const user = await db.users.findById(orderId);\n  const payment = await chargeCard(user.cardId, amount);\n\n  // Product events automatically enriched with trace context\n  // Sent to: OTLP + PostHog + Slack (all in one call!)\n  track('order.completed', { orderId, amount, userId: user.id });\n\n  return payment;\n});\n```\n\n**That's it.** Every call to `processOrder()` now:\n\n- ✅ Creates a span with automatic error handling\n- ✅ Tracks metrics (duration, success rate)\n- ✅ Sends events with `traceId` and `spanId` to **all** adapters\n- ✅ Works with **any** OTLP-compatible backend (Grafana, Datadog, New Relic, Tempo, etc.)\n\nWrap 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.\n\n**[→ See complete examples and API docs](./packages/autotel/README.md#quick-start)**\n\n## Agent Skills\n\nautotel 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.\n\n```bash\nnpx skills add https://github.com/jagreehal/autotel\n```\n\nOr browse the [`skills/`](./skills) directory directly. Highlights:\n\n- **[`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.\n- **[`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.\n- **[`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.\n- **[`tune-sampling`](./packages/autotel/skills/tune-sampling/SKILL.md)**: head and tail sampling strategies, AI-aware and Cloudflare-aware.\n- **[`build-audit-trails`](./packages/autotel/skills/build-audit-trails/SKILL.md)**: tamper-aware audit logs on top of OTel spans.\n- **[`debug-missing-spans`](./packages/autotel/skills/debug-missing-spans/SKILL.md)**: top-to-bottom troubleshooting walkthrough.\n- **[`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.\n\nSee [`skills/README.md`](./skills/README.md) for the full index.\n\n## Packages\n\nThis monorepo contains the following packages:\n\n### [autotel](./packages/autotel)\n\n[![npm](https://img.shields.io/npm/v/autotel.svg)](https://www.npmjs.com/package/autotel)\n\nCore library providing ergonomic OpenTelemetry instrumentation with:\n\n- Drop-in DX with `trace()`, `span()`, and decorators\n- Adaptive sampling (10% baseline, 100% errors/slow paths)\n- Production hardening (rate limiting, circuit breakers, redaction)\n- Auto trace context enrichment\n- Typed error and audit catalogs (`defineErrorCatalog`, `defineAuditCatalog`)\n- LLM observability via OpenLLMetry, plus per-model cost estimation (`recordLLMCost`)\n- AI workflow patterns (multi-agent, RAG, evaluation loops)\n\n**[→ View full documentation](./packages/autotel/README.md)**\n\n### [autotel-subscribers](./packages/autotel-subscribers)\n\n[![npm](https://img.shields.io/npm/v/autotel-subscribers.svg)](https://www.npmjs.com/package/autotel-subscribers)\n\nProduct events subscribers for:\n\n- PostHog\n- Mixpanel\n- Amplitude\n- Slack webhooks\n- Custom webhooks\n- Filesystem NDJSON (for agents, scripts, and evals)\n\n**[→ View subscribers documentation](./packages/autotel-subscribers/README.md)**\n\n### [autotel-edge](./packages/autotel-edge)\n\n[![npm](https://img.shields.io/npm/v/autotel-edge.svg)](https://www.npmjs.com/package/autotel-edge)\n\nEdge runtime support for:\n\n- Cloudflare Workers\n- Vercel Edge Functions\n- Other edge environments\n\n**[→ View edge documentation](./packages/autotel-edge/README.md)**\n\n### [autotel-adapters](./packages/autotel-adapters)\n\nComposable framework DX adapters on top of `autotel` core:\n\n- `useLogger(...)` style ergonomics for framework handlers\n- `withAutotel(...)` wrappers for Next, Nitro, Cloudflare, Express, and Fastify\n- One canonical wide event per request, emitted automatically (`autoEmit`, default on; opt out per handler)\n- `parseError()` and drain pipeline composition\n- Extensible toolkit for custom framework adapters\n\n**[→ View adapters documentation](./packages/autotel-adapters/README.md)**\n\n### [autotel-audit](./packages/autotel-audit)\n\n[![npm](https://img.shields.io/npm/v/autotel-audit.svg)](https://www.npmjs.com/package/autotel-audit)\n\nAudit-focused helpers for compliance logging with automatic tail-sampling bypass:\n\n- `withAudit(...)`: structured audit metadata with automatic outcome tagging\n- `forceKeepAuditEvent(...)`: keep critical audit trails past tail-drop sampling\n- `setAuditAttributes(...)`: normalized `audit.*` span attributes\n- Type-safe metadata schemas and backend integration\n\n**[→ View audit documentation](./packages/autotel-audit/README.md)**\n\n## Migrating from OpenTelemetry?\n\n**[Migration Guide](./docs/MIGRATION.md)** - Migrate from vanilla OpenTelemetry to autotel:\n\n- Quick start with copy-paste code examples\n- Pattern-by-pattern transformations (environment variables, manual SDK setup, manual spans, logger integration, sampling)\n- Side-by-side before/after comparisons\n- 9-phase migration checklist\n- Edge cases and when not to migrate\n\nTypical migration: Replace `NODE_OPTIONS` and 30+ lines of SDK boilerplate with `init()`, wrap functions with `trace()` instead of manual `span.start()`/`span.end()`.\n\n## Quick Start\n\n```bash\nnpm install autotel\n# Optional: Add event subscribers (PostHog, Slack, Mixpanel, etc.)\nnpm install autotel-subscribers\n# Optional but recommended for local DX\nnpm install -D autotel-devtools\n# or\npnpm add autotel\npnpm add autotel-subscribers  # Optional\npnpm add -D autotel-devtools  # Optional but recommended\n```\n\n### Quick Local Observability\n\nFor the fastest feedback loop, run local devtools and point autotel at it:\n\n```typescript\nimport { init, trace } from 'autotel';\n\ninit({\n  service: 'my-app',\n  devtools: true,\n});\n\nconst result = await trace(async () =\u003e 'success')();\n```\n\nThat gives you:\n- traces, metrics, and logs in one local UI\n- no manual OTLP URL wiring for day-to-day development\n- the same `init()` surface you can later point at Grafana, Datadog, or any OTLP backend\n\nIf you want autotel to boot the local devtools server for you:\n\n```typescript\ninit({\n  service: 'my-app',\n  devtools: { embedded: true },\n});\n```\n\nThis requires `autotel-devtools` to be installed. If it is not installed, autotel falls back to `http://127.0.0.1:4318`.\n\n### Quick Debug Mode\n\nSee traces during development without configuring a backend:\n\n```typescript\nimport { init, trace } from 'autotel';\n\n// Start with console-only (no backend needed)\ninit({\n  service: 'my-app',\n  debug: true  // Outputs spans to console\n});\n\n// Your traced functions work as normal\nconst result = await trace(async () =\u003e {\n  // Your code here\n  return 'success';\n})();\n\n// Span printed to console automatically!\n```\n\n**How it works:**\n- `debug: true` - Print spans to console AND send to backend (if endpoint configured)\n  - No endpoint = console-only output for local development\n  - With endpoint = console + backend (verify before choosing provider)\n- No debug flag - Send to backend only (default production behavior)\n\nOr use environment variable:\n```bash\nAUTOTEL_DEBUG=true node server.js\n```\n\n### Environment Variables\n\nConfigure autotel using standard OpenTelemetry environment variables:\n\n```bash\nexport OTEL_SERVICE_NAME=my-app\nexport OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318\nexport OTEL_EXPORTER_OTLP_HEADERS=x-honeycomb-team=YOUR_API_KEY\nexport OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production\n```\n\nFor local development, `devtools: true` is usually a better default than setting `OTEL_EXPORTER_OTLP_ENDPOINT` manually.\n\nThen call `init()` without any config - it picks up env vars automatically:\n\n```typescript\ninit({ service: 'my-app' }); // Minimal config, env vars fill the rest\n```\n\n**[→ See complete environment variable documentation](./packages/autotel/README.md#configuration-reference)**\n\n**[→ Full API documentation](./packages/autotel/README.md)**\n\n## Development\n\n### Prerequisites\n\n- Node.js 22+\n- pnpm 8+\n\n### Setup\n\n```bash\n# Clone and install dependencies\ngit clone https://github.com/jagreehal/autotel.git\ncd autotel\npnpm install\n\n# Build all packages\npnpm build\n\n# Run tests\npnpm test\n\n# Run example apps\npnpm --filter @jagreehal/example-basic start\npnpm --filter @jagreehal/example-http start\n```\n\n### Project Structure\n\n```text\nautotel/\n├── packages/\n│   ├── autotel/          # Core library\n│   ├── autotel-subscribers/ # Event subscribers\n│   └── autotel-edge/     # Edge runtime support\n├── apps/\n│   ├── example-basic/        # Basic usage example\n│   ├── example-http/         # Express server example\n│   └── cloudflare-example/   # Cloudflare Workers example\n└── turbo.json                # Turborepo configuration\n```\n\n### Available Scripts\n\n```bash\n# Development\npnpm dev              # Watch mode for all packages\npnpm build            # Build all packages\npnpm test             # Run all tests\npnpm test:integration # Run integration tests\n\n# Code quality\npnpm lint             # Lint all packages\npnpm format           # Format code with Prettier\npnpm type-check       # TypeScript type checking\n\n# Releases\npnpm changeset        # Create a changeset\npnpm version-packages # Version packages\npnpm release          # Publish to npm\n```\n\n### Running Examples\n\n#### Basic Example\n\n```bash\npnpm --filter @jagreehal/example-basic start\n```\n\n#### HTTP Server Example\n\n```bash\npnpm --filter @jagreehal/example-http start\n```\n\n#### Cloudflare Workers Example\n\n```bash\npnpm --filter cloudflare-example dev\n```\n\n## Contributing\n\nWe welcome contributions! Please see our [contributing guidelines](./CONTRIBUTING.md) for details.\n\n### Development Workflow\n\n1. **Fork and clone** the repository\n2. **Create a branch** for your feature: `git checkout -b feature/my-feature`\n3. **Make your changes** and add tests\n4. **Run tests**: `pnpm test`\n5. **Create a changeset**: `pnpm changeset`\n6. **Commit your changes**: `git commit -am \"Add new feature\"`\n7. **Push to your fork**: `git push origin feature/my-feature`\n8. **Open a pull request**\n\n### Adding a Changeset\n\nWe use [changesets](https://github.com/changesets/changesets) for version management:\n\n```bash\npnpm changeset\n```\n\nFollow the prompts to:\n\n1. Select which packages changed\n2. Choose semver bump (major/minor/patch)\n3. Write a summary of your changes\n\n## Architecture\n\nAutotel is built on top of OpenTelemetry and provides:\n\n- **Ergonomic API layer** - Wraps verbose OpenTelemetry APIs\n- **Smart defaults** - Production-ready configuration without tuning\n- **Platform agnostic** - Works with any OTLP-compatible backend\n- **Type-safe** - Full TypeScript support with strict types\n- **Modular design** - Use only what you need\n\n## Why Autotel?\n\n| Challenge                           | With autotel                                    |\n| ----------------------------------- | --------------------------------------------------- |\n| Raw OpenTelemetry is verbose        | One-line `trace()` wrapper with automatic lifecycle |\n| Vendor SDKs create lock-in          | OTLP-native, works with any backend                 |\n| Need both observability \u0026 events | Unified API for traces, metrics, logs, and events   |\n| Production safety concerns          | Built-in sampling, rate limiting, redaction         |\n\n## Troubleshooting\n\nHaving 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.\n\n## Roadmap\n\n- [x] Core tracing API\n- [x] Metrics support\n- [x] Log correlation\n- [x] Product events subscribers\n- [x] Edge runtime support\n- [x] LLM observability (OpenLLMetry)\n\n## Community \u0026 Support\n\n- [Report bugs](https://github.com/jagreehal/autotel/issues)\n- [Request features](https://github.com/jagreehal/autotel/discussions)\n- [Join discussions](https://github.com/jagreehal/autotel/discussions)\n\n## License\n\nMIT - See [LICENSE](./LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjagreehal%2Fautotel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjagreehal%2Fautotel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjagreehal%2Fautotel/lists"}