autotel
Instruments applications with tracing and structured logging for comprehensive observability.
Install
mkdir -p .claude/skills/autotel && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/12000" && unzip -o skill.zip -d .claude/skills/autotel && rm skill.zipInstalls to .claude/skills/autotel
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when instrumenting with trace/span/track, reviewing code for logging and observability patterns, converting console.log to wide events, adding structured errors, setting up canonical log lines, configuring init(), adding subscribers, or working in the autotel monorepo.Key capabilities
- →Instrument functions with tracing using `trace()`
- →Add structured errors with `createStructuredError()`
- →Accumulate request context using `getRequestLogger()`
- →Track events using `ctx.track` or standalone `track()`
How it works
The skill provides APIs like `trace()` to wrap functions, `createStructuredError()` to add context to errors, and `getRequestLogger()` to accumulate request-specific attributes, all contributing to observability.
Inputs & outputs
When to use autotel
- →Adding tracing to functions
- →Converting console.log to wide events
- →Improving error observability
About this skill
Autotel
Philosophy: "Write once, observe everywhere" - instrument once, stream to any OTLP-compatible backend.
trace() wraps functions. getRequestLogger() accumulates context. createStructuredError() adds why/fix/link to errors. Canonical log lines emit one wide event per request automatically.
When to Use
- Instrumenting functions with tracing
- Code uses
console.log/console.errorfor observability - Error handling lacks structured context (no why, fix, or link)
- Adding tracing to any Node.js or edge runtime handler
- Reviewing code for observability anti-patterns
- Setting up observability in Cloudflare Workers, Hono, or Next.js
- Working in the autotel monorepo
Quick Reference
| Task | Reference |
|---|---|
| Convert console.log to wide events | wide-events.md |
| Add structured errors | structured-errors.md |
| Accumulate request context | request-logger.md |
| Review code for anti-patterns | code-review.md |
| Add attribute redaction | (use `init({ attributeRedactor: 'default' |
| Lock init from re-initialization | (use lockLogger() in framework plugins) |
Tracing API
import { trace, span } from 'autotel';
// Factory pattern (receives ctx for attributes)
export const createUser = trace((ctx) => async (data) => {
ctx.setAttribute('user.id', data.id);
return await db.users.create(data);
});
// Direct pattern (no ctx needed)
export const getUser = trace(async (id) => {
return await db.users.findById(id);
});
// Nested span
span('db.insert', async () => {
await db.insert(record);
});
Recording Errors
Default: throw, don't catch. trace() records status, exception, and structured attributes when the wrapped function rejects.
import { trace, createStructuredError } from 'autotel';
export const charge = trace((ctx) => async (cart) => {
if (!cart.items.length) {
throw createStructuredError({
message: 'Cart is empty',
why: 'User submitted checkout with no items',
fix: 'Validate cart on the client before submit',
link: 'https://docs.example.com/errors/empty-cart',
});
}
return await processCart(cart);
});
Fallbacks, in order:
- Attach call-site context, then rethrow:
getRequestLogger(ctx).error(err, { step }). Use when the rethrown error needs context only known at the catch site. - Writing instrumentation/middleware that wraps user handlers:
ctx.recordError(err)from inside atrace((ctx) => ...)callback. Sets ERROR status, structurederror.*attributes, and (during the back-compat window) records the exception. Acceptsunknownso noas Errorcast is needed in catch blocks. For code that doesn't have actxhandle, use the standalone formrecordStructuredError(ctx, err).
// Inside a trace() callback — instrumentation wrapping a user handler:
return trace({ name }, async (ctx) => {
try {
return await userHandler(args);
} catch (err) {
ctx.recordError(err); // ergonomic replacement for ctx.recordException
throw err;
}
});
ctx.recordException(...) and ctx.addEvent(...) are intentionally hidden from the TraceContext type per OTEP 4430 (March 2026. Span Event API deprecation). The runtime methods exist for back-compat only; new code MUST go through createStructuredError, ctx.recordError(err) / recordStructuredError(ctx, err), or the request logger.
Request Logger
import { trace, getRequestLogger } from 'autotel';
export const handleOrder = trace((ctx) => async (req) => {
const log = getRequestLogger(ctx);
log.set({ feature: 'checkout', tier: req.user.tier });
const cart = await loadCart(req.cartId);
log.set({ cart_items: cart.items.length, cart_total: cart.total });
try {
const payment = await processPayment(cart);
log.set({ payment_method: payment.method });
} catch (error) {
// Fallback pattern: attach call-site context, then rethrow.
// Default is to let the error propagate and let trace() record it.
log.error(error, { step: 'payment' });
throw error;
}
});
Event Tracking
import { trace, getEventQueue } from 'autotel';
// Inside trace() — use ctx.track for ergonomic, ctx-bound emission:
export const signup = trace((ctx) => async (data) => {
ctx.track('user.signup', { userId: data.id, plan: data.plan });
return await db.users.create(data);
});
// Outside trace() — use the standalone track():
import { track } from 'autotel';
track('user.signup', { userId: '123', plan: 'pro' });
// MUST flush before assertions or shutdown
await getEventQueue()?.flush();
Correlation ID
import { getOrCreateCorrelationId, runWithCorrelationId } from 'autotel';
const correlationId = getOrCreateCorrelationId();
runWithCorrelationId(incomingId, () => handleRequest());
Framework Adapters
// Cloudflare Workers
import { init, wrapModule, trace } from 'autotel-cloudflare';
const processOrder = trace(async (orderId: string, kv: KVNamespace) => {
return await kv.get(orderId);
});
export default wrapModule(
{ service: { name: 'my-worker' } },
{
async fetch(_req, env) {
return Response.json(await processOrder('123', env.ORDERS_KV));
},
},
);
// Next.js
import { withAutotel, useLogger } from 'autotel-adapters/next';
export const POST = withAutotel(async (request) => {
const log = useLogger(request);
log.set({ feature: 'checkout' });
return Response.json({ ok: true });
});
// Hono (with autotel-hono middleware already creating spans)
import { useLogger } from 'autotel-adapters/hono';
app.get('/orders/:id', (c) => {
const log = useLogger(c);
log.set({ route: c.req.path });
return c.json({ ok: true });
});
Anti-Patterns to Detect
| Anti-Pattern | Fix |
|---|---|
console.log('user created', userId) | log.set({ user_id: userId }) inside trace() |
catch (e) { throw e } | Delete the catch: trace() records errors automatically. Or log.error(e, { step }); throw e to attach call-site context |
catch (e) { res.json({ error: e.message }) } | parseError(e) for consistent shape |
throw new Error('Payment failed') | createStructuredError({ message, why, fix, link }) |
ctx.recordException(err) / span.recordException(err) | App code: throw createStructuredError(...). Instrumentation: ctx.recordError(err) (or recordStructuredError(ctx, err) if you don't have a ctx handle). Span Event API is deprecated (OTEP 4430) and type-gated out of TraceContext |
ctx.addEvent('name', { ... }) / span.addEvent(...) | Discrete event inside trace(): ctx.track('event.name', { ... }) (or standalone track('event.name', { ... }) when there's no ctx handle). Wide-event attribute: getRequestLogger(ctx).set({ ... }) |
(ctx as any).recordException(err) / as unknown as { recordException } | Don't bypass the type gate: use recordStructuredError(ctx, err) instead |
Manual console.log at start/end of function | trace() wrapper handles lifecycle |
| Separate request ID generation | ctx.correlationId provides automatic correlation |
init() Configuration
Signals: Traces, Metrics, Logs
When endpoint is set, traces and metrics are auto-configured by default. Logs are opt-in to avoid unexpected export and preserve OTel SDK OTEL_LOGS_EXPORTER handling:
in
---
*Content truncated.*
When not to use it
- →When the user wants to use `ctx.recordException` or `ctx.addEvent` for new code
- →When the user wants to hand-build log lines from string interpolation
- →When the user wants to use `console.log` for observability
Limitations
- →New code must use `createStructuredError`, `ctx.recordError(err)`, or the request logger
- →`ctx.recordException` and `ctx.addEvent` are hidden from `TraceContext` type
- →Requires flushing event queue before assertions or shutdown
How it compares
This skill implements a 'write once, observe everywhere' philosophy by providing a unified instrumentation framework for tracing, structured errors, and context accumulation, enabling streaming to any OTLP-compatible backend.
Compared to similar skills
autotel side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| autotel (this skill) | 0 | 1mo | Review | Intermediate |
| ai-debug-harness | 0 | 3mo | Review | Advanced |
| gcloud-usage | 1 | 7mo | No flags | Intermediate |
| devops-troubleshooter | 1 | 4mo | No flags | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
ai-debug-harness
DeandreFu
Self-driving Electron + Node debug harness with NDJSON logs, Playwright E2E, doctor preflight, and a YAML-frontmatter cookbook of known causes. Use when a voice-chat E2E flow misbehaves locally, audio publish silently fails, the agent worker emits warnings, or any LiveKit/Electron/Fastify error appe
gcloud-usage
fcakyon
This skill should be used when user asks about "GCloud logs", "Cloud Logging queries", "Google Cloud metrics", "GCP observability", "trace analysis", or "debugging production issues on GCP".
devops-troubleshooter
sickn33
Expert DevOps troubleshooter specializing in rapid incident response, advanced debugging, and modern observability. Masters log analysis, distributed tracing, Kubernetes debugging, performance optimization, and root cause analysis. Handles production outages, system reliability, and preventive monitoring. Use PROACTIVELY for debugging, incident response, or system troubleshooting.
analyze-prod-issue
MaxPayne89
>-
service-mesh-observability
wshobson
Implement comprehensive observability for service meshes including distributed tracing, metrics, and visualization. Use when setting up mesh monitoring, debugging latency issues, or implementing SLOs for service communication.
observability-monitoring-monitor-setup
sickn33
You are a monitoring and observability expert specializing in implementing comprehensive monitoring solutions. Set up metrics collection, distributed tracing, log aggregation, and create insightful da