البحث عن خطأ برمجي: كيف أنقذ مكدس ELK فريقي من جحيم ملفات السجل؟

يا جماعة الخير، السلام عليكم. اسمي أبو عمر، وهذا الموقف صار معي قبل كم سنة، بس والله للآن بتذكره كأنه مبارح.

كنا في نص الليل، الساعة بتدق 2 الفجر، وفريقنا كله “فاتح بالحيط”. كان عنا تطبيق مهم جداً لعميل كبير، وفجأة بلش التطبيق يتصرف بغرابة. طلبات بتفشل بشكل عشوائي، المستخدمين بشتكوا من بطء وأخطاء غريبة، وما في أي نمط واضح للمشكلة. الوضع كان كارثي، والضغط علينا من كل حدب وصوب.

شو الحل؟ قلنا “خلينا نشوف السجلات (Logs)”. وهون بلشت المأساة الحقيقية. تطبيقنا كان عبارة عن خدمات مصغرة (Microservices)، يعني عندنا 10 سيرفرات مختلفة، وكل سيرفر عليه كومة ملفات سجل. صرت أنا وزميلي “نطنط” من سيرفر لسيرفر باستخدام SSH، ونستخدم أمر grep و tail و less في محاولة يائسة نلاقي أي إشي يدلنا على المشكلة.

كان الوضع أشبه بالبحث عن إبرة سوادء في كومة قش في ليلة ظلماء. ملفات بتنسيقات مختلفة، توقيتات زمنية مش متزامنة بين السيرفرات، وأحجام ملفات بالجيجابايت. بعد ساعتين من التخبيط والبحث العقيم، صرخت فيهم: “خلص! بكفي! هاي شغلانة بتجلط ومش رح توصلنا لنتيجة. من بكرة الصبح، أول إشي رح نعمله هو بناء نظام تسجيل مركزي. ما رح أسمح لهالمهزلة تتكرر”.

وهكذا كانت البداية… بداية رحلتنا مع مكدس ELK الذي أنقذنا من هذا الجحيم.

ما هي مشكلة ملفات السجل المبعثرة؟

القصة اللي حكيتها مش مجرد فضفضة يا جماعة. هي بتلخص معاناة حقيقية بتواجهها أغلب الفرق البرمجية اللي ما عندها نظام تسجيل مركزي. المشكلة أعمق من مجرد إزعاج، الها أبعاد خطيرة:

  • إضاعة وقت كارثية: الوقت اللي بتقضيه في الدخول لكل سيرفر والبحث اليدوي هو وقت ثمين كان ممكن تستغله في حل المشكلة نفسها.
  • صعوبة ربط الأحداث: لما يكون عندك طلب بمر عبر 3 خدمات مختلفة، كيف بدك تتبع رحلته بالكامل إذا كانت سجلات كل خدمة في مكان منعزل؟ شبه مستحيل.
  • فقدان الرؤية الشاملة: أنت لا ترى الصورة الكبيرة. ما بتقدر تعرف الأنماط، مثل “هل كل أخطاء 500 بتيجي من الخدمة الفلانية؟” أو “هل في زيادة مفاجئة في عدد الطلبات على النظام؟”.
  • مشاكل أذونات وأمان: هل من المنطقي تعطي كل مطور في الفريق صلاحية الدخول (SSH) على سيرفرات الإنتاج؟ طبعاً لا. هذا بيخلق عنق زجاجة، بحيث بس شخص أو شخصين عندهم القدرة على البحث.

ببساطة، بدون نظام تسجيل مركزي، أنت تقود طائرة في الضباب وأنت أعمى.

الحل السحري: مكدس ELK Stack

ELK هو اختصار لثلاثة مشاريع مفتوحة المصدر بتشتغل مع بعضها بشكل متناغم لحل مشكلة السجلات هاي. مؤخراً صاروا يسموه Elastic Stack لأنه انضافت عليه مكونات جديدة مثل الـ Beats، بس الاسم القديم لسا دارج.

خلينا نفصصهم حبة حبة:

  • E – Elasticsearch: هذا هو القلب النابض للمنظومة. هو محرك بحث وتحليل قوي جداً. فكر فيه كقاعدة بيانات ضخمة ومفهرسة مصممة خصيصاً لتخزين كميات هائلة من البيانات النصية (زي سجلاتنا) والبحث فيها بسرعة خيالية.
  • L – Logstash: هذا هو “السبّاك” أو خط الأنابيب. وظيفته يجمع السجلات من مصادر مختلفة (ملفات، قواعد بيانات، رسائل…)، وبعدها يقوم بمعالجتها وتصفيتها وتحويلها لصيغة موحدة ومرتبة، وأخيراً يرسلها لوجهتها النهائية (اللي هي Elasticsearch).
  • K – Kibana: هذه هي الواجهة الجميلة اللي بنتعامل معها. هي أداة تصور (Visualization) بتخليك تبحث في البيانات المخزنة في Elasticsearch وتعمل رسوم بيانية ولوحات معلومات (Dashboards) تفاعلية ورهيبة. هي اللي بتحول كومة البيانات لرسومات وقصص مفهومة.

رحلة خط السجل (Log Entry) من التطبيق إلى لوحة المعلومات

عشان نفهم الموضوع عملياً، تخيل معي رحلة سجل خطأ واحد من لحظة حدوثه:

  1. التطبيق يكتب السجل: تطبيقك (مثلاً تطبيق ويب) بواجه خطأ وبيكتب سطر في ملف error.log على السيرفر.
  2. Filebeat يلتقط السطر: على نفس السيرفر، بيكون في وكيل (agent) خفيف اسمه Filebeat (جزء من عائلة Beats). وظيفته يراقب ملف error.log وأي سطر جديد بينضاف، بياخده فوراً وببعته لـ Logstash.
  3. Logstash يعالج وينظف: بيستقبل Logstash السطر الخام. هنا بتبلش عملية “الطبخ”. ممكن يستخدم فلاتر مثل “grok” عشان يفصص السطر ويفهم أجزاءه (مثل التاريخ، مستوى الخطأ، الرسالة، عنوان IP…). بعدها بحوله لصيغة JSON مرتبة.
  4. Elasticsearch يخزن ويفهرس: بيستلم Elasticsearch كائن الـ JSON المرتب من Logstash، وبخزنه وبفهرسه فوراً. الآن صار السجل جاهز للبحث.
  5. Kibana يعرض ويحلل: أنت، يا “أبو عمر” المطور، بتفتح متصفحك على واجهة Kibana. بتكتب في شريط البحث “level:error AND status:500″، وفي أقل من ثانية، بيعرضلك Kibana كل الأخطاء من نوع 500 اللي صارت في كل النظام، مع رسوم بيانية بتوضحلك من أي خدمة اجت ومتى صارت.

شفت الفرق؟ بدل ما تبحث عن إبرة في كومة قش، صار عندك مغناطيس ضخم بيجذبلك كل الإبر اللي بدك إياها فوراً.

مثال عملي: كيف نجهز Logstash لمعالجة سجلات Nginx؟

الكلام النظري حلو، بس خلينا نشوف شوية كود. لنفترض عندك سجلات خادم الويب Nginx بالصيغة الافتراضية. السطر الواحد بيكون شكله هيك:

127.0.0.1 - - [10/Oct/2023:13:55:36 +0000] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0"

بدون معالجة، هذا السطر رح يدخل على Elasticsearch ككتلة نصية واحدة، والبحث فيه صعب. هنا يأتي دور Logstash. بنعمل ملف إعدادات بسيط nginx.conf لـ Logstash:


# /etc/logstash/conf.d/nginx.conf

input {
  # Logstash يستمع للبيانات القادمة من Filebeat على هذا المنفذ
  beats {
    port => 5044
  }
}

filter {
  # إذا كان السجل قادم من ملف سجلات Nginx
  if [fileset][module] == "nginx" and [fileset][name] == "access" {
    # استخدم فلتر grok لتفصيص السجل
    grok {
      match => { "message" => "%{IPORHOST:clientip} %{USER:ident} %{USER:auth} [%{HTTPDATE:timestamp}] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response:int} (?:-|%{NUMBER:bytes:int}) %{QS:referrer} %{QS:agent}" }
    }
    
    # حول حقل التاريخ إلى صيغة يفهمها Elasticsearch
    date {
      match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
      target => "@timestamp"
    }

    # استخرج معلومات الموقع الجغرافي من IP العميل
    geoip {
      source => "clientip"
    }
  }
}

output {
  # أرسل النتيجة النهائية إلى Elasticsearch
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "nginx-logs-%{+YYYY.MM.dd}"
  }
}

شرح الكود السابق:

  • Input: نخبر Logstash أن يستمع للبيانات القادمة من Filebeat على المنفذ 5044.
  • Filter: هذا هو الجزء الأهم.
    • نستخدم grok مع نمط معين لتحليل سطر سجل Nginx. كل جزء مثل %{IPORHOST:clientip} يعني “ابحث عن شيء يشبه الـ IP أو اسم المضيف، وخزن قيمته في حقل جديد اسمه clientip“.
    • نستخدم فلتر date لتحويل صيغة التاريخ في السجل إلى الصيغة القياسية @timestamp التي يعتمدها ELK.
    • نستخدم فلتر geoip (وهذا سحر بحد ذاته) ليقوم Logstash تلقائياً بأخذ حقل clientip والبحث في قاعدة بيانات داخلية لتحديد البلد والمدينة والإحداثيات الجغرافية لهذا الـ IP!
  • Output: نرسل الوثيقة (Document) المعالجة والمنظمة إلى خادم Elasticsearch، ونطلب منه أن يضعها في فهرس (index) يومي (مثلاً nginx-logs-2023.10.26). هذا يسهل إدارة البيانات وحذف القديم منها.

نصائح من خبرة أبو عمر

بعد سنوات من التعامل مع ELK، تعلمت كم شغلة بالطريقة الصعبة. خذوا هالنصائح العملية اللي رح توفر عليكم وقت وجهد:

نصيحة 1: ابدأ بالأساسيات ثم توسع

لا تحاول من أول يوم تجمع سجلات من كل الأنظمة في الشركة. ابدأ بتطبيق واحد مهم تعاني من مشاكله. جهز الـ Stack، اجمع سجلاته، تعلم كيف تبحث في Kibana وتعمل لوحة معلومات بسيطة. لما تتقن العملية وتشوف الفائدة، وقتها توسع لباقي الأنظمة. “شوي شوي بتوصل”.

نصيحة 2: السجلات المنظمة (Structured Logging) هي المستقبل

فلتر grok قوي، ولكنه مثل “الترقيع”. الحل الأمثل هو أن تجعل تطبيقاتك تكتب السجلات بصيغة منظمة من الأصل، وأفضل صيغة هي JSON. بدلاً من أن يكتب تطبيقك سطراً كهذا:

ERROR: Failed to process payment for user 123. Reason: Insufficient funds.

اجعله يكتب كائن JSON:


{
  "timestamp": "2023-10-26T10:30:00Z",
  "level": "ERROR",
  "message": "Failed to process payment",
  "context": {
    "userId": 123,
    "reason": "Insufficient funds",
    "transactionId": "txn_abcdef12345"
  }
}

هذا يغنيك عن الحاجة لـ grok تماماً. Logstash و Elasticsearch يفهمون JSON بشكل أصلي، وستحصل على حقول مفصلة وجاهزة للبحث والفلترة بدون أي مجهود إضافي.

نصيحة 3: انتبه للموارد

مكدس ELK، خصوصاً Elasticsearch، يمكن أن يكون شرهاً للموارد (CPU, RAM, Disk). خطط جيداً لحجم البيانات التي ستجمعها ومدة الاحتفاظ بها. استخدم أدوات مثل Curator لحذف الفهارس القديمة تلقائياً. لا تجمع كل شيء، اجمع فقط ما تحتاجه.

نصيحة 4: لا تنسَ البدائل

ELK هو الخيار الأشهر والأقوى في العالم مفتوح المصدر، ولكنه ليس الوحيد. من الجيد أن تعرف عن البدائل مثل Graylog (أسهل في الإعداد المبدئي) أو مكدس Grafana Loki (مصمم ليتكامل بشكل رائع مع Prometheus ومناسب جداً لبيئة Kubernetes).

الخلاصة: من كومة قش إلى مكتبة منظمة

في النهاية يا جماعة، الاستثمار في نظام تسجيل مركزي مثل ELK ليس رفاهية، بل هو ضرورة قصوى لأي مشروع برمجي جاد. هو الفرق بين أن تقضي ليلتك في تخبيط عشوائي ويأس، وبين أن تجد سبب المشكلة في 30 ثانية وأنت تشرب فنجان قهوتك. ☕

نعم، الإعداد الأولي يحتاج بعض الجهد والتعلم، لكن العائد على هذا الاستثمار هائل. أنت لا تبني مجرد أداة، بل تبني ثقافة جديدة في فريقك: ثقافة الاعتماد على البيانات، سرعة الاستجابة للمشاكل، والرؤية الواضحة لما يحدث داخل أنظمتك.

فيا خوي المبرمج، ما تخلوا السجلات تهزمكم. سيطروا عليها، حولوها من عبء إلى أقوى سلاح في ترسانتكم. 👍

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

برمجة وقواعد بيانات

تحديثات قاعدة البيانات بدون توقف: كيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من جحيم التوقفات المجدولة؟

هل سئمت من إيقاف الخدمة مع كل تحديث لهيكلة قاعدة البيانات؟ أشارككم قصة حقيقية وكيف أنقذنا نمط التوسيع والتعاقد (Expand/Contract) من ليالي النشر الطويلة والمُجهدة،...

4 يونيو، 2026 قراءة المزيد
الشبكات والـ APIs

كانت إعادة المحاولة كارثة: كيف أنقذتنا مفاتيح عدم تكرار العمليات (Idempotency Keys) من جحيم الفواتير المزدوجة؟

أشارككم قصة حقيقية من الخنادق البرمجية، يوم كاد خطأ بسيط في إعادة محاولة طلبات الدفع أن يكلفنا سمعتنا وأموال عملائنا. اكتشفوا معنا كيف كانت مفاتيح...

4 يونيو، 2026 قراءة المزيد
الحوسبة السحابية

من التوقف التام إلى النجاة: كيف أنقذتنا استراتيجية “الضوء المرشد” (Pilot Light) يوم انقطعت السحابة؟

أتذكر ذلك اليوم جيدًا، فنجان القهوة الصباحي، وصوت تنبيهات المراقبة يصرخ كأنه يوم القيامة. كانت منطقة سحابية كاملة قد توقفت عن العمل، لكن بفضل استراتيجية...

4 يونيو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

كانت مهمتي البرمجية للاختبار مجرد كود: كيف أنقذني توثيق القرارات من جحيم الصمت بعد المقابلة؟

أشارككم قصة حقيقية من بداياتي، وكيف تعلمت بالطريقة الصعبة أن المهمة البرمجية ليست مجرد كتابة كود، بل هي فرصة لإظهار طريقة تفكيرك. اكتشف كيف يمكن...

4 يونيو، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

من الانتظار لأيام إلى الدفع في ثوانٍ: كيف أنقذتنا شبكات الدفع الفوري من جحيم التحويلات البنكية؟

أسرد لكم من واقع تجربتي كـ "أبو عمر"، كيف عانينا من بطء وتكلفة التحويلات البنكية الدولية، وكيف جاءت شبكات الدفع الفوري ومعيار ISO 20022 لتكون...

4 يونيو، 2026 قراءة المزيد
البنية التحتية وإدارة السيرفرات

كان كل خادم لدينا ‘ندفة ثلج’ فريدة: كيف أنقذنا ‘الكود كبنية تحتية’ (IaC) من جحيم الانجراف اليدوي؟

في هذه المقالة، أشارككم قصة حقيقية من قلب المعركة التقنية مع "خوادم ندفات الثلج" الفوضوية. سنغوص في مفهوم "الكود كبنية تحتية" (IaC) وكيف أن أدوات...

4 يونيو، 2026 قراءة المزيد
اختبارات الاداء والجودة

كانت تغطية الاختبارات 100% لكن الأخطاء تتسرب: كيف أنقذنا “الاختبار الطفري” من جحيم الثقة الزائفة؟

كنا نظن أن تغطية الاختبار بنسبة 100% هي درعنا الواقي، لكن الأخطاء كانت تتسلل إلى الإنتاج كاللصوص في ليل بهيم. اكتشف كيف أنقذنا "الاختبار الطفري"...

4 يونيو، 2026 قراءة المزيد
البودكاست