Traces
OpenTelemetry auto-instrumentation handles most tracing automatically. This page covers manual span creation and exception recording for cases where you need more control.
How Spans Map to Traceway
| OTel Span | Traceway Concept |
|---|---|
| Root SERVER span with HTTP attributes | Endpoint (e.g., GET /api/users) |
| Root span (other kinds) | Task |
| Child span | Span |
| Exception event on any span | Issue |
See OTel Trace Mapping for full details on attributes and conventions.
Manual Span Creation
Use @opentelemetry/api to create custom spans for operations that aren't auto-instrumented:
import { trace, SpanStatusCode } from "@opentelemetry/api";
const tracer = trace.getTracer("my-service");
async function processOrder(orderId: string) {
return tracer.startActiveSpan("process-order", async (span) => {
try {
span.setAttribute("order.id", orderId);
await validateOrder(orderId);
await chargePayment(orderId);
await sendConfirmation(orderId);
span.setStatus({ code: SpanStatusCode.OK });
} catch (error) {
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
span.recordException(error);
throw error;
} finally {
span.end();
}
});
}Nested Spans
Spans created inside an active span are automatically linked as children:
async function chargePayment(orderId: string) {
return tracer.startActiveSpan("charge-payment", async (span) => {
try {
const result = await paymentGateway.charge(orderId);
span.setAttribute("payment.status", result.status);
return result;
} finally {
span.end();
}
});
}Recording Exceptions
Exceptions recorded as span events appear as Issues in Traceway:
import { trace, SpanStatusCode } from "@opentelemetry/api";
function riskyOperation() {
const span = trace.getActiveSpan();
try {
doSomethingDangerous();
} catch (error) {
if (span) {
span.recordException(error);
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
}
throw error;
}
}The recordException call adds an event with exception.type, exception.message, and exception.stacktrace attributes. Traceway normalizes and hashes the stack trace to group identical errors into a single Issue.
Span Attributes
Add attributes to enrich your spans with context:
span.setAttribute("user.id", userId);
span.setAttribute("db.statement", "SELECT * FROM users");
span.setAttributes({
"order.id": orderId,
"order.total": 99.99,
"order.items": 3,
});Context Propagation
OTel automatically propagates trace context across async operations. For manual propagation across service boundaries, use the W3C Trace Context headers:
import { propagation, context } from "@opentelemetry/api";
// Inject trace context into outgoing request headers
const headers = {};
propagation.inject(context.active(), headers);
// The headers now contain `traceparent` and optionally `tracestate`
await fetch("https://other-service.com/api", { headers });Next Steps
- Metrics — custom counters, histograms, and gauges
- Quick Start — setup and installation