- Posted on
- • Artificial Intelligence
Artificial Intelligence DevOps Monitoring
- Author
-
-
- User
- linuxbash
- Posts by this author
- Posts by this author
-
AI-Driven DevOps Monitoring on Linux (with Bash-friendly tooling)
Incidents don’t announce themselves. They creep in as small drifts in CPU, a spike in GPU temperature, or a slow bleed in request latency—and by the time your static thresholds fire, customer impact has begun. AI-assisted monitoring changes that equation. With a small amount of Bash glue and open tooling on Linux, you can surface anomalies earlier, reduce alert noise, and catch regressions right after deploys.
This guide shows you how to bolt an AI-assisted anomaly detector onto a familiar, open-source monitoring stack (Prometheus + Grafana), using lightweight Python and standard Linux tools. You’ll get:
A clear, minimal architecture that runs locally or in prod
Installation commands for apt, dnf, and zypper where applicable
3–5 actionable steps, including an anomaly detector you can extend
Why AI for DevOps Monitoring?
Dynamic baselines beat static thresholds. Microservices, autoscaling, and day/night cycles change “normal” constantly. AI models can learn (or approximate) normal from recent history and flag outliers reliably.
Earlier signals, fewer pages. Anomaly detection captures subtle drifts before they turn into outages, improving MTTR and often MTTD.
Works with what you have. OpenMetrics and Prometheus expose the data; lightweight Python does the math. No vendor lock-in, no heavy infrastructure required.
Good for humans. Turn “thousands of metrics” into “three unusual patterns,” giving SREs and developers time to focus.
Step 1 — Install the fundamentals (metrics first)
We’ll start with:
node_exporter for host metrics
Prometheus for scraping and querying
Grafana for visualization
First, install common prerequisites:
Debian/Ubuntu (apt):
sudo apt update sudo apt install -y curl jq python3 python3-pip podmanFedora/RHEL/CentOS Stream (dnf):
sudo dnf install -y curl jq python3 python3-pip podmanopenSUSE Leap/Tumbleweed (zypper):
sudo zypper refresh sudo zypper install -y curl jq python3 python3-pip podman
Install and start node_exporter (host metrics):
Debian/Ubuntu (apt):
sudo apt install -y prometheus-node-exporter sudo systemctl enable --now prometheus-node-exporterFedora/RHEL/CentOS Stream (dnf):
sudo dnf install -y node_exporter sudo systemctl enable --now node_exporteropenSUSE Leap/Tumbleweed (zypper):
sudo zypper install -y golang-github-prometheus-node_exporter sudo systemctl enable --now node_exporter
Note: Package names may vary slightly by distro version. If your repository lacks Grafana or newer Prometheus, use containers below.
Step 2 — Stand up Prometheus and Grafana quickly (containers)
We’ll use Podman, but you can swap podman with docker if you prefer.
Create a Prometheus config that scrapes node_exporter:
mkdir -p ~/ai-devops/monitoring
cat > ~/ai-devops/monitoring/prometheus.yml << 'YAML'
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
YAML
Run Prometheus:
podman run -d --name prometheus \
-p 9090:9090 \
-v ~/ai-devops/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:Z \
quay.io/prometheus/prometheus:latest \
--config.file=/etc/prometheus/prometheus.yml
Run Grafana:
podman volume create grafana-storage
podman run -d --name grafana \
-p 3000:3000 \
-e GF_SECURITY_ADMIN_PASSWORD='admin' \
-v grafana-storage:/var/lib/grafana \
docker.io/grafana/grafana:latest
Open Prometheus: http://localhost:9090
Open Grafana: http://localhost:3000 (user: admin, pass: admin as set above)
In Grafana, add Prometheus as a data source: URL http://host.docker.internal:9090 (macOS/Windows) or http://localhost:9090 (Linux). For Podman on Linux, localhost works.
Tip: Prefer native packages? Try:
Debian/Ubuntu:
sudo apt install -y prometheus grafana(if available), else use containers.Fedora:
sudo dnf install -y prometheus grafanaopenSUSE:
sudo zypper install -y prometheus grafana
If a package isn’t in your repo, stick with the container method above for predictable versions.
Step 3 — Add AI-assisted anomaly detection (lightweight Python)
We’ll pull a PromQL time series from Prometheus and flag anomalies using a robust Z-score (Median Absolute Deviation). This avoids heavy ML dependencies while catching real outliers.
Install Python deps:
python3 -m pip install --user numpy requests
Create the detector script:
mkdir -p ~/ai-devops/ai
cat > ~/ai-devops/ai/ai_mon.py << 'PY'
#!/usr/bin/env python3
import os, time, json, math
import requests
import numpy as np
from datetime import datetime, timedelta, timezone
from urllib.parse import quote_plus
PROM_URL = os.getenv("PROM_URL", "http://localhost:9090")
# PromQL for host CPU utilization (percentage):
# 100 - avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100
PROMQL = os.getenv(
"PROMQL",
'100 - avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100'
)
WINDOW_MINUTES = int(os.getenv("WINDOW_MINUTES", "60"))
STEP = os.getenv("STEP", "30s")
Z_THRESHOLD = float(os.getenv("Z_THRESHOLD", "4.0")) # robust z-score threshold
ALERT_WEBHOOK = os.getenv("ALERT_WEBHOOK", "") # e.g., Slack Incoming Webhook URL
ALERT_PREFIX = os.getenv("ALERT_PREFIX", "[AI-MON]")
def robust_z_scores(values):
# Return z-scores using median and MAD (median absolute deviation)
arr = np.array(values, dtype=float)
med = np.median(arr)
mad = np.median(np.abs(arr - med))
if mad == 0:
# fallback to std to avoid divide by zero
std = np.std(arr) or 1.0
return (arr - np.mean(arr)) / std
return 0.6745 * (arr - med) / mad
def query_range(prom_url, promql, start_ts, end_ts, step):
url = f"{prom_url}/api/v1/query_range?query={quote_plus(promql)}&start={start_ts}&end={end_ts}&step={step}"
r = requests.get(url, timeout=15)
r.raise_for_status()
data = r.json()
if data.get("status") != "success":
raise RuntimeError(f"Prometheus error: {data}")
return data["data"]["result"]
def post_alert(webhook, text):
if not webhook:
print(text)
return
try:
requests.post(webhook, json={"text": text}, timeout=10)
except Exception as e:
print(f"Alert post failed: {e}")
def main():
now = datetime.now(timezone.utc)
start = now - timedelta(minutes=WINDOW_MINUTES)
series = query_range(PROM_URL, PROMQL, int(start.timestamp()), int(now.timestamp()), STEP)
anomalies = []
for s in series:
instance = s["metric"].get("instance", "unknown")
# Each value: [timestamp, value_str]
values = [float(v[1]) for v in s["values"] if v[1] not in ("NaN", "Inf")]
if len(values) < 10:
continue
z = robust_z_scores(values)
latest = values[-1]
latest_z = float(z[-1])
if math.isnan(latest_z):
continue
if abs(latest_z) >= Z_THRESHOLD:
anomalies.append((instance, latest, latest_z))
if anomalies:
lines = [f"{ALERT_PREFIX} Anomalies detected for query:\n{PROMQL}"]
for inst, val, z in anomalies:
lines.append(f"- instance={inst} value={val:.2f}% z={z:.2f}")
post_alert(ALERT_WEBHOOK, "\n".join(lines))
else:
print("No anomalies.")
if __name__ == "__main__":
main()
PY
chmod +x ~/ai-devops/ai/ai_mon.py
Run it ad-hoc:
export PROM_URL="http://localhost:9090"
export ALERT_WEBHOOK="" # optional Slack Incoming Webhook URL
~/ai-devops/ai/ai_mon.py
Tune it:
PROMQL: Point to any high-signal SLI (e.g., 99th latency, error rate, queue depth)
Z_THRESHOLD: Lower for more sensitivity; raise to reduce noise
WINDOW_MINUTES and STEP: Match your signal’s cadence
Optional: Send to Slack (Incoming Webhook):
export ALERT_WEBHOOK="https://hooks.slack.com/services/XXX/YYY/ZZZ"
Alternative: Send to Alertmanager
- Post JSON to Alertmanager’s /api/v2/alerts with standard labels/annotations (requires Alertmanager accessible). Slack is simpler to start.
Step 4 — Automate and harden (systemd timers; Bash-first)
Use a user-level systemd timer to run detection every minute.
Create a service:
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/ai-mon.service << 'UNIT'
[Unit]
Description=AI anomaly detector for Prometheus
[Service]
Type=oneshot
Environment=PROM_URL=http://localhost:9090
# Example robust CPU utilization PromQL:
Environment=PROMQL=100 - avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100
Environment=Z_THRESHOLD=4.0
# Uncomment to enable Slack alerts:
# Environment=ALERT_WEBHOOK=https://hooks.slack.com/services/XXX/YYY/ZZZ
ExecStart=%h/ai-devops/ai/ai_mon.py
UNIT
Create a timer:
cat > ~/.config/systemd/user/ai-mon.timer << 'UNIT'
[Unit]
Description=Run AI anomaly detector every minute
[Timer]
OnCalendar=*:0/1
Persistent=true
[Install]
WantedBy=timers.target
UNIT
systemctl --user daemon-reload
systemctl --user enable --now ai-mon.timer
systemctl --user list-timers | grep ai-mon
This runs your AI check every minute and only pages when behavior strays off the learned baseline.
Optional: GPU and logs
GPU monitoring (NVIDIA DCGM Exporter) via container:
podman run -d --name dcgm-exporter --privileged -p 9400:9400 \ nvcr.io/nvidia/k8s/dcgm-exporter:latestThen add it to Prometheus targets and point PROMQL to GPU utilization or temperature.
Logs: Add Loki + Promtail for AI-on-logs later. Start with metrics first to keep scope tight; add logs once dashboards are stable.
Real-world examples where this shines
Post-deploy latency regression: p99 jumped only 12%—below static thresholds—but anomaly detection flagged it within 2 minutes, enabling an immediate rollback.
GPU thermal runaway: Training job caused intermittent GPU temperature spikes. MAD-based detector alerted on the spike pattern, not just occasional high temps, preventing throttling.
Slowly increasing error rate: An upstream timeout drifted from 0.1% to 0.6% over an hour; anomaly detection caught the trend before SLOs were breached.
Practical tips for success
Start with high-signal metrics: latency, error rate, queue depth, CPU saturation, JVM GC pauses, GPU utilization/temperature.
Keep label cardinality in check: too many labels balloon series count and degrade Prometheus performance.
Baseline per service/instance: anomalies that aggregate over instances can hide outliers.
Review weekly: tune thresholds and queries based on actual incidents and false positives.
Version your queries: store PROMQL in Git next to your services for reproducibility.
Conclusion and next steps
You don’t need a giant ML platform to get AI benefits in monitoring. With node_exporter, Prometheus, Grafana, and a 100-line Python script, you can detect anomalies earlier and reduce noise—today.
Next steps:
Add a second detector for your top SLI (e.g., 99th percentile latency)
Wire Slack or Alertmanager, then tune sensitivity for one week
Expand coverage: add GPU metrics or a critical business KPI
Automate dashboards and detectors via Git, and review weekly
Have questions or want a follow-up post on OpenTelemetry + anomaly detection for traces? Tell me what you’re instrumenting, and I’ll tailor the next guide.