可观测性

网关暴露三类信号:Prometheus 指标、结构化日志、按需 OTLP tracing。

健康检查

路径含义失败行为
GET /healthz进程在跑就返回 200,不查依赖。用于 K8s liveness。-
GET /readyz检查 DB / Redis 可达性。用于 K8s readiness。任意依赖不可达返回 503。

两个端点无需认证。

Prometheus 指标

GET /metrics 返回 Prometheus text 格式,需要在 YAML 里 observability.metrics: true(默认开)。

代理与缓存

指标类型Labels含义
gateway_cache_hit_totalcountertier={l1|l2}KV 缓存命中次数(底层 KvStore)。
gateway_cache_miss_totalcounter-KV 缓存未命中。
gateway_cache_write_totalcounter-KV 缓存写入。
gateway_cache_response_hit_totalcounter-路由级响应缓存命中(用户视角)。
gateway_cache_response_write_totalcounter-路由级响应缓存写入。

限流与预算

指标类型Labels含义
gateway_ratelimit_hit_totalcounterkind={rpm|tpm|concurrency}触发限流的次数。
gateway_budget_pcthistogrambudget=<name>每次请求后预算使用率(0–1)。
gateway_budget_threshold_totalcounterbudget=<name>, action={alert|block}阈值跨越次数。

日志写入

指标类型Labels含义
gateway_log_write_totalcounter-日志条目成功落库。
gateway_log_write_error_totalcounter-日志落库失败。
gateway_log_drop_totalcounterreason=full异步队列满,日志被丢弃。

配置热重载

指标类型Labels含义
gateway_config_reload_totalcounter-配置热重载成功次数。
gateway_config_reload_error_totalcounter-配置热重载失败次数。持续 > 0 必报警

推荐告警

# 持续限流(可能是上游限速或恶意流量)
rate(gateway_ratelimit_hit_total[5m]) > 1

# 日志写入失败累积
increase(gateway_log_write_error_total[10m]) > 0

# 配置加载失败
increase(gateway_config_reload_error_total[5m]) > 0

# 任何预算跨过 80% 警告线
increase(gateway_budget_threshold_total{action="alert"}[1h]) > 0

# 任何预算跨过 100% 拦截线
increase(gateway_budget_threshold_total{action="block"}[1h]) > 0

结构化日志

进程 stdout 输出 tracing JSON。字段示意:

{
  "timestamp": "2026-05-15T03:21:11.234Z",
  "level": "INFO",
  "fields": {
    "message": "proxy request completed",
    "request_id": "req_...",
    "project_id": "default",
    "gateway_key_id": "key_...",
    "namespace": "openai",
    "model": "gpt-4o-mini",
    "status": 200,
    "input_tokens": 12,
    "output_tokens": 64,
    "cost_usd": 0.00031,
    "elapsed_ms": 842,
    "upstream_ms": 800,
    "queue_ms": 12,
    "cache": "MISS",
    "outcome": "primary"
  }
}
  • 等级由 RUST_LOG 控制(EnvFilter 语法)。默认 info,sqlx::query=warn
  • observability.tracing.format: text 可改为人类可读格式。
  • 不要在生产开 debug:Postgres / SQLite 的查询会以 INFO 级吐出。

请求日志(数据库)

每条 HTTP 代理请求都会异步写入 request_logs 表,字段比 stdout 日志更全(包含 request/response body 摘要)。通过 Admin API 检索。

字段类型含义
idstringlog_xxx,响应头 X-Gateway-Request-Id 返回的就是它。
project_id / gateway_key_idstring归属。
namespace / model / pathstring路由信息(namespace 来自 URL /v1/{namespace}/... 段)。
statusstringok / gateway_error / upstream_error
http_statusint实际返回客户端的状态码。
errorstring?错误码字符串(如 budget_exceededrate_limited)。
input_tokens / output_tokensint上游或估算值。
cost_usdfloatpricing-catalog.json 计算。
request_body / response_bodystring各限 64KB,超出截断。
cachestringhit / miss / refresh / bypass
outcomestringprimary / fallback:N / error
elapsed_ms / upstream_ms / queue_msint计时拆分。

保留期:Lite 模式由 storage.sqlite.log_retention_days 控制(默认 30 天),后台定期清理。Standard 模式目前不自动清理,需要在 Postgres 侧用 partition 或定时任务管理。

OTLP Tracing

observability:
  tracing:
    enabled: true
    format: json
    otlp_endpoint: http://otel-collector:4318

启用后会同时把 span 推到 OTLP HTTP 端点。span 名:

  • proxy.request — 顶层,涵盖整个请求。
    • proxy.attempt — 每次上游尝试,带 attempt.indextarget.provideroutcome 等。
    • cache.lookup / cache.write
    • ratelimit.check / budget.check

Span 上的 request_id attribute 与 X-Gateway-Request-Id、Admin API 日志条目的 id 相同,便于跨系统对齐。