From harness-claude
Instruments distributed traces with OpenTelemetry spans to visualize request flow across services. Helps debug slow requests, identify latency sources, and correlate logs to traces.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:otel-tracing-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Instrument distributed traces with OpenTelemetry spans to visualize request flow across services
Instrument distributed traces with OpenTelemetry spans to visualize request flow across services
trace.getTracer('service-name', '1.0.0').tracer.startActiveSpan to automatically propagate context to child spans.span.setAttribute('user.id', userId).span.setStatus({ code: SpanStatusCode.ERROR, message }).finally block — unfinished spans leak memory.http.method, db.system, rpc.method).// services/order-service.ts
import { trace, SpanStatusCode, SpanKind } from '@opentelemetry/api';
const tracer = trace.getTracer('order-service', '1.0.0');
export async function createOrder(userId: string, items: OrderItem[]): Promise<Order> {
return tracer.startActiveSpan(
'createOrder',
{
kind: SpanKind.INTERNAL,
attributes: {
'user.id': userId,
'order.item_count': items.length,
},
},
async (span) => {
try {
// Child span — automatically linked to parent via active context
const inventory = await checkInventory(items);
const order = await tracer.startActiveSpan('db.insertOrder', async (dbSpan) => {
try {
dbSpan.setAttribute('db.system', 'postgresql');
dbSpan.setAttribute('db.operation', 'INSERT');
const result = await db.orders.create({ userId, items, inventory });
return result;
} finally {
dbSpan.end();
}
});
span.setAttribute('order.id', order.id);
span.setStatus({ code: SpanStatusCode.OK });
return order;
} catch (error) {
span.setStatus({
code: SpanStatusCode.ERROR,
message: error instanceof Error ? error.message : 'Unknown error',
});
span.recordException(error as Error);
throw error;
} finally {
span.end();
}
}
);
}
Span hierarchy: Traces are trees of spans. The root span represents the entire request. Child spans represent sub-operations. The span context (trace ID + span ID) propagates automatically when using startActiveSpan.
Span kinds:
SERVER — handling an incoming requestCLIENT — making an outgoing requestINTERNAL — internal operation (default)PRODUCER — sending a message to a queueCONSUMER — receiving a message from a queueSemantic conventions (use these attribute names for tool compatibility):
span.setAttribute('http.method', 'POST');
span.setAttribute('http.url', '/api/orders');
span.setAttribute('http.status_code', 201);
span.setAttribute('db.system', 'postgresql');
span.setAttribute('db.statement', 'INSERT INTO orders ...');
span.setAttribute('messaging.system', 'rabbitmq');
span.setAttribute('messaging.destination', 'order-events');
Span events: Add timestamped events within a span for notable occurrences:
span.addEvent('inventory.checked', {
'inventory.available': true,
'inventory.reserved_count': 5,
});
Common mistakes:
https://opentelemetry.io/docs/concepts/signals/traces/
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudePropagates trace context and emits spans across microservices using OpenTelemetry. Helps debug latency, intermittent failures, and request-level performance.
OpenTelemetry tracing discipline: correct spans, propagation, and semantic conventions produce useful traces. Invoke whenever task involves any interaction with distributed tracing — span creation, context propagation, instrumentation, sampling configuration, or OpenTelemetry SDK setup.
Guides implementing distributed tracing in microservices with OpenTelemetry, covering traces, spans, context propagation, and cross-service debugging.