Golden Signals in NGINX

This guide shows how to instrument any NGINX server to expose the 4 Golden Signals, Throughput (rate), Latency, Errors, and Traffic, using access logs and a lightweight log-based exporter.

Prerequisites

  • NGINX installed and configured.

  • Access to the /var/log/nginx/access.log.

  • Docker or Docker Compose.

  • Prometheus or OpenTelemetry Collector available.

  • Grafana for visualization (optional but recommended).

Configure the NGINX log

Step 1: Update the nginx.conf

Open your nginx.conf and add the following log format:

log_format main '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '"$http_referer" "$http_user_agent" "$http_x_forwarded_for" '
                'rt=$request_time '
                'urt=$upstream_response_time '
                'rlen=$request_length '
                'conn=$connection conn_reqs=$connection_requests';

access_log /var/log/nginx/access.log main;

Important: This adds essential fields for observability: request time, status, method, path, response size, among others.

Step 2: Restart NGINX

sudo nginx -t && nginx -s reload

Start the NGINX log exporter

Option A: Docker Compose

services:
  nginx_http_metrics:
    image: leonardozwirtes/nginx_http_metrics:latest
    container_name: nginx_http_metrics
    network_mode: host
    ports:
      - "2112:2112"
    environment:
      LOG_PATH: /var/log/nginx/access.log # Or the correct path
    volumes:
      - /var/log/nginx:/var/log/nginx:ro
    restart: unless-stopped
    labels:
      org.label-schema.group: "monitoring"
docker-compose up -d

Option B: Direct Docker

docker run -d \\
  -p 2112:2112 \\
  -v /var/log/nginx:/logs:ro \\
  -e LOG_PATH=/logs/access.log \\
  leonardozwirtes/nginx_http_metrics:latest

Configure Prometheus (alternative)

Add to your prometheus.yml:

scrape_configs:
  - job_name: 'nginx_http_metrics'
    static_configs:
      - targets: ['<IP-OU-HOST-DO-EXPORTER>:2112']

Example using Docker Compose (if Prometheus is on the same network):

scrape_configs:
  - job_name: 'nginx_http_metrics'
    static_configs:
      - targets: ['nginx_http_metrics:2112']

Important: Then restart Prometheus.

Integrate with the OpenTelemetry Collector (Better)

Important: If you're already using OpenTelemetry — or want a lighter and more flexible alternative to Prometheus — the Collector is the best option.

Basic example of configuration (otel-collector-config.yaml):

receivers:
  prometheus:
    config:
      scrape_configs:
        - job_name: 'nginx_http_metrics'
          static_configs:
            - targets: ['nginx_http_metrics:2112']

exporters:
  prometheusremotewrite:
    endpoint: <https://mimir.elvenobservability.com/api/v1/push>

service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [prometheusremotewrite]

To run the Collector:

otelcol-contrib --config otel-collector-config.yaml

Important: With the Collector, you can send metrics not only to Grafana, Tempo, Loki, or Prometheus — but also to any OTLP-compatible backend, with full control over routes, filters, and transformations.

Access the metrics endpoint

You can test the exporter with:

curl <http://localhost:2112/metrics>

Or access it in the browser:

<http://localhost:2112/metrics>

You will see metrics such as:

http_requests_total
http_duration_seconds_bucket
http_errors_total
http_traffic_bytes_total

Use the ready-made dashboard in Grafana

We created a dashboard ready to visualize all the Golden Signals of NGINX: Grafana Dashboard: NGINX Golden Signals

Included dashboards:

Dashboard
Metric

Requests per second

rate(http_requests_total[1m])

Error rate (4xx/5xx)

rate(http_errors_total[1m])

Latency P95

histogram_quantile(0.95, rate(http_duration_seconds_bucket[5m]))

Traffic per route

rate(http_traffic_bytes_total[1m])

Path normalization

To avoid label cardinality explosion, the following rules are applied:

  • /user/123/user/:id

  • /api/*/api

  • .php/:php

  • .env/:env

  • /admin/*/admin

  • Qualquer path com mais de 5 barras → /:complex

Summary

Step
Ddescription

Configure nginx logging

Add log_format ao nginx.conf

Start the exporter

Via Docker ou Docker Compose

Collect the metrics

Via Prometheus ou Collector

View in grafana

Use the Golden Signals dashboard (link above)

Bonus: Coverage of the Golden Signals

Signal
Metric

Throughput

http_requests_total

Latency

http_duration_seconds

Errors

http_errors_total

Traffic

http_traffic_bytes_total

Last updated

Was this helpful?