הסבר על רישום ביומן

במאמר הזה נסביר על תהליך הרישום ביומן, כולל תקני יומנים, הנחיות לגבי רמות, סיווגים, מטרות ותוצאות משוערות של נתונים בכמה סטאקים.

תקני יומנים

הרישום ביומן ב-Android הוא מורכב בגלל השילוב של הסטנדרטים שבהם נעשה שימוש ב-logcat. אלה התקנים העיקריים שבהם נעשה שימוש:

מקור דוגמאות הנחיות ברמת הסטאק
RFC 5424 (תקן syslog) ליבה של Linux, הרבה אפליקציות Unix ליבה, דמונים של מערכת
android.util.Log Android framework + רישום ביומן של האפליקציה מסגרת Android ואפליקציית מערכת
java.util.logging.Level רישום ביומן כללי ב-Java אפליקציה שאינה אפליקציית מערכת

איור 1: תקני רמות יומנים.

למרות שלכל אחד מהסטנדרטים האלה יש מבנה דומה של רמות, יש הבדלים ברמת הפירוט. התאמות משוערות בין התקנים השונים:

רמה של RFC 5424 רמת החומרה של RFC 5424 תיאור של 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
- - שליחת הודעות מפורטות (verbose) 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 משאירות עקבות ביומן בקוד האפליקציה. דגלים בוליאניים של 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

האפשרות הזו שימושית לטיפול במספר סוגים של גרסאות build של אפליקציות (לדוגמה, גרסאות build לפיתוח לעומת גרסאות build למהדורה) שבהן הקוד הבסיסי צפוי להיות זהה, אבל רמות היומנים המותרות שונות. צריך להגדיר מדיניות מפורשת לאפליקציות (במיוחד לאפליקציות מערכת) ולפעול לפיה כדי לקבוע איך סוגי גרסאות build וציפיות לגרסאות משפיע על הפלט של היומנים.

רישום ביומן המערכת בסביבת זמן הריצה של Android‏ (ART)

יש כמה כיתות זמינות לאפליקציות ולשירותים של המערכת:

כיתה מטרה
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 של יומני השגיאות לא תואמות ביחס של 1:1:

java.util.Logging.Level android.util.Log
SEVERE Log.wtf
SEVERE Log.e

איור 9: רמת השגיאה ברישום ביומן רגיל של Java לעומת רישום ביומן של Android.

במקרים כאלה, צריך להשתמש בתקן הספציפי כדי לקבוע איזו רמה צריך להחיל.

במהלך פיתוח מערכת עם כמה רכיבים ברמת הערימה, צריך לפעול לפי תרשים 1 כדי לקבוע באיזה תקן להשתמש בכל רכיב. תרשים 2 מציג מדריך להודעות ברמות שונות.

אבטחה ופרטיות

אין לתעד פרטים אישיים מזהים (PII). זה כולל פרטים כמו:

  • כתובות אימייל
  • מספרי טלפון
  • שמות

באופן דומה, פרטים מסוימים נחשבים למידע רגיש גם אם הם לא מזהים באופן מפורש את האדם.

לדוגמה, למרות שמידע על אזור זמן לא נחשב לפרט אישי מזהה, הוא כן מספק אינדיקציה למיקום המשוער של המשתמש.

מדיניות הרישום ביומן והפרטים הקבילים צריכים להיבדק במסגרת בדיקת האבטחה והפרטיות לפני הפרסום.

מקובצי היומן במכשיר

הגישה לכל יומני המכשיר, כולל באמצעות android.permission.READ_LOGS, מוגבלת:

  • אם אפליקציה ברקע מבקשת גישה לכל יומני המכשיר, הבקשה נדחית באופן אוטומטי, אלא אם האפליקציה:
    • שיתוף מזהה ה-UID של המערכת.
    • נעשה שימוש בתהליך מערכת מקורי (UID < APP_UID).
    • נעשה שימוש ב-DropBoxManager.
    • גישה רק למאגר הנתונים הזמני של יומן האירועים.
    • נעשה שימוש ב-API של EventLog.
    • שימוש בבדיקות עם מכשירי מדידה.
  • אם אפליקציה בחזית עם READ_LOGS מבקשת גישה ליומני המכשיר, המערכת מבקשת מהמשתמש לאשר או לדחות את בקשת הגישה.