ทำความเข้าใจเกี่ยวกับการบันทึก

บทความนี้ครอบคลุมกระบวนการบันทึก รวมถึงมาตรฐานบันทึก แนวทางระดับ คลาส วัตถุประสงค์ และการประมาณมัลติสแต็ก

มาตรฐานบันทึก

การเข้าสู่ระบบ Android มีความซับซ้อนเนื่องจากมีการผสมผสานมาตรฐานที่รวมอยู่ใน logcat มาตรฐานหลักที่ใช้มีรายละเอียดดังนี้:

แหล่งที่มา ตัวอย่าง คำแนะนำระดับกองซ้อน
RFC 5424 (มาตรฐาน syslog ) เคอร์เนล Linux, แอปพลิเคชั่น Unix มากมาย เคอร์เนล daemons ระบบ
android.util.Log การบันทึกเฟรมเวิร์ก Android + แอปพลิเคชัน เฟรมเวิร์ก Android และแอปพลิเคชันระบบ
java.util.logging.Level การบันทึกทั่วไปใน Java แอปพลิเคชันที่ไม่ใช่ระบบ

รูปที่ 1: มาตรฐานระดับบันทึก

แม้ว่าแต่ละมาตรฐานเหล่านี้จะมีโครงสร้างในระดับเดียวกัน แต่ก็มีรายละเอียดที่แตกต่างกันไป ความเทียบเท่าโดยประมาณของมาตรฐานมีดังนี้:

ระดับ RFC 5424 RFC 5424 ความรุนแรง คำอธิบาย RFC 5424 android.util.Log java.util.logging.ระดับ
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 Runtime (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 จัดเตรียม wrapper สำหรับกลุ่มบันทึกย่อยโดยใช้รูปแบบแมโครต่อไปนี้:

[Sublog Buffer ID] LOG [Log Level ID]

ตัวอย่างเช่น RLOGD สอดคล้องกับ [Radio log buffer ID] LOG [Debug Level] Wrapper 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
รุนแรง Log.wtf
รุนแรง Log.e

รูปที่ 9: ระดับข้อผิดพลาดในการบันทึก Java มาตรฐานเทียบกับการบันทึกของ Android

ในกรณีเช่นนี้ ให้ใช้มาตรฐานส่วนบุคคลเพื่อพิจารณาว่าจะใช้ระดับใด

ในระหว่างการพัฒนาระบบที่มีส่วนประกอบหลายระดับสแต็ก ให้ทำตามรูปที่ 1 เพื่อกำหนดมาตรฐานที่จะใช้ต่อส่วนประกอบ สำหรับคำแนะนำโดยประมาณเกี่ยวกับการส่งข้อความตามระดับ ให้ทำตามรูปที่ 2

ความปลอดภัยและความเป็นส่วนตัว

อย่าบันทึกข้อมูลที่สามารถระบุตัวบุคคลได้ (PII) ซึ่งรวมถึงรายละเอียดต่างๆ เช่น:

  • ที่อยู่อีเมล
  • หมายเลขโทรศัพท์
  • ชื่อ

ในทำนองเดียวกัน รายละเอียดบางอย่างถือว่าละเอียดอ่อนแม้ว่าจะไม่สามารถระบุตัวบุคคลได้อย่างชัดเจนก็ตาม

ตัวอย่างเช่น แม้ว่าข้อมูลเขตเวลาจะไม่ถือว่าสามารถระบุตัวบุคคลได้ แต่ก็ให้ข้อมูลระบุตำแหน่งโดยประมาณของผู้ใช้

นโยบายบันทึกและรายละเอียดที่ยอมรับได้จะต้องได้รับการจัดการโดยเป็นส่วนหนึ่งของการตรวจสอบความปลอดภัยและความเป็นส่วนตัวก่อนเผยแพร่

บันทึกอุปกรณ์

การเข้าถึงบันทึกอุปกรณ์ทั้งหมด รวมถึงการใช้ android.permission.READ_LOGS ถูกจำกัด:

  • หากแอปในเบื้องหลังร้องขอการเข้าถึงบันทึกอุปกรณ์ทั้งหมด คำขอนั้นจะถูกปฏิเสธโดยอัตโนมัติ เว้นแต่แอปจะ:
    • แบ่งปัน UID ของระบบ
    • ใช้กระบวนการของระบบดั้งเดิม ( UID < APP_UID )
    • ใช้ DropBoxManager
    • เข้าถึงเฉพาะบัฟเฟอร์บันทึกเหตุการณ์เท่านั้น
    • ใช้ EventLog API
    • ใช้การทดสอบแบบมีเครื่องมือ
  • หากแอปที่อยู่เบื้องหน้าที่มี READ_LOGS ร้องขอการเข้าถึงบันทึกอุปกรณ์ ระบบจะแจ้งให้ผู้ใช้อนุมัติหรือปฏิเสธคำขอเข้าถึง