مقدمة: لماذا تعتبر المراقبة أمرًا حيويًا لتطبيقات Kotlin
\nتطبيقات Kotlin الحديثة التي تعمل على JVM (Java Virtual Machine) غالبًا ما تصبح عقدًا حرجة في البنية التحتية. بدون مراقبة مناسبة، فإنك تخاطر بمواجهة أعطال مفاجئة، أو تسرب للذاكرة، أو تدهور في الأداء قد يظل غير مكتشف حتى وقوع الحادث. في هذه المقالة، سنشرح كيفية بناء نظام مراقبة متكامل لتطبيقات Kotlin «من الألف إلى الياء»: من جمع المقاييس الأساسية (CPU، الذاكرة، GC) إلى إعداد التنبيهات في Grafana و Prometheus.
\nسنناقش ثلاث أدوات رئيسية: Micrometer (واجهة للمقاييس)، Prometheus (مخزن ومجمع)، و Grafana (تصور البيانات والتنبيهات). جميع أمثلة الكود مكتوبة بلغة Kotlin.
\n\n1. أساسيات جمع المقاييس: Micrometer و Prometheus
\nMicrometer هو المعيار الفعلي لواجهة المراقبة في نظام Spring و Kotlin. فهو يوفر واجهة برمجة تطبيقات (API) موحدة لإرسال المقاييس إلى أنظمة مختلفة (Prometheus، Datadog، New Relic، وغيرها).
\n\n1.1. إضافة التبعيات (Gradle)
\ndependencies {\n implementation("io.micrometer:micrometer-registry-prometheus:1.12.0")\n implementation("org.springframework.boot:spring-boot-starter-actuator")\n}\nبالنسبة لـ Ktor أو Kotlin النقي بدون Spring، يمكن إضافة micrometer-core و micrometer-registry-prometheus فقط.
1.2. التكوين الأساسي لـ Micrometer في Spring Boot
\nفي ملف application.yml، يكفي تفعيل Actuator ونقطة نهاية Prometheus:
management:\n endpoints:\n web:\n exposure:\n include: health,info,prometheus\n metrics:\n export:\n prometheus:\n enabled: true\nبعد تشغيل التطبيق، ستكون المقاييس متاحة على العنوان /actuator/prometheus.
1.3. إنشاء مقاييس مخصصة (مثال بلغة Kotlin)
\nلنفترض أنك تريد حساب عدد الطلبات التي تمت معالجتها ووقت معالجتها:
\nimport io.micrometer.core.instrument.MeterRegistry\nimport io.micrometer.core.instrument.Timer\nimport org.springframework.stereotype.Service\nimport java.util.concurrent.atomic.AtomicLong\n\n@Service\nclass OrderService(private val registry: MeterRegistry) {\n\n private val processedOrders: AtomicLong = registry.gauge(\n "orders.processed.count",\n AtomicLong(0)\n )\n private val orderProcessingTime: Timer = registry.timer("orders.processing.time")\n\n fun processOrder(orderId: String) {\n val sample = Timer.start()\n try {\n // منطق معالجة الطلب\n Thread.sleep((50..200).random().toLong())\n processedOrders.incrementAndGet()\n } finally {\n sample.stop(orderProcessingTime)\n }\n }\n}\nالآن ستظهر المقاييس orders_processed_count و orders_processing_time_seconds في Prometheus.
2. إعداد Prometheus لجمع المقاييس
\nPrometheus هو خادم يقوم بـ «سحب» (استعلام) المقاييس من تطبيقاتك وفقًا لجدول زمني.
\n\n2.1. تكوين ملف prometheus.yml
\nأضف خدمة Kotlin الخاصة بك كهدف (target):
\nscrape_configs:\n - job_name: 'kotlin-app'\n metrics_path: '/actuator/prometheus'\n static_configs:\n - targets: ['localhost:8080']\nإذا كان التطبيق يعمل في Docker/Kubernetes، استخدم اكتشاف الخدمة (service discovery).
\n\n2.2. مقاييس JVM الهامة الافتراضية
\nيقوم Micrometer تلقائيًا بتصدير العديد من مقاييس JVM:
\n- \n
jvm_memory_used_bytes— الذاكرة المستخدمة (heap/non-heap) \n jvm_gc_pause_seconds— وقت توقف GC \n jvm_threads_live_threads— عدد الخيوط النشطة \n process_cpu_usage— استخدام وحدة المعالجة المركزية (CPU) من قبل العملية \n
هذه البيانات متاحة بالفعل في Prome