انتقل إلى المحتوى الرئيسي

TP11.2 - المراقبة باستخدام Prometheus و Grafana

أهداف التمرين​

في هذا التمرين، سوف تقوم بـ:

  1. ✅ تكوين Prometheus لجمع المقاييس
  2. ✅ إنشاء لوحات معلومات Grafana
  3. ✅ عرض مقاييس التطبيق
  4. ✅ تكوين التنبيهات

المدة المقدرة: 1 ساعة و 30 دقيقة

المتطلبات المسبقة: تثبيت Docker، إكمال TP11.1


السياق​

سوف تقوم بإعداد مجموعة مراقبة كاملة لتطبيق التجارة الإلكترونية من TP1.

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ Spring Boot │────▶│ Prometheus │────▶│ Grafana │
│ /actuator │ │ (جمع) │ │ (عرض) │
│ /prometheus │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘

الجزء 1: Docker Compose​

هيكل المشروع​

project/
├── src/
├── pom.xml
├── docker-compose.yml
├── prometheus/
│ └── prometheus.yml
└── grafana/
└── provisioning/
└── datasources/
└── datasource.yml

docker-compose.yml​

version: '3.8'

services:
# تطبيق Spring Boot الخاص بك
app:
build: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=docker
networks:
- monitoring

# Prometheus - جمع المقاييس
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks:
- monitoring

# Grafana - عرض
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus
networks:
- monitoring

volumes:
prometheus_data:
grafana_data:

networks:
monitoring:
driver: bridge

الجزء 2: تكوين Prometheus​

prometheus/prometheus.yml​

global:
scrape_interval: 15s # تردد الجمع
evaluation_interval: 15s # تردد تقييم القواعد

scrape_configs:
# Prometheus يجمع نفسه
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

# تطبيق Spring Boot
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
scrape_interval: 10s
static_configs:
- targets: ['app:8080'] # 'app' = اسم خدمة Docker
labels:
application: 'ecommerce-app'
environment: 'development'

# إذا كنت تشغل التطبيق محليًا (خارج Docker)
# - job_name: 'spring-boot-local'
# metrics_path: '/actuator/prometheus'
# static_configs:
# - targets: ['host.docker.internal:8080']

الجزء 3: تكوين Grafana​

grafana/provisioning/datasources/datasource.yml​

apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true

الجزء 4: تشغيل المجموعة​

بدء الخدمات​

# بدء المجموعة
docker-compose up -d

# التحقق من السجلات
docker-compose logs -f

# التحقق من أن كل شيء يعمل
curl http://localhost:8080/actuator/prometheus # التطبيق
curl http://localhost:9090/targets # Prometheus
# Grafana: http://localhost:3000 (admin/admin)

بدون Docker (تطبيق محلي)​

إذا كنت تشغل التطبيق خارج Docker:

# prometheus.yml - تعديل الهدف
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['host.docker.internal:8080']

الجزء 5: التحقق من Prometheus​

الوصول إلى Prometheus​

افتح http://localhost:9090

التحقق من الأهداف​

اذهب إلى Status → Targets

يجب أن ترى:

  • spring-boot-app بحالة UP

استعلامات PromQL​

اختبر هذه الاستعلامات في علامة التبويب Graph:

# الذاكرة المستخدمة في JVM
jvm_memory_used_bytes{area="heap"}

# الطلبات HTTP في الثانية
rate(http_server_requests_seconds_count[5m])

# زمن الاستجابة P99
histogram_quantile(0.99, rate(http_server_requests_seconds_bucket[5m]))

# الأوامر المعلقة
business_orders_pending

# المنتجات منخفضة المخزون
business_products_low_stock

الجزء 6: إنشاء لوحة معلومات Grafana​

تسجيل الدخول​

  1. افتح http://localhost:3000
  2. تسجيل الدخول: admin / admin
  3. تغيير كلمة المرور

إنشاء لوحة معلومات​

  1. انقر على + → Dashboard
  2. انقر على Add visualization
  3. اختر Prometheus كمصدر بيانات

اللوحة 1: الطلبات/الثانية​

الاستعلام:

sum(rate(http_server_requests_seconds_count{application="ecommerce-app"}[5m]))

الإعدادات:

  • العنوان: "Requests per Second"
  • النوع: Stat أو Time series

اللوحة 2: زمن الاستجابة P95​

الاستعلام:

histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket{application="ecommerce-app"}[5m])) by (le))

الإعدادات:

  • العنوان: "P95 Latency"
  • الوحدة: seconds (s)

اللوحة 3: ذاكرة JVM​

الاستعلام:

jvm_memory_used_bytes{area="heap", application="ecommerce-app"} / 1024 / 1024

الإعدادات:

  • العنوان: "Heap Memory Used (MB)"
  • الوحدة: megabytes

اللوحة 4: الأوامر حسب الحالة​

الاستعلامات:

business_orders_pending
business_orders_completed
business_orders_cancelled

الإعدادات:

  • العنوان: "Orders by Status"
  • النوع: Stat (مع التكرار لكل استعلام)

اللوحة 5: المنتجات منخفضة المخزون​

الاستعلام:

business_products_low_stock

الإعدادات:

  • العنوان: "Products with Low Stock"
  • النوع: Gauge
  • العتبات: 0-5 أخضر، 5-10 أصفر، 10+ أحمر

اللوحة 6: الإيرادات الكلية​

الاستعلام:

business_revenue_total

الإعدادات:

  • العنوان: "Total Revenue"
  • الوحدة: العملة ($)

الجزء 7: JSON للوحة المعلومات (استيراد)​

يمكنك استيراد هذه اللوحة المعدة مسبقًا:

{
"title": "E-Commerce Application",
"panels": [
{
"title": "Requests/sec",
"type": "stat",
"targets": [
{
"expr": "sum(rate(http_server_requests_seconds_count[5m]))",
"refId": "A"
}
],
"gridPos": {"h": 4, "w": 6, "x": 0, "y": 0}
},
{
"title": "P95 Latency",
"type": "gauge",
"targets": [
{
"expr": "histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le))",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {"unit": "s", "thresholds": {"steps": [{"value": 0, "color": "green"}, {"value": 0.5, "color": "yellow"}, {"value": 1, "color": "red"}]}}
},
"gridPos": {"h": 4, "w": 6, "x": 6, "y": 0}
},
{
"title": "Heap Memory (MB)",
"type": "timeseries",
"targets": [
{
"expr": "jvm_memory_used_bytes{area=\"heap\"} / 1024 / 1024",
"refId": "A"
}
],
"fieldConfig": {"defaults": {"unit": "decmbytes"}},
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}
},
{
"title": "Orders Pending",
"type": "stat",
"targets": [{"expr": "business_orders_pending", "refId": "A"}],
"gridPos": {"h": 4, "w": 4, "x": 0, "y": 4}
},
{
"title": "Low Stock Products",
"type": "stat",
"targets": [{"expr": "business_products_low_stock", "refId": "A"}],
"fieldConfig": {
"defaults": {"thresholds": {"steps": [{"value": 0, "color": "green"}, {"value": 5, "color": "yellow"}, {"value": 10, "color": "red"}]}}
},
"gridPos": {"h": 4, "w": 4, "x": 4, "y": 4}
},
{
"title": "Total Revenue",
"type": "stat",
"targets": [{"expr": "business_revenue_total", "refId": "A"}],
"fieldConfig": {"defaults": {"unit": "currencyUSD"}},
"gridPos": {"h": 4, "w": 4, "x": 8, "y": 4}
}
],
"refresh": "10s",
"time": {"from": "now-1h", "to": "now"}
}

للاستيراد:

  1. Dashboard → Import
  2. لصق JSON
  3. اختر مصدر بيانات Prometheus
  4. استيراد

الجزء 8: توليد حركة المرور​

سكربت الاختبار​

#!/bin/bash
# generate-traffic.sh

API_URL="http://localhost:8080"

# إنشاء أوامر
for i in {1..20}; do
curl -X POST "$API_URL/api/orders" \
-H "Content-Type: application/json" \
-d "{\"customerEmail\":\"user$i@test.com\",\"total\":$((RANDOM % 500 + 100))}"
sleep 0.5
done

# استعراض المنتجات
for i in {1..50}; do
curl "$API_URL/api/products" > /dev/null 2>&1
sleep 0.2
done

echo "Traffic generated!"

قم بتشغيل السكربت وراقب المقاييس في Grafana.


الجزء 9: التنبيهات (إضافي)​

إضافة تنبيهات في Grafana​

  1. اذهب إلى لوحة (مثال: Low Stock Products)
  2. انقر على Alert → Create alert rule
  3. قم بالتكوين:
    • الشرط: query A > 10
    • التقييم كل: 1m
    • لمدة: 5m (يجب أن يكون صحيحًا لمدة 5 دقائق)
  4. أضف إشعارًا (بريد إلكتروني، Slack، إلخ.)

التنبيهات في Prometheus​

أنشئ prometheus/alert.rules.yml:

groups:
- name: spring-boot-alerts
rules:
- alert: HighMemoryUsage
expr: jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} > 0.9
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage detected"
description: "Heap memory is above 90%"

- alert: HighErrorRate
expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_count[5m])) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "High error rate"
description: "Error rate is above 5%"

- alert: LowStock
expr: business_products_low_stock > 10
for: 10m
labels:
severity: warning
annotations:
summary: "Many products with low stock"

قائمة التحقق النهائية​

  • Docker Compose يبدأ بدون أخطاء
  • Prometheus يجمع التطبيق (الهدف UP)
  • المقاييس مرئية في Prometheus
  • لوحة معلومات Grafana تعمل
  • المقاييس التجارية (الأوامر، المنتجات) معروضة
  • تحديث تلقائي للوحة المعلومات

🎯 الوحدة مكتملة!​

تهانينا! لقد أكملت الوحدة 11 - Spring Boot Actuator والمراقبة.

ملخص:

  • الفصل 1: مقدمة في Actuator
  • الفصل 2: نقاط النهاية
  • الفصل 3: مقاييس Micrometer
  • الفصل 4: فحوصات الصحة
  • TP1: تكوين Actuator
  • TP2: Prometheus و Grafana

المهارات المكتسبة:

  • ✅ تكوين كامل لـ Actuator
  • ✅ فحوصات صحة مخصصة
  • ✅ مقاييس تجارية باستخدام Micrometer
  • ✅ مجموعة مراقبة Prometheus/Grafana
  • ✅ لوحات معلومات وعروض

➡️ العودة إلى الوحدة 11


⬅️ العودة إلى خطة الدورة