DEV Community

Abhishek Dave for SSOJet

Posted on • Originally published at ssojet.com on

Traces vs Metrics vs Logs in OpenTelemetry

I’ve been diving deep into OpenTelemetry lately and wanted to share what I’ve learned about the three pillars of observability. If you’re anything like me, you’ve probably been confused about when to use traces vs metrics vs logs. In this post, I’ll break down each of these observability signals and share some real-world examples. I’ll also cover how these three pieces fit together in OpenTelemetry’s framework, and share some practical tips. Whether you’re just getting started with observability or looking to level up your debugging game, this guide should help clear the fog. OpenTelemetry, the CNCF-backed standard for observability, helps developers collect traces , metrics , and logs in a unified way.

But what’s the difference between these three pillars? And how can you actually implement them in your Go or Node.js apps?

Let’s break it down.


🧵 Traces: Follow the Request’s Journey

Traces track the full lifecycle of a request across services.

Imagine a user hits your frontend, which calls your API, which queries a database. A trace captures that entire flow as a tree of spans , each representing an operation.

✅ What Traces Answer

  • Where is the latency coming from?
  • Which service is failing?
  • How are requests flowing through the system?

🧪 Go Example

tr := otel.Tracer("my-service")
ctx, span := tr.Start(ctx, "HandleRequest")
defer span.End()

// Do some work...

Enter fullscreen mode Exit fullscreen mode

🧪 Node.js Example

const tracer = opentelemetry.trace.getTracer('my-service');
const span = tracer.startSpan('handleRequest');
// ...work...
span.end();

Enter fullscreen mode Exit fullscreen mode

📈 Metrics: Know the System Health

Metrics are numerical values measured over time. Think counters, gauges, histograms.

They help you understand system-wide health and performance trends.

✅ What Metrics Answer

  • What’s the current CPU/memory usage?
  • How many requests/errors per second?
  • Is latency getting worse over time?

🧪 Go Example

meter := global.Meter("my-service")
counter, _ := meter.Int64Counter("http_requests_total")

counter.Add(ctx, 1, attribute.String("route", "/login"))

Enter fullscreen mode Exit fullscreen mode

🧪 Node.js Example (with Prometheus)

const client = require('prom-client');
const httpCounter = new client.Counter({
  name: 'http_requests_total',
  help: 'Total HTTP requests',
});

httpCounter.inc();

Enter fullscreen mode Exit fullscreen mode

📜 Logs: Details When You Need Them

Logs are textual messages generated during code execution. They’re often rich with context and great for debugging.

With OpenTelemetry, logs can be correlated with traces using trace_id and span_id.

✅ What Logs Answer

  • What exactly happened here?
  • What was the value of X during that error?
  • Stack traces and errors with context

🧪 Go Example

log.Printf("User %s failed login, traceID: %s", userID, trace.SpanContextFromContext(ctx).TraceID())

Enter fullscreen mode Exit fullscreen mode

🧪 Node.js Example

console.log(`User login failed. traceId: ${span.spanContext().traceId}`);

Enter fullscreen mode Exit fullscreen mode

🔄 How They Work Together

Imagine a slow API request:

  • 📈 Metrics show API latency has spiked.
  • 🧵 A trace shows which service or DB call is slowing things down.
  • 📜 Logs show the exact error message or bad config that caused the issue.

Together, these three tools give you complete visibility.


⚙ Minimal Go Setup (Traces Only)

func initTracer() {
    exporter, _ := otlptracehttp.New(context.Background())
    tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
    otel.SetTracerProvider(tp)
}

Enter fullscreen mode Exit fullscreen mode

⚙ Minimal Node.js Setup (Traces Only)

const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');

const provider = new NodeTracerProvider();
provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter()));
provider.register();

Enter fullscreen mode Exit fullscreen mode

📌 Summary

Feature Traces Metrics Logs
Purpose Request flow analysis System performance overview Debugging and forensics
Format Spans (structured) Numbers over time Text (structured/unstructured)
Best For Debugging latency, dependencies Monitoring health & throughput Investigating specific issues

✨ Final Thoughts

Start with tracing — it’s the easiest way to understand what your system is actually doing. Add metrics for system health and logs for depth. With OpenTelemetry, you can collect all three in a consistent, vendor-neutral way.

Top comments (0)