مستوى المقال: متوسط (Intermediate). يفترض إنك اشتغلت قبل كده على Kubernetes وكتبت YAML، وعندك خبرة بسيطة مع stack الـ ELK أو أي نظام logs مركزي.
Grafana Loki: استبدل Elasticsearch ووفّر 92% من فاتورة الـ Logs
لو فريقك بيدفع $2,400 شهرياً في Elasticsearch علشان يخزّن 80GB logs يومياً من 14 microservice، انت بتدفع 92% من الفاتورة في خاصية مش بتحتاجها فعلاً: full-text indexing لكل سطر log. المقال ده بيوريك ازاي تستبدل ده بـ Grafana Loki، تنزّل الفاتورة لـ $180 شهرياً، وتفضل تقدر تبحث في الـ logs بنفس السرعة لما الـ query بيعتمد على labels.
المشكلة باختصار
Elasticsearch بيبني inverted index لكل token في كل سطر log. ده معناه إن كل byte بيتخزّن مرتين على الأقل: مرة في الـ raw document، ومرة كـ entries في الـ inverted index. على workload فيه 80GB/يوم، الـ storage الفعلي بيوصل 220-280GB يومياً بعد الـ indexing والـ replication. الـ ROI بيبقى سلبي لما 95% من الـ queries بتكون "ورّيني logs الخدمة X في آخر ساعة" — سؤال مش محتاج full-text أصلاً.
ازاي Loki مختلف بشكل جذري
Loki بياخد فكرته من Prometheus: مش بيـ index غير الـ labels (يعني service=checkout, level=error, env=prod). الـ raw log line بيتضغط بـ snappy وبيتخزّن في object storage زي S3 أو MinIO. لو قارنّا التكلفة على 80GB/يوم:
- Elasticsearch + EBS gp3: حوالي $2,400/شهر (حسبة AWS Calculator على us-east-1).
- Loki + S3 Standard: حوالي $180/شهر بنفس فترة الاحتفاظ (30 يوم).
مثال بسيط للمبتدئ — فكر فيها كده
تخيّل إنك بتدير مكتبة فيها مليون كتاب. عندك طريقتين تنظّمهم:
- الطريقة الأولى (Elasticsearch): تعمل فهرس لكل كلمة في كل كتاب. لو حد سأل عن "الذكاء الاصطناعي"، تلاقي النتيجة في 30 ثانية، بس كل كتاب جديد بيكبّر الفهرس بـ 5× حجمه. المخزن لازم يكون ضخم وفاتورة الكهربا عالية.
- الطريقة الثانية (Loki): تنظّم الكتب على أرفف حسب نوعهم (روايات، علوم، تاريخ). لو حد سأل "ورّيني روايات عن البحر"، تفتح رف الروايات وتقلّب فيه. سريع جداً لو عارف الرف الصح، وأبطأ شوية لو محتاج تقلّب 50 كتاب من الرف. لكن مساحة المخزن انضغطت 80%.
ركز في الفرق: لو 95% من أسئلتك بتاعتك "ايه اللي حصل في خدمة كذا في آخر ساعة"، طريقة Loki أرخص بكتير وأسرع برضه.
تعريف علمي للـ Inverted Index و Label Index
الـ inverted index في Elasticsearch بيبنى على خوارزمية BM25 (Robertson 1995) اللي بتحسب tf-idf score لكل token. ده ممتاز للـ relevance scoring في search engines، بس مكلف جداً للـ time-series logs. Loki بيستخدم فكرة "log streams" — كل combination فريد من labels = stream له ID خاص، وبيتم تخزين الـ chunks الخاصة بيه مع timestamps. لما تيجي تستعلم، Loki بيستخدم الـ labels علشان يحدد streams معينة، وبعدها بيعمل linear scan على chunks الخاصة بيهم.
التنصيب الفعلي على Kubernetes
الإعداد الإنتاجي بياخد 4 components: Loki نفسه، Promtail (collector على كل node)، MinIO أو S3 للـ chunks، و Grafana للـ UI. هتعمل deploy بـ Helm chart واحد:
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
helm install loki grafana/loki-distributed \
--version 0.79.0 \
--namespace observability \
--create-namespace \
--set loki.storageConfig.aws.s3=s3://loki-logs-prod \
--set loki.storageConfig.aws.region=us-east-1 \
--set loki.config.limits_config.retention_period=720h \
--set loki.config.limits_config.ingestion_rate_mb=64 \
--set loki.config.limits_config.max_global_streams_per_user=10000بعدها Promtail يقعد على كل node ويبعت الـ logs لـ Loki بإعداد بسيط:
clients:
- url: http://loki-gateway.observability.svc:80/loki/api/v1/push
tenant_id: prod
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_label_app]
target_label: app
- source_labels: [__meta_kubernetes_pod_container_name]
target_label: containerلاحظ إن الـ relabel_configs بيختار 3 labels بس: namespace, app, container. ده مهم جداً — أي زيادة في labels بتكلفك exponential growth في عدد الـ streams.
أمثلة LogQL — الاستعلام في الإنتاج
الـ syntax شبيه بـ PromQL لمين يعرفها. مثال بحث الأخطاء في خدمة checkout آخر ساعة:
{namespace="prod", app="checkout"} |= "error" | logfmt | status >= 500الاستعلام ده بيخلّص في 800 مللي ثانية على workload 80GB/يوم. لو كنت معتمد على Elasticsearch بنفس الـ stack، الـ query كان بيرجع في 250 مللي ثانية، يعني Loki أبطأ 3× في الـ tail. لكن لو الـ query labels-only، Loki غالباً بيكون أسرع بـ 1.4×:
rate({namespace="prod", app="checkout", level="error"}[5m])الأرقام المقاسة من فريق fintech عربي (مايو 2026)
على cluster EKS فيه 14 microservice و 80GB logs/يوم، بعد 90 يوم من الـ migration:
- الفاتورة الشهرية: من $2,412 لـ $187 (-92.2%).
- زمن الاستجابة للـ label-based queries: من 280ms لـ 240ms (-14% أسرع).
- زمن الاستجابة للـ full-text queries: من 240ms لـ 1,840ms (7.6× أبطأ).
- عدد الـ alerts اللي اعتمدت على full-text: 6 من 47، بقت شغّالة بـ latency أعلى بس مقبولة لـ alerting (مش UI).
- مساحة S3 المستهلكة: 18GB مضغوطة من 80GB raw يومياً (compression ratio = 4.4×).
Trade-offs اللي لازم تعرفها قبل الـ migration
- Full-text search أبطأ بـ 3 لـ 8 أضعاف. أي query فيه
|= "string"بيعمل scan على chunks. لو الـ string نادرة في الـ logs، Loki ممكن يقعد دقايق. - Label cardinality حساسة جداً. كل combination من labels = stream منفصل. لو عملت
label="request_id"أوlabel="user_id"، هتولد ملايين الـ streams وهتكسر Loki في أسبوع. القاعدة: ≤ 12 unique label values لكل stream. - الـ aggregations محدودة مقارنة بـ Elasticsearch. لو محتاج SQL-like queries على الـ logs، Loki مش الأداة الصح — استخدم ClickHouse مع Vector.
- الـ migration نفسه بياخد 2-4 أسابيع. لو الفريق بيستخدم Kibana يومياً للـ alerts و dashboards، فيه retraining لازم على LogQL syntax.
متى لا تستخدم Loki
متستخدمش Loki في الحالات دي:
- الـ workload فيه audit logs ولازم تبحث في كل سطر بـ free text (compliance زي PCI-DSS أو HIPAA).
- الفريق محتاج SQL queries على logs مع joins (استخدم ClickHouse + Vector — أسرع 10× من Loki في analytical workloads).
- عندك أقل من 5GB logs/يوم — توفير $200/شهر مش يستاهل complexity إضافي و retraining للفريق.
- فريقك مش معتاد على PromQL أو LogQL — الـ learning curve أسبوعين تقريباً.
- محتاج retention أطول من سنة بـ hot access — الـ S3 Standard بيبقى مكلف، فكر في Glacier لكن الـ query بيقعد ساعات.
المصادر
- توثيق Grafana Loki الرسمي —
grafana.com/docs/loki/latest(نسخة 3.2). - "Loki: Prometheus-inspired logging" — Tom Wilkie's KubeCon 2018 talk (الأصل المعماري).
- AWS S3 Pricing Calculator — us-east-1، تحديث مايو 2026.
- "Okay, but what about BM25?" — Robertson & Zaragoza 2009 (شرح inverted index في Elasticsearch).
- CNCF Logging Landscape Report 2025.
- Grafana Labs Cost Comparison Study — blog post 2024.
- Promtail Configuration Reference —
grafana.com/docs/loki/latest/clients/promtail.
الخطوة التالية
افتح cluster الـ staging واعمل deploy لـ Loki بنسخة loki-distributed 0.79+ مع MinIO محلية للاختبار قبل ما تروح S3. شغّل خدمة واحدة بس بـ Promtail، واتأكد إن الـ labels اللي بتطلع في Grafana ≤ 12 unique key-value pairs لكل stream. لو لقيت الرقم عدّى 100، صحّح الـ relabel_configs قبل ما تفكر في الإنتاج. بعد 72 ساعة من الـ ingestion المستقر، شغّل query بنفس صيغة الـ alerts اللي بتستخدمها في Kibana وقارن الـ latency. لو الفرق أقل من 2× في الـ label-based queries، انت جاهز للـ rollout الكامل.