Skip to content

Logging and Monitoring in API Gateway — Observability for API Traffic

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Logging and Monitoring in API Gateway. We cover key concepts, practical examples, and best practices to help you master this topic.

Logging and monitoring in an API gateway captures every request and response passing through the system, providing centralized observability for latency, error rates, traffic patterns, and debugging across all backend services.

What You'll Learn

  • Structured logging for API requests and responses
  • Metrics collection: request count, latency, error rate, status codes
  • Distributed tracing across gateway and backend services

Why It Matters

Without centralized logging at the gateway, debugging requires checking logs from every backend service individually. The gateway sees every request and response, making it the perfect single source of truth for API observability, error tracking, and performance monitoring.

Real-World Use

Durga Antivirus Pro's gateway logs every request with a unique trace ID, client IP, route, status code, and response time. When a partner reports slow responses, the operations team queries the gateway logs by trace ID and identifies which backend service caused the delay.

flowchart LR
    Request["Request"] --> GW["Gateway"]
    GW -->|"Log: trace_id, path, duration"| Logger["Central Logger"]
    GW --> Metrics["Prometheus\nMetrics"]
    Logger --> ELK["Elasticsearch /\nKibana"]
    Metrics --> Grafana["Grafana\nDashboard"]
    style GW fill:#dbeafe,stroke:#2563eb

Structured Request Logging

import logging
import uuid
import time
from flask import Flask, request, g

app = Flask(__name__)
logger = logging.getLogger("gateway")

@app.before_request
def start_logging():
    g.start_time = time.time()
    g.trace_id = request.headers.get("X-Trace-ID", str(uuid.uuid4()))

@app.after_request
def log_response(response):
    duration = time.time() - g.start_time
    log_data = {
        "trace_id": g.trace_id,
        "method": request.method,
        "path": request.path,
        "status": response.status_code,
        "duration_ms": round(duration * 1000, 2),
        "client_ip": request.remote_addr,
        "user_agent": request.headers.get("User-Agent", ""),
        "content_length": response.content_length,
    }
    logger.info("api_request", extra=log_data)
    response.headers["X-Trace-ID"] = g.trace_id
    return response

Metrics Collection with Prometheus

from prometheus_client import Counter, Histogram, generate_latest
from flask import Response

REQUEST_COUNT = Counter(
    "gateway_requests_total",
    "Total requests",
    ["method", "path", "status"]
)

REQUEST_DURATION = Histogram(
    "gateway_request_duration_seconds",
    "Request duration in seconds",
    ["method", "path"],
    buckets=[0.01, 0.05, 0.1, 0.5, 1, 5]
)

@app.after_request
def record_metrics(response):
    REQUEST_COUNT.labels(
        method=request.method,
        path=request.path,
        status=response.status_code
    ).inc()
    REQUEST_DURATION.labels(
        method=request.method,
        path=request.path
    ).observe(time.time() - g.start_time)
    return response

@app.route("/metrics")
def metrics():
    return Response(generate_latest(), mimetype="text/plain")

Distributed Tracing

Pass the trace context to backend services for end-to-end tracing:

@app.before_request
def inject_trace_context():
    trace_id = g.trace_id
    span_id = uuid.uuid4().hex[:16]
    request.trace_context = {
        "trace_id": trace_id,
        "span_id": span_id,
        "parent_span_id": request.headers.get("X-Span-ID", ""),
    }

def forward_with_tracing(backend_url):
    headers = {
        "X-Trace-ID": g.trace_id,
        "X-Span-ID": request.trace_context["span_id"],
    }
    resp = requests.get(backend_url, headers=headers)
    return resp

Common Mistakes

1. Logging Sensitive Data

Never log authorization headers, API keys, passwords, or personal data. Configure log filters to redact sensitive fields.

2. No Sampling for High-Volume APIs

Logging every request on a high-traffic gateway generates terabytes per day. Use sampling strategies for debug-level logs.

3. Synchronous Logging Blocking Requests

Logging disk I/O can block the request. Use async loggers or offload logging to a background queue.

4. Metrics Without Labels

A single counter for all requests provides no actionable data. Label by route, status code, method, and backend service.

5. Not Propagating Trace Context

Without propagation, you cannot trace a request across gateway and backend services. Always forward trace headers.

Practice Questions

  1. Why is the gateway the best place for centralized API logging?
  2. What is the difference between structured logging and plain text logging?
  3. Why should trace IDs be propagated to backend services?
  4. What metrics should a gateway expose for monitoring?
  5. How can you prevent logging sensitive data?

Answers:

  1. The gateway handles every API request, providing complete visibility into traffic patterns, errors, and performance across all backends.
  2. Structured logging uses key-value pairs (JSON) that are machine-parseable, enabling queries like "find all requests with status 500 in the last hour."
  3. Trace IDs correlate the gateway request with backend logs, enabling end-to-end debugging of multi-service requests.
  4. Request count (by route/status), latency (average, p95, p99), error rate, active connections, and cache hit ratio.
  5. Use log filters or middleware that redacts headers and fields matching patterns like Authorization, password, token, secret.

Challenge: Design a logging Strategy for a gateway handling 10,000 requests per second. Decide what to log at info vs. debug level, how to sample, where to store logs, and what to redact.

FAQ

What is the difference between logging and monitoring?

: Logging records detailed events for debugging. Monitoring aggregates metrics for dashboards, alerts, and trend analysis.

How long should gateway logs be retained?

: 30 days for detailed logs, 90 days for aggregated metrics. Compliance requirements may extend retention.

What is a good p99 latency target for API gateways?

: Under 100ms for most APIs. The gateway should add less than 5ms to the total response time.

Should the gateway log request bodies?

: Logging bodies is useful for debugging but expensive. Log bodies only for error responses or specific routes.

How do you alert on gateway metrics?

: Set alerts for error rate > 1%, p99 latency > 500ms, and any route with 0 requests in 5 minutes (dead backend).

Mini Project

Add structured logging and Prometheus metrics to a Flask gateway. Log trace ID, method, path, status, and duration for every request. Expose a /metrics endpoint with request count and latency histograms. Add a /logs endpoint that returns the last 100 log entries.

What's Next

Continue with Kong API Gateway to explore a production-grade gateway, or explore AWS API Gateway for cloud-managed solutions.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro