أذكر تلك الليلة جيدًا، كانت ليلة خميس من شتاء قارس، وكنا قد أطلقنا للتو حملة تخفيضات ضخمة على متجر إلكتروني لأحد عملائنا الكبار. الساعة كانت تشير إلى الثانية صباحًا، وأنا في فراشي شبه نائم، أحلم ربما بكود نظيف وسيرفرات لا تتعطل أبدًا. وفجأة، اهتز الهاتف بجانبي كأنه صاعقة. مجموعة الواتساب الخاصة بفريق الطوارئ تشتعل بالرسائل: “الموقع بطيء جدًا!”، “عمليات الدفع تفشل!”، “العملاء يشتكون على تويتر!”.
قفزت من السرير، وشغّلت اللابتوب وقلبي يدق في حلقي. فتحنا عشرات النوافذ، واحد يفحص سجلات (logs) السيرفر، وآخر يراقب استهلاك الـ CPU، وأنا أحاول تتبع الطلبات في قاعدة البيانات. الكل يصرخ في الاجتماع الطارئ: “هل هو الكود الجديد؟”، “هل هي قاعدة البيانات؟”، “هل هي هجمة DDoS؟”. كنا كمن يبحث عن إبرة في كومة قش عملاقة ومشتعلة. بعد ساعتين من الجحيم، اكتشفنا المشكلة: إحدى الاستعلامات (queries) في قاعدة البيانات، مع الضغط الهائل للحملة، بدأت تستهلك كل اتصالات قاعدة البيانات المتاحة، مما أدى إلى شلل تام في النظام.
في تلك الليلة، بينما كنت أعود إلى الفراش منهكًا في الرابعة فجرًا، أقسمت أن هذا الوضع لا يمكن أن يستمر. لا يمكن أن تكون وظيفتنا هي إطفاء الحرائق فقط. يجب أن نكون رجال إطفاء يمنعون الحرائق من الحدوث أصلًا. وهنا بدأت رحلتنا مع Prometheus.
ما هو جحيم “المراقبة التفاعلية” (Reactive Monitoring)؟
قبل أن نغوص في الحل، دعونا نُعرّف الوحش الذي كنا نحاربه. ما مررنا به في تلك الليلة هو مثال صارخ على المراقبة التفاعلية. إنها فلسفة “انتظر حتى ينكسر شيء ما، ثم أصلحه بأسرع ما يمكن”.
عيوب هذا النهج قاتلة:
- إزعاج مستمر: استيقاظ في منتصف الليل، مكالمات طوارئ، وضغط نفسي هائل.
- تأثير على المستخدم: أنت لا تكتشف المشكلة إلا بعد أن يكون عملاؤك قد عانوا منها بالفعل، مما يضر بسمعة المنتج.
- صعوبة التشخيص: عندما ينهار النظام، يكون الجميع في حالة ذعر، وتشخيص المشكلة تحت الضغط يؤدي إلى أخطاء فادحة.
- بيانات ضائعة: غالبًا ما تفتقر إلى البيانات التاريخية لمعرفة “كيف كان الوضع الطبيعي؟” قبل الانهيار.
باختصار، أنت دائمًا في موقف ضعف، دائمًا في وضع رد الفعل. وهذا، يا أصدقائي، ليس هندسة برمجيات، بل هو سحر وشعوذة.
دخول البطل: Prometheus.. ليس مجرد أداة، بل فلسفة!
عندما بدأنا البحث عن حلول، ظهر اسم Prometheus مرارًا وتكرارًا. في البداية، ظنناه مجرد أداة أخرى لجمع المقاييس (metrics) مثل أدوات قديمة عرفناها. لكننا كنا مخطئين. Prometheus ليس أداة فحسب، بل هو تحوّل في العقلية من التفاعلية إلى المراقبة الاستباقية (Proactive Monitoring).
الفكرة بسيطة وعبقرية في آن واحد. بدلًا من أن تقوم تطبيقاتك وسيرفراتك “بإرسال” (push) بياناتها عند حدوث مشكلة، يقوم Prometheus “بسحب” (pull) البيانات منها بشكل دوري كل بضع ثوانٍ. إنه مثل “مُختار الحارة” الذي يمر على كل “الدكاكين” (التطبيقات والسيرفرات) كل دقيقة ليسألها: “كيف حالك اليوم؟ كم زبونًا خدمتي؟ هل كل شيء على ما يرام؟”.
هذا النهج البسيط يغير كل شيء.
كيف يعمل Prometheus باختصار؟
لنُبسّط المنظومة العملاقة هذه إلى أجزاء مفهومة:
- خادم Prometheus: هو القلب النابض. وظيفته الأساسية هي الاتصال بشكل دوري بأهداف (targets) محددة مسبقًا عبر بروتوكول HTTP.
- الأهداف (Targets) و الـ Exporters: الهدف هو أي شيء تريد مراقبته (تطبيق، قاعدة بيانات، سيرفر…). ولكي يفهم Prometheus ما يقوله الهدف، يجب أن يعرض الهدف بياناته بتنسيق معين على نقطة نهاية (endpoint) محددة، عادةً ما تكون
/metrics. إذا كان التطبيق لا يدعم هذا بشكل أصلي (مثل قاعدة بيانات MySQL أو نظام التشغيل نفسه)، نستخدم برنامجًا وسيطًا صغيرًا يسمى Exporter. هذا الوسيط يترجم حالة النظام إلى لغة يفهمها Prometheus. - قاعدة بيانات السلاسل الزمنية (TSDB): يقوم Prometheus بتخزين كل البيانات التي يجمعها في قاعدة بيانات مُحسّنة خصيصًا لتخزين البيانات المرتبطة بالوقت. كل مقياس (مثل
http_requests_total) يتم تخزينه مع قيمته والوقت الدقيق لجمعه. - لغة الاستعلام (PromQL): هنا يكمن السحر الحقيقي. PromQL هي لغة قوية جدًا تتيح لك ليس فقط عرض البيانات، بل تحليلها والتنبؤ بسلوكها. يمكنك أن تسأل أسئلة معقدة مثل: “أعطني معدل الأخطاء في الدقيقة الأخيرة للتطبيق X، وقارنه بنفس الفترة من الأسبوع الماضي”.
- مدير التنبيهات (Alertmanager): هذا هو الجزء الذي يوقظك من النوم، لكن بذكاء هذه المرة. بدلًا من إرسال تنبيه مع كل خطأ، يمكنك ضبط قواعد معقدة مثل: “لا ترسل تنبيهًا إلا إذا كان معدل الأخطاء أعلى من 5% لمدة 5 دقائق متتالية”. هذا يقلل من الضوضاء بشكل كبير.
يلا نشتغل: مثال عملي بسيط
الكلام النظري جميل، لكن دعونا نرى كيف يمكن تطبيق هذا عمليًا. سنقوم بمثال بسيط: لدينا تطبيق Node.js ونريد مراقبته باستخدام Prometheus.
الخطوة 1: تجهيز تطبيق Node.js لعرض المقاييس
أولًا، نحتاج إلى جعل تطبيقنا يتحدث لغة Prometheus. سنستخدم مكتبة prom-client الشهيرة.
ثبّت المكتبة:
npm install prom-client
الآن، عدّل على كود السيرفر الخاص بك (لنفترض أنك تستخدم Express.js):
const express = require('express');
const client = require('prom-client');
const app = express();
// إنشاء سجل (registry) لجمع المقاييس الافتراضية (CPU, memory usage)
const register = new client.Registry();
client.collectDefaultMetrics({ register });
// إنشاء مقياس مخصص: عداد لإجمالي عدد الطلبات
const httpRequestCounter = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
registers: [register],
});
// Middleware لزيادة العداد مع كل طلب
app.use((req, res, next) => {
res.on('finish', () => {
httpRequestCounter.inc({
method: req.method,
route: req.route ? req.route.path : 'unknown',
status_code: res.statusCode
});
});
next();
});
app.get('/', (req, res) => {
res.send('يا هلا! Welcome to Abu Omar's server!');
});
app.get('/fast', (req, res) => {
res.status(200).send('Fast response!');
});
app.get('/slow', (req, res) => {
setTimeout(() => {
res.status(500).send('Slow response and error!');
}, 2000);
});
// نقطة النهاية التي سيقوم Prometheus بسحب البيانات منها
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
const port = 3000;
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
إذا قمت بتشغيل هذا الكود وزرت الرابط http://localhost:3000/metrics، سترى الكثير من النصوص التي تبدو غريبة. هذه هي المقاييس التي سيفهمها Prometheus.
الخطوة 2: تشغيل Prometheus
أسهل طريقة لتشغيل Prometheus محليًا هي باستخدام Docker. أولًا، قم بإنشاء ملف إعدادات بسيط باسم prometheus.yml:
global:
scrape_interval: 15s # كل كم ثانية يتم سحب البيانات
scrape_configs:
- job_name: 'prometheus' # مراقبة بروميثيوس نفسه
static_configs:
- targets: ['localhost:9090']
- job_name: 'my-node-app' # مراقبة تطبيقنا
static_configs:
# استخدم host.docker.internal للوصول إلى localhost من داخل الكونتينر
- targets: ['host.docker.internal:3000']
الآن، شغّل Prometheus باستخدام Docker:
docker run -d
-p 9090:9090
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml
prom/prometheus
بعد بضع ثوانٍ، افتح متصفحك على http://localhost:9090. يمكنك الذهاب إلى قائمة Status -> Targets لترى أن Prometheus قد وجد تطبيقك وهو يقوم بسحب البيانات منه بنجاح.
الخطوة 3: الاستعلام والتنبيه
الآن اذهب إلى واجهة Prometheus الرئيسية (Graph). في شريط البحث، يمكنك كتابة استعلامات PromQL. جرب هذه:
http_requests_total: سيعرض لك إجمالي عدد الطلبات مع كل التسميات (labels).sum(rate(http_requests_total[5m])) by (route): هذا استعلام أقوى. إنه يحسب “معدل” الطلبات في الثانية خلال آخر 5 دقائق، مجمّعة حسب المسار (route).
بالنسبة لنا، الاستعلام الذي كان سينقذنا في تلك الليلة المشؤومة هو شيء من هذا القبيل:
“أعطني التطبيقات التي لديها عدد اتصالات بقاعدة البيانات قريب من الحد الأقصى”
أو
“نبّهني إذا زاد متوسط زمن استجابة واجهة برمجة التطبيقات (API) للدفع عن 500 مللي ثانية لمدة دقيقتين”.
هذه هي القوة الحقيقية: الانتقال من السؤال “هل الموقع يعمل؟” إلى “هل صحة الموقع تتدهور؟”. أنت الآن تتنبأ بالمشكلة قبل وقوعها.
نصائح أبو عمر العملية 📝
بعد سنوات من العمل مع Prometheus في بيئات مختلفة، من الشركات الناشئة الصغيرة إلى الأنظمة الموزعة الضخمة، إليكم بعض الدروس التي تعلمتها بالطريقة الصعبة:
- ابدأ بما يهم البزنس: لا تراقب فقط استهلاك الـ CPU والذاكرة. هذه مقاييس نظام. ابدأ بمراقبة ما يهم المستخدم والعمل التجاري: عدد عمليات التسجيل، عدد الطلبات المكتملة، معدل أخطاء الدفع. هذه تسمى مؤشرات مستوى الخدمة (SLIs).
- التسميات (Labels) هي كل شيء: قوة Prometheus تكمن في التسميات. خطط جيدًا للتسميات التي ستستخدمها. تسميات جيدة تعني استعلامات قوية، وتسميات سيئة تعني فوضى.
- التنبيهات يجب أن تكون قابلة للتنفيذ: القاعدة الذهبية هي: إذا وصلك تنبيه لا يتطلب منك القيام بأي إجراء فوري، فهو تنبيه سيء. قم بضبطه أو حذفه. كثرة التنبيهات الكاذبة تؤدي إلى “إرهاق التنبيهات”، حيث يبدأ الفريق في تجاهلها جميعًا.
- استخدم Grafana للعرض: Prometheus قوي في جمع البيانات والاستعلام عنها، لكن واجهته الرسومية بسيطة. قم بربطه بـ Grafana لإنشاء لوحات معلومات (dashboards) رائعة وسهلة الفهم ومشاركتها مع الفريق بأكمله، حتى مع المدراء غير التقنيين.
- لا تخف من PromQL: في البداية، تبدو لغة PromQL معقدة، لكن استثمر الوقت في تعلمها. إنها مهارة ستجعلك لا تقدر بثمن في أي فريق DevOps أو SRE.
الخلاصة: نم قرير العين
التحول إلى Prometheus لم يكن مجرد تغيير تقني، بل كان تغييرًا ثقافيًا في فريقنا. انتقلنا من فريق إطفاء حرائق مرهق ومحبط، إلى فريق هندسي استباقي يثق في أنظمته. لم نعد نخشى إطلاق الميزات الجديدة أو حملات التسويق الضخمة.
بالطبع، الأعطال ما زالت تحدث، فلا يوجد نظام مثالي 100%. لكن الفرق الآن أننا نكتشف بوادر المشكلة قبل أن تصبح كارثة. بدلًا من مكالمة هاتفية مذعورة في الثانية صباحًا تقول “الموقع كله معطل!”، يأتينا تنبيه هادئ على Slack في فترة الظهيرة يقول “معدل الخطأ في خدمة الدفع ارتفع بنسبة 3% خلال الساعة الماضية”. وهذا، يا أصدقائي، هو الفرق بين الجحيم والنعيم في عالمنا الرقمي.
فيا صديقي المطور، لا تنتظر حتى تباغتك الأعطال في منتصف الليل. ابدأ اليوم، تعلم هذه الأدوات، وغيّر عقليتك. صدقني، نومك الهانئ سيشكرك لاحقًا. 😴 <– 😎