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

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

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

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

แหล่งที่มา ตัวอย่าง คําแนะนําระดับสแต็ก
RFC 5424 (มาตรฐาน syslog) เคอร์เนล Linux, แอป Unix จำนวนมาก เคอร์เนล ดีแอม่อนของระบบ
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 สำหรับกลุ่ม sublogs โดยใช้รูปแบบมาโครต่อไปนี้

[Sublog Buffer ID] LOG [Log Level ID]

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

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