Self-hosting
How-to

Monitor the platform

Deploy, verify, and operate Agent Barn’s namespace-scoped Prometheus, Grafana, Alertmanager, Agent health, API, database, Tool Call, LiteLLM, and OpenRouter monitoring.

For
Platform engineers, self-hosted operators, and incident responders
On this page
  1. Overview
  2. Monitoring architecture
  3. What the stack covers
  4. Before you begin
  5. 1. Configure monitoring
  6. 2. Deploy monitoring
  7. 3. Access Grafana
  8. 4. Verify scrape targets
  9. 5. Use the dashboards
  10. Understand the alerts
  11. 6. Respond to alerts
  12. 7. Monitor Agent coverage
  13. Cover the monitoring gaps
  14. 8. Validate monitoring changes
  15. Troubleshooting
  16. Next steps

Monitoring outcome

Actionable namespace signals with explicit coverage gaps

Complete this guide to operate the built-in stack and connect every alert to a verified response path.

  • Prometheus discovers the expected Services and Agent endpoints.
  • Grafana’s four provisioned dashboards display current environment data.
  • Alertmanager sends firing and resolved notifications to Slack.
  • External monitoring covers infrastructure and recovery signals the chart cannot collect.

Overview

Agent Barn deploys a namespace-scoped monitoring stack through the regular Helmfile release.

Services and AgentsPrometheusAlert rulesAlertmanagerSlack
GrafanaProvisioned dashboards read from Prometheus

The design fits environments where Agent Barn controls a Kubernetes namespace but cannot install cluster-wide operators, CRDs, ClusterRoles, or admission webhooks.

EnvironmentNamespaceEnvironment label
Productionagent-farmproduction
Stagingagent-farm-stagingstaging

Monitoring architecture

The chart under helm/monitoring/ deploys plain Prometheus, Grafana, Alertmanager, and kube-state-metrics. It does not use Prometheus Operator or monitoring CRDs.

Namespace workloadsAPI :8000 and ingest :8001LiteLLM :4000Agent health :8081
PrometheusScrape, retain, evaluate
GrafanaTLS ingress
AlertmanagerInternal → Slack
All discovery and storage stay inside the release namespace; only Grafana receives ingress.
ComponentResponsibilityExposure
PrometheusScrapes metrics, stores time series, and evaluates alert rulesCluster-internal
AlertmanagerGroups alerts and sends firing and resolved notifications to SlackCluster-internal
GrafanaDisplays provisioned dashboards backed by PrometheusTraefik ingress with TLS
kube-state-metricsExposes selected pod state and restart metricsCluster-internal

Namespace-scoped access

The chart creates no RBAC resources. Prometheus and kube-state-metrics reuse the existing <namespace>-user ServiceAccount: agent-farm-user in production and agent-farm-staging-user in staging. Prometheus mounts that token for discovery in its own namespace.

Grafana does not mount a Kubernetes ServiceAccount token. Its dashboards come from a ConfigMap rather than a Kubernetes-discovery sidecar.

GrafanaTraefik and TLS ingressOperator-facing
PrometheusCluster-internalTemporary port-forward only
AlertmanagerCluster-internalTemporary port-forward only

What the stack covers

AreaIncluded signalsImportant boundary
Product APIAvailability, request rate, response status, latency, restartsNo end-user synthetic monitoring
Ingest APIAvailability and Tool Call outcome countersA healthy main API does not prove ingest works
Application PostgreSQLAPI database-connectivity probeNo replication, capacity, backup, or restore monitoring
AgentsScrape availability, runtime connectivity, token validation, ERROR state, restartsExisting resources may need rebuilding before discovery works
LiteLLMAvailability, requests, failures, tokens, and spendDoes not monitor the LiteLLM database directly
OpenRouterRemaining key limit and credit-poll healthLow-credit alert requires a limit on the key
Kubernetes podsRestarts and selected pod labelsNo node, kubelet, cAdvisor, CPU, or memory metrics
Alert deliverySlack firing and resolved notificationsSlack is the only built-in receiver
DashboardsFour provisioned operational dashboardsPrometheus retains metrics for 15 days
Business audit dataActivity, Tool Calls, costs, and Event Deliveries in Agent BarnUse the product UI; Prometheus is not durable audit storage

Before you begin

You need:

  • A deployed Agent Barn environment and access to its target namespace.
  • Helm and Helmfile for manual deployments.
  • DNS for Grafana and a working letsencrypt-http01 ClusterIssuer.
  • A strong Grafana administrator password and a Slack incoming webhook for #alerts.
  • A durable StorageClass for Prometheus.
  • An OpenRouter inference key when you want credit monitoring.

Prometheus, Grafana, and Alertmanager each run one replica. Prometheus scrapes every 30 seconds, evaluates rules every minute, retains metrics for 15 days, and uses a 10 GiB persistent volume.

Prometheus defaults
Scrape interval:   30 seconds
Rule evaluation:   1 minute
Retention:         15 days
Persistent volume: 10 GiB

Plan an independent check for the monitoring stack itself. A total Prometheus or Alertmanager failure can prevent the built-in system from reporting its own outage.

Configure monitoring

GitHub Actions deployment

NameTypeEnvironment behavior
SLACK_ALERTS_WEBHOOK_URLSecretShared by production and staging
GRAFANA_ADMIN_PASSWORDSecretProduction Grafana password
STAGING_GRAFANA_ADMIN_PASSWORDSecretStaging Grafana password
GRAFANA_HOSTVariableProduction Grafana hostname
STAGING_GRAFANA_HOSTVariableStaging Grafana hostname
OPENROUTER_API_KEYSecretUsed by the API and credit probe
STORAGE_CLASSVariableUsed by the Prometheus persistent volume

The workflow derives the environment label from the target branch. Use distinct Grafana passwords and hostnames; the current workflow shares the Slack webhook and OpenRouter key.

Manual deployment

Protected production environment
ENVIRONMENT=production
NAMESPACE=agent-farm

GRAFANA_HOST=grafana.agentbarn.example.com
GRAFANA_ADMIN_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
SLACK_ALERTS_WEBHOOK_URL=https://hooks.slack.com/services/REPLACE_WITH_WEBHOOK

STORAGE_CLASS=REPLACE_WITH_DURABLE_STORAGE_CLASS
OPENROUTER_API_KEY=sk-or-REPLACE_WITH_OPENROUTER_KEY

Do not commit a populated deployment environment file.

Configure DNS and TLS

Point GRAFANA_HOST at cluster ingress. Grafana uses Traefik, the grafana-tls Secret, and the fixed letsencrypt-http01 ClusterIssuer. INGRESS_CLUSTER_ISSUER does not change the Grafana issuer.

Configure OpenRouter credit monitoring

The main API polls OpenRouter GET /key with the inference key and records limit_remaining. An unlimited key reports positive infinity, so OpenRouterCreditsLow cannot fire until the key has a limit.

Deploy the stack

The monitoring release is part of the regular Helmfile deployment and depends on the Agent Barn API release.

Production deployment
ENV_FILE=.env.deploy bash deploy.sh
Staging deployment
ENV_FILE=.env.deploy.staging bash deploy.sh
Staging monitoring values
ENVIRONMENT=staging
NAMESPACE=agent-farm-staging
GRAFANA_HOST=grafana-staging.agentbarn.example.com
Releases and resources
helm list --namespace agent-farm

kubectl get pods,services,persistentvolumeclaims,ingress \
  --namespace agent-farm

kubectl get certificate,challenge \
  --namespace agent-farm
Wait for readiness
kubectl get pods \
  --namespace agent-farm \
  --watch

Expected components include Prometheus, Alertmanager, Grafana, and kube-state-metrics. Confirm the Prometheus claim and Grafana certificate are ready.

Access Grafana

Grafana address
https://GRAFANA_HOST
Grafana administrator
Username: admin
Password: the value of GRAFANA_ADMIN_PASSWORD
  1. Confirm the provisioned Prometheus data source is healthy.
  2. Open every built-in dashboard and confirm current environment data appears.
  3. Restrict the Grafana hostname through organizational network or identity controls.

Dashboards are provisioned from the grafana-dashboards ConfigMap. Treat JSON under helm/monitoring/dashboards/ as the source of truth rather than UI-only edits.

Verify scrape targets

Prometheus is cluster-internal. Open a temporary authorized port-forward:

Shell
kubectl port-forward \
  --namespace agent-farm \
  service/monitoring-prometheus-server \
  9090:80

Open http://localhost:9090/targets and verify:

JobExpected targets
agentbarn-apiMain http endpoint and ingest endpoint
litellmLiteLLM http endpoint
agentOne target for every discoverable running Agent
kube-state-metricsNamespace pod-state metrics
prometheusPrometheus self-scrape
PromQL
up{job="agentbarn-api"}
agentbarn_database_up
up{job="litellm"}
up{job="agent"}
agentbarn_agents_in_error
agentbarn_openrouter_credits_scrape_ok

up == 1 means successful scraping. up == 0 means a discovered target cannot be scraped. An absent target indicates discovery, label, Service, or endpoint failure.

Understand the two API endpoints

EndpointPortImportant metrics
Main API8000HTTP requests, database probe, Agents in ERROR, OpenRouter credits
Ingest API8001Ingest HTTP requests and Tool Call outcome counter

The database, Agent ERROR, and OpenRouter gauges exist only on the main API process. Tool Call outcome metrics are emitted by ingest.

Use the dashboards

Agent Barn provisions four dashboards from a ConfigMap; no Grafana sidecar discovers them.

DashboardSignalsUse
API HealthAPI and ingest availability, database reachability, request rate and latency, API pod restartsStart with UI or API availability and latency incidents
Agent HealthDiscovered and down Agents, ERROR state, token validation, runtime connectivity, pod generations and restartsFilter and investigate by Organization and Agent
Error RatesAPI 5xx ratios, Tool Call error ratio and outcomes, failures grouped by toolSeparate API failures from tool, credential, and provider failures
LLM Costs & ErrorsLiteLLM health, OpenRouter credits, spend, requests, failures, tokens, and model attributionUse product and provider records for durable cost investigation

Agent series receive stable app, agent_name, org_id, and org_name labels from Service labels, preserving identity across pod replacements.

A high Tool Call error ratio does not necessarily mean the API is failing. Check the affected tool, Agent credentials, provider access, and recent configuration changes.

Metrics remain for 15 days. Use Agent Barn cost surfaces and provider billing records for durable cost investigation.

Understand the alerts

API and database alerts

AlertSeverityFires when
APIDowncriticalThe main API target fails scrapes for 2 minutes
APIAbsentcriticalThe main API target is absent for 5 minutes
IngestAPIDownwarningThe ingest process fails scrapes for 5 minutes
DatabaseDowncriticalThe API database probe reports failure for 2 minutes

Error-rate alerts

AlertSeverityFires when
HighAPI5xxRatewarningAPI 5xx ratio exceeds 5% for 5 minutes with non-trivial traffic
HighAPI5xxRatecriticalAPI 5xx ratio exceeds 20% for 5 minutes with non-trivial traffic
HighToolCallErrorRatewarningTool Call error ratio exceeds 25% over 15 minutes and remains elevated for 10 minutes

Agent alerts

AlertSeverityFires when
AgentTargetDowncriticalAn Agent health endpoint cannot be scraped for 2 minutes
AgentUnhealthywarningA previously connected runtime remains unhealthy for 10 minutes
AgentSlackTokensInvalidwarningThe Agent token-validation gauge reports failure for 10 minutes
AgentsInErrorStatewarningAt least one Agent remains in control-plane ERROR for 5 minutes

LiteLLM and OpenRouter alerts

AlertSeverityFires when
LiteLLMDowncriticalLiteLLM is down or absent for 3 minutes
OpenRouterCreditsLowcriticalRemaining key limit is below USD 5 for 15 minutes
OpenRouterCreditsUnknownwarningThe credit poll fails for 30 minutes

DatabaseDown bridges short metric gaps during API rollouts. API ratio alerts include request-rate gates. AgentUnhealthy applies only after agent_healthz_ever_connected reports a prior connection.

The Agent token metric and alert retain Slack-specific names; verify the actual platform for non-Slack Agents. The OpenRouter poll is cached for five minutes and separates stale credit value from scrape health.

Alert delivery behavior

  • Alerts route to Slack #alerts and group by alert name and Organization name.
  • New groups wait 30 seconds, group updates send every five minutes, and unresolved alerts repeat every four hours.
  • Resolved notifications are sent and Slack titles include the environment label.
  • The webhook is stored in a Kubernetes Secret mounted into Alertmanager, not the rendered ConfigMap.

Respond to alerts

  1. Confirm whether the alert is from production or staging.
  2. Identify the affected service, Organization, or Agent.
  3. Confirm the signal in Grafana or Prometheus.
  4. Check the current Kubernetes workload state.
  5. Review recent deployments, migrations, and configuration changes.
  6. Inspect service or Agent logs.
  7. Mitigate user impact.
  8. Verify recovery from the original signal.
  9. Record the incident and any missing monitoring.
Kubernetes state and events
kubectl get pods,deployments,statefulsets,jobs,cronjobs \
  --namespace agent-farm

kubectl get events \
  --namespace agent-farm \
  --sort-by=.lastTimestamp
Workload details and logs
kubectl describe pod POD_NAME \
  --namespace agent-farm

kubectl logs POD_NAME \
  --namespace agent-farm \
  --all-containers \
  --tail=200

Inspect Alertmanager

Shell
kubectl port-forward \
  --namespace agent-farm \
  service/monitoring-alertmanager \
  9093:9093

Open http://localhost:9093 to inspect grouping, delivery, and active silences. A silence suppresses notifications; it does not repair the failure.

Correlate product evidence

SignalFollow-up surface
Agent down or unhealthyAgent health and logs
Agent in ERRORAgent lifecycle status and last_error
Tool Call errorsActivity and Tool Calls
Unexpected spendCost review
Delivery processing concernPlatform Event Deliveries
Credential validation failureAgent credentials and integration validation

Platform Administrators can inspect Event Deliveries at /dashboard/platform/event-deliveries. The built-in rules do not alert on Redis, workers, reconciliation, or Event Delivery lifecycle state.

Monitor Agent coverage

Prometheus discovers Agent metrics on port 8081 through Services with agentbarn.io/component=agent and an endpoint named healthz.

Agents created before monitoring

Existing Agents may lack the health script, endpoint, or labels. Stop and start each affected Agent once so the API rebuilds its Kubernetes resources.

Services with the old component label

When metrics already exist and only the old pre-rebrand label is missing, patch the Service without restarting:

Shell
kubectl label services \
  --namespace agent-farm \
  --selector agentfarm.io/component=agent \
  agentbarn.io/component=agent \
  --overwrite
Verify Agent Services
kubectl get services \
  --namespace agent-farm \
  --selector agentbarn.io/component=agent \
  --show-labels

Prometheus derives app, agent-name, org-id, and org-name from the Service. Restart an Agent when its target lacks current identity labels.

Cover the monitoring gaps

The namespace stack intentionally leaves these production responsibilities to operators.

Missing coverageRecommended external control
Node CPU, memory, disk, and healthCluster or infrastructure monitoring
Container CPU and memorykubelet/cAdvisor or managed Kubernetes observability
PVC capacity and storage latencyStorage and volume monitoring
PostgreSQL replication and internal healthPostgreSQL exporter or managed database monitoring
Backup success and restore readinessBackup-system alerts and scheduled restore tests
Certificate expiry and renewalcert-manager or external certificate monitoring
Public UI and API reachabilityExternal synthetic probes
DNS availabilityExternal DNS monitoring
Redis and worker readinessAdditional application and Redis metrics
Event Delivery backlog or dead lettersPlatform Event Deliveries plus additional alert rules
Firecrawl health and capacityFirecrawl-specific monitoring
Email delivery and provider quotaCloudflare provider monitoring
Long-term metricsRemote write or an externally managed metrics platform
Monitoring-stack availabilityIndependent external checks
High availabilityA separately designed and tested HA architecture

Validate monitoring changes

Shell
helm dependency build helm/monitoring
make check-monitoring

make check-monitoring renders the chart, extracts alert rules, parses dashboard PromQL, runs promtool checks, and executes alert threshold and annotation unit tests. It needs Helm, Docker, and built chart dependencies.

Chart.lock pins dependencies; downloaded archives under helm/monitoring/charts/ are not committed. Monitoring CI runs for helm/monitoring/**, the workflow, and relevant Make target changes.

Verify alert delivery in staging

  • Produce a safe, known staging alert and observe it pending, then firing.
  • Confirm Alertmanager receives it and Slack shows the environment-tagged notification.
  • Remove the condition and confirm both the rule and Slack notification resolve.
  • Verify the response procedure identifies the correct first checks.

Operational checklist

  • Initial setup

  • After deployment

  • Ongoing operations

Troubleshooting

SymptomLikely causeResolution
Helmfile reports a missing Grafana or Slack valueRequired monitoring environment variables are absentAdd GRAFANA_HOST, GRAFANA_ADMIN_PASSWORD, and SLACK_ALERTS_WEBHOOK_URL
Grafana ingress has no certificateDNS or the fixed letsencrypt-http01 ClusterIssuer is unavailableVerify DNS, Ingress, Certificate, Challenge, and ClusterIssuer resources
Grafana opens but dashboards are missingThe dashboards ConfigMap was not mounted or Grafana has not received the updateInspect grafana-dashboards and redeploy the chart
Grafana dashboards show no dataThe Prometheus data source or scrape targets are unavailableVerify the data source, Prometheus pod, and /targets
Prometheus cannot discover any targetsIts ServiceAccount lacks namespace read accessVerify the <namespace>-user ServiceAccount and tenant RoleBinding
API target is absentAPI Service labels or endpoints do not match discovery rulesInspect the agentbarn-api Service and its http and ingest endpoints
Database alert fires while PostgreSQL is runningThe API cannot authenticate, resolve, or query the databaseInspect API logs, the database Service, credentials, and migration state
Tool Call dashboard is emptyIngest is not receiving Tool Call resultsVerify the ingest target, Agent ingest configuration, and recent Tool Calls
Agents do not appear in PrometheusTheir Services lack current labels or health endpointsStop and start old Agents, or patch only the legacy component label
Agent appears down after pod replacementThe Service has no ready healthz endpointInspect Agent readiness, health server, Service, and endpoint
Slack token alert appears for another platformThe current metric and alert names remain Slack-specificVerify actual platform credentials through health and logs
OpenRouter credits show infinityThe key has no credit limitConfigure a key limit if low-credit alerting is required
OpenRouterCreditsUnknown firesThe key is invalid or OpenRouter is unreachableVerify API configuration, egress, and the OpenRouter key
Low-credit alert never firesThe key has no limit or the poll is unhealthyCheck both remaining-credit and scrape-health gauges
Slack receives no alertsWebhook, Secret mount, Alertmanager route, or Slack access is invalidInspect the Secret, Alertmanager pod, configuration, and logs
Staging alerts look like productionENVIRONMENT is wrongCorrect the environment label and redeploy monitoring
CPU and memory panels are unavailableNode and cAdvisor scraping is intentionally disabledAdd separate cluster-level infrastructure monitoring
Prometheus data ends after 15 daysThe retention period elapsedAdd remote storage for longer retention
A monitoring pod failure produced no Slack alertThe stack cannot reliably monitor its own total failureAdd an independent external availability check

Next steps

Continue the self-hosting sequence Upgrade Agent Barn → Review, stage, deploy, verify, and recover future releases.
Documentation