Bài viết này trình bày quy trình ghi nhật ký, bao gồm các tiêu chuẩn nhật ký, nguyên tắc cấp, lớp, mục đích và các phương pháp ước chừng nhiều ngăn xếp.
Tiêu chuẩn nhật ký
Việc đăng nhập vào Android rất phức tạp do sự kết hợp của các tiêu chuẩn được sử dụng được kết hợp trong logcat
. Sau đây là thông tin chi tiết về các tiêu chuẩn chính được sử dụng:
Nguồn | Ví dụ | Hướng dẫn về cấp ngăn xếp |
---|---|---|
RFC 5424 (tiêu chuẩn syslog ) |
Nhân Linux, nhiều ứng dụng Unix | Hạt nhân, trình nền hệ thống |
android.util.Log |
Khung Android + ghi nhật ký ứng dụng | Khung Android và ứng dụng hệ thống |
java.util.logging.Level |
Ghi nhật ký chung trong Java | ứng dụng không phải hệ thống |
Hình 1: Các tiêu chuẩn về cấp độ nhật ký.
Mặc dù mỗi tiêu chuẩn này đều có cấu trúc cấp tương tự, nhưng chúng khác nhau về độ chi tiết. Sau đây là các giá trị tương đương gần đúng giữa các tiêu chuẩn:
Cấp độ RFC 5424 | Mức độ nghiêm trọng theo RFC 5424 | Mô tả RFC 5424 | android.util.Log | java.util.logging.Level |
---|---|---|---|---|
0 | Khẩn cấp | Không dùng được hệ thống | Log.e / Log.wtf |
SEVERE |
1 | Cảnh báo | Phải hành động ngay lập tức | Log.e / Log.wtf |
SEVERE |
2 | Quan trọng | Điều kiện nghiêm trọng | Log.e / Log.wtf |
SEVERE |
3 | Lỗi | Điều kiện lỗi | Log.e |
SEVERE |
4 | Cảnh báo | Điều kiện cảnh báo | Log.w |
WARNING |
5 | Thông báo | Bình thường nhưng có ý nghĩa | Log.w |
WARNING |
6 | Nút thông tin | Thông báo thông tin | Log.i |
INFO |
7 | Gỡ lỗi | Thông báo ở cấp gỡ lỗi | Log.d |
CONFIG , FINE |
- | - | Thông báo chi tiết | Log.v |
FINER / FINEST |
Hình 2: Các cấp độ ghi nhật ký syslog
, Android và Java.
Nguyên tắc về cấp độ nhật ký
Hiện có các nguyên tắc hiện hành cho từng tiêu chuẩn nhật ký. Cấp độ nhật ký được chọn tuân theo tiêu chuẩn thích hợp đang được sử dụng, chẳng hạn như sử dụng tiêu chuẩn syslog
để phát triển hạt nhân.
Thứ tự cấp độ nhật ký, từ thấp đến cao, được thể hiện trong ba hình dưới đây:
ERROR |
Những nhật ký này luôn được giữ lại. |
WARN |
Những nhật ký này luôn được giữ lại. |
INFO |
Những nhật ký này luôn được giữ lại. |
DEBUG |
Các nhật ký này được biên dịch nhưng bị xoá trong thời gian chạy. |
VERBOSE |
Các nhật ký này không bao giờ được biên dịch vào ứng dụng, ngoại trừ trong quá trình phát triển. |
Hình 3: android.util.Log
CONFIG |
Cấp thông báo cho thông báo cấu hình tĩnh |
FINE |
Cấp thông báo cung cấp thông tin theo dõi |
FINER |
Cho biết một thông báo theo dõi khá chi tiết |
FINEST |
Cho biết thông báo theo dõi chi tiết |
INFO |
Cấp thông báo cho thông báo thông tin |
SEVERE |
Mức thông báo cho biết lỗi nghiêm trọng |
WARNING |
Cấp độ thông báo cho biết có thể xảy ra sự cố |
Hình 4: java.util.Logging.Level
.
0 | Khẩn cấp | Không dùng được hệ thống |
1 | Cảnh báo | Phải hành động ngay lập tức |
2 | Quan trọng | Điều kiện nghiêm trọng |
3 | Lỗi | Điều kiện lỗi |
4 | Cảnh báo | Điều kiện cảnh báo |
5 | Thông báo | Tình trạng bình thường nhưng đáng kể |
6 | Thông tin | Thông báo thông tin |
7 | Gỡ lỗi | Thông báo ở cấp gỡ lỗi |
Hình 5: RFC 5424
– Mục 6.2.1.
Ghi nhật ký ứng dụng
Lớp android.util.Log
thực hiện việc ghi nhật ký có chọn lọc bằng TAG
thông qua Log#isLoggable
, như minh hoạ dưới đây:
if (Log.isLoggable("FOO_TAG", Log.VERBOSE)) { Log.v("FOO_TAG", "Message for logging."); } |
---|
Bạn có thể điều chỉnh nhật ký trong thời gian chạy để cung cấp một cấp độ ghi nhật ký như minh hoạ dưới đây:
adb shell setprop log.tag.FOO_TAG VERBOSE |
---|
Các thuộc tính log.tag.*
sẽ được đặt lại khi khởi động lại. Cũng có các biến thể liên tục tồn tại sau khi khởi động lại. Hãy xem bên dưới:
adb shell setprop persist.log.tag.FOO_TAG VERBOSE |
---|
Log#isLoggable
kiểm tra để lại dấu vết nhật ký trong mã ứng dụng. Cờ Boolean DEBUG
bỏ qua dấu vết nhật ký bằng cách sử dụng tính năng tối ưu hoá trình biên dịch được đặt thành false
, như minh hoạ bên dưới:
private final static boolean DEBUG = false; |
---|
Bạn có thể xoá tính năng ghi nhật ký trên cơ sở từng APK thông qua các quy tắc ProGuard bằng R8
tại thời điểm biên dịch. Ví dụ sau đây xoá mọi nội dung dưới nhật ký cấp INFO
cho 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 |
---|
Điều này rất hữu ích khi xử lý nhiều loại bản dựng ứng dụng (ví dụ: bản dựng phát triển so với bản phát hành) trong đó mã cơ bản dự kiến sẽ giống nhau, nhưng các cấp độ nhật ký được phép lại khác nhau. Bạn phải đặt và tuân thủ một chính sách rõ ràng cho các ứng dụng (đặc biệt là ứng dụng hệ thống) để quyết định mức độ tác động của các loại bản dựng và kỳ vọng phát hành đối với đầu ra nhật ký.
Ghi nhật ký hệ thống trong Android Runtime (ART)
Có một số lớp có sẵn cho các ứng dụng và dịch vụ hệ thống:
Lớp | Mục đích |
---|---|
android.telephony.Rlog |
Ghi nhật ký đài |
android.util.Log |
Ghi nhật ký ứng dụng chung |
android.util.EventLog |
Ghi nhật ký sự kiện chẩn đoán của nhà tích hợp hệ thống |
android.util.Slog |
Ghi nhật ký khung nền tảng |
Hình 6: Các lớp nhật ký hệ thống và mục đích có sẵn.
Mặc dù android.util.Log
và android.util.Slog
sử dụng cùng một tiêu chuẩn cấp độ nhật ký, nhưng Slog
là một lớp @hide
mà chỉ nền tảng mới có thể sử dụng. Các cấp EventLog
được liên kết với các mục nhập trong tệp event.logtags
trong /system/etc/event-log-tags
.
Ghi nhật ký gốc
Việc ghi nhật ký trong C/C++ tuân theo tiêu chuẩn syslog
với syslog
(2) tương ứng với hạt nhân Linux syslog
kiểm soát vùng đệm printk
và syslog
(3) tương ứng với trình ghi nhật ký hệ thống chung. Android sử dụng thư viện liblog
để ghi nhật ký hệ thống chung.
liblog
cung cấp trình bao bọc cho các nhóm blog con bằng cách sử dụng biểu mẫu macro sau:
[Sublog Buffer ID] LOG [Log Level ID] |
Ví dụ: RLOGD
tương ứng với [Radio log buffer ID] LOG [Debug Level]
.
Sau đây là các trình bao bọc liblog
chính:
Lớp trình bao bọc | Hàm mẫu |
---|---|
log_main.h |
ALOGV , ALOGW |
log_radio.h |
RLOGD , RLOGE |
log_system.h |
SLOGI , SLOGW |
Hình 7: Trình bao bọc liblog
.
Android có các giao diện cấp cao hơn để ghi nhật ký được ưu tiên hơn so với việc sử dụng trực tiếp liblog
, như dưới đây:
Thư viện | Cách sử dụng |
---|---|
async_safe |
Thư viện chỉ dành cho việc ghi nhật ký từ các môi trường an toàn với tín hiệu không đồng bộ |
libbase |
Thư viện ghi nhật ký cung cấp giao diện luồng C++ để ghi nhật ký, tương tự như tính năng ghi nhật ký kiểu Google (glog). Bạn có thể sử dụng libbase trong cả dự án bên ngoài và trong các ứng dụng sử dụng libbase_ndk . |
Hình 8: Thư viện nhật ký cấp cao hơn.
Xấp xỉ nhiều ngăn xếp
Do sự khác biệt về mức độ chi tiết và ý định cấp, không có tiêu chuẩn ghi nhật ký nào khớp chính xác hoặc rõ ràng với các tiêu chuẩn ghi nhật ký khác. Ví dụ: cấp java.util.logging.Level
và android.util.Log
cho nhật ký lỗi không khớp 1:1:
java.util.Logging.Level | android.util.Log |
---|---|
NẶNG | Log.wtf |
NẶNG | Log.e |
Hình 9: Cấp lỗi trong tính năng ghi nhật ký Java chuẩn so với tính năng ghi nhật ký Android.
Trong trường hợp như vậy, hãy sử dụng tiêu chuẩn riêng lẻ để xác định cấp độ cần áp dụng.
Trong quá trình phát triển hệ thống có nhiều thành phần cấp ngăn xếp, hãy làm theo Hình 1 để xác định tiêu chuẩn nào sẽ sử dụng cho mỗi thành phần. Để biết hướng dẫn gần đúng về cách gửi tin nhắn theo cấp, hãy làm theo Hình 2.
Bảo mật và quyền riêng tư
Không ghi lại Thông tin nhận dạng cá nhân (PII). Thông tin này bao gồm các chi tiết như:
- Địa chỉ email
- Số điện thoại
- Tên
Tương tự, một số thông tin chi tiết nhất định được coi là nhạy cảm ngay cả khi không thể nhận dạng cá nhân một cách rõ ràng.
Ví dụ: mặc dù thông tin múi giờ không được coi là thông tin nhận dạng cá nhân, nhưng thông tin này cho biết vị trí ước chừng của người dùng.
Chính sách nhật ký và thông tin chi tiết được chấp nhận phải được xử lý trong quá trình xem xét bảo mật và quyền riêng tư trước khi phát hành.
Nhật ký thiết bị
Quyền truy cập vào tất cả nhật ký thiết bị, bao gồm cả việc sử dụng android.permission.READ_LOGS
bị hạn chế:
- Nếu một ứng dụng chạy ở chế độ nền yêu cầu quyền truy cập vào tất cả nhật ký thiết bị, thì yêu cầu đó sẽ tự động bị từ chối, trừ phi ứng dụng:
- Chia sẻ UID của hệ thống.
- Sử dụng quy trình hệ thống gốc (
UID
<APP_UID
). - Sử dụng
DropBoxManager
- Chỉ truy cập vào vùng đệm nhật ký sự kiện.
- Sử dụng API
EventLog
. - Sử dụng kiểm thử đo lường.
- Nếu một ứng dụng trên nền trước có
READ_LOGS
yêu cầu quyền truy cập vào nhật ký thiết bị, thì hệ thống sẽ nhắc người dùng phê duyệt hoặc từ chối yêu cầu truy cập đó.