تعتمد البنية التحتية الحديثة بشكل كبير على المقاييس، لكن جزءاً كبيراً من وظائف المسار الحرج للمؤسسات لا يزال يعمل على تطبيقات قديمة. غالباً ما تكون هذه الأنظمة غامضة وتفتقر إلى نقاط نهاية API أصلية لأدوات المراقبة الحديثة. يخلق هذا الفجوة نقاط عمياء قد تؤدي إلى انقطاعات غير متوقعة وتدهور في الأداء. في هذا الدليل، سنستكشف كيفية سد هذه الفجوة من خلال بناء مُصدّرات Prometheus مخصصة. من خلال تغليف المنطق القديم في طبقة مقاييس، يمكنك كشف مؤشرات الصحة الحيوية لوحات Grafana وPrometheus الحالية دون تعديل شفرة التطبيق الأساسية.
فهم نمط المُصدّر (Exporter)
مُصدّر Prometheus هو خدمة منفصلة تعرض المقاييس بتنسيق يمكن لـ Prometheus قراءته (scrape). وعلى عكس التطبيق نفسه، الذي قد يكون مكتوباً بلغة COBOL أو Delphi أو إصدار قديم من Java، يعمل المُصدّر كغلاف رقيق. يتفاعل مع النظام القديم عبر الواجهات المتاحة—مثل SNMP، أو واجهات برمجة التطبيقات HTTP، أو استعلامات قاعدة البيانات—ويترجم تلك الاستجابات إلى تنسيق عرض متوافق مع Prometheus.
هذا الفصل بين المسؤوليات أمر بالغ الأهمية. فهو يتيح لك إدارة صحة التطبيق القديم بشكل مستقل عن منطق التطبيق. إذا فشل المُصدّر، تظل بنية المراقبة مستقرة. وإذا فشل التطبيق القديم، يقوم المُصدّر ببساطة بالإبلاغ عن حالات الصفر أو الأخطاء، مما ينبه فريقك قبل أن يلاحظ المستخدمون ذلك.
اختيار اللغة المناسبة
عند بناء مُصدّر، غالباً ما يحدد اختيار لغة البرمجة سهولة الصيانة والأداء. تهيمن لغتان على هذا المجال: Go وPython.
Go هي المعيار الصناعي لكتابة المُصدّرات. مكتبة prometheus/client_golang الرسمية قوية، وآمنة النوع، وتُترجم إلى ملف تنفيذي ثابت واحد، مما يجعل النشر سهلاً في البيئات الحاوية (containerized). إنها عالية الأداء وتتعامل مع التزامن بشكل جيد.
Python ممتازة للنماذج الأولية السريعة، خاصة إذا كان فريقك على دراية بالفعل بمكتبات معالجة البيانات مثل Pandas لتجميع المقاييس. حزمة prometheus_client سهلة الاستخدام ولكنها قد تكون أبطأ في سيناريوهات الإنتاج العالي (high-throughput).
مثال تنفيذي باستخدام Go
لنلقِ نظرة على مثال عملي باستخدام Go. افترض أن لديك قاعدة بيانات مخزون قديمة تخزن مستويات المخزون. تريد كشف عدد العناصر ذات المخزون المنخفض. إليك كيفية هيكلة المُصدّر:
package main
import (
"log"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// LowStockCollector يطبق واجهة prometheus.Collector.
type LowStockCollector struct {
LowStockCount *prometheus.Desc
}
// NewLowStockCollector تهيئ مُجمع جديد.
func NewLowStockCollector() *LowStockCollector {
return &LowStockCollector{
LowStockCount: prometheus.NewDesc(
"legacy_inventory_low_stock",
"عدد العناصر ذات المخزون المنخفض في قاعدة البيانات القديمة",
nil, nil,
),
}
}
// Describe ترسل أوصاف كل مقياس مرتبط بهذا المُجمع.
func (c *LowStockCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- c.LowStockCount
}
// Collect يتم استدعاؤها بواسطة سجل Prometheus عند جمع المقاييس.
func (c *LowStockCollector) Collect(ch chan<- prometheus.Metric) {
// محاكاة جلب البيانات من النظام القديم
count := fetchLowStockCountFromLegacyDB()
ch <- prometheus.MustNewConstMetric(
c.LowStockCount,
prometheus.GaugeValue,
float64(count),
)
}
func main() {
registry := prometheus.NewRegistry()
collector := NewLowStockCollector()
registry.MustRegister(collector)
http.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))
log.Fatal(http.ListenAndServe(":9100", nil))
}
func fetchLowStockCountFromLegacyDB() int {
// منطق استعلام قاعدة البيانات القديمة يذهب هنا
return 42
}
في هذا المثال، نعرف مُجمعاً مخصصاً يطبق طريقتي Describe وCollect. طريقة Collect هي حيث تتفاعل مع النظام القديم. من خلال كشف هذا على /metrics، يمكن لـ Prometheus قراءة البيانات دون الحاجة إلى تعديل التطبيق القديم.
معالجة المصادقة والأمان
غالباً ما تفتقر الأنظمة القديمة إلى آليات المصادقة الحديثة. ومع ذلك، يجب تأمين المُصدّر نفسه. بما أن المُصدّر خدمة منفصلة، يمكنك وضعه خلف وكيل عكسي مثل Nginx أو Apache، وإضافة مصادقة أساسية أو mTLS. يضمن هذا أنه حتى إذا كانت الواجهة القديمة غير مؤمنة، فإن نقطة نهاية المقاييس تظل محمية من الوصول غير المصرح به.
الخاتمة
تمديد قابلية المراقبة إلى التطبيقات القديمة ليس مجرد ضرورة تقنية؛ بل هو ضرورة أعمال. من خلال بناء مُصدّرات Prometheus مخصصة، تحصل على رؤية للأنظمة التي كانت ستظل صناديق سوداء بخلاف ذلك. سواء اخترت Go للأداء أو Python للبساطة، فإن المفتاح هو إبقاء المُصدّر خفيفاً ومركزاً. يسمح لك هذا النهج بتحديث بنية المراقبة الخاصة بك تدريجياً مع الحفاظ على استقرار البنية التحتية القديمة الحرجة. ابدأ بشكل صغير، وكشف مقياساً واحداً، ثم توسع من هناك.