مقدمة: لماذا المراقبة هي أساس استقرار الإنتاج
\n\nفي التطوير الحديث، كتابة الكود ليست سوى نصف المهمة. لكي يعمل التطبيق المكتوب بلغة Kotlin بثبات تحت الحمل، من الضروري فهم حالته الداخلية. توفر السجلات الأساسية وفحوصات الصحة (health checks) صورة سطحية فقط. تتيح المراقبة المتقدمة مع المقاييس والتنبيهات ليس فقط تسجيل الأعطال، بل التنبؤ بها، وتحديد الاختناقات، والاستجابة السريعة للشذوذ. في هذه المقالة، سنشرح كيفية بناء نظام مراقبة جاهز للإنتاج لتطبيقات Kotlin باستخدام مجموعة التقنيات Micrometer + Prometheus + Alertmanager + Grafana.\n
\n\n1. جمع المقاييس باستخدام Micrometer و Prometheus
\n\nMicrometer هو واجهة (Facade) لجمع المقاييس، والتي أصبحت بحكم الواقع المعيار في عالم JVM و Kotlin. وهو يدعم العديد من الأنظمة الخلفية: Prometheus، Datadog، New Relic وغيرها. بالنسبة لتطبيقات Kotlin (Spring Boot، Ktor، http4k)، فإن التكامل بسيط.\n
\n\n1.1. الإعداد والتوصيل
\nأضف التبعيات اللازمة في ملف build.gradle.kts:
// لـ Spring Boot\nimplementation("io.micrometer:micrometer-registry-prometheus")\n\n// لـ Ktor (إعداد يدوي)\nimplementation("io.micrometer:micrometer-core:1.12.0")\nimplementation("io.micrometer:micrometer-registry-prometheus:1.12.0")\n\nبالنسبة لـ Spring Boot، يتم إنشاء MeterRegistry تلقائياً. في Ktor، تحتاج إلى تهيئته يدوياً:
import io.micrometer.prometheus.PrometheusMeterRegistry\nimport io.micrometer.core.instrument.Clock\nimport io.prometheus.client.CollectorRegistry\n\nval registry = PrometheusMeterRegistry(\n PrometheusConfig.DEFAULT,\n CollectorRegistry.defaultRegistry,\n Clock.SYSTEM\n)\n\n// تصدير نقطة النهاية /metrics\nembeddedServer(Netty, port = 8080) {\n routing {\n get("/metrics") {\n call.respondText(registry.scrape())\n }\n }\n}.start(wait = true)\n\n1.2. المقاييس المخصصة
\nبالإضافة إلى المقاييس القياسية (JVM، CPU، الذاكرة)، أضف مقاييس الأعمال. مثال على عداد الطلبات المعالجة:
\nval orderCounter = Counter.builder("orders.processed")\n .description("Total processed orders")\n .register(registry)\n\nfun processOrder(order: Order) {\n // منطق الأعمال\n orderCounter.increment()\n}\n\nأو مدرج تكراري (Histogram) لوقت تنفيذ الطلب:
\nval requestTimer = Timer.builder("http.requests.duration")\n .description("Duration of HTTP requests")\n .publishPercentiles(0.5, 0.95, 0.99)\n .sla(Duration.ofMillis(100), Duration.ofMillis(500))\n .register(registry)\n\nfun handleRequest(block: () -> Response): Response {\n return requestTimer.record(block)\n}\n\n2. التنبيهات المتقدمة: من القيم الحدية إلى التنبؤات
\n\nغالباً ما تؤدي التنبيهات المبنية على حدود بسيطة (مثل CPU > 90%) إلى إنذارات كاذبة. على المستوى المتقدم، نستخدم Alertmanager وقواعد PromQL مع التجميع والتنبؤ.\n
\n\n2.1. إعداد Alertmanager
\nإعداد ملف alertmanager.yml لإرسال الإشعارات إلى Telegram و Slack:
route:\n receiver: 'team-alerts'\n group_wait: 30s\n group_interval: 5m\n repeat_interval: 1h\n\nreceivers:\n- name: 'team-alerts'\n telegram_configs:\n - bot_token: 'YOUR_BOT_TOKEN'\n chat_id: -123456789\n parse_mode: 'HTML'\n slack_configs:\n - api_url: 'https://hooks.slack.com/services/...'\n channel: '#alerts'\n\n2.2. قواعد PromQL للتنبيهات الذكية
\nفي ملف rules.yml، نصف قاعدة يتم تفعيلها إذا تجاوز المئين 95 لوقت الاستجابة 500 مللي ثانية لمدة 5 دقائق:
groups:\n- name: http_latency\n rules:\n - alert: HighLatencyP95\n expr: |\n histogram_quantile(0.95,\n sum(rate(http_requests_duration_seconds_bucket[5m])) by (le, endpoint)\n ) > 0.5\n for: 5m\n ann