Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/observability/smoke-metrics.sh
T

118 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Smoke-test the /status and /metrics endpoints on a deployed boilerplate.
#
# Usage:
# METRICS_TOKEN=... scripts/observability/smoke-metrics.sh # uses staging defaults
# METRICS_TOKEN=... scripts/observability/smoke-metrics.sh https://api.example.com https://worker.example.com:9100 https://app.example.com
#
# Exits non-zero on the first failing assertion. Designed to run from CI
# after deploy and from the operator's laptop.
set -euo pipefail
API_BASE="${1:-https://api.boiler.saas-ctrl.com}"
WORKER_BASE="${2:-}"
WEB_BASE="${3:-https://app.boiler.saas-ctrl.com}"
if [ -z "${METRICS_TOKEN:-}" ]; then
echo "FAIL: METRICS_TOKEN env var is required." >&2
exit 2
fi
EXIT_CODE=0
probe_status() {
local label="$1"
local url="$2"
local response status body
response=$(curl --max-time 10 --silent --show-error --write-out '\n%{http_code}' "$url" || true)
status=$(printf '%s' "$response" | tail -n1)
body=$(printf '%s' "$response" | sed '$d')
if [ "$status" != "200" ] && [ "$status" != "503" ]; then
echo "FAIL: ${label} /status returned ${status} (expected 200 or 503)" >&2
echo "Body: ${body}" >&2
EXIT_CODE=1
return
fi
if ! printf '%s' "$body" | grep -q '"service":"' ; then
echo "FAIL: ${label} /status JSON missing service field" >&2
echo "Body: ${body}" >&2
EXIT_CODE=1
return
fi
echo "OK: ${label} /status (HTTP ${status})"
}
probe_metrics_unauth() {
local label="$1"
local url="$2"
local status
status=$(curl --max-time 10 --silent --output /dev/null --write-out '%{http_code}' "$url" || true)
if [ "$status" != "401" ] && [ "$status" != "404" ]; then
echo "FAIL: ${label} /metrics without token returned ${status} (expected 401 or 404)" >&2
EXIT_CODE=1
return
fi
echo "OK: ${label} /metrics without token (HTTP ${status})"
}
probe_metrics_authed() {
local label="$1"
local url="$2"
local response status body
response=$(curl --max-time 10 --silent --show-error -H "Authorization: Bearer ${METRICS_TOKEN}" \
--write-out '\n%{http_code}' "$url" || true)
status=$(printf '%s' "$response" | tail -n1)
body=$(printf '%s' "$response" | sed '$d')
if [ "$status" != "200" ]; then
echo "FAIL: ${label} /metrics returned ${status} (expected 200)" >&2
echo "Body (first 200 chars): $(printf '%s' "$body" | head -c 200)" >&2
EXIT_CODE=1
return
fi
for expected in "http_requests_total" "process_cpu_seconds_total"; do
if ! printf '%s' "$body" | grep -q "$expected" ; then
echo "FAIL: ${label} /metrics missing metric '${expected}'" >&2
EXIT_CODE=1
return
fi
done
echo "OK: ${label} /metrics (HTTP 200, expected metric names found)"
}
# API
probe_status "api" "${API_BASE}/status"
probe_metrics_unauth "api" "${API_BASE}/metrics"
probe_metrics_authed "api" "${API_BASE}/metrics"
# Web (uses /api/status + /api/metrics resource routes)
probe_status "web" "${WEB_BASE}/api/status"
probe_metrics_unauth "web" "${WEB_BASE}/api/metrics"
probe_metrics_authed "web" "${WEB_BASE}/api/metrics"
# Worker — only probed when the caller passed a URL (worker admin server is
# typically on a private network without TLS).
if [ -n "$WORKER_BASE" ]; then
probe_status "worker" "${WORKER_BASE}/status"
probe_metrics_unauth "worker" "${WORKER_BASE}/metrics"
probe_metrics_authed "worker" "${WORKER_BASE}/metrics"
else
echo "SKIP: worker /status + /metrics (pass a URL as the second positional arg to enable)"
fi
if [ $EXIT_CODE -eq 0 ]; then
echo "All smoke checks passed."
fi
exit $EXIT_CODE