Trace Correlation
Track a single request as it flows through your entire microservices architecture. See the complete journey from API gateway to database and back.
What is Trace Correlation?
trace_id. When a user reports "payment failed", you can see every log from every service involved in that transaction.Why Trace Correlation?
Debug Faster
See the entire request flow in one unified timeline.
Find Root Causes
Identify exactly which service caused the original failure.
Performance
See where time is spent across your service mesh.
Step 1: Generate & Extract Trace ID
When a request enters your system, generate a unique trace ID and pass it through all services. Our SDKs provide built-in extractors for common headers.
Node.js / TypeScript
import { LuminaLog, generateTraceId, getTraceIdFromRequest } from '@luminalog/sdk';
const logger = new LuminaLog({ apiKey: process.env.LUMINALOG_API_KEY });
// Middleware to extract/generate trace ID
app.use((req, res, next) => {
// Checks x-trace-id, x-request-id, or W3C traceparent
req.traceId = getTraceIdFromRequest(req);
// Return to client for support debugging
res.setHeader('x-trace-id', req.traceId);
next();
});
// Log with trace context
app.post('/api/checkout', async (req, res) => {
logger.info('Processing checkout', {
trace_id: req.traceId,
user_id: req.user.id
});
});Python
from luminalog import LuminaLog, get_trace_id_from_request
logger = LuminaLog(api_key=os.getenv('LUMINALOG_API_KEY'))
@app.middleware("http")
async def trace_middleware(request: Request, call_next):
# Automatically extracts from standard headers
request.state.trace_id = get_trace_id_from_request(request)
response = await call_next(request)
response.headers["x-trace-id"] = request.state.trace_id
return response
@app.post("/api/checkout")
async def checkout(request: Request):
logger.info("Processing checkout", {
"trace_id": request.state.trace_id
})Go
import "github.com/luminalog/sdk-go/luminalog"
func middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Built-in extractor for Go http.Request
traceID := luminalog.GetTraceIDFromRequest(r)
ctx := context.WithValue(r.Context(), "trace_id", traceID)
w.Header().Set("x-trace-id", traceID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}Advanced: Span Hierarchy
For complex flows, use span_id and parent_span_id to create a hierarchical view of operations within a single trace.
import { generateSpanId } from '@luminalog/sdk';
// 1. Service A starts a process
const rootSpanId = generateSpanId();
logger.info('Primary task started', {
trace_id: req.traceId,
span_id: rootSpanId
});
// 2. Service A calls a sub-component or background task
const subTaskId = generateSpanId();
logger.info('Sub-task initiated', {
trace_id: req.traceId,
span_id: subTaskId,
parent_span_id: rootSpanId // Establishes hierarchy
});Spans are visualized as nested elements in the dashboard timeline, making it easy to see which operation triggered another.
Propagation Strategies
Pass the trace_id and the current span_id to downstream services to maintain continuity.
HTTP Propagation
await fetch('https://auth-service/v1/verify', {
headers: {
'x-trace-id': currentTraceId,
'x-parent-span-id': currentSpanId,
'traceparent': `00-${currentTraceId}-${currentSpanId}-01`
}
});Queue Propagation
// SQS / RabbitMQ / Kafka
const message = {
data: req.body,
_context: {
trace_id: req.traceId,
parent_span_id: rootSpanId
}
};
await queue.send(JSON.stringify(message));Step 3: View the Trace
In the LuminaLog dashboard, click the "View Trace" button on any log entry. Our engine automatically reconstructs the tree using your identifiers.
- Chronological request flow
- Visual hierarchy of nested spans
- Error highlighting across the entire chain
- Sub-millisecond performance timing
trace_id: 8f2b...9a41
Best Practices
Recommended
- •Use
getTraceIdFromRequestat the ingress to handle W3C headers. - •Generate a new
span_idfor expensive async operations. - •Pass the context through headers in internal microservice calls.
Avoid
- •Don't log
trace_idinside the message—use the metadata field. - •Don't use sequential IDs; always use UUIDs for safety.