Structured Logging — الجوهر وتنسيقات البيانات ومبدأ العمل في التطبيقات

المؤلف: IT Sectr نُشر: 2026-05-28 وقت القراءة: 8 دق

Structured Logging هو نهج لتسجيل السجلات حيث يتم تمثيل كل رسالة بتنسيق قابل للقراءة آلياً مع أزواج مفتاح-قيمة، بدلاً من النص غير المنظم. على عكس السلاسل المسطحة، تحتوي السجلات المنظمة على بيانات وصفية: الطابع الزمني، المستوى، الوحدة، معرف الطلب — ويمكن فهرستها بواسطة أنظمة التحليل. وفقاً لـ O'Reilly Effective Logging، فإن الانتقال إلى التنسيقات المنظمة يقلل وقت البحث عن الحوادث من ساعات إلى دقائق بفضل إمكانية التصفية حسب الحقول. هذا هو المعيار الفعلي في التطوير المحمول والخوادم الحديث: JSON وlogfmt يسمحان بمعالجة السجلات بواسطة البرامج، وليس بالعينين.

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

  • Structured Logging — تمثيل السجلات بتنسيق مفتاح-قيمة بدلاً من النص المسطح، مناسب للمعالجة الآلية
  • JSON — التنسيق الأكثر شيوعاً للسجلات المنظمة، مدعوم من جميع أنظمة الجمع والتحليل الحديثة
  • Logfmt — تنسيق مضغوط من Heroku، مناسب للقراءة البشرية والتحليل عبر grep
  • ELK Stack — Elasticsearch، Logstash، Kibana — البنية التحتية القياسية لتخزين وعرض السجلات المنظمة
  • السياق — معرف الطلب، جلسة المستخدم، إصدار التطبيق — حقول إلزامية لكل رسالة منظمة

ما هو Structured Logging

Structured Logging هو طريقة لتسجيل السجلات حيث يحتوي كل رسالة على حقول مسماة بقيم محددة النوع. بدلاً من سلسلة مثل User 42 logged in from device ABC، يبدو السجل المنظم كمجموعة من الحقول: user_id=42, event=login, device_id=ABC, timestamp=2026-07-04T10:30:00Z.

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

وفقاً لـ Honeycomb.io (2023)، الفرق التي تستخدم structured logging في الإنتاج تكتشف الحوادث في المتوسط أسرع بـ4 مرات مقارنة بالفرق التي تعتمد على السجلات النصية وgrep.

تنسيقات السجلات المنظمة

Structured Logging يدعم عدة تنسيقات للتسلسل. يعتمد اختيار التنسيق على البنية التحتية: JSON مناسب للتكامل مع Elasticsearch والأنظمة السحابية، logfmt للعرض في الطرفية عبر tail وgrep، Protocol Buffers للأنظمة عالية الأداء ذات قيود عرض النطاق.

التنسيقمثالمتى تستخدم
JSON{"event":"login","user_id":42}ELK Stack، المجمعات السحابية، الخدمات المصغرة
Logfmtevent=login user_id=42 duration_ms=150الطرفية، tail، heroku logs
MessagePackالمكافئ الثنائي لـJSONالأنظمة عالية التحميل، إنترنت الأشياء

JSON — تنسيق عالمي

JSON هو التنسيق الأكثر شيوعاً للسجلات المنظمة. وهو مدعوم أصلياً من جميع أنظمة الجمع: Logstash، Fluentd، Amazon CloudWatch، Google Cloud Logging. سجلات JSON سهلة القراءة للبشر والتحليل بواسطة أي لغة برمجة دون مكتبات إضافية. العيب الرئيسي هو الإسهاب: كل زوج مفتاح-قيمة يتطلب علامات اقتباس ونقطتين، مما يزيد حجم البيانات المخزنة بنسبة 30–50% مقارنة بـlogfmt.

Logfmt — تنسيق مضغوط

Logfmt تم تطويره في Heroku للرؤية في الطرفية. إنه أكثر ضغطاً من JSON، ويحافظ على قابلية القراءة البشرية، ويمكن معالجته بسهولة باستخدام cut وawk. مثال: ts=2026-07-04T10:30:00Z level=error module=api status=500. Logfmt لا يتطلب هروب معظم الأحرف ومناسب تماماً لتسجيل stdout في الحاويات.

لماذا تحتاج Structured Logging في التطوير المحمول

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

السجلات النصية على الأجهزة المحمولة عديمة الفائدة تقريباً — لا يمكن للمطور تطبيق grep على سجلات جهاز المستخدم. يتم إرسال السجلات المنظمة إلى الأنظمة السحابية (Firebase، Sentry، Datadog) ويتم فهرستها هناك. يمكن بناء استعلام مثل عرض جميع الأعطال على iOS 17.4، إصدار التطبيق 3.2، في وحدة الدفع والحصول على تحديد دقيق في ثوانٍ.

وفقاً لـ Sentry (2024)، التطبيقات التي تستخدم breadcrumbs منظمة لديها سياق أكثر بنسبة 60% في كل تقرير عطل مقارنة بالتطبيقات التي تسجل فقط نص الخطأ. هذا يؤثر مباشرة على سرعة إصلاح الخلل.

أدوات الجمع والتحليل

ELK Stack — Elasticsearch، Logstash، Kibana — يظل البنية التحتية القياسية للعمل مع السجلات المنظمة. Logstash يستقبل السجلات بتنسيق JSON، ويحولها ويرسلها إلى Elasticsearch للفهرسة، Kibana يوفر واجهة بصرية للاستعلامات ولوحات المعلومات.

للتطبيقات المحمولة، الحلول السحابية شائعة: Firebase Crashlytics مع سجلات مخصصة، Sentry مع breadcrumbs، Datadog مع تتبع APM. تستقبل السجلات المنظمة مباشرة من SDK المحمول ولا تتطلب نشر خلفية خاصة. Firebase يقدم حزمة مجانية لتقارير الأعطال، Sentry يضيف التتبع الموزع، وDatadog يتكامل مع APM لتتبع أداء الطلبات على العميل والخادم في وقت واحد.

Grafana Loki — بديل لـElasticsearch محسّن للسجلات. Loki لا يفهرس محتوى الرسائل افتراضياً بل يستخدم التصنيفات (labels) للتصفية. هذا أرخص بكثير في التخزين وأسرع للاستعلامات على مجموعة ثابتة من الحقول.

swift
// التسجيل المنظم عبر Swift Logger بتنسيق JSON
struct StructuredLog {
    let event: String
    let attributes: [String: Any]
    let level: String

    func serialize() -> String {
        var base = "event=\(event) level=\(level)"
        for (key, value) in attributes {
            base += " \(key)=\(value)"
        }
        return base
    }
}

أفضل ممارسات Structured Logging

القاعدة الأولى للتسجيل المنظم: كل رسالة يجب أن تحتوي على معرف طلب أو جلسة. بدون سياق، السجل الفردي عديم الفائدة — من المستحيل معرفة أي مستخدم أو طلب ينتمي إليه. أضف correlation ID عند بدء الجلسة وقم بتمريره عبر جميع طبقات التطبيق.

القاعدة الثانية: تحديد نوع الحقول. الحقول الرقمية (duration_ms, status_code, retry_count) يجب إرسالها كأرقام وليس كسلاسل نصية. Elasticsearch والأنظمة المماثلة تفهرس الأرقام والسلاسل بشكل مختلف: الأرقام يمكن تجميعها (متوسط، وسيط، نسبة مئوية)، السلاسل تدعم البحث النصي الكامل. التحديد الخاطئ للنوع يمنع بناء لوحات تحليلية.

القاعدة الثالثة: تجنب الكائنات المتداخلة. سجلات JSON بعمق تداخل أكثر من مستويين يصعب تصفيتها وعرضها. بدلاً من {"user": {"name": "Alice", "role": "admin"}}، استخدم مفاتيح مسطحة: user_name=Alice user_role=admin.

kotlin
// التسجيل المنظم على Android عبر Timber + logfmt
class StructuredTree : Timber.Tree() {
    override fun log(priority: Int, tag: String?,
                  message: String?, t: Throwable?) {
        val level = priorityToLevel(priority)
        val logfmt = "level=$level tag=$tag message=$message"
        sendToRemote(logfmt)
    }
}

الحقول الإلزامية

الحد الأدنى من الحقول لكل رسالة منظمة: timestamp بصيغة ISO 8601، level (debug/info/warn/error/fatal)، logger (اسم الوحدة أو الفئة)، message (وصف الحدث قابل للقراءة البشرية). بالإضافة: correlation_id، user_id (إذا كان معروفاً)، version (إصدار التطبيق)، platform (iOS/Android)، environment (dev/staging/prod).

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

أمثلة على التسجيل المنظم في Swift وKotlin

على iOS، يمكن تنفيذ التسجيل المنظم عبر غلاف حول os_log يقوم بتسلسل الحقول إلى تنسيق logfmt. على Android، عبر Timber مع Tree مخصص يقوم بتحويل الرسائل إلى JSON أو logfmt قبل الإرسال إلى الخادم.

swift
import OSLog

struct StructuredLogger {
    let subsystem: String
    let category: String

    func log(level: OSLogType,
              event: String,
              context: [String: Any]) {
        let oslogger = Logger(
            subsystem: subsystem,
            category: category
        )
        let fields = context.map {
            "\($0.key)=\($0.value)"
        }.joined(separator: " ")
        oslogger.log(level: level,
                     "\(event) \(fields)")
    }
}

Structured vs Unstructured: مقارنة الأساليب

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

المعيارالسجلات النصيةالسجلات المنظمة
قابلية القراءةعالية في الطرفيةمتوسطة (تتطلب pretty-print)
البحثgrep حسب النص الفرعياستعلامات حسب الحقول والقيم
التجميعغير مدعوممتوسط، وسيط، نسب مئوية
التكامليتطلب تحليلاًأصلي في ELK/Loki/Datadog
حجم التخزينأصغر (بدون بيانات وصفية)أكبر (حقول + قيم)

الأسئلة الشائعة

ما هو أفضل تنسيق لتسجيل السجلات المحمولة؟

لإرسال الخادم، استخدم JSON — مدعوم أصلياً من Firebase Crashlytics وSentry وDatadog. للعرض المحلي في سجلات Xcode أو Android Studio، استخدم logfmt — إنه أكثر ضغطاً ويُقرأ بدون تنسيق.

هل يجب التسجيل بتنسيق منظم على العميل؟

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

كيف يختلف logfmt عن JSON؟

Logfmt أكثر ضغطاً (حجم أقل بنسبة 30–50%) وأسهل للقراءة في الطرفية. JSON يدعم الكائنات والمصفوفات المتداخلة ولكنه يتطلب هروب علامات الاقتباس. يعتمد الاختيار على البنية التحتية: لـELK — JSON، للعرض في الطرفية — logfmt.

كيف أضيف correlation ID إلى جميع السجلات؟

أنشئ مثيلاً واحداً من UUID عند بدء التطبيق، واحفظه في singleton أو حاوية DI، ومرره إلى جميع مسجلات السجلات عبر المنشئ. بديل — استخدام التخزين المحلي للخيط أو Continuation Local Storage في coroutines Kotlin.

هل يمكن خلط السجلات المنظمة والنصية؟

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

الخلاصة

  • Structured Logging — تنسيق سجلات بأزواج مفتاح-قيمة، مناسب للفهرسة والاستعلامات التلقائية، على عكس السلاسل النصية
  • JSON وlogfmt — التنسيقان الرئيسيان: JSON عالمي لأنظمة الجمع، logfmt مضغوط للعرض في الطرفية وسجلات docker
  • Correlation ID — حقل إلزامي لكل رسالة منظمة، بدونه لا يمكن ربط السجلات في جلسة مستخدم
  • ELK Stack وGrafana Loki — حلول البنية التحتية القياسية لتخزين وفهرسة وعرض السجلات المنظمة
  • الأداء — الفرق التي تستخدم structured logging تكتشف الحوادث أسرع بـ4 مرات بفضل الاستعلامات حسب الحقول بدلاً من grep حسب النص
  • تحديد النوع — يجب إرسال الأرقام كأرقام وليس كسلاسل، لتمكين التجميعات (متوسط، وسيط، نسب مئوية) في أنظمة التحليلات

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا