Application Metrics
AuthProxy stores Admin UI-facing application metrics in the appMetrics store. This store includes request-event records, optional full request/response payloads, and periodic resource snapshots used for time-series dashboards.
Configuration
Section titled “Configuration”appMetrics is required because request-event listing and metrics queries are routed through it. In development the store can use the same SQLite or Postgres database as the primary application database; appMetrics tracks its migrations in app_metrics_schema_migrations so it does not conflict with the primary schema_migrations table. Deployed environments should prefer ClickHouse or a dedicated Postgres database when request volume is high.
appMetrics: resourceSnapshotInterval: 15m database: provider: clickhouse addresses: - localhost:8123 database: authproxy user: authproxy password: authproxy requestEvents: fullRequestRecording: never blobStorage: provider: s3 bucket: authproxy-request-logsKey settings:
| Setting | Purpose |
|---|---|
appMetrics.database |
Database for request events and resource sample tables; can be shared with the primary application database for development. |
appMetrics.resourceSnapshotInterval |
Cadence for the worker snapshot job. Defaults to 15m. |
appMetrics.requestEvents.fullRequestRecording |
never (default) or always; controls whether full request/response bodies are captured. |
appMetrics.requestEvents.flushInterval |
Request events are buffered in memory and written in batches; this is the maximum time an event waits before being written. Defaults to 5s. |
appMetrics.requestEvents.flushBatchSize |
Number of buffered events that triggers an immediate write. Defaults to 1000. |
appMetrics.requestEvents.maxBufferedRecords |
Upper bound on events waiting to be written. If the database falls behind, further events are dropped (and a warning is logged) rather than growing memory. Defaults to 100000. |
appMetrics.blobStorage |
Stores full request/response payloads when capture is enabled. |
The resource snapshot worker stores live resources at each interval. Deleted resources remain visible in historical time slices where they were sampled, but they are excluded from later snapshots.
See Database migrations for status inspection, explicit migration commands, and locking behavior across SQLite, PostgreSQL, and ClickHouse.
Request events
Section titled “Request events”List request-event metadata with GET /api/v1/metrics/request-events. Filters
include namespace, connector, connection, method, status range, path, response
source, rate-limit id, label selector, and timestamp range. Fetch one event at
GET /api/v1/metrics/request-events/{id}.
Request events use the authproxy.net/v1alpha1 envelope, but they are immutable
observations rather than resources with client-managed desired state. Event
identity, namespace, the frozen label snapshot, and timestamp are in
metadata; observed request and response facts are in spec. Resource
attribution uses typed references. In particular, connectorRef.generation
records the connector generation used for the request.
apiVersion: authproxy.net/v1alpha1kind: RequestEventmetadata: id: req_01example namespace: root.acme labels: team: payments createdAt: 2026-09-06T17:30:00Zspec: requestType: proxy correlationId: corr-123 durationMilliseconds: 150 namespaceRef: apiVersion: authproxy.net/v1alpha1 kind: Namespace id: root.acme actorRef: apiVersion: authproxy.net/v1alpha1 kind: Actor id: act_01example name: billing-service namespace: root.acme connectionRef: apiVersion: authproxy.net/v1alpha1 kind: Connection id: cxn_01example name: production namespace: root.acme connectorRef: apiVersion: authproxy.net/v1alpha1 kind: Connector id: cxr_01example name: provider namespace: root.integrations generation: 3 request: method: GET host: api.example.com scheme: https path: /v1/items response: statusCode: 200 source: upstream captureAvailable: falseList responses use kind: RequestEventList; pagination is returned in
metadata.continue, and the exact match count (when available) is returned in
metadata.total. Existing request-event filters retain their current query
parameter names, including connectorGeneration for generation-specific queries.
Full request and response payloads are separate encrypted blobs and exist only
when fullRequestRecording is always. Keep recording at never unless the
debugging or audit requirement justifies the additional sensitive data,
storage, access control, and retention burden.
When capture is present, spec.capture contains the original URL, headers, and
request/response bodies; body values use base64 on the wire. These fields are
not metadata and are redacted by default. AuthProxy returns unredacted capture
only when the authenticated actor has secrets:replay; otherwise the response
includes X-AuthProxy-Data-Redacted: true when capture fields were masked.
Treat replayed data as sensitive even when a particular request appears
harmless.
Query API
Section titled “Query API”Use POST /api/v1/metrics/query with a time range, optional namespace matcher, optional label selector, and one or more query refs.
{ "range": { "start": "2026-05-25T12:00:00Z", "end": "2026-05-25T13:00:00Z", "step": "15m" }, "namespace": "root.**", "labelSelector": "env=prod", "queries": [ { "refId": "connections", "metric": "resources.connections", "aggregation": "count", "groupBy": ["state", "health_state"] } ]}Responses are returned as labeled time series:
{ "series": [ { "refId": "connections", "metric": "resources.connections", "aggregation": "count", "labels": { "state": "configured", "healthState": "healthy" }, "points": [ {"timestamp": "2026-05-25T12:00:00Z", "value": 4} ] } ]}Metrics
Section titled “Metrics”Request-event metrics are computed from stored request events.
| Metric | Aggregations | group_by |
|---|---|---|
request_events |
count |
type, method, response_status_code, response_source, connector_id |
request_events.errors |
count |
type, method, response_status_code, response_source, connector_id |
request_events.duration_ms |
avg, p95 |
type, method, response_status_code, response_source, connector_id |
Resource metrics are computed from periodic app-metrics resource samples.
| Metric | Aggregations | group_by |
|---|---|---|
resources.connections |
count |
state, health_state, connector_id, connector_generation |
resources.actors |
count |
namespace |
resources.connectors |
count |
state, connector_generation, namespace |
resources.connector_generations |
count |
state, connector_id, connector_generation, namespace |
resources.namespaces |
count |
state, namespace |
resources.rate_limits |
count |
mode, namespace |
Resource metrics are gauges. Each bucket reports the counts from the most
recent snapshot taken before the bucket ends, so a value carries forward
into buckets that have no snapshot of their own. This covers steps shorter
than resourceSnapshotInterval and buckets that don’t line up with snapshot
times. A snapshot is carried forward for at most 2.5 snapshot intervals past
a bucket’s end. Buckets with no snapshot in that window, such as those before
the first snapshot or while the worker is stopped, have no point in the
response, so charts show a gap instead of a drop to zero. Within a snapshot,
a group with no matching resources reports 0.
All metric queries accept the same namespace matcher and label selector fields. Label selectors evaluate against the frozen labels stored with the request event or resource sample, not the current live resource.
Implicit apxy/<rt>/-/name labels therefore preserve the name captured in that
sample or request snapshot. Renaming a live resource does not rewrite
historical metrics data.