Learn Echo - Observability & Monitoring
Series/Learn Echo/Episode 18
Episode 18 of 23

Learn Echo - Observability & Monitoring

This episode makes the application observable: Prometheus metrics, distributed tracing with OpenTelemetry, structured logs with slog, health check endpoints, and dashboard and alerting integration for latency, error rate, and throughput.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Introduction

An application running in production is an application that must be observed. Observability unites three pillars: metrics for numbers, logs for details, and traces for flows. This episode connects all three to Echo with industry-standard tooling.

Episode 18 covers Prometheus metrics, tracing with OpenTelemetry, structured logs with slog, health check endpoints, and dashboard and alerting integration.

Prometheus Metrics

Adding a Metrics Endpoint

Prometheus collects metrics by pulling an HTTP endpoint. Echo makes this easy through echo-contrib:

Install echo-contrib
go get github.com/labstack/echo-contrib/prometheus
Installing the Prometheus middleware
import "github.com/labstack/echo-contrib/prometheus"
 
p := prometheus.NewPrometheus("echo", nil)
p.Use(e)
e.GET("/metrics", prometheus.Handler())

Metrics like request count, latency, and status codes are now available at /metrics. The p.Use(e) call installs the metrics middleware, while prometheus.Handler() serves the scrape endpoint — Prometheus just needs to be configured to pull it on each interval.

Prometheus scrape configuration
scrape_configs:
  - job_name: belajar-echo
    static_configs:
      - targets: ["api:8080"]

Tracing with OpenTelemetry

Automatic Instrumentation with otecho

OpenTelemetry gives you distributed traces — the journey of one request through many services. Echo instrumentation is available via the OTel contribution:

Installing the OpenTelemetry tracer
import "go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho"
 
tp, err := initTracer(ctx)
e.Use(otelecho.Middleware("belajar-echo"))

Every request now produces a span that carries propagation context. Spans can be linked to the database and HTTP calls inside them:

Creating a span inside a handler
_, span := otel.Tracer("service").Start(c.Request().Context(), "processOrder")
defer span.End()

Traces are sent to a backend like Jaeger or Tempo, then linked to logs through the same trace_id — an important bridge for end-to-end debugging.

Structured Logs and Health Checks

Unifying trace_id with Logs

In episode 11 you started logging a request_id. Integrate it with the OTel trace_id so logs and traces can be linked:

Injecting trace_id into slog
slog.Info("order diproses",
	"order_id", order.ID,
	"trace_id", span.SpanContext().TraceID().String(),
)

One trace_id links logs, metrics, and traces for a single request — the key to fast debugging.

Health Check Endpoints

Infrastructure like Kubernetes performs health checks periodically. Provide dedicated endpoints:

Readiness endpoint
e.GET("/health/live", func(c echo.Context) error {
	return c.JSON(http.StatusOK, map[string]string{"status": "alive"})
})
 
e.GET("/health/ready", func(c echo.Context) error {
	if err := db.Ping(c.Request().Context()); err != nil {
		return echo.NewHTTPError(http.StatusServiceUnavailable, "db tidak siap")
	}
	return c.JSON(http.StatusOK, map[string]string{"status": "ready"})
})

/health/live indicates the process is alive; /health/ready indicates the dependencies are ready. Keep them separate so restarts and traffic routing don't hit the wrong target.

Dashboards and Alerting

Grafana for Visualization

Data from Prometheus is visualized in Grafana. The metrics always monitored:

  • Latency: the p95 and p99 percentiles of request duration.
  • Error rate: the percentage of 5xx statuses against the total.
  • Throughput: the number of requests per second.

Alerting triggers actions when thresholds are exceeded:

Prometheus alerting rules
groups:
  - name: api
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{code=~"5.."}[5m]))
            / sum(rate(http_requests_total[5m])) > 0.05
        for: 10m
        labels:
          severity: critical
        annotations:
          summary: "Error rate di atas 5 persen selama 10 menit"

This rule sounds the alarm when more than 5 percent of requests fail for 10 minutes.

Closing

Episode 18 makes your application truly observable: Prometheus metrics at /metrics, distributed tracing with OpenTelemetry and otecho, structured logs unified with trace_id, health checks split between live and ready, and dashboards and alerting for latency, error rate, and throughput.

Key takeaways:

  • echo-contrib/prometheus provides scrape-ready metrics.
  • otecho instruments every request into a trace.
  • Link the trace_id across logs, metrics, and traces.
  • Provide separate /health/live and /health/ready.
  • Grafana visualizes latency, error rate, and throughput.
  • Alerting is triggered by PromQL expressions, e.g. error rate above 5 percent.
  • Observability is three pillars: metrics, logs, and traces.

In episode 19 next, we'll discuss performance & troubleshooting — reducing allocations and reuse, connection pooling, Redis caching, HTTP server tuning, and troubleshooting route conflicts, binding errors, deadlocks, goroutine leaks, and the v4 to v5 migration.

Learn Echo - Observability & Monitoring | Learn Echo