ทําความเข้าใจการบันทึก

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

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

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

แหล่งที่มา ตัวอย่าง คำแนะนำเกี่ยวกับระดับของกอง
RFC 5424 (มาตรฐาน syslog) เคอร์เนล Linux, แอป Unix จำนวนมาก เคอร์เนล, Daemon ของระบบ
android.util.Log การบันทึกเฟรมเวิร์ก Android + แอป เฟรมเวิร์ก 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
- - การรับส่งข้อความแบบละเอียด Log.v FINER / FINEST

รูปที่ 2: ระดับการบันทึกของ syslog, Android และ Java

หลักเกณฑ์ระดับบันทึก

มีหลักเกณฑ์ที่มีอยู่สำหรับมาตรฐานบันทึกแต่ละรายการ ระดับบันทึกที่เลือก จะเป็นไปตามมาตรฐานที่เหมาะสมที่ใช้ เช่น การใช้syslog มาตรฐานสำหรับการพัฒนาเคอร์เนล

ลำดับระดับบันทึกจากน้อยไปมากแสดงในรูปที่ 3 ด้านล่าง

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

ซึ่งมีประโยชน์ในการจัดการบิลด์แอปหลายประเภท (เช่น บิลด์สำหรับพัฒนาเทียบกับบิลด์ที่เผยแพร่) ซึ่งคาดว่าโค้ดพื้นฐานจะเหมือนกัน แต่ระดับบันทึกที่อนุญาตจะแตกต่างกัน ต้องกำหนดและปฏิบัติตามนโยบายที่ชัดเจนสำหรับแอป (โดยเฉพาะแอปของระบบ) เพื่อพิจารณาว่าประเภทบิลด์และความคาดหวังในการเผยแพร่ส่งผลต่อเอาต์พุตของบันทึกอย่างไร

การบันทึกของระบบใน 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) สอดคล้องกับ เคอร์เนล Linux syslog ที่ควบคุมบัฟเฟอร์ printk และ syslog(3) สอดคล้องกับเครื่องมือบันทึกทั่วไปของระบบ Android ใช้ไลบรารี liblog สำหรับการบันทึกระบบทั่วไป

liblog มี Wrapper สำหรับกลุ่มบันทึกย่อยโดยใช้มาโครต่อไปนี้ รูปแบบ:

[Sublog Buffer ID] LOG [Log Level ID]

RLOGD เช่น สอดคล้องกับ [Radio log buffer ID] LOG [Debug Level] โดยliblog Wrapper หลักๆ มีดังนี้

คลาส Wrapper ฟังก์ชันตัวอย่าง
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

รูปที่ 7: liblog Wrapper

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 ขอสิทธิ์เข้าถึงบันทึกของอุปกรณ์ ระบบจะแจ้งให้ผู้ใช้อนุมัติหรือปฏิเสธคำขอเข้าถึง