بناء بنية تحتية موثوقة للتسجيل من الصفر

٢٧ ديسمبر ٢٠٢٥

Building a Reliable Logging Infrastructure from Scratch

ملخص

  • بنية تحتية للسجلات موثوقة ضرورية لتصحيح الأخطاء، المراقبة، والامتثال.
  • جمع السجلات المركزي والتنسيقات المُهيكلة (مثل JSON) تجعل التحليل أسهل بكثير.
  • استخدم مُشحّلي السجلات (مثل Fluentd، Logstash) لتجميع السجلات من خدمات متعددة.
  • أولوية للأمان: تشفير السجلات أثناء النقل والتحكم الصارم في الوصول.
  • صمم للتوسع — من التطوير المحلي إلى أنظمة الإنتاج متعددة المناطق.

ما ستتعلمه

  • كيفية تصميم بنية تحتية للسجلات تتوسع من فريق صغير إلى مستوى المؤسسة.
  • الاختلافات بين مختلف هياكل السجلات (قائمة على الوكيل، سايدكار، مركزية).
  • كيفية إعداد طبقات الجمع، النقل، التخزين، والعرض المرئي.
  • كيفية استخدام إعدادات السجلات الحديثة في بايثون في الإنتاج.
  • الأخطاء الشائعة، اعتبارات الأداء، وأفضل ممارسات الأمان.

المتطلبات الأساسية

يجب أن تكون مرتاحًا مع:

  • إدارة نظام أساسية (لينكس أو بيئات حاوية)
  • معرفة ببيئات السحابة (AWS، GCP، أو Azure)
  • معرفة أساسية ببايثون لعرض الأمثلة البرمجية

السجلات هي فتات الخبز لأنظمتك — فهي تروي قصة ما يحدث داخل خدماتك. سواء كنت تصحح أخطاء API الفاشلة، أو تراقب الأداء، أو تفتش إجراءات المستخدم، فإن بنية السجلات المصممة جيدًا هي أفضل حليف لك.

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

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


فهم البنية التحتية للسجلات

البنية التحتية للسجلات عادةً ما تحتوي على أربع طبقات:

  1. التجميع – جمع السجلات من التطبيقات، الحاويات، والأنظمة.
  2. النقل – نقل السجلات إلى موقع مركزي.
  3. التخزين – فهرسة وتخزين السجلات بكفاءة.
  4. التحليل & العرض المرئي – البحث، التنبيه، واستخلاص الرؤى.

هذا رؤية عامة لكيفية تفاعل هذه الطبقات:

graph TD
  A[Applications] --> B[Log Shipper]
  B --> C[Central Log Collector]
  C --> D[Storage Backend]
  D --> E[Visualization / Query Layer]

يمكن تنفيذ كل طبقة باستخدام أدوات مختلفة — على سبيل المثال، Fluent Bit للتجميع، Kafka للنقل، Elasticsearch للتخزين، وKibana أو Grafana للعرض المرئي.


خطوة بخطوة: بناء خط أنابيب السجلات

لنقم ببناء خط أنابيب سجلات مصغرة ولكن جاهزة للإنتاج باستخدام مكونات مفتوحة المصدر.

الخطوة 1: إنشاء سجلات مُهيكلة

الخطوة الأولى هي التأكد من أن تطبيقاتك تنتج سجلات مُهيكلة. JSON هو التنسيق الأكثر شيوعًا لأنه قابل للقراءة الآلية وسهل التحليل.

فيما يلي مثال بايثون باستخدام وحدة logging المدمجة مع dictConfig() لإخراج مُهيكل:

import logging
import logging.config
import json

LOGGING_CONFIG = {
    'version': 1,
    'formatters': {
        'json': {
            'format': ('{"timestamp": "%(asctime)s", "level": "%(levelname)s", '
                       '"message": "%(message)s", "module": "%(module)s"}')
        }
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'json'
        }
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO'
    }
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger(__name__)

logger.info("User login successful", extra={"user_id": 42})

الإخراج:

{"timestamp": "2025-03-04 12:45:21,123", "level": "INFO", "message": "User login successful", "module": "auth"}

السجلات المنظمة تجعل من السهل على الأنظمة اللاحقة (مثل Elasticsearch أو Loki) تحليل البيانات وفهرستها.


الخطوة 2: جمع السجلات باستخدام Fluent Bit

Fluent Bit هو أداة خفيفة لنقل السجلات تقوم بجمع السجلات من مصادر متعددة وإرسالها.

مثال التكوين (fluent-bit.conf):

[INPUT]
    Name tail
    Path /var/log/app/*.log
    Parser json

[OUTPUT]
    Name  es
    Match *
    Host  elasticsearch
    Port  9200
    Index app-logs

تشغيل Fluent Bit كحاوية:

Docker run -v $(pwd)/fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf:ro \
  fluent/fluent-bit:latest

هذا التكوين يتتبع جميع الملفات .log، ويحللها كـ JSON، ويقوم بإرسالها إلى Elasticsearch.


الخطوة 3: تخزين السجلات في Elasticsearch

يوفر Elasticsearch محرك بحث نصي موزع مثالي لتخزين السجلات1. يقوم بفهرسة كل حقل JSON، مما يمكّن من إجراء استعلامات وعمليات تجميع سريعة.

مثال الاستعلام:

curl -X GET "http://localhost:9200/app-logs/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": { "message": "error" }
  }
}'

الإخراج:

{
  "hits": {
    "total": 3,
    "hits": [
      {"_source": {"message": "database connection error"}},
      {"_source": {"message": "timeout error"}},
      {"_source": {"message": "authentication error"}}
    ]
  }
}

الخطوة 4: تصور باستخدام Kibana

Kibana هي طبقة التصور الخاصة بـ Elasticsearch. تتيح لك بناء لوحات المعلومات، وضبط التنبيهات، وتصور الاتجاهات.

على سبيل المثال، يمكنك إنشاء لوحة عرض تظهر:

  • معدلات الأخطاء عبر الزمن
  • أعلى 10 نقاط نهاية حسب زمن الاستجابة
  • إجراءات المستخدمين حسب المنطقة

هنا حيث تتحول السجلات إلى رؤى قابلة للتنفيذ.


المقارنة: هياكل السجلات الشائعة

نوع العمارة الوصف المزايا العيوب
قائم على الوكيل كل خادم يشغل جامع سجلات (مثل Fluent Bit). بسيط، قابل للتوسع، مقاوم للأخطاء. يتطلب صيانة الوكيل.
نمط Sidecar كل حاوية لها جامع سجلات مخصص. عزل لكل خدمة، جيد لـ Kubernetes. استخدام موارد أكبر.
جامع مركزي يتم بث السجلات إلى خدمة مركزية (مثل syslog). إدارة أسهل. نقطة فشل واحدة إذا لم يتم النسخ.
السجلات Serverless سجلات طبيعية للسحابة (مثل AWS CloudWatch). لا حاجة لإدارة البنية التحتية. الاعتماد على المورد، مرونة محدودة.

متى تستخدم مقابل متى لا تستخدم

السيناريو استخدام بنية السجلات تجنب / استخدام بدائل
تطبيقات موزعة متعددة الخدمات ✅ السجلات المركزية ضرورية ❌ سجلات محلية فقط
متطلبات الامتثال أو المراجعة ✅ سجلات منظمة وغير قابلة للتغيير ❌ سجلات مؤقتة
مشاريع محلية صغيرة ❌ مبالغ فيه؛ سجلات ملف بسيطة كافية ✅ إعداد أبسط
أحمال عمل Serverless فقط ⚙️ استخدام سجلات مدارة (CloudWatch, Stackdriver) ❌ تجميع ذاتي الإدارة

مثال من الواقع: نتفليكس والمراقبة

تستخدم نتفليكس سجلات منظمة وأنابيب تجميع مركزية للتعامل مع بيانات التليميترية عالية الحجم، مما يمكّن المهندسين من تتبع طلبات المستخدم عبر الخدمات المختلفة بكفاءة.


الأخطاء الشائعة والحلول

المزالق الوصف الحل
سجلات غير منظمة صعبة التحليل والفهرسة. استخدم تنسيقات JSON أو key-value.
حمل السجلات الزائد ضوضاء كثيرة، تخزين مكلف. قم بتطبيق مستويات السجلات وسياسات الاحتفاظ.
غياب السياق السجلات تفتقر إلى correlation IDs. أضف request IDs أو trace IDs في كل سجل.
تسريبات أمنية بيانات حساسة في السجلات. قم بتنظيف السجلات قبل الإرسال.
استعلامات بطيئة فهارس Elasticsearch كبيرة جدًا. استخدم index lifecycle management.

اعتبارات الأداء

  • Batching: Shippers مثل Fluent Bit تجمع السجلات قبل الإرسال، مما يقلل من الحمل الشبكي.
  • Compression: استخدم gzip أو zstd لنقل السجلات لتقليل عرض النطاق.
  • Indexing strategy: قم بتدوير indices يوميًا أو ساعيًا لتحسين أداء الاستعلامات.
  • Retention policy: أرشفة السجلات الأقدم إلى S3 أو Glacier للتحكم في التكلفة.

Benchmarks تظهر عادةً أن Batching و Compression يمكن أن يقللا بشكل كبير تأخير الإدخال في أحمال I/O-bound1.


اعتبارات الأمان

الأمان في السجلات غالبًا ما يُهمل. اتبع أفضل الممارسات التالية:

  1. Encrypt in transit – استخدم TLS لنقل جميع السجلات.
  2. Encrypt at rest – قم بتمكين تشفير القرص لـ Elasticsearch أو مجموعات S3.
  3. Access control – استخدم التحكم في الوصول القائم على الأدوار (RBAC) لمشاهدي السجلات.
  4. Mask sensitive data – لا تسجل أبدًا كلمات المرور أو الرموز أو PII.
  5. Audit logging – احتفظ بسجلات مراجعة غير قابلة للتغيير للامتثال.

رؤى حول القابلية للتوسع

مع نمو البنية التحتية:

  • Horizontal scaling: أضف المزيد من Shippers وعقد التخزين.
  • Partitioning: قسم السجلات حسب الخدمة أو المنطقة.
  • Queue buffering: استخدم Kafka أو AWS Kinesis بين الجمع والتخزين.
  • Caching: خزن الاستعلامات المتكررة في Kibana.

الأنظمة الكبيرة غالبًا ما تتبنى خط أنابيب متعدد الطبقات: Fluent Bit → Kafka → Elasticsearch2. هذا يفصل بين الإدخال والتخزين، مما يحسن المرونة.


اختبار البنية التحتية للسجلات

الاختبار يضمن الموثوقية تحت الحمل.

اختبار الوحدة لإخراج السجلات

import logging
from io import StringIO

def test_json_logging():
    stream = StringIO()
    handler = logging.StreamHandler(stream)
    formatter = logging.Formatter('{"msg": "%(message)s"}')
    handler.setFormatter(formatter)

    logger = logging.getLogger('test')
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)

    logger.info('hello')
    assert 'hello' in stream.getvalue()

اختبار التكامل

  • حاكِ حجم سجلات عالي وتحقق من سرعة الإدخال.
  • اختبر استعلامات Elasticsearch للتأكد من صحتها.
  • تحقق من سياسات الاحتفاظ والحذف.

أنماط معالجة الأخطاء

عند فشل شاحنات السجلات أو عدم توفر التخزين:

  • Retry with backoff – تجنب إثقال الأنظمة التالية.
  • Fallback to local disk – خزن السجلات مؤقتًا محليًا.
  • Dead letter queues – احفظ السجلات غير الصالحة.

مثال على إعداد إعادة المحاولة في Fluent Bit:

[OUTPUT]
    Name es
    Retry_Limit False
    Retry_Backoff True

نصائح المراقبة والقابلية للرصد

  • استخدم Prometheus metrics لصحة خط أنابيب السجلات.
  • راقب معدل الإدخال، معدل الأخطاء، وعمق الطابور.
  • اضبط تنبيهات لسجلات مفقودة (كشف الصمت).
  • صوِّر تأخير خط الأنابيب في Grafana.

الأخطاء الشائعة التي يرتكبها الجميع

  • تسجيل بيانات تصحيح أخطاء كثيرة في الإنتاج.
  • نسيان تدوير أو أرشفة السجلات.
  • تجاهل التنسيقات المنظمة.
  • خلط stdout وسجلات الملفات بشكل غير متسق.
  • عدم الاختبار تحت حمل يشبه الإنتاج.

دليل استكشاف الأخطاء وإصلاحها

المشكلة السبب المحتمل الإصلاح
سجلات مفقودة من Kibana تهيئة Fluent Bit خاطئة تحقق من قواعد تطابق الإخراج
استخدام مرتفع لوحدة معالجة Elasticsearch أجزاء كبيرة جدًا قلل عدد الأجزاء
سجلات مكررة عدة جامعين يقرأون نفس الملف استخدم علامات فريدة
سجلات متأخرة ازدحام الشبكة فعّل التجميع والضغط
كشف بيانات حساسة تشفير غير كامل طبّق فلاتر regex

تحدي جربه بنفسك

  1. قم بإعداد مجموعة Elasticsearch + Kibana محلية.
  2. قم بتكوين Fluent Bit لإرسال السجلات من تطبيق Python.
  3. أضف correlation ID إلى كل سجل.
  4. أنشئ لوحة تحكم Kibana تظهر اتجاهات الأخطاء.

النقاط الرئيسية

التسجيل ليس فكرة لاحقة — إنه ذاكرة نظامك.

  • ابدأ بسجلات منظمة.
  • توحيد جمع وتحليل.
  • أأمن pipeline وقم بتوسيعه.
  • راقب وحسّن باستمرار.

أسئلة متكررة

Q1: هل يجب أن أسجل كل شيء؟
لا. سجل بذكاء — ركز على الأخطاء والتحذيرات والأحداث التجارية الرئيسية.

Q2: كم يجب أن أحتفظ بالسجلات؟
يعتمد على متطلبات الامتثال. عادةً 30–90 يومًا للسجلات التشغيلية، وأطول للتدقيق.

Q3: ما الفرق بين المقاييس والسجلات؟
المقاييس هي بيانات رقمية مجمعة؛ السجلات هي سجلات أحداث مفصلة.

Q4: كيف أتعامل مع السجلات من Kubernetes؟
استخدم DaemonSets مع Fluent Bit أو Fluentd لجمع سجلات الحاويات.

Q5: كيف أخفض تكاليف التخزين؟
اضغط، أرشف، وطبق سياسات الاحتفاظ.


الخطوات التالية

  • جرّب Grafana Loki كبديل خفيف لـ Elasticsearch.
  • استكشف OpenTelemetry للرصد الموحد.
  • أتمتة اختبارات استقبال السجلات في CI/CD.

الهوامش

  1. توثيق Elasticsearch – https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html 2

  2. الوثائق الرسمية لـ Fluent Bit – https://docs.fluentbit.io/manual/