A3S Docs
A3S Gateway

Observability

Prometheus metrics, structured logging, distributed tracing, CLI inspection, and optional Dashboard API

Observability

A3S Gateway provides built-in Prometheus metrics, structured access logging, distributed tracing, CLI-based configuration inspection, and an optional Dashboard API on a dedicated management listener.

Management Inspection

Use the CLI for local and CI/CD workflows:

a3s-gateway validate --config gateway.acl
a3s-gateway config --config gateway.acl summary
a3s-gateway config --config gateway.acl entrypoints
a3s-gateway config --config gateway.acl routes
a3s-gateway config --config gateway.acl services
a3s-gateway config --config gateway.acl middlewares
a3s-gateway config --config gateway.acl providers
a3s-gateway config --config gateway.acl json
a3s-gateway management events --url http://127.0.0.1:9090/api/gateway
a3s-gateway management validate --url http://127.0.0.1:9090/api/gateway --file gateway.acl
a3s-gateway management reload --url http://127.0.0.1:9090/api/gateway --file gateway.acl

Enable the Dashboard API only when you need remote inspection:

management {
  enabled        = true
  address        = "127.0.0.1:9090"
  path_prefix    = "/api/gateway"
  auth_token_env = "A3S_GATEWAY_ADMIN_TOKEN"
  allowed_ips    = ["127.0.0.1", "::1"]

  tls {
    cert_file           = "/etc/a3s/admin/server.crt"
    key_file            = "/etc/a3s/admin/server.key"
    client_ca_file      = "/etc/a3s/admin/client-ca.crt"
    require_client_cert = true
  }
}

Dashboard requests must include Authorization: Bearer <token> when auth_token_env is set. Requests must also come from allowed_ips. When management.tls.require_client_cert = true, clients must present a certificate signed by client_ca_file.

For mTLS-protected management listeners, add --ca-cert, --client-cert, and --client-key to the management events CLI command.

EndpointResponse
GET /api/gateway/healthGateway health JSON
GET /api/gateway/metricsPrometheus text format
GET /api/gateway/configActive configuration JSON
GET /api/gateway/routesConfigured routes
GET /api/gateway/servicesServices with backend health
GET /api/gateway/backendsBackends with connection counts
GET /api/gateway/eventsRecent management security audit events
GET /api/gateway/versionBinary version
POST /api/gateway/config/validateValidate an ACL payload without applying it
POST /api/gateway/config/reloadTransactionally reload from an ACL payload

Prometheus Metrics

gateway_requests_total 12345
gateway_responses_total{status_class="2xx"} 11000
gateway_responses_total{status_class="3xx"} 500
gateway_responses_total{status_class="4xx"} 700
gateway_responses_total{status_class="5xx"} 145
gateway_response_bytes_total 987654321
gateway_active_connections 42
gateway_router_requests{router="api"} 8000
gateway_router_requests{router="web"} 4345
gateway_backend_requests{backend="http://127.0.0.1:8001"} 6000
gateway_backend_requests{backend="http://127.0.0.1:8002"} 6345

Grafana Queries

# Request rate
rate(gateway_requests_total[5m])

# Error rate (4xx + 5xx)
rate(gateway_responses_total{status_class=~"4xx|5xx"}[5m])

# Success rate %
rate(gateway_responses_total{status_class="2xx"}[5m])
  / rate(gateway_requests_total[5m]) * 100

# Active connections
gateway_active_connections

# Traffic by router
rate(gateway_router_requests[5m])

# Throughput (bytes/sec)
rate(gateway_response_bytes_total[5m])

Access Logging

Structured JSON access logs via the tracing crate:

{
  "timestamp": "2025-01-15T10:30:00Z",
  "client_ip": "203.0.113.42",
  "method": "POST",
  "path": "/api/v1/chat",
  "status": 200,
  "request_duration_ms": 145,
  "bytes_sent": 2048,
  "router": "api",
  "service": "api-backend",
  "backend": "http://127.0.0.1:8001"
}

Log Levels

# Via CLI
a3s-gateway --config gateway.acl --log-level debug

# Via environment
RUST_LOG=a3s_gateway=debug a3s-gateway --config gateway.acl

Prop

Type

Distributed Tracing

A3S Gateway propagates trace context across services:

  • W3C Trace Context: traceparent / tracestate headers
  • B3/Zipkin: X-B3-TraceId / X-B3-SpanId headers

Spans are created for request lifecycle, backend connections, and health check probes.

On this page