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

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

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

การบันทึกใน 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 จะตรวจสอบบันทึกการออกจากระบบในโค้ดของแอป 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)

มีคลาสที่พร้อมใช้งานหลายคลาสสำหรับแอปและบริการของระบบ ดังนี้

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