السجلات على نطاق واسع: ELK وLoki

مشروع: منصة تسجيل مركزية

18 دقيقة الدرس 10 من 28

مشروع: منصة تسجيل مركزية

كل مفهوم من المفاهيم التي تناولناها في الدروس التسعة السابقة يتلاقى هنا. تعلمت كيف تتدفق السجلات عبر خط الأنابيب، وكيف تُصدر أحداثاً منظمة، وكيف تُهيئ مكدس ELK وGrafana Loki، وكيف تتعامل Elasticsearch مع الشاردات والاحتفاظ بالبيانات، وكيف يُشحن Fluent Bit وPromtail السجلات في Kubernetes، وكيف تكتب استعلامات LogQL وKibana KQL، وكيف توازن التكلفة مع الامتثال. هذا المشروع الختامي يجمع كل ذلك معاً من خلال تصميم منصة تسجيل مركزية كاملة لبيئة خدمات مصغرة حقيقية — النوع من الأنظمة التي ستصممها على لوح الكتابة في مقابلة هندسية بمستوى المهندسين الأوائل، أو تقترحها في مراجعة معمارية بشركة كبرى.

نطاق المشكلة

أنت تنضم إلى شركة تقنية مالية تشغّل 60 خدمة مصغرة عبر ثلاثة كلاسترات Kubernetes (us-east-1 وeu-west-1 وap-southeast-1). الوضع الحالي: كل خدمة تكتب إلى stdout، وأداة kubectl logs هي الأداة الوحيدة للتحقيق، ولا يوجد احتفاظ بالبيانات يتجاوز 72 ساعة من المخزن المؤقت للعقدة. حادثة P0 في الربع الماضي استغرقت أربع ساعات للتشخيص لأن الحاوية المعنية أُعيد جدولتها وضاعت سجلاتها. وافقت الإدارة على إنشاء منصة تسجيل مركزية. مهمتك هي تصميمها وتنفيذها.

المتطلبات المجمّعة من أصحاب المصلحة: بحث نصي كامل في جميع السجلات خلال 30 ثانية من الإصدار؛ احتفاظ لمدة 90 يوماً مع استعلامات سريعة (أقل من 5 ثوان) لآخر 7 أيام؛ امتثال PCI-DSS (أرقام البطاقات ورموز CVV وأرقام PAN الخام يجب ألا تصل قط إلى طبقة التخزين)؛ تنبيهات على ارتفاعات معدل الأخطاء؛ تكلفة لا تتجاوز 4,000 دولار شهرياً عند استيعاب 200 جيجابايت يومياً؛ وواجهة استعلام موحدة لجميع المناطق الثلاث.

اختيار المكدس المناسب

عند معدل 200 جيجابايت يومياً، كلا ELK وLoki قابلان للتطبيق. يتوقف القرار على أنماط الاستعلام. التحقيق في حوادث التقنية المالية يعتمد تقريباً دائماً على الحقول — "أرني جميع المعاملات التي فشل فيها user_id=U123 خلال الساعة الأخيرة" — وهذا يتوافق تماماً مع الفهرس المعكوس لـElasticsearch. النموذج القائم على التسميات في Loki يتطلب أن يسبق كل استعلام مجموعة التسميات الصحيحة، والبحث العشوائي في الحقول يحتاج إلى خط أنابيب | json | line_format في LogQL، وهو أبطأ بهذا الحجم. القرار: ELK للتخزين الأساسي، وLoki كنظام مساعد خفيف لسجلات البنية التحتية والنظام. يعمل OpenTelemetry Collector كطبقة جمع وتوجيه موحدة.

المبدأ الأساسي: اختر نظام التخزين ليتناسب مع نمط استعلامك السائد. ELK يتفوق في البحث النصي الكامل والبحث في الحقول. Loki يتفوق في تنوع التسميات وتكلفة التخزين وتكامله الأصلي مع Grafana لسجلات العمليات. معظم المؤسسات الكبيرة تشغّل الاثنين معاً.

معمارية خط الأنابيب

يُظهر الرسم البياني أدناه خط الأنابيب الكامل من البداية إلى النهاية. كل حاوية خدمة مصغرة تُصدر JSON منظماً إلى stdout. مجموعات DaemonSet من Fluent Bit تجمع البيانات وتثريها ببيانات Kubernetes الوصفية. يستقبل OpenTelemetry Collector البيانات من أساطيل Fluent Bit في المناطق الثلاث، ويُطبق إخفاء بيانات PCI، ثم يوزعها على Kafka (للمتانة وإعادة التشغيل) ومباشرة إلى نسخة Loki إقليمية (لسجلات البنية التحتية). يقرأ Logstash من Kafka ويكتب إلى كلاستر Elasticsearch مُنسوخ عالمياً. تُوفر Kibana وGrafana واجهات الاستعلام.

Centralized Logging Pipeline Architecture us-east-1 eu-west-1 ap-southeast-1 Microservices (20) Microservices (20) Microservices (20) Fluent Bit DaemonSet Fluent Bit DaemonSet Fluent Bit DaemonSet OTel Collector (PCI Redaction) Kafka (3 topics) Logstash Consumers Elasticsearch Cluster Loki (infra logs) infra only
خط أنابيب التسجيل المركزي من البداية إلى النهاية: تُغذي ثلاثة كلاسترات إقليمية مجمّع OTel Collector العالمي الذي يُخفي بيانات PCI، ويوزع البيانات على Kafka للمتانة، ثم تُفهرس Logstash البيانات في Elasticsearch. تتدفق سجلات البنية التحتية أيضاً إلى نسخة Loki إقليمية.

إخفاء بيانات PCI على مستوى طبقة الجمع

أصعب متطلبات الامتثال هو ضمان عدم وصول أرقام البطاقات إلى Elasticsearch قط. المكان الصحيح لتطبيق ذلك هو OpenTelemetry Collector وليس التطبيق — الإخفاء على مستوى التطبيق يسهل إغفاله عبر 60 خدمة، وسطر سجل واحد مفقود يُعدّ انتهاكاً للامتثال. يُطبق معالج transform في OTel Collector قواعد OTTL (لغة تحويل OpenTelemetry) قبل إعادة توجيه أي بيانات.

## otelcol-config.yaml — PCI redaction in the transform processor processors: transform/redact_pci: log_statements: - context: log statements: ## Redact 13-19 digit PAN patterns (Visa, MC, Amex, Discover) - replace_pattern(body, "\\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})\\b", "***REDACTED-PAN***") ## Redact 3-4 digit CVV adjacent to card fields - replace_pattern(attributes["card.cvv"], ".*", "***") ## Drop any log body containing raw track data - delete_matching_keys(attributes, "^track[12]$") ## After redaction, hash user IDs for pseudonymisation transform/pseudonymise: log_statements: - context: log statements: - set(attributes["user.id.hash"], SHA256(attributes["user.id"])) - delete_key(attributes, "user.id") service: pipelines: logs: receivers: [otlp, fluentforward] processors: [memory_limiter, transform/redact_pci, transform/pseudonymise, batch] exporters: [kafka, loki]
فخ شائع في الإنتاج: الإخفاء القائم على التعبيرات النمطية لديه ثغرات. دائماً ادمجه مع طبقة تحكم ثانية: أمان حقول Elasticsearch (حظر الوصول إلى أي حقل يطابق *.card* أو *.pan*) واستعلامات تدقيق دورية تُنبّه إذا وصل نمط PAN إلى الفهرس. الدفاع متعدد الطبقات هو المعيار الذي يفرضه PCI، وليس الاعتماد على طبقة إخفاء واحدة.

تصميم موضوعات Kafka

عند معدل 200 جيجابايت يومياً (حوالي 2.3 ميجابايت/ثانية في المتوسط مع ذروات تصل إلى 20 ميجابايت/ثانية)، يمكن الاعتماد على موضوع Kafka واحد لكنه يُنشئ اقتراناً تشغيلياً. النمط المُتبع في بيئات التقنية المالية الكبيرة هو ثلاثة موضوعات مُقسّمة حسب الأهمية: logs.critical (للأخطاء والحرجة، احتفاظ Kafka لمدة 48 ساعة، 12 قسماً)، وlogs.standard (للمعلومات والتحذيرات، 24 ساعة، 24 قسماً)، وlogs.debug (لمستوى debug — معطّل في الإنتاج افتراضياً، 6 ساعات، 6 أقسام). تشغّل Logstash مجموعات مستهلكين منفصلة لكل موضوع حتى لا تُعيد إعادة تشغيل Logstash معالجة ضوضاء debug عبر مسار الفهرسة المكلف.

استراتيجية فهرس Elasticsearch

استخدم ILM (إدارة دورة حياة الفهرس) بثلاث مراحل. تعمل مرحلة hot على عقد مدعومة بأقراص SSD، وتحتفظ ببيانات 7 أيام، وتستخدم شارداً أساسياً واحداً لكل 30 جيجابايت من الحجم اليومي (أي عند 200 جيجابايت يومياً: ~7 شاردات أساسية لكل فهرس يومي). تنتقل مرحلة warm إلى التخزين العام بعد 7 أيام وتدمج قطع البيانات قسراً إلى قطعة واحدة لكل شارد (تحسين للقراءة فقط). تنقل مرحلة cold البيانات إلى لقطات قابلة للبحث مدعومة بـS3 بعد 30 يوماً، مع إبقاء البيانات قابلة للاستعلام بتكلفة تخزين شبه معدومة. عند اليوم 90، يحذف ILM الفهرس.

## ILM policy — logs-policy.json PUT _ilm/policy/fintech-logs-policy { "policy": { "phases": { "hot": { "min_age": "0ms", "actions": { "rollover": { "max_primary_shard_size": "30gb", "max_age": "1d" }, "set_priority": { "priority": 100 } } }, "warm": { "min_age": "7d", "actions": { "forcemerge": { "max_num_segments": 1 }, "shrink": { "number_of_shards": 1 }, "set_priority": { "priority": 50 } } }, "cold": { "min_age": "30d", "actions": { "searchable_snapshot": { "snapshot_repository": "s3-logs-repo" }, "set_priority": { "priority": 0 } } }, "delete": { "min_age": "90d", "actions": { "delete": {} } } } } }

التنبيه على ارتفاعات معدل الأخطاء

تُشكّل تنبيهات Kibana (أو Elasticsearch Watcher في المكدسات القديمة) طبقة التنبيه التشغيلي. التنبيه الأساسي لبيئة التقنية المالية هو حد معدل الأخطاء لكل خدمة: إذا أصدرت خدمة أكثر من 50 حدث بمستوى error في أي نافذة زمنية مدتها 5 دقائق، يُنبّه المهندس المناوب. تنبيه ثانوي يُطلق عندما تتجاوز نسبة الأخطاء إلى إجمالي الأحداث 5% — وهذا يكشف التدهور الذي لا يزال ضمن الحدود المطلقة لكنه يُشير إلى مشكلة منهجية.

ادمج هذه التنبيهات مع لوحة تحكم Grafana المدعومة بـLoki لسجلات البنية التحتية: تشبع نظام الملفات في العقدة، وأحداث تجاوز المخزن المؤقت لـFluent Bit، وتأخر مستهلك Kafka على logs.critical. تأخر مستهلك Kafka هو إشارة صحة خط الأنابيب الأهم — إذا تأخرت Logstash، ستصل السجلات في النهاية (Kafka يحتفظ بها)، لكن المحققين في الحوادث لن يروا الأحداث الأخيرة.

قائمة التحقق من النشر

عندما يمر هذا التصميم عبر مراجعة جاهزية الإنتاج، تتضمن قائمة التحقق: تفعيل storage.type filesystem في Fluent Bit على كل عقدة؛ نشر OTel Collector كـDeployment (وليس DaemonSet) مع HPA مبني على طول طابور الجامع؛ معامل نسخ Kafka 3 مع min.insync.replicas=2؛ النسخ العابر للكلاسترات في Elasticsearch من us-east-1 إلى eu-west-1 للطبقة الساخنة ذات 24 ساعة (للتعافي من الكوارث)؛ تهيئة Kibana Spaces بحيث يرى كل فريق فقط سجلات فضاء أسمائه (RBAC)؛ جدولة استعلام تدقيق PCI ربع سنوي كـWatcher؛ وروابط كتيبات التشغيل مضمّنة في كل تنبيه Kibana.

ممارسة المحترفين: خزّن جميع لوحات تحكم Kibana وقوالب الفهرس وسياسات ILM وتعريفات Watcher كملفات YAML في مستودع git وطبّقها عبر واجهة برمجة Elasticsearch أثناء CI/CD. هذا يمنحك سجلاً تاريخياً لتهيئة الاستيضاح — عندما يبدأ تنبيه في الاختلال، يمكنك معرفة من غيّر الحد ولماذا عبر git blame. توفر Grafana إمكانية مماثلة من خلال دليل التوفير.

لقد صممت الآن منصة تسجيل مركزية جاهزة للإنتاج ومتوافقة مع PCI ومتعددة المناطق: إصدار منظم، وجمع مثري، ونقل متين، وتخزين متدرج محسوب التكلفة، وإخفاء تلقائي للامتثال على مستوى خط الأنابيب، وتنبيهات قابلة للتنفيذ. هذه هي المعمارية التي يفخر بها المهندس الأول الكبير في مصرف كبير أو شركة مدفوعات.