فهم التسجيل

تتناول هذه المقالة عملية التسجيل، بما في ذلك معايير السجلّ وإرشادات المستوى والفئات والأغراض والتقديرات المتعدّدة.

معايير السجلّ

تتسم عملية تسجيل الدخول على Android بالتعقيد بسبب مزيج المعايير المستخدَمة التي يتم دمجها في logcat. في ما يلي تفاصيل عن المعايير الرئيسية المستخدَمة:

المصدر أمثلة إرشادات حول مستوى التجميع
RFC 5424 (syslog) نواة Linux والعديد من تطبيقات Unix النواة، وبرامج النظام الخفية
android.util.Log تسجيل بيانات إطار عمل Android والتطبيقات إطار عمل Android وتطبيق النظام
java.util.logging.Level تسجيل البيانات العامة في Java تطبيق غير تابع للنظام

الشكل 1: معايير مستوى السجلّ

على الرغم من أنّ كل معيار من هذه المعايير يتضمّن بنية مستوى مشابهة، إلا أنّها تختلف في مستوى التفاصيل. في ما يلي القيم التقريبية المكافئة في جميع المعايير:

مستوى RFC 5424 RFC 5424 Severity وصف RFC 5424 android.util.Log java.util.logging.Level
0 طوارئ النظام غير قابل للاستخدام Log.e / Log.wtf SEVERE
1 تنبيه يجب اتخاذ إجراء على الفور Log.e / Log.wtf SEVERE
2 مهم الحالات الحرجة Log.e / Log.wtf SEVERE
3 خطأ شروط الخطأ Log.e SEVERE
4 تحذير شروط التحذير Log.w WARNING
5 إشعار عادي ولكن مهم Log.w WARNING
6 معلومات الرسائل الإعلامية Log.i INFO
7 تصحيح الأخطاء رسائل مستوى تصحيح الأخطاء Log.d CONFIG، FINE
- - الرسائل المطوَّلة Log.v FINER / FINEST

الشكل 2: مستويات التسجيل في syslog وAndroid وJava

إرشادات حول مستوى السجلّ

تتوفّر إرشادات حالية لكل معيار من معايير السجلّ. يتبع مستوى السجلّ الذي تم اختياره المعيار المناسب المستخدَم، مثل استخدام معيار syslog لتطوير النواة.

يتم عرض ترتيبات مستوى السجلّ، من الأقل إلى الأكثر، في الأشكال الثلاثة أدناه:

ERROR ويتم الاحتفاظ بهذه السجلات دائمًا.
WARN ويتم الاحتفاظ بهذه السجلات دائمًا.
INFO ويتم الاحتفاظ بهذه السجلات دائمًا.
DEBUG يتم تجميع هذه السجلات ولكن يتم إزالتها في وقت التشغيل.
VERBOSE ولا يتم تجميع هذه السجلّات في تطبيق أبدًا إلا أثناء عملية التطوير.

الشكل 3: android.util.Log

CONFIG مستوى الرسالة لرسائل الإعدادات الثابتة
FINE مستوى الرسالة الذي يوفّر معلومات التتبُّع
FINER تشير إلى رسالة تتبُّع مفصّلة إلى حدّ ما
FINEST تشير إلى رسالة تتبُّع مفصّلة للغاية
INFO مستوى الرسالة للرسائل الإعلامية
SEVERE مستوى الرسالة الذي يشير إلى حدوث عطل خطير
WARNING مستوى الرسالة الذي يشير إلى مشكلة محتملة

الشكل 4: java.util.Logging.Level.

0 طوارئ النظام غير قابل للاستخدام
1 تنبيه يجب اتخاذ إجراء على الفور
2 مهم الحالات الحرجة
3 خطأ شروط الخطأ
4 تحذير شروط التحذير
5 إشعار حالة عادية ولكنها مهمة
6 شاشات توقف معرفية رسائل المعلومات
7 تصحيح الأخطاء رسائل مستوى تصحيح الأخطاء

الشكل 5: RFC 5424 - الفقرة 6.2.1

تسجيل بيانات التطبيقات

يتم تنفيذ التسجيل الانتقائي باستخدام الفئة TAG من خلال الفئة android.util.Log باستخدام Log#isLoggable، كما هو موضّح أدناه:

if (Log.isLoggable("FOO_TAG", Log.VERBOSE)) {
 Log.v("FOO_TAG", "Message for logging.");
}

يمكن ضبط السجلات في وقت التشغيل لتوفير مستوى محدّد من التسجيل على النحو الموضّح أدناه:

adb shell setprop log.tag.FOO_TAG VERBOSE

تتم إعادة ضبط خصائص log.tag.* عند إعادة التشغيل. هناك أيضًا متغيرات ثابتة تظل متاحة حتى بعد إعادة التشغيل. يُرجى الاطّلاع على ما يلي:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

تترك عمليات التحقّق من Log#isLoggable آثارًا في سجلّات رموز التطبيق. تتجاوز علامات Boolean DEBUG عمليات تتبُّع السجلّ باستخدام تحسينات المترجم التي تم ضبطها على false، كما هو موضّح أدناه:

private final static boolean DEBUG = false;

… If (DEBUG) { Log.v("FOO_TAG", "Extra debug logging."); }

يمكن إزالة التسجيل على أساس كل حزمة APK من خلال مجموعات قواعد ProGuard باستخدام R8 في وقت التجميع. يزيل المثال التالي كل ما هو أدنى من مستوى INFO لتسجيل الدخول إلى android.util.Log:

# This allows proguard to strip isLoggable() blocks containing only <=INFO log
# code from release builds.
-assumenosideeffects class android.util.Log {
  static *** i(...);
  static *** d(...);
  static *** v(...);
  static *** isLoggable(...);
}
-maximumremovedandroidloglevel 4

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

تسجيل بيانات النظام في وقت تشغيل Android (ART)

تتوفّر عدة فئات للتطبيقات والخدمات على النظام، وهي:

الفئة Purpose
android.telephony.Rlog تسجيل بيانات الراديو
android.util.Log تسجيل بيانات التطبيق العامة
android.util.EventLog تسجيل أحداث التشخيص لمُدمِج الأنظمة
android.util.Slog تسجيل إطار عمل النظام الأساسي

الشكل 6: فئات سجلّات النظام المتاحة وأغراضها

على الرغم من أنّ android.util.Log وandroid.util.Slog تستخدمان معايير مستوى السجلّ نفسها، إلا أنّ Slog هي فئة @hide لا يمكن استخدامها إلا من خلال المنصّة. يتم ربط مستويات EventLog بالإدخالات في ملف event.logtags في /system/etc/event-log-tags.

التسجيل الأصلي

يتّبع تسجيل الدخول في C/C++‎ معيار syslog، حيث يتوافق syslog(2) مع syslog لنواة Linux الذي يتحكّم في المخزن المؤقت printk، ويتوافق syslog(3) مع أداة تسجيل النظام العامة. يستخدم Android مكتبة liblog لتسجيل بيانات النظام العامة.

توفّر liblog برامج تضمين لمجموعات السجلات الفرعية باستخدام شكل الماكرو التالي:

[Sublog Buffer ID] LOG [Log Level ID]

على سبيل المثال، يتوافق RLOGD مع [Radio log buffer ID] LOG [Debug Level]. في ما يلي أهم أغلفة liblog:

فئة التغليف أمثلة على الدوال
log_main.h ALOGV، ALOGW
log_radio.h RLOGD، RLOGE
log_system.h SLOGI، SLOGW

الشكل 7: أغلفة liblog

يوفّر نظام التشغيل Android واجهات ذات مستوى أعلى لتسجيل البيانات، وهي أفضل من الاستخدام المباشر، كما هو موضّح أدناه:liblog

المكتبة الاستخدام
async_safe مكتبة لتسجيل البيانات من بيئات آمنة للإشارات غير المتزامنة فقط
libbase مكتبة تسجيل تقدّم واجهة بث بلغة C++‎ لتسجيل البيانات، على غرار تسجيل البيانات بنمط Google (glog). يمكن استخدام libbase في المشاريع الخارجية، كما تتوفّر في التطبيقات التي تستخدم libbase_ndk.

الشكل 8: مكتبات السجلّات ذات المستوى الأعلى

التقريبات المتعددة المكدّسة

بسبب الاختلافات في مستوى التفاصيل ومستوى الهدف، لا تتوفّر مطابقة واضحة أو دقيقة لمعايير التسجيل المختلفة. على سبيل المثال، لا يتطابق المستويان java.util.logging.Level وandroid.util.Log لسجلّات الأخطاء مع بعضهما البعض:

java.util.Logging.Level android.util.Log
شديد Log.wtf
شديد Log.e

الشكل 9: مستوى الخطأ في تسجيل الدخول العادي في Java مقارنةً بتسجيل الدخول في Android

في حالات مثل هذه، استخدِم المعيار الفردي لتحديد المستوى الذي يجب تطبيقه.

أثناء تطوير النظام باستخدام مكوّنات متعددة على مستوى الحزمة، اتّبِع الشكل 1 لتحديد المعيار الذي يجب استخدامه لكل مكوّن. للحصول على دليل تقريبي بشأن الرسائل حسب المستوى، يُرجى الرجوع إلى الشكل 2.

الأمان والخصوصية

لا تسجِّل معلومات تكشف الهوية الشخصية (PII). ويشمل ذلك تفاصيل مثل:

  • عناوين البريد الإلكتروني
  • أرقام الهاتف
  • الأسماء

وبالمثل، تُعد بعض التفاصيل حساسة حتى إذا لم تكن تحدّد الهوية الشخصية بشكل صريح.

على سبيل المثال، على الرغم من أنّ معلومات المنطقة الزمنية لا تُعدّ معلومات تحدّد الهوية الشخصية، إلا أنّها تشير إلى الموقع الجغرافي التقريبي للمستخدم.

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

سجلّات الجهاز

يتم حظر الوصول إلى جميع سجلّات الجهاز، بما في ذلك استخدام android.permission.READ_LOGS:

  • إذا طلب تطبيق يعمل في الخلفية الوصول إلى جميع سجلات الجهاز، سيتم رفض الطلب تلقائيًا إلا إذا كان التطبيق:
    • تشارك هذه السمة رقم تعريف المستخدم في النظام.
    • يستخدم عملية نظام أصلية (UID < APP_UID).
    • يتم استخدام "DropBoxManager".
    • لا يمكن الوصول إلا إلى المخزن المؤقت لسجلّ الأحداث.
    • يستخدم واجهة برمجة التطبيقات EventLog.
    • تستخدِم اختبارات لقياس حالة التطبيق.
  • إذا طلب تطبيق في المقدّمة يتضمّن READ_LOGS الوصول إلى سجلات الجهاز، سيطلب النظام من المستخدم الموافقة على طلب الوصول أو رفضه.