Apinizer Worker Diagnostics İzleme ve Raporlama
1-) Nasıl Çalışır?
Bu kılavuzda, bir Apinizer Worker pod'unun diagnostic metriklerini periyodik olarak toplayan ve gün sonunda bu verilerden tek dosyalık interaktif bir HTML rapor üreten basit bir izleme çözümü anlatılmaktadır.
Çözüm üç parçadan oluşur:
- Bir toplayıcı shell script (
monitor.sh) — verilen ortamın Worker Diagnostics API'sini (/allendpoint'i) periyodik olarak okur, satır başına bir JSON kaydı olacak şekilde JSONL dosyasına ekler. Aynı script, ortam adı + Worker URL + Env ID argümanları ile birden fazla ortam için paralel olarak çalıştırılabilir. - Bir Python rapor üretici (
generate_report.py) — belirtilen ortamın JSONL dosyasını okur; memory, thread, GC, connection, health metriklerini normalize eder; istatistikler, anomali tespiti ve Chart.js tabanlı interaktif grafiklerle zenginleştirilmiş tek bir HTML dosyası üretir. - Bir orkestratör script (
make-report.sh) — verilen ortam adına ve tarihe göre JSONL dosyasını bulur, asgari kayıt sayısını kontrol eder ve rapor üreticiyi çağırır.
Akış şu şekildedir: Apinizer Worker (/apinizer/diagnostics/all) → monitor.sh <ortam> (her 2 dakikada bir) → <ortam>-worker-diagnostics-YYYYMMDD.jsonl → make-report.sh <ortam> → generate_report.py → apinizer-worker-rapor-<ortam>-YYYYMMDD.html
2-) Ön Koşullar
Çözümü çalıştıracağınız makinede aşağıdaki gereksinimler karşılanmalıdır:
bash,curl,sed,wc(tipik bir Linux ortamında mevcut)python3(3.9 veya üzeri;list[dict]gibi type hint'ler için gerekli)- Rapor üretici yalnızca standart kütüphaneyi kullanır;
pip installgerekmez. Grafiklerin çizimi için gereken Chart.js, üretilen HTML dosyasına CDN üzerinden gömülüdür — raporu görüntülerken internet bağlantısı yeterlidir. - Worker pod'larının Diagnostics API'sine ağ erişimi (ör. cluster dışından NodePort veya Ingress üzerinden).
Ayrıca her ortam için ENV_ID değerine ihtiyacınız olacak. Bu değer, Apinizer API Manager arayüzünde Ortamlar menüsü altında ilgili ortamın detayından kopyalanabilir ve Diagnostics API çağrılarında Authorization header'ı olarak kullanılır.
3-) Diagnostics API
Apinizer Worker, pod'un mevcut durumunu sorgulamak için aşağıdaki diagnostic endpoint'leri sunar:
| Endpoint | Açıklama |
|---|---|
/jvm | JVM seviyesindeki memory (heap, non-heap), GC sayaçları ve uptime bilgisini döner. |
/threads | Thread sayıları, thread state dağılımı (RUNNABLE / WAITING / TIMED_WAITING) ve executor pool durumlarını içerir. |
/threaddump | Tüm thread'lerin anlık stack trace'lerini döner. Tanı amaçlıdır; periyodik toplama için uygun değildir. |
/connections | Worker'a özgü HTTP connection pool metriklerini (leased, available, pending, maxTotal) içerir. |
/env | Çalışma ortamı bilgilerini (environment variable'lar, sistem özellikleri) döner. |
/health | Pod sağlık durumu (UP / DOWN) ve alt sağlık kontrolleri (memory, threads, connections). |
/hazelcast | Cache-spesifik metrikleri (cluster üyeleri, dağıtık veri yapıları durumu) döner. |
/pod-version | Pod'un sürüm bilgisini döner. |
/all | Yukarıdaki tüm metrikleri tek bir JSON yanıtı içinde birleştirir. |
Bu kılavuzdaki rapor üretici (generate_report.py), pod başına memory + thread + GC + connection + health metriklerini birlikte gösteren bütünleşik bir rapor sunduğundan, yalnızca /all endpoint'inin yanıt yapısı ile uyumlu çalışır. Toplayıcı script bu nedenle /all endpoint'ini kullanır. Diğer endpoint'leri ham veri amacıyla curl veya benzeri bir araçla doğrudan çağırabilirsiniz; ancak monitor.sh ile toplanan JSONL dosyasından rapor üretmek istiyorsanız /all kullanmanız zorunludur.
Toplayıcı script, Worker üzerindeki aşağıdaki endpoint'i çağırır:
GET {WORKER_URL}/apinizer/diagnostics/all?internal=true
Authorization: {ENV_ID}
Endpoint, o pod'a ait JVM, thread, GC, connection pool ve health bilgilerini içeren geniş bir JSON döner. Örnek yanıtın üst düzey alanları şu şekildedir:
{
"podName": "apinizer-worker-xxxx",
"podIp": "10.244.1.23",
"envName": "prod",
"version": "...",
"responseTime": 12,
"jvm": {
"memory": { "heap": { "used": 0, "max": 0 }, "nonHeap": { "used": 0 } },
"gc": [ { "name": "G1 Young Generation", "collectionCount": 0, "collectionTime": 0 } ],
"uptime": 0
},
"threads": {
"summary": { "threadCount": 0, "peakThreadCount": 0, "daemonThreadCount": 0, "totalStartedThreadCount": 0 },
"states": { "RUNNABLE": 0, "WAITING": 0, "TIMED_WAITING": 0 },
"executorPools": { "apinizer-async": { "poolSize": 0, "activeCount": 0, "queueSize": 0, "rejectedTaskCount": 0 },
"apinizer-maintenance": { "queueSize": 0, "rejectedTaskCount": 0 } }
},
"connections": { "pools": [ { "leased": 0, "available": 0, "pending": 0, "maxTotal": 0 } ] },
"health": { "status": "UP",
"checks": { "memory": { "status": "UP" },
"threads": { "deadlocks": 0 },
"connections": { "activeConnections": 0 } } }
}
ENV_ID değeri yanlış girildiğinde Worker 401 Unauthorized döner. Toplayıcı script bu durumu algılar ve ilgili satırı dosyaya hata kaydı olarak yazar; ancak sonraki örneklemeler de başarısız olmaya devam eder. Script'i başlatır başlatmaz ilk çıktıyı kontrol etmeniz önerilir.
4-) Toplayıcı Script'in Kurulumu
Tek bir monitor.sh dosyası, hangi ortamı izleyeceğiniz bilgisini argüman olarak alır. Bu sayede farklı ortamları (ör. dev, prod, staging) izlemek için ayrı script dosyalarına gerek kalmaz; aynı script dosyası birden fazla terminalde farklı argümanlarla çalıştırılarak paralel izleme yapılabilir.
Bu kılavuzda anlatılan üç script'in (monitor.sh, generate_report.py, make-report.sh) hazır kopyalarına aşağıdaki bağlantıdan erişebilirsiniz:
Dosyaları aynı dizine indirip chmod +x monitor.sh make-report.sh komutuyla çalıştırılabilir yapmanız yeterlidir.
monitor.sh — Dinamik Toplayıcı Script
Aşağıdaki script'i monitor.sh adıyla kaydedin. Kullanım sırasında ortam adı, Worker URL ve Env ID değerlerini komut satırında argüman olarak geçirin.
#!/usr/bin/env bash
# Apinizer Worker — Dinamik ortam izleyici
# Her 2 dakikada bir Diagnostics API'sinin /all endpoint'ini okur, JSONL dosyasına yazar.
#
# Kullanım:
# 1) Argümanlarla:
# ./monitor.sh <ORTAM_ADI> <WORKER_URL> <ENV_ID> [INTERVAL_SN]
# ./monitor.sh dev http://worker-dev.kurum.local:8091 69db6b2268bd1a7a04552ad6
# ./monitor.sh prod http://worker-prod.kurum.local:8091 63ca7ed05c8e155862d99e88 60
#
# 2) Aşağıdaki varsayılanları doldurup argümansız çalıştırarak:
# ./monitor.sh
#
# Çıktı: <ORTAM_ADI>-worker-diagnostics-YYYYMMDD.jsonl
# ── Varsayılan Yapılandırma (argüman verilmezse kullanılır) ──────────────────
DEFAULT_ENV_NAME="" # Örn: dev | prod | staging
DEFAULT_WORKER_URL="" # Örn: http://worker.kurum.local:8091
DEFAULT_ENV_ID="" # API Manager → Ortamlar → <ortam> → ID
DEFAULT_INTERVAL=120
ENDPOINT="all" # /all — tüm metrikleri birleştiren endpoint
# ── Argüman İşleme ───────────────────────────────────────────────────────────
ENV_NAME="${1:-$DEFAULT_ENV_NAME}"
WORKER_URL="${2:-$DEFAULT_WORKER_URL}"
ENV_ID="${3:-$DEFAULT_ENV_ID}"
INTERVAL="${4:-$DEFAULT_INTERVAL}"
# ── Kod (değiştirmeyin) ──────────────────────────────────────────────────────
set -uo pipefail
usage() {
cat <<EOF
Kullanım: $0 <ORTAM_ADI> <WORKER_URL> <ENV_ID> [INTERVAL_SN]
Örnek:
$0 dev http://worker-dev.kurum.local:8091 69db6b2268bd1a7a04552ad6
$0 prod http://worker-prod.kurum.local:8091 63ca7ed05c8e155862d99e88 60
Not: Scriptin başındaki DEFAULT_* değerlerini doldurursanız argümansız da
çalıştırabilirsiniz.
EOF
exit 1
}
if [[ -z "$ENV_NAME" || -z "$WORKER_URL" || -z "$ENV_ID" ]]; then
echo "HATA: ORTAM_ADI, WORKER_URL ve ENV_ID zorunlu."
echo
usage
fi
# Ortam adı dosya güvenli olsun (boşluk, slash vs. kabul etmiyoruz)
if [[ ! "$ENV_NAME" =~ ^[A-Za-z0-9._-]+$ ]]; then
echo "HATA: ORTAM_ADI sadece harf, rakam, '.', '_', '-' içerebilir."
exit 1
fi
OUTPUT_FILE="${ENV_NAME}-worker-diagnostics-$(date +%Y%m%d).jsonl"
TMP_BODY="/tmp/_wdiag_${ENV_NAME}_body.tmp"
collect() {
local ts
ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
local response http_code body
response=$(curl -s --max-time 30 \
-o "$TMP_BODY" \
-w "%{http_code}" \
-H "Authorization: ${ENV_ID}" \
"${WORKER_URL}/apinizer/diagnostics/${ENDPOINT}?internal=true" 2>/dev/null)
http_code="$response"
body=$(cat "$TMP_BODY" 2>/dev/null)
if [[ -z "$body" ]]; then
echo "{\"collectedAt\":\"${ts}\",\"error\":\"bağlantı hatası\"}" >> "$OUTPUT_FILE"
echo " HATA: Worker'a ulaşılamadı (${WORKER_URL})"
return 1
fi
if [[ "$http_code" == "401" ]]; then
echo "{\"collectedAt\":\"${ts}\",\"error\":\"yetkisiz - ENV_ID hatalı\"}" >> "$OUTPUT_FILE"
echo " HATA: 401 Unauthorized — ENV_ID değerini kontrol edin."
return 1
fi
local line
line=$(echo "$body" | sed "s/^{/{\"collectedAt\":\"${ts}\",/")
echo "$line" >> "$OUTPUT_FILE"
}
echo "[${ENV_NAME}] Worker Diagnostics izleme başladı"
echo " Ortam : $ENV_NAME"
echo " Worker : $WORKER_URL"
echo " Endpoint : /$ENDPOINT"
echo " Aralık : ${INTERVAL}s"
echo " Çıktı : $OUTPUT_FILE"
echo " Durdurmak için Ctrl+C"
echo "──────────────────────────────────────────"
while true; do
printf "[%s] Okunuyor... " "$(date '+%H:%M:%S')"
if collect; then
echo "OK → $OUTPUT_FILE"
fi
sleep "$INTERVAL"
done
Script'i Çalıştırılabilir Yapma ve Başlatma
chmod +x monitor.sh
# Tek bir ortam için:
./monitor.sh prod http://worker-prod.kurum.local:8091 63ca7ed05c8e155862d99e88
# Birden fazla ortamı paralel izlemek için — farklı terminallerde (veya tmux pane'lerinde):
./monitor.sh dev http://worker-dev.kurum.local:8091 69db6b2268bd1a7a04552ad6
./monitor.sh prod http://worker-prod.kurum.local:8091 63ca7ed05c8e155862d99e88
Her çalıştırma, argümandaki ortam adını kullanarak kendi JSONL dosyasını üretir (dev-worker-diagnostics-20260422.jsonl, prod-worker-diagnostics-20260422.jsonl gibi); dosyalar birbirine karışmaz.
Script varsayılan olarak her 120 saniyede bir örnekleme alır. Daha sık veya daha seyrek örnekleme için dördüncü argüman olarak saniye cinsinden bir değer geçirebilirsiniz (ör. ./monitor.sh prod <url> <id> 60). 60 saniyenin altına inmek Worker üzerinde gereksiz yük oluşturabilir; 300 saniyenin üzeri ise kısa süreli spike'ları kaçırabilir.
Arka Planda Sürekli Çalıştırma
İzleme script'leri while true döngüsüyle çalıştığı için, terminal oturumu kapandığında durur. Sürekli çalışır halde tutmak için kullanım senaryonuza göre aşağıdaki yöntemlerden biri tercih edilebilir:
- Test / geliştirme ortamı için
tmuxveyascreen— Script'i ayrı bir tmux oturumunda başlatırsanız, SSH bağlantınızı kapatsanız bile çalışmaya devam eder. Daha sonra oturuma yeniden bağlanıp çıktıyı canlı izleyebilirsiniz. Hızlı ve basit bir çözümdür; ancak sunucu yeniden başlatıldığında script otomatik olarak ayağa kalkmaz. - Üretim ortamı için
systemdservisi — Linux'ta arka plan servislerini yöneten standart yöntemdir. Her ortam için bir.serviceunit dosyası yazılır; komut satırı olarakExecStart=/path/to/monitor.sh prod <url> <id>gibi argümanlar verilir. Bu sayede sunucu yeniden başlatıldığında servis otomatik başlar, beklenmedik şekilde çıkarsa otomatik olarak yeniden denenir (Restart=always), ve çıktısı sistem log'larına (journalctl) düşer. Üretim kullanımında süreklilik ve gözlemlenebilirlik açısından tercih edilen yöntem budur.
Konteyner tabanlı bir yaklaşım tercih ediliyorsa, toplayıcı script ortam bilgilerini environment variable olarak alan küçük bir Docker image içine yerleştirilip Kubernetes üzerinde kalıcı bir Deployment veya zamanlanmış bir CronJob olarak da koşturulabilir.