Prometheus metrics
Every Prometheus metric the MAQPNA gateway, operator, identity broker and attestation service export, with the alert rules, dashboards and PromQL queries that ship with the Helm chart.
This page lists every Prometheus metric that MAQPNA components export, grouped by component. Use it when you write your own alerts or dashboards, or when you need to know what a series means. To turn on scraping, alerts and dashboards step by step, read Monitoring and alerts. For how metrics fit with traces and the audit ledger, read Observability.
Where metrics come from#
| Component | Endpoint | Port (chart default) | How it is built |
|---|---|---|---|
Gateway (maqpna-gateway) |
GET /metrics |
8080 (http), or the adminListen port when set |
Hand-written text exposition (cmd/maqpna-gateway/metrics.go and one renderer per feature) |
Operator (maqpna-operator) |
GET /metrics |
8080 (metrics, --metrics-bind-address) |
controller-runtime registry (internal/controller/metrics.go), plus the standard controller-runtime and Go runtime metrics |
Attestation service (maqpna-attest) |
GET /metrics |
8082 (http) |
Hand-written (cmd/maqpna-attest/server.go) |
Identity broker (maqpna-identity) |
GET /metrics |
8081 (http) |
maqpna_build_info only |
flowchart LR
P["Prometheus"] -->|"scrape :8080/metrics<br/>or adminListen port"| GW["Gateway"]
P -->|"scrape :8080/metrics"| OP["Operator"]
P -->|"scrape :8082/metrics"| AT["Attestation service"]
P -.->|"build info only"| ID["Identity broker :8081"]
P --> R["PrometheusRule<br/>alerts"]
G["Grafana"] --> P
The gateway has no client library. It writes the text format by hand, so some series only appear once the feature that owns them is configured (for example DPoP, the audit collector or a transparency log). A counter with labels has no series until the first event.
Every component#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_build_info |
gauge | component, version, commit, goversion, tags |
Build of the running binary. Always 1. Exported by the gateway, operator, identity broker and attestation service, so maqpna version --check, maqpna doctor and dashboards can find version skew. |
Gateway#
Tool calls and MCP servers#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_decisions_total |
counter | action, server |
Policy decisions for tool calls, by decision (for example allow, deny) and MCP server. Calls denied before the server is known use server="unknown". |
maqpna_gateway_requests_total |
counter | server, method, code |
MCP HTTP requests by MCP server, JSON-RPC method and HTTP status. |
maqpna_gateway_upstream_latency_seconds |
histogram | server |
Latency of the MCP server round trip for allowed tool calls. Buckets: 0.005 to 30 s. |
maqpna_gateway_upstream_errors_total |
counter | server |
Failed round trips to an MCP server. |
maqpna_gateway_upstreams_configured |
gauge | none | MCP servers the gateway knows. |
maqpna_gateway_auth_failures_total |
counter | reason |
Rejected session tokens, by reason. |
maqpna_gateway_trusted_keys |
gauge | none | Token verification keys loaded (files and JWKS). |
maqpna_gateway_tool_pin_events_total |
counter | server, event |
Tool pinning events (tool definitions learned, drift found) by MCP server. |
maqpna_gateway_svid_checks_total |
counter | result |
X.509-SVID client certificate checks, by result. Present when tls is configured. |
maqpna_gateway_dpop_requests_total |
counter | outcome |
Requests by DPoP outcome. bound means a valid proof by the token's key. |
Policy, approvals and taint#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_policies_loaded |
gauge | none | Policies in the loaded policy set. |
maqpna_gateway_policy_revision |
gauge | none | Revision of the policy set in force. |
maqpna_gateway_policy_reloads_total |
counter | result |
Policy file reloads, success or failure. |
maqpna_gateway_dryrun_decisions_total |
counter | policy, would |
What dry-run policies would have decided, by policy and action. |
maqpna_gateway_cedar_available |
gauge | none | 1 when this gateway build includes the Cedar adapter (-tags cedar). |
maqpna_gateway_cedar_policies_unavailable |
gauge | none | Policies with Cedar text that this gateway cannot evaluate. They deny. |
maqpna_gateway_rego_evaluations_total |
counter | outcome |
Evaluations by the OPA sidecar, ok or error. error means the call failed closed. Present when the OPA sidecar is configured. |
maqpna_gateway_approvals_pending |
gauge | none | Approvals waiting for a human decision. |
maqpna_gateway_taint_events_total |
counter | op, label |
Session taint label changes, by operation and label. |
maqpna_gateway_tainted_sessions |
gauge | none | Sessions that currently carry taint. |
maqpna_gateway_guard_checks_total |
counter | guard, target, outcome |
Prompt-injection classifier checks, by guard, target and outcome. |
maqpna_gateway_guard_blocked_total |
counter | guard, target |
Tool results withheld or calls denied by a guard. |
maqpna_gateway_guard_latency_seconds |
summary | guard |
Classifier latency for answered checks (_sum and _count only). |
maqpna_gateway_arg_captures_total |
counter | outcome |
Argument captures, written, dropped or failed. |
Data loss prevention (DLP)#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_dlp_hits_total |
counter | detector, direction, action |
DLP detector matches, by detector, direction (arguments or response) and the configured action. |
Kill switch and revocations#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_revoked_total |
counter | scope |
Calls denied by a revocation, by matcher scope. |
maqpna_gateway_revocations_active |
gauge | source |
Revocation entries loaded, breakglass or file. |
maqpna_gateway_revocation_propagation_seconds |
summary | none | Time from an AgentRevocation's creation to its enforcement by this replica (_sum and _count). |
maqpna_gateway_revocation_propagation_max_seconds |
gauge | none | Longest revocation propagation time seen by this replica. |
maqpna_gateway_revocation_list_ok |
gauge | none | 1 when the revocation list is readable. 0 while the gateway fails closed and denies every call. |
Budgets and cost#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_metered_cost_usd |
gauge | none | Total metered cost in USD since the metering state began. |
maqpna_gateway_budget_denied_total |
counter | scope |
Calls denied because a budget was exhausted, by scope and window. |
maqpna_gateway_budget_alerts_total |
counter | scope, percent |
budget.threshold alerts sent, by scope and window and threshold percent. |
maqpna_gateway_rate_limited_total |
counter | none | Model calls rejected by the tokens-per-minute limit. |
Model calls#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_model_routes |
gauge | none | Model routes loaded (static and from modelsFile). |
maqpna_gateway_model_requests_total |
counter | route, status |
Model call requests through /llm, by route and HTTP status. |
maqpna_gateway_model_tokens_total |
counter | route, kind |
Model tokens metered, by route and kind (prompt or completion). |
maqpna_gateway_model_failovers_total |
counter | route, from, to |
Model calls that failed over from one endpoint to the next. |
maqpna_gateway_model_endpoint_failures_total |
counter | route, endpoint |
Failed model endpoint attempts (transport error, timeout, 5xx, 429). |
maqpna_gateway_model_endpoint_skipped_total |
counter | route, endpoint, reason |
Model endpoints skipped during selection, by reason. |
maqpna_gateway_model_circuits_open |
gauge | none | Model endpoints whose circuit breaker is open. |
Agent-to-agent calls#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_a2a_calls_total |
counter | hop, kind, decision |
Agent-to-agent (A2A) calls, by hop, target kind and decision. |
maqpna_gateway_a2a_routes |
gauge | none | A2A targets the gateway can route to. |
Sandbox tools#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_web_calls_total |
counter | tool, result |
Calls to the built-in maqpna-web tools, by tool and result. |
maqpna_gateway_egress_requests_total |
counter | kind, decision |
Requests through the browser egress proxy, by kind and decision. |
maqpna_gateway_exec_total |
counter | result |
Code-interpreter exec requests, by result. |
Audit ledger#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_audit_head_seq |
gauge | none | Sequence number of the last audit record. |
maqpna_gateway_audit_errors_total |
counter | none | Failed audit ledger appends. |
maqpna_gateway_audit_commit_seconds |
histogram | none | Time for one group-committed batch of audit records to become durable (fsync, or the shared-chain transaction with PostgreSQL state). Every governed call waits for it. |
maqpna_gateway_audit_committed_records_total |
counter | none | Audit records committed. |
maqpna_gateway_audit_signed_checkpoint_seq |
gauge | none | Ledger sequence of the last signed checkpoint. Present when auditCheckpointKey is set. |
maqpna_gateway_audit_retention_below_ai_act |
gauge | none | 1 when the sovereignty policy's auditRetentionDays is below the EU AI Act minimum (Art. 19 and 26(6)). Present when a sovereignty policy is loaded. |
maqpna_gateway_audit_sink_lag |
gauge | sink |
Ledger records not yet delivered to an audit sink (SIEM or WORM). |
maqpna_gateway_audit_sink_delivered_total |
counter | sink |
Records delivered to the sink. |
maqpna_gateway_audit_sink_errors_total |
counter | sink |
Failed deliveries to the sink. |
maqpna_gateway_audit_sink_dead_lettered_total |
counter | sink |
Records the collector rejected permanently, written to the sink's dead-letter file. |
Transparency log anchors#
Present when transparencyLog is configured.
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_audit_anchor_seq |
gauge | none | Ledger sequence of the last head anchored in the transparency log. |
maqpna_gateway_audit_anchors_total |
counter | none | Anchors submitted. |
maqpna_gateway_audit_anchor_errors_total |
counter | none | Failed transparency log submissions (retried with backoff). |
maqpna_gateway_audit_anchor_last_success_timestamp_seconds |
gauge | none | Unix time of the last successful anchor. |
Offline edge and audit collector#
The audit_forward and offline series come from an edge gateway with offline configured. The audit_collector series come from the central gateway with auditCollector configured.
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_audit_forward_unforwarded_records |
gauge | none | Ledger records the collector has not acknowledged yet. |
maqpna_gateway_audit_forward_oldest_unforwarded_age_seconds |
gauge | none | Age of the oldest record not yet acknowledged (0: none). |
maqpna_gateway_audit_forward_last_ack_timestamp_seconds |
gauge | none | Unix time of the last acknowledgement (0: never). |
maqpna_gateway_audit_forward_acked_seq |
gauge | none | Highest sequence the collector acknowledged. |
maqpna_gateway_audit_forward_spool_bytes |
gauge | none | Bytes in the local spool. |
maqpna_gateway_audit_forward_spool_max_bytes |
gauge | none | Spool size limit. |
maqpna_gateway_audit_forward_spool_full |
gauge | none | 1 while the spool is full and tool calls are denied. |
maqpna_gateway_audit_forward_connected |
gauge | none | 1 while the edge is connected to the collector. |
maqpna_gateway_audit_forward_errors_total |
counter | none | Forwarding errors. |
maqpna_gateway_offline_denials_total |
counter | rule |
Tool calls denied by an offline rule: spool-full, revocation-stale or approval-offline. |
maqpna_gateway_audit_collector_segments_total |
counter | result |
Ledger segments received from edge gateways, by result. |
maqpna_gateway_audit_collector_refused_total |
counter | reason |
Refused segments, by reason (for example gap, fork, signature). |
maqpna_gateway_audit_collector_edge_seq |
gauge | edge |
Highest contiguous sequence stored for each edge. |
Configuration, state and high availability#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_configsync_last_success_timestamp_seconds |
gauge | configmap |
Unix time of the last successful read of a ConfigMap synced from the Kubernetes API (0: never). Present with configSync. |
maqpna_gateway_configsync_errors_total |
counter | configmap |
Failed reads of a synced ConfigMap. |
maqpna_gateway_config_bundle_revision |
gauge | none | Revision of the signed configuration bundle in force (0: none). |
maqpna_gateway_config_bundles_applied_total |
counter | none | Configuration bundles applied. |
maqpna_gateway_config_bundles_refused_total |
counter | reason |
Configuration bundles refused, by reason. |
maqpna_gateway_state_backend_info |
gauge | type |
Configured state backend (file or postgres). Always 1. |
maqpna_gateway_leader |
gauge | job |
1 when this replica leads a background job, 0 when it stands by. |
OpenTelemetry#
| Name | Type | Labels | Meaning |
|---|---|---|---|
mcp_server_operation_duration_seconds |
histogram | mcp_method_name, error_type |
MCP request processing time at the gateway (OTel semantic convention mcp.server.operation.duration). |
gen_ai_client_token_usage |
histogram | gen_ai_operation_name, gen_ai_provider_name, maqpna_model_route, gen_ai_token_type |
Model tokens per call (OTel semantic convention gen_ai.client.token.usage). |
gen_ai_client_operation_duration_seconds |
histogram | gen_ai_operation_name, gen_ai_provider_name, gen_ai_request_model, gen_ai_response_model, error_type |
Duration of model calls, MCP tool calls (execute_tool) and A2A calls (invoke_agent) (OTel semantic convention gen_ai.client.operation.duration). |
maqpna_gateway_otel_spans_exported_total |
counter | none | Spans the OTLP collector accepted. Present when trace export is on. |
maqpna_gateway_otel_spans_dropped_total |
counter | none | Spans dropped because the export queue was full. |
maqpna_gateway_otel_spans_failed_total |
counter | none | Spans whose export failed after retries. |
maqpna_gateway_otel_queue_length |
gauge | none | Spans waiting in the export queue. |
Integrations#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_gateway_llamay_contexts |
gauge | none | llamay inference contexts bound to sessions. |
maqpna_gateway_llamay_context_ops_total |
counter | op |
llamay context operations: create, fork, drop, stale, busy, error. |
maqpna_gateway_llamay_audit_verified |
gauge | anchor |
1 while the llamay request audit chain verifies. |
maqpna_gateway_llamay_anchor_append_failures_total |
counter | anchor |
llamay audit anchor records the ledger could not append (retried). |
maqpna_gateway_llamay_audit_head_seq |
gauge | anchor |
Last verified sequence of the llamay request audit chain. |
maqpna_gateway_kosa8_mirror_total |
counter | outcome |
Decisions mirrored to the kosa8 audit chain, ok, error or dropped. |
maqpna_gateway_kosa8_audit_verified |
gauge | none | 1 while kosa8d reports its audit chain verified. |
maqpna_gateway_kosa8_anchor_append_failures_total |
counter | none | kosa8 audit anchor records the ledger could not append (retried). |
maqpna_gateway_kosa8_audit_head_seq |
gauge | none | kosa8 audit sequence last anchored in the ledger. |
Licence#
The gateway and the operator export the same licence series. The licence never affects agent traffic.
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_license_state |
gauge | edition, state |
1 for the current state, 0 for the others. States: none (Community), invalid, valid, grace, expired. |
maqpna_license_days_left |
gauge | none | Days until the licence expires. Negative during the grace period and after. Only for a verified licence. |
maqpna_license_node_limit |
gauge | none | Contracted node limit (0: unlimited). Only for a verified licence. |
Operator#
Registered on the controller-runtime registry and served on --metrics-bind-address (default :8080).
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_session_ready_seconds |
histogram | tier, mode |
Time from AgentSession creation to its first Running phase. mode is claim (warm pool) or direct (operator-created sandbox). Buckets: 0.1 to 60 s. |
maqpna_sessions |
gauge | namespace, tier, phase |
Sessions by namespace, trust tier and phase. Reported by the leader replica only. |
maqpna_session_phase_transitions_total |
counter | from, to, reason |
Session phase changes. reason is the Ready condition reason after the change. |
maqpna_session_outcomes_total |
counter | tier, result |
Ended sessions by trust tier and status.outcome.result (Succeeded, Failed, Expired, Revoked, Cancelled). |
maqpna_token_mint_seconds |
histogram | none | Latency of session token mints at the identity broker, successful and failed. Buckets: 0.005 to 5 s. |
maqpna_warm_pool_ready |
gauge | tier |
Ready warm sandboxes of a trust tier, summed over warm-pool namespaces. Absent when the tier has no warm pool. |
maqpna_reconcile_errors_total |
counter | controller, reason |
Reconcile errors by controller and Kubernetes API status reason (Conflict, NotFound, Forbidden, and so on; Other for non-API errors). |
maqpna_reconcile_duration_seconds |
histogram | controller |
Reconcile latency. Buckets: 0.001 to 10 s. |
maqpna_rendered_configmap_bytes |
gauge | name |
Size (keys and values) of each gateway ConfigMap the operator renders. Kubernetes rejects ConfigMaps over 1 MiB. |
maqpna_billable_nodes |
gauge | period |
Distinct nodes running agent sandbox pods: current (last sample), day and month (UTC high-water marks). Leader only. Sampled every minute by default (--node-count-interval). |
maqpna_license_state, maqpna_license_days_left, maqpna_license_node_limit |
gauge | as above | Licence series, the same as the gateway's. |
Attestation service#
| Name | Type | Labels | Meaning |
|---|---|---|---|
maqpna_attest_success_total |
counter | none | Successful attestation-gated releases. |
maqpna_attest_failure_total |
counter | reason |
Failed attestations, by reason. |
maqpna_attest_releases_created_total |
counter | none | Releases the operator registered. |
maqpna_attest_releases_pending |
gauge | none | Releases not yet consumed. |
maqpna_attest_renewal_success_total |
counter | none | Successful token renewals. |
maqpna_attest_renewal_failure_total |
counter | reason |
Failed token renewals, by reason. |
maqpna_attest_renewals_active |
gauge | none | Renewals that have not reached renewUntil. |
Alert rules in the chart#
Set monitoring.prometheusRule.enabled: true to render a PrometheusRule (monitoring.coreos.com/v1, needs the Prometheus Operator CRDs). Each alert links to <runbookBaseURL>#<alert name in lower case>. The default base URL is https://docs.maqpna.com/operations/monitoring-and-alerts/. Turn off single alerts with monitoring.prometheusRule.disabled, for example [MaqpnaBudgetExceeded].
| Group | Alert | Severity | Fires when (default threshold value) |
|---|---|---|---|
maqpna-sessions |
MaqpnaSessionReadySLO (two rules, mode: claim and mode: direct) |
warning | p90 of maqpna_session_ready_seconds per tier is above sessionReadyWarmP90Seconds / sessionReadyColdP90Seconds (5) for sessionReadyFor (15m) |
maqpna-sessions |
MaqpnaSessionFailureRate |
warning | More than sessionFailureRatio (0.25) of sessions ended in 30 minutes are Failed, with at least 5 ended, for 15m |
maqpna-sessions |
MaqpnaWarmPoolEmpty |
warning | maqpna_warm_pool_ready == 0 for 10m |
maqpna-sessions |
MaqpnaTokenMintSlow |
warning | p99 of maqpna_token_mint_seconds above tokenMintP99Seconds (1) for 15m |
maqpna-operator |
MaqpnaOperatorReconcileErrors |
warning | Reconcile errors (not Conflict) above reconcileErrorsPerSecond (0.05) per second for 15m |
maqpna-operator |
MaqpnaConfigMapNearLimit |
warning | maqpna_rendered_configmap_bytes above configMapBytes (819200) for 5m |
maqpna-gateway |
MaqpnaGatewayAuditCommitSlow |
warning | p99 of maqpna_gateway_audit_commit_seconds above auditCommitP99Seconds (0.05) for 10m |
maqpna-gateway |
MaqpnaAuditLedgerUnavailable |
critical | Any increase of maqpna_gateway_audit_errors_total in 5m |
maqpna-gateway |
MaqpnaGatewayNotReady |
critical | No ready gateway pod for 5m (needs kube-state-metrics; kubeStateMetrics: true) |
maqpna-gateway |
MaqpnaApprovalsBacklog |
warning | maqpna_gateway_approvals_pending above approvalsBacklog (50) for approvalsBacklogFor (10m) |
maqpna-gateway |
MaqpnaRevocationListUnavailable |
critical | maqpna_gateway_revocation_list_ok == 0 for revocationListUnavailableFor (10s) |
maqpna-gateway |
MaqpnaRevocationLag |
critical | Last configSync read of the revocations ConfigMap older than revocationLagSeconds (10) for revocationLagFor (1m) |
maqpna-gateway |
MaqpnaConfigSyncFailures |
warning | Any maqpna_gateway_policy_reloads_total{result="failure"} in 10m, for 5m |
maqpna-gateway |
MaqpnaGatewayDenyRateHigh |
warning | Deny share of decisions above denyRatio (0.5) with more than 0.05 decisions per second, for 15m |
maqpna-gateway |
MaqpnaGatewayUpstreamErrors |
warning | Failing share of MCP server round trips above upstreamErrorRatio (0.05) for 10m |
maqpna-gateway |
MaqpnaBudgetExceeded |
info | Any maqpna_gateway_budget_denied_total increase in 15m |
maqpna-gateway |
MaqpnaModelCircuitOpen |
warning | maqpna_gateway_model_circuits_open > 0 for 10m |
maqpna-evidence |
MaqpnaAuditSinkLag |
warning | maqpna_gateway_audit_sink_lag above auditSinkLag (1000) for 15m |
maqpna-evidence |
MaqpnaAttestationFailureRate |
warning | Attestation failure share above attestFailureRatio (0.1) for 10m |
maqpna-license |
MaqpnaLicenseExpiring |
warning / critical | maqpna_license_days_left below licenseExpiryWarnDays (30) (warning) or licenseExpiryCriticalDays (7) (critical), for 1h |
maqpna-license |
MaqpnaLicenseNodeLimitExceeded |
info | maqpna_billable_nodes{period="month"} above a non-zero maqpna_license_node_limit, for 1h |
All thresholds live under monitoring.prometheusRule.thresholds in the Helm values. Add labels to every alert with monitoring.prometheusRule.additionalAlertLabels, and labels on the rule object (for your Prometheus ruleSelector) with monitoring.prometheusRule.labels. What each alert means and what to do is in Monitoring and alerts.
Dashboards in the chart#
Set monitoring.dashboards.enabled: true to render one ConfigMap per file in deploy/helm/maqpna/dashboards/, labelled grafana_dashboard: "1" for the Grafana sidecar (kube-prometheus-stack). Each dashboard has a datasource variable, so it works with any Prometheus data source.
| Dashboard (uid) | ConfigMap | Rows and panels |
|---|---|---|
MAQPNA / Gateway (maqpna-gateway) |
<release>-dashboard-gateway |
Overview: tool calls per second, deny ratio, pending approvals, revocation list, decisions, decisions by server. Upstreams and models: upstream latency p99, upstream errors, model requests, model tokens. Governance: revoked calls, budget denials, DLP hits, auth failures, policy reloads, guard blocks. |
MAQPNA / Sessions (maqpna-sessions) |
<release>-dashboard-sessions |
Start latency: warm and cold p90, sessions started, ended, latency by mode and by tier. Lifecycle and outcomes: sessions by phase, outcomes, sessions by namespace, phase transitions. Warm pools and identity: warm pool ready sandboxes, token mint latency. Operator: reconcile errors, reconcile p99, rendered gateway ConfigMaps. |
MAQPNA / Evidence (maqpna-evidence) |
<release>-dashboard-evidence |
Audit ledger: commit p99, append errors, ledger head, retention below AI Act, commit latency, committed records, sink lag, sink delivery and errors. Attestation: attestations, releases and renewals. |
Other values: monitoring.dashboards.namespace (default: the release namespace), labels and annotations (for example grafana_folder: MAQPNA).
Useful PromQL#
Tool calls per second by decision:
sum by (action) (rate(maqpna_gateway_decisions_total[5m]))
Share of tool calls denied, per MCP server:
sum by (server) (rate(maqpna_gateway_decisions_total{action="deny"}[15m]))
/ sum by (server) (rate(maqpna_gateway_decisions_total[15m]))
p99 latency of each MCP server:
histogram_quantile(0.99, sum by (le, server) (rate(maqpna_gateway_upstream_latency_seconds_bucket[5m])))
Model tokens per hour, by route and kind:
sum by (route, kind) (increase(maqpna_gateway_model_tokens_total[1h]))
Model call error rate, by route:
sum by (route) (rate(maqpna_gateway_model_requests_total{status=~"5..|429"}[10m]))
/ sum by (route) (rate(maqpna_gateway_model_requests_total[10m]))
Spend so far (USD), highest replica:
max(maqpna_gateway_metered_cost_usd)
How far a replica's revocation list is behind (seconds):
max by (pod) (time() - maqpna_gateway_configsync_last_success_timestamp_seconds{configmap="maqpna-revocations"})
Average revocation propagation time per replica:
rate(maqpna_gateway_revocation_propagation_seconds_sum[15m])
/ rate(maqpna_gateway_revocation_propagation_seconds_count[15m])
Audit records written but not yet signed in a checkpoint:
max(maqpna_gateway_audit_head_seq) - max(maqpna_gateway_audit_signed_checkpoint_seq)
Warm-pool session start p90 by trust tier:
histogram_quantile(0.9, sum by (le, tier) (rate(maqpna_session_ready_seconds_bucket{mode="claim"}[15m])))
Running sessions per namespace:
sum by (namespace) (maqpna_sessions{phase="Running"})
Components running a different version from the gateway:
count by (version) (maqpna_build_info)
Check it worked#
Port-forward to the gateway and read its metrics. Use the admin port instead of 8080 when adminListen is set.
kubectl -n maqpna-system port-forward svc/maqpna-gateway 8080:8080
curl -s http://127.0.0.1:8080/metrics | grep '^maqpna_build_info'
In Prometheus, up{job=~".*maqpna.*"} should be 1 for the operator, the gateway and (when enabled) the attestation service.
What can go wrong#
| Symptom | Cause | Fix |
|---|---|---|
Gateway target is down with 404 |
adminListen is set, so /metrics moved to the admin port. |
Use the chart's ServiceMonitor (it scrapes the admin port), or scrape the admin port yourself. |
| Targets in the MAQPNA namespace time out | The control-plane NetworkPolicies admit only pods of the release namespace. | Set networkPolicy.controlPlane.metricsFrom to your Prometheus pods. |
| A metric from this page is missing | The feature that owns it is not configured, or no event has happened yet. | Check the "Present when" notes above; counters with labels appear after the first event. |
maqpna_sessions shows exported_namespace |
Your own scrape config does not honour labels. | Set honor_labels: true for the operator target. |
helm install fails on ServiceMonitor |
serviceMonitor.enabled: true without the Prometheus Operator CRDs. |
Install the Prometheus Operator first, or leave serviceMonitor.enabled: false. |
Next steps#
- Monitoring and alerts: turn on scraping, alerts and dashboards, and the runbook for each alert.
- Observability: how metrics, traces and the audit ledger fit together.
- Ports and endpoints: which port serves
/metricson each component. - Gateway configuration:
adminListen,oteland the other keys that change what is exported. - Helm values: every
monitoring.*andserviceMonitor.*value.