Monitoring Guide

Monitoring Guide

Comprehensive monitoring and observability for the agentic-sandbox VM orchestration platform.

Status: Production-ready Last Updated: 2026-02-01 Audience: Operators, DevOps engineers, SREs

SSH policy: Direct `ssh agent@...` commands in this guide are dev/break-glass diagnostics. They bypass gateway policy and audit guarantees. Managed-profile SSH should use the gateway-mediated access model described in `ADR-029` and the `SSH gateway rollout plan`.


Quick Start

For operators who want to get monitoring up and running quickly.

Prerequisites

# Ubuntu 24.04 LTS or later
sudo apt update
sudo apt install -y prometheus prometheus-alertmanager grafana

# Start services
sudo systemctl enable --now prometheus alertmanager grafana-server

Deploy Configuration

# Navigate to repository root
cd /path/to/agentic-sandbox

# Deploy Prometheus configuration
sudo cp scripts/prometheus/prometheus.yml /etc/prometheus/prometheus.yml
sudo cp scripts/prometheus/rules/agentic-sandbox.yml /etc/prometheus/rules/agentic-sandbox.yml
sudo chown -R prometheus:prometheus /etc/prometheus

# Deploy Alertmanager configuration
sudo cp scripts/prometheus/alertmanager.yml /etc/alertmanager/alertmanager.yml
sudo chown prometheus:prometheus /etc/alertmanager/alertmanager.yml

# Edit Alertmanager to add your notification channels
sudo nano /etc/alertmanager/alertmanager.yml
# Replace YOUR/WEBHOOK/URL with Slack webhook URL

# Restart services
sudo systemctl restart prometheus alertmanager

Verify Deployment

# Check Prometheus targets
curl http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | {job, health}'

# Check alerts are loading
curl http://localhost:9090/api/v1/alerts | jq '.data.alerts | length'

# Access dashboards
echo "Prometheus: http://localhost:9090"
echo "Grafana: http://localhost:3000 (admin/admin)"
echo "Alertmanager: http://localhost:9093"

Import Grafana Dashboard

1. Access Grafana at http://localhost:3000 (default credentials: admin/admin) 2. Navigate to ConfigurationData SourcesAdd data source 3. Select Prometheus 4. Set URL to `http://localhost:9090` 5. Click Save & Test 6. Navigate to DashboardsImport 7. Upload `scripts/prometheus/agentic-sandbox.json`

  • Compatibility path for the original issue-61 deliverable:

`deploy/grafana/agentic-sandbox.json` 8. Select Prometheus data source 9. Click Import


Architecture Overview

┌──────────────────────────────────────────────────────────────────┐
│                        Host System                                │
│                                                                   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │              Management Server (Rust)                    │   │
│  │  • Exports /metrics endpoint (port 8122)                 │   │
│  │  • Atomic counters (lock-free)                           │   │
│  │  • Histogram buckets for latency                         │   │
│  │  • Per-agent labeled metrics                             │   │
│  └────────────┬─────────────────────────────────────────────┘   │
│               │                                                   │
│               │ scrape every 15s                                  │
│               │                                                   │
│  ┌────────────▼─────────────────────────────────────────────┐   │
│  │            Prometheus (localhost:9090)                   │   │
│  │  • Stores time-series metrics (90-day retention)         │   │
│  │  • Evaluates alert rules (every 30-60s)                  │   │
│  │  • Records SLI/SLO metrics                               │   │
│  └────────────┬─────────────────────────────────────────────┘   │
│               │                                                   │
│               │ send alerts                                       │
│               │                                                   │
│  ┌────────────▼─────────────────────────────────────────────┐   │
│  │         Alertmanager (localhost:9093)                    │   │
│  │  • Routes alerts by severity                             │   │
│  │  • Inhibits redundant alerts                             │   │
│  │  • Sends to Slack/PagerDuty/Email                        │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │              Grafana (localhost:3000)                    │   │
│  │  • Queries Prometheus for visualization                  │   │
│  │  • Pre-built dashboards (import JSON)                    │   │
│  │  • SLO compliance tracking                               │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │              Agent VMs (192.168.122.0/24)                │   │
│  │  • node_exporter on port 9100                            │   │
│  │  • System metrics (CPU, memory, disk, network)           │   │
│  │  • Custom metrics via textfile collector                 │   │
│  └──────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────┘

Configuration Reference

Environment Variables

The management server supports extensive telemetry configuration via environment variables.

Metrics Configuration

VariableTypeDefaultDescription
`METRICS_ENABLED`boolean`true`Enable/disable Prometheus metrics endpoint

Example:

# Disable metrics (not recommended for production)
export METRICS_ENABLED=false
./management/target/release/agentic-management

Logging Configuration

VariableTypeDefaultDescription
`LOG_LEVEL`string`info`Log verbosity: `trace`, `debug`, `info`, `warn`, `error`
`LOG_FORMAT`string`pretty`Output format: `pretty`, `json`, `compact`
`LOG_FILE`path(none)Optional file path for log output
`LOG_FILE_ROTATION`string`daily`Rotation policy: `hourly`, `daily`, `never`
`LOG_FILE_RETENTION_DAYS`integer`7`Days to retain rotated log files

Production Example:

export LOG_LEVEL=info
export LOG_FORMAT=json
export LOG_FILE=/var/log/agentic-management/server.log
export LOG_FILE_ROTATION=daily
export LOG_FILE_RETENTION_DAYS=30

./management/target/release/agentic-management

Development Example:

export LOG_LEVEL=debug
export LOG_FORMAT=pretty

./management/dev.sh

Log Format Examples

Pretty Format (human-readable, colored):

2026-02-01T10:30:45.123Z  INFO agentic_management::grpc: agent connected agent_id="agent-01"
2026-02-01T10:30:46.234Z  INFO agentic_management::dispatch: command dispatched command_id="cmd-abc123"
2026-02-01T10:30:47.345Z  WARN agentic_management::orchestrator: task timeout task_id="task-xyz789"

JSON Format (machine-readable, for log aggregation):

{"timestamp":"2026-02-01T10:30:45.123Z","level":"INFO","target":"agentic_management::grpc","fields":{"message":"agent connected","agent_id":"agent-01"}}
{"timestamp":"2026-02-01T10:30:46.234Z","level":"INFO","target":"agentic_management::dispatch","fields":{"message":"command dispatched","command_id":"cmd-abc123"}}
{"timestamp":"2026-02-01T10:30:47.345Z","level":"WARN","target":"agentic_management::orchestrator","fields":{"message":"task timeout","task_id":"task-xyz789"}}

Compact Format (minimal, single-line):

10:30:45 INFO agent connected agent_id="agent-01"
10:30:46 INFO command dispatched command_id="cmd-abc123"
10:30:47 WARN task timeout task_id="task-xyz789"

Prometheus Setup

Scrape Configuration

The management server exposes Prometheus metrics at `http://localhost:8122/metrics`.

Container runtime signals are exposed by the management server when Docker monitoring is enabled:

  • `agentic_containers_by_status{status="running"}` / `agentic_containers_by_status{status="stopped"}`

Recommended scrape interval: 15 seconds

Example prometheus.yml snippet:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  # Management server metrics
  - job_name: 'management-server'
    static_configs:
      - targets: ['localhost:8122']
        labels:
          service: 'agentic-sandbox'
          component: 'management'

  # Agent VM system metrics (node_exporter)
  - job_name: 'agent-vms'
    static_configs:
      - targets:
          - '192.168.122.201:9100'  # agent-01
          - '192.168.122.202:9100'  # agent-02
          - '192.168.122.203:9100'  # agent-03
        labels:
          service: 'agentic-sandbox'
          component: 'agent'

  # Dynamic agent discovery (optional)
  - job_name: 'agent-vms-dynamic'
    file_sd_configs:
      - files:
          - '/etc/prometheus/targets/agents.json'
        refresh_interval: 30s

Alert Rules

Alert rules are defined in `scripts/prometheus/rules/agentic-sandbox.yml` and organized into six groups. The compact issue-61 compatibility copy is published at `deploy/prometheus/alerts.yml`.

1. agent-health - Agent VM resource monitoring 2. command-execution - Command processing monitoring 3. task-orchestration - Task lifecycle monitoring 4. management-server - Server health monitoring 5. slo-violations - SLO compliance monitoring 6. storage-quotas - Storage monitoring

Total alert rules: 20 in the canonical rules file and 17 in the compact compatibility alert file, across all severity levels.

Alert rule deployment:

sudo cp scripts/prometheus/rules/agentic-sandbox.yml /etc/prometheus/rules/
sudo chown prometheus:prometheus /etc/prometheus/rules/agentic-sandbox.yml
sudo systemctl reload prometheus

Verify alert rules loaded:

curl http://localhost:9090/api/v1/rules | jq '.data.groups[] | {name, file}'

Alert Rule Examples

Critical Alert: Agent Disconnected

- alert: AgentDisconnected
  expr: |
    up{job="agent-vms"} == 0
  for: 2m
  labels:
    severity: critical
    component: agent
  annotations:
    summary: "Agent {{ $labels.agent_id }} disconnected"
    description: "Agent has been unreachable for 2 minutes"

Triggered when: node_exporter on agent VM becomes unreachable for 2 minutes Response: Page on-call engineer via PagerDuty Runbook: https://docs.example.com/runbooks/agent-disconnected

Warning Alert: High Command Failure Rate

- alert: HighCommandFailureRate
  expr: |
    (rate(agentic_commands_by_result{result="failed"}[5m]) / rate(agentic_commands_total[5m])) > 0.05
  for: 10m
  labels:
    severity: warning
    component: management
  annotations:
    summary: "High command failure rate"
    description: "{{ $value | humanizePercentage }} of commands are failing (> 5% threshold)"

Triggered when: More than 5% of commands fail over a 10-minute period Response: Best-effort during business hours Runbook: https://docs.example.com/runbooks/high-command-failure-rate

Emergency Alert: Error Budget Depleted

- alert: ErrorBudgetDepleted
  expr: |
    (
      (rate(agentic_commands_by_result{result="failed"}[24h]) +
       rate(agentic_task_outcomes_total{outcome="failure"}[24h])) /
      (rate(agentic_commands_total[24h]) + rate(agentic_tasks_total[24h]))
    ) > 0.009
  for: 10m
  labels:
    severity: emergency
    component: slo
  annotations:
    summary: "Error budget critically depleted"
    description: "Error rate is {{ $value | humanizePercentage }} (> 0.9%, leaving < 10% error budget)"

Triggered when: Combined error rate exceeds 0.9%, leaving less than 10% of error budget Response: Immediate escalation to incident commander Runbook: https://docs.example.com/runbooks/error-budget-depleted


Grafana Setup

Data Source Configuration

1. Navigate to ConfigurationData Sources 2. Click Add data source 3. Select Prometheus 4. Configure:

5. Click Save & Test

Dashboard Import

The pre-built Grafana dashboard is located at `scripts/prometheus/agentic-sandbox.json`. The issue-61 compatibility copy is published at `deploy/grafana/agentic-sandbox.json`.

Import steps: 1. Navigate to DashboardsImport 2. Upload `scripts/prometheus/agentic-sandbox.json`

  • Compatibility path: `deploy/grafana/agentic-sandbox.json`

3. Select Prometheus as the data source 4. Click Import

Dashboard UID: `agentic-sandbox-overview` Refresh interval: 30 seconds (auto-refresh)

Dashboard Panels

The dashboard includes the following panels:

1. Fleet Status (Stat Panels)

  • Total agents connected
  • Agents ready
  • Agents busy
  • Current tasks running

2. Agent Availability (Time Series)

  • Agent count over time (stacked by status)
  • 99% SLO threshold line
  • 7-day view

3. Command Throughput (Time Series)

  • Commands per second
  • Success vs. failure rate
  • 5-minute rate

4. Command Latency (Time Series)

  • P50, P95, P99 latency percentiles
  • Histogram quantiles
  • 5-second threshold line (warning)

5. Task States (Pie Chart)

  • Distribution: pending, running, completed, failed
  • Live counts

6. Error Rate (Time Series)

  • Command failure rate percentage
  • Task failure rate percentage
  • 5% threshold line (warning)

7. gRPC Request Rate (Time Series)

  • Requests per second by method (Connect, Dispatch)
  • 1-minute rate

8. WebSocket Connections (Time Series)

  • Current active connections
  • Total connections (counter)

9. Agent CPU Usage (Time Series)

  • CPU usage percentage per agent from `node_cpu_seconds_total`
  • Warning and critical threshold lines for sustained saturation

10. Agent Memory Usage (Time Series)

  • Memory usage percentage per agent from `node_memory_MemAvailable_bytes`
  • Warning and critical threshold lines for memory pressure

11. Storage Quotas (Bar Gauge)

  • Per-agent inbox usage (GB)
  • 50GB quota threshold (red at 80%)

12. Agent Status Table

  • Active session count per agent
  • Restart count per agent
  • Current inbox usage per agent

Variable Configuration

Dashboard supports the following variables for filtering:

  • $agent_id - Filter by specific agent (multi-select)
  • $time_range - Customize time range (5m, 15m, 1h, 6h, 24h, 7d)

OpenTelemetry Setup (Optional)

The management server includes OpenTelemetry support for distributed tracing.

Configuration

# Enable OpenTelemetry (currently disabled by default)
export OTEL_ENABLED=true
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_SERVICE_NAME=agentic-management

./management/target/release/agentic-management

Tempo Backend

Example docker-compose.yml for Tempo:

version: '3.8'
services:
  tempo:
    image: grafana/tempo:2.3.0
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
      - tempo-data:/var/tempo
    ports:
      - "4317:4317"  # OTLP gRPC
      - "3200:3200"  # Tempo HTTP

volumes:
  tempo-data:

Jaeger Backend

Alternative using Jaeger:

docker run -d --name jaeger \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 4317:4317 \
  -p 16686:16686 \
  jaegertracing/all-in-one:1.50

Access Jaeger UI at http://localhost:16686

Trace Correlation

When OpenTelemetry is enabled, all logs include trace context:

{
  "timestamp": "2026-02-01T10:30:45.123Z",
  "level": "INFO",
  "target": "agentic_management::dispatch",
  "trace_id": "a1b2c3d4e5f6g7h8i9j0",
  "span_id": "1a2b3c4d5e6f7g8h",
  "fields": {
    "message": "command dispatched",
    "command_id": "cmd-abc123"
  }
}

Query logs by trace_id in Loki or correlate traces in Grafana Explore.


Alerting

Severity Levels

SeverityCountResponse TimeNotification ChannelExample
WARNING10Best-effort, business hoursSlack #alertsAgent CPU > 80% for 10m
CRITICAL7< 30 minutesPagerDuty + SlackManagement server down
EMERGENCY1ImmediatePagerDuty + Slack #incidents + SMSError budget < 10%

Alert Groups

1. Agent Health (4 alerts)

AlertSeverityThresholdDuration
AgentHighCPUWARNING> 80%10m
AgentHighMemoryWARNING> 85%10m
AgentDiskFullCRITICAL> 90%5m
AgentDisconnectedCRITICALUnreachable2m

2. Command Execution (3 alerts)

AlertSeverityThresholdDuration
HighCommandFailureRateWARNING> 5%10m
CommandExecutionStalledCRITICAL0 commands with running tasks5m
SlowCommandExecutionWARNINGP95 > 5s10m

3. Task Orchestration (3 alerts)

AlertSeverityThresholdDuration
HighTaskFailureRateWARNING> 10%30m
TaskQueueBacklogCRITICAL> 10 pending15m
HighTaskTimeoutRateWARNING> 5%30m

4. Management Server (3 alerts)

AlertSeverityThresholdDuration
ManagementServerDownCRITICALUnreachable2m
HighGrpcErrorRateWARNING> 5%10m
HighWebSocketChurnWARNING> 10 conn/s15m

5. SLO Violations (4 alerts)

AlertSeverityThresholdDuration
AgentAvailabilitySLOViolationCRITICAL< 99%30m
CommandSuccessRateSLOViolationCRITICAL< 99%30m
TaskSuccessRateSLOViolationWARNING< 95%1h
ErrorBudgetDepletedEMERGENCY< 10% remaining10m

6. Storage Quotas (3 alerts)

AlertSeverityThresholdDuration
AgentInboxQuotaWarningWARNING> 80% of 50GB30m
AgentInboxQuotaExceededCRITICAL> 95% of 50GB10m
HighDiskIOWaitWARNING> 80%10m

Notification Routing

Alertmanager routing configuration:

route:
  group_by: ['alertname', 'severity', 'component']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'slack-alerts'

  routes:
    # CRITICAL and EMERGENCY to PagerDuty
    - match_re:
        severity: ^(critical|emergency)$
      receiver: 'pagerduty'
      continue: true  # Also send to Slack

    # EMERGENCY to incident channel
    - match:
        severity: emergency
      receiver: 'slack-incidents'

    # All alerts to general channel
    - receiver: 'slack-alerts'

receivers:
  - name: 'slack-alerts'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
        channel: '#agentic-sandbox-alerts'
        title: '{{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.summary }}\
{{ end }}'

  - name: 'slack-incidents'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
        channel: '#agentic-sandbox-incidents'
        title: 'EMERGENCY: {{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.description }}\
{{ end }}'

  - name: 'pagerduty'
    pagerduty_configs:
      - service_key: 'YOUR_PAGERDUTY_SERVICE_KEY'
        description: '{{ .GroupLabels.alertname }}'

Integration with PagerDuty

1. Create a new service in PagerDuty 2. Select Events API v2 integration 3. Copy the integration key 4. Add to `alertmanager.yml` under `pagerduty_configs.service_key` 5. Restart Alertmanager

Integration with Slack

1. Create a new Slack app at https://api.slack.com/apps 2. Enable Incoming Webhooks 3. Add webhook to workspace (select channels: #agentic-sandbox-alerts, #agentic-sandbox-incidents) 4. Copy webhook URLs 5. Add to `alertmanager.yml` under `slack_configs.api_url` 6. Restart Alertmanager


Useful PromQL Queries

Agent Health

# Agent CPU usage by agent (percentage)
100 - (avg by (agent_id) (rate(node_cpu_seconds_total{mode="idle",job="agent-vms"}[5m])) * 100)

# Agent memory usage by agent (percentage)
(1 - (node_memory_MemAvailable_bytes{job="agent-vms"} / node_memory_MemTotal_bytes{job="agent-vms"})) * 100

# Agent disk usage by agent (percentage)
(1 - (node_filesystem_avail_bytes{mountpoint="/",job="agent-vms"} / node_filesystem_size_bytes{mountpoint="/",job="agent-vms"})) * 100

# Agent uptime (hours)
(time() - node_boot_time_seconds{job="agent-vms"}) / 3600

# Agents that are unreachable
up{job="agent-vms"} == 0

Command Execution

# Command success rate (percentage, 5m window)
(rate(agentic_commands_by_result{result="success"}[5m]) / rate(agentic_commands_total[5m])) * 100

# Command failure rate (percentage, 5m window)
(rate(agentic_commands_by_result{result="failed"}[5m]) / rate(agentic_commands_total[5m])) * 100

# Commands per second (1m rate)
rate(agentic_commands_total[1m])

# Command latency P50 (median)
histogram_quantile(0.50, rate(agentic_command_latency_seconds_bucket[5m]))

# Command latency P95
histogram_quantile(0.95, rate(agentic_command_latency_seconds_bucket[5m]))

# Command latency P99
histogram_quantile(0.99, rate(agentic_command_latency_seconds_bucket[5m]))

Task Orchestration

# Tasks pending (current count)
agentic_tasks_by_state{state="pending"}

# Tasks running (current count)
agentic_tasks_by_state{state="running"}

# Task success rate (percentage, 1h window)
(rate(agentic_task_outcomes_total{outcome="success"}[1h]) /
 (rate(agentic_task_outcomes_total{outcome="success"}[1h]) +
  rate(agentic_task_outcomes_total{outcome="failure"}[1h]))) * 100

# Task failure rate (percentage, 1h window)
(rate(agentic_task_outcomes_total{outcome="failure"}[1h]) /
 (rate(agentic_task_outcomes_total{outcome="success"}[1h]) +
  rate(agentic_task_outcomes_total{outcome="failure"}[1h]))) * 100

# Task timeout rate (percentage, 1h window)
(rate(agentic_task_outcomes_total{outcome="timeout"}[1h]) / rate(agentic_tasks_total[1h])) * 100

Storage

# Agents over 80% inbox quota
(agentic_agentshare_inbox_bytes / (50 * 1024 * 1024 * 1024)) > 0.80

# Total inbox storage used (GB)
sum(agentic_agentshare_inbox_bytes) / (1024 * 1024 * 1024)

# Per-agent inbox usage (GB)
agentic_agentshare_inbox_bytes / (1024 * 1024 * 1024)

# Disk I/O wait time (percentage)
rate(node_disk_io_time_seconds_total{job="agent-vms"}[5m]) * 100

SLO Compliance

# Agent availability SLO (target: 99%)
(avg_over_time(agentic_agents_by_status{status="ready"}[5m]) /
 scalar(agentic_agents_connected)) * 100

# Command success rate SLO (target: 99%)
(rate(agentic_commands_by_result{result="success"}[1h]) /
 rate(agentic_commands_total[1h])) * 100

# Task success rate SLO (target: 95%)
(rate(agentic_task_outcomes_total{outcome="success"}[1h]) /
 (rate(agentic_task_outcomes_total{outcome="success"}[1h]) +
  rate(agentic_task_outcomes_total{outcome="failure"}[1h]))) * 100

# Combined error budget remaining (percentage)
(1 - (
  (rate(agentic_commands_by_result{result="failed"}[24h]) +
   rate(agentic_task_outcomes_total{outcome="failure"}[24h])) /
  (rate(agentic_commands_total[24h]) + rate(agentic_tasks_total[24h]))
) / 0.01) * 100

Troubleshooting

Metrics Not Appearing in Prometheus

Symptom: No metrics visible for management server or agent VMs

Check 1: Verify metrics endpoint is accessible

curl http://localhost:8122/metrics

Expected: Prometheus text format output with metric names starting with `agentic_`

Check 2: Verify Prometheus scrape configuration

promtool check config /etc/prometheus/prometheus.yml

Expected: `SUCCESS: 0 rule files found`

Check 3: Verify Prometheus is scraping target

curl http://localhost:9090/api/v1/targets | jq '.data.activeTargets[] | select(.labels.job=="management-server")'

Expected: `"health": "up"` and `"lastError": ""`

Check 4: Check Prometheus logs

sudo journalctl -u prometheus -n 50 --no-pager

Look for: Scrape errors, configuration errors, target discovery issues

Alerts Not Firing

Symptom: Expected alerts not triggering despite conditions being met

Check 1: Verify alert rules syntax

promtool check rules /etc/prometheus/rules/agentic-sandbox.yml

Expected: `SUCCESS: X rules found`

Check 2: View active alerts in Prometheus

curl http://localhost:9090/api/v1/alerts | jq '.data.alerts[] | {alertname: .labels.alertname, state: .state}'

Expected: Alert should appear with `"state": "firing"` when condition is met

Check 3: Check Alertmanager status

curl http://localhost:9093/api/v1/status | jq '.'

Expected: `"uptime"` field present, `"versionInfo"` matches installed version

Check 4: Check Alertmanager logs

sudo journalctl -u alertmanager -n 50 --no-pager

Look for: Routing errors, notification failures

Grafana Dashboard Not Loading Data

Symptom: Dashboard panels show "No Data" or errors

Check 1: Verify Prometheus data source

  • Navigate to ConfigurationData SourcesPrometheus
  • Click Save & Test
  • Should show green "Data source is working" message

Check 2: Verify PromQL queries in Explore

  • Navigate to Explore
  • Select Prometheus data source
  • Run test query: `agentic_agents_connected`
  • Should return current agent count

Check 3: Check dashboard time range

  • Ensure time range is set to "Last 1 hour" or similar
  • Check that data exists for selected time range

Check 4: Check browser console for errors

  • Open browser DevTools (F12)
  • Look for JavaScript errors or network errors

Agent VMs Not Reporting Metrics

Symptom: node_exporter metrics missing for specific agent VMs

Check 1: Verify node_exporter is running

# Dev/break-glass direct SSH diagnostic.
ssh [email protected]
sudo systemctl status prometheus-node-exporter

Expected: `active (running)`

Check 2: Verify node_exporter endpoint

curl http://192.168.122.201:9100/metrics | head -20

Expected: Prometheus text format output with metrics like `node_cpu_seconds_total`

Check 3: Check firewall rules

# Dev/break-glass direct SSH diagnostic.
ssh [email protected]
sudo ufw status

Expected: Port 9100 allowed from host IP

Check 4: Verify network connectivity

ping -c 3 192.168.122.201
nc -zv 192.168.122.201 9100

Expected: Ping successful, port 9100 open

High Memory Usage in Prometheus

Symptom: Prometheus consuming excessive memory

Check 1: Review retention settings

grep -i retention /etc/prometheus/prometheus.yml

Recommended: 90 days (`--storage.tsdb.retention.time=90d`)

Check 2: Check TSDB size

du -sh /var/lib/prometheus/metrics2

Expected: Roughly 50MB per day per agent (1.5GB per agent for 30 days)

Check 3: Reduce scrape interval if needed

global:
  scrape_interval: 30s  # Increase from 15s to reduce load

Check 4: Consider remote write for long-term storage

remote_write:
  - url: http://remote-prometheus:9090/api/v1/write

Production Checklist

Pre-Deployment

  • [ ] Prometheus installed and configured
  • [ ] Grafana installed and configured
  • [ ] Alertmanager installed and configured
  • [ ] Slack webhook URL configured
  • [ ] PagerDuty integration configured
  • [ ] Alert rules deployed
  • [ ] Dashboard imported
  • [ ] Data source tested
  • [ ] Firewall rules configured (ports 9090, 9093, 3000)
  • [ ] node_exporter installed on all agent VMs
  • [ ] Retention policy configured (90 days)
  • [ ] Backup strategy for Prometheus TSDB

Post-Deployment

  • [ ] All targets showing as "UP" in Prometheus
  • [ ] At least one alert firing (test alert)
  • [ ] Slack notifications received
  • [ ] PagerDuty notifications received
  • [ ] Dashboard loading data successfully
  • [ ] All panels populated with metrics
  • [ ] SLO compliance at target levels
  • [ ] Error budget > 50%
  • [ ] Runbooks created for critical alerts
  • [ ] On-call rotation established
  • [ ] Escalation policy documented
  • [ ] ORR (Operational Readiness Review) completed

References

  • Alert Rules: `scripts/prometheus/rules/agentic-sandbox.yml`
  • Prometheus Config: `scripts/prometheus/prometheus.yml`
  • Alertmanager Config: `scripts/prometheus/alertmanager.yml`
  • Grafana Dashboard: `scripts/prometheus/agentic-sandbox.json`
  • Metrics Implementation: `management/src/telemetry/metrics.rs`
  • Logging Implementation: `management/src/telemetry/logging.rs`
  • Observability Design: `docs/OBSERVABILITY_DESIGN.md`
  • Quick Reference: `docs/observability/QUICK_REFERENCE.md`
  • Prometheus Documentation: https://prometheus.io/docs/
  • Grafana Documentation: https://grafana.com/docs/
  • Node Exporter: https://github.com/prometheus/node_exporter

Last Updated: 2026-02-01 Maintained By: Platform Team Status: Production-ready