Logcat là một công cụ dòng lệnh giúp kết xuất nhật ký thông báo của hệ thống, bao gồm các thông báo mà bạn đã viết từ ứng dụng của mình bằng lớp Log
.
Trang này giới thiệu về công cụ dòng lệnh logcat
, nhưng bạn cũng có thể xem các thông điệp nhật ký từ cửa sổ Logcat trong Android Studio. Để biết
thông tin về cách xem và lọc nhật ký trong Android Studio,
hãy xem phần Viết và xem nhật ký bằng
Logcat.
Tổng quan về hệ thống ghi nhật ký
Hệ thống ghi nhật ký Android là một tập hợp các vùng đệm tròn có cấu trúc được duy trì bởi quy trình
hệ thống logd
. Tập hợp các vùng đệm có sẵn đã được hệ thống cố định và xác định. Những vùng đệm phù hợp nhất là:
main
: Lưu trữ hầu hết nhật ký ứng dụng.system
: Lưu trữ thông báo bắt nguồn từ hệ điều hành Android.-
crash
: Lưu trữ nhật ký sự cố. Mỗi mục nhập nhật ký có một mức độ ưu tiên, một thẻ giúp xác định nguồn gốc của nhật ký và thông điệp nhật ký thực tế.
Giao diện C/C++ chính của hệ thống ghi nhật ký là thư viện chia sẻ liblog
và tiêu đề <android/log.h>
của thư viện.
Sau cùng, tất cả các phương thức ghi nhật ký theo ngôn ngữ (bao gồm cả android.util.Log
) sẽ gọi hàm __android_log_write
. Theo mặc định, lệnh này sẽ gọi hàm __android_log_logd_logger
. Hàm này gửi mục nhập nhật ký đến logd
bằng một socket. Kể từ API cấp 30, bạn có thể thay đổi hàm ghi nhật ký bằng cách gọi __android_set_log_writer
. Bạn có thể xem thêm thông tin trong tài liệu về NDK.
Nhật ký hiển thị bởi adb logcat
sẽ trải qua 4 cấp độ lọc:
- Lọc theo thời gian biên dịch
- Tuỳ thuộc vào chế độ cài đặt biên dịch, một số nhật ký có thể bị
xoá hoàn toàn khỏi tệp nhị phân. Ví dụ: bạn có thể định cấu hình Proguard để xoá các lệnh gọi đến
Log.d
từ mã Java. - Lọc theo thuộc tính hệ thống
liblog
truy vấn một tập hợp các thuộc tính hệ thống để xác định mức độ nghiêm trọng tối thiểu sẽ được gửi tớilogd
. Nếu nhật ký của bạn có thẻMyApp
, các thuộc tính sau sẽ được kiểm tra và dự kiến chứa chữ cái đầu tiên của mức độ nghiêm trọng tối thiểu (V
,D
,I
,W
,E
hoặcS
để vô hiệu hoá toàn bộ nhật ký):log.tag.MyApp
persist.log.tag.MyApp
log.tag
persist.log.tag
- Lọc theo ứng dụng
- Nếu không có thuộc tính nào được thiết lập,
liblog
sẽ sử dụng mức độ ưu tiên tối thiểu do__android_log_set_minimum_priority
thiết lập. Chế độ cài đặt mặc định làINFO
. - Lọc theo hiển thị
adb logcat
hỗ trợ các bộ lọc khác có thể làm giảm số lượng nhật ký xuất hiện tronglogd
. Hãy xem phần lọc đầu ra nhật ký để biết thêm chi tiết.
Cú pháp dòng lệnh
Cú pháp thường dùng để chạy logcat
thông qua shell adb
là:
[adb] shell logcat [<option>] ... [<filter-spec>] ...
Ngoài ra, còn có cú pháp viết tắt của adb logcat
, nhưng cú pháp đó chỉ mở rộng thành adb shell logcat
.
Tuỳ chọn
logcat
có rất nhiều tuỳ chọn. Các tuỳ chọn có sẵn tuỳ theo phiên bản hệ điều hành của thiết bị bạn đang sử dụng. Để xem thông tin trợ giúp về logcat
dành cho thiết bị bạn đang dùng, hãy thực hiện:
adb logcat --help
Xin lưu ý rằng vì logcat
là một công cụ dành cho nhà phát triển hệ điều hành cũng như nhà phát triển ứng dụng (các nhà phát triển ứng dụng dùng Android Studio) nên nhiều tuỳ chọn trong số này chỉ sử dụng được dưới dạng root
.
Lọc đầu ra nhật ký
Thẻ của thông điệp nhật ký là một chuỗi ngắn cho biết thành phần hệ thống nơi bắt nguồn thông điệp. Ví dụ: "View" cho hệ thống xem.
Mức độ ưu tiên là một trong những giá trị ký tự sau, được sắp xếp theo thứ tự ưu tiên từ thấp nhất đến cao nhất:
V
: Chi tiết (mức độ ưu tiên thấp nhất)D
: Gỡ lỗiI
: Thông tinW
: Cảnh báoE
: LỗiF
: Nghiêm trọngS
: Ẩn (mức độ ưu tiên cao nhất, khi đó không có nội dung nào được in lên màn hình)
Để lấy danh sách các thẻ có mức độ ưu tiên được dùng trong hệ thống, hãy chạy
logcat
và quan sát 2 cột đầu tiên của các thông điệp được cung cấp dưới dạng
<priority>/<tag>
.
Sau đây là ví dụ về kết quả đầu ra ngắn gọn của logcat
thu được bằng lệnh logcat -v brief output
. Kết quả đầu ra này cho biết thông điệp liên quan đến mức độ ưu tiên "I" và thẻ "ActivityManager":
I/ActivityManager( 585): Starting activity: Intent { action=android.intent.action...}
Để giảm đầu ra nhật ký xuống mức có thể quản lý, hãy hạn chế đầu ra nhật ký bằng cách sử dụng biểu thức lọc. Biểu thức lọc giúp bạn cho hệ thống biết các kiểu kết hợp mức độ ưu tiên thẻ mà mình quan tâm. Hệ thống sẽ chặn các thông điệp khác đối với các thẻ được chỉ định.
Biểu thức lọc tuân theo định dạng tag:priority ...
, trong đó tag
là thẻ mà bạn quan tâm và priority
chỉ mức độ ưu tiên tối thiểu để báo cáo cho thẻ đó. Thông điệp cho thẻ đó ở mức ưu tiên hoặc cao hơn mức ưu tiên được chỉ định sẽ được ghi vào nhật ký. Cung cấp số lượng tiêu chí tag:priority
bất kỳ trong một
biểu thức lọc. Chuỗi tiêu chí cần được phân tách bằng khoảng trắng.
Sau đây là ví dụ về một biểu thức lọc chặn toàn bộ thông điệp nhật ký ngoại trừ những thông điệp chứa thẻ "ActivityManager" có mức độ ưu tiên "Thông tin" trở lên và những thông điệp chứa thẻ "MyApp" có mức độ ưu tiên "Gỡ lỗi" trở lên:
adb logcat ActivityManager:I MyApp:D *:S
Phần tử cuối cùng trong biểu thức trên, *:S
, đặt mức độ ưu tiên cho toàn bộ thẻ thành "ẩn" để đảm bảo chỉ các thông điệp nhật ký chứa thẻ "ActivityManager" và "MyApp" mới được xuất hiện. Việc sử dụng *:S
đảm bảo đầu ra nhật ký chỉ được phép sử dụng các bộ lọc mà bạn chỉ định rõ ràng. *:S
cho phép các bộ lọc của bạn hoạt động như danh sách kiểm tra kết quả đầu ra nhật ký.
Lưu ý: Với một số shell, ký tự "*
" là một định danh được dành riêng. Nếu bạn đang dùng một shell như vậy, hãy đưa biểu thức lọc vào trong dấu ngoặc kép: adb logcat
"ActivityManager:I MyApp:D *:S"
Biểu thức lọc sau đây hiển thị tất cả thông điệp nhật ký có mức độ ưu tiên "cảnh báo" trở lên tại toàn bộ thẻ:
adb logcat *:W
Nếu đang chạy logcat
trên máy tính phát triển thay vì chạy trên
shell adb
từ xa, bạn vẫn có thể đặt biểu thức lọc mặc định bằng cách xuất giá trị cho
biến môi trường ANDROID_LOG_TAGS
:
export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"
Bộ lọc ANDROID_LOG_TAGS
không được xuất sang thực thể trình mô phỏng/thiết bị nếu bạn đang chạy logcat
trên một shell từ xa hoặc đang sử dụng adb shell
logcat
.
Kiểm soát định dạng đầu ra của nhật ký
Thông điệp nhật ký còn chứa một số trường siêu dữ liệu ngoài thẻ và mức độ ưu tiên. Bạn có thể chỉnh sửa định dạng đầu ra của các thông điệp để những thông điệp này hiển thị một trường siêu dữ liệu cụ thể. Để thực hiện điều đó, hãy sử dụng tuỳ chọn -v
và chỉ định một trong các định dạng đầu ra được hỗ trợ sau:
brief
: Hiển thị mức độ ưu tiên, thẻ và PID của quy trình tạo thông điệp.long
: Hiển thị tất cả trường siêu dữ liệu và thông điệp riêng với các dòng trống.process
: Chỉ hiển thị PID.raw
: Hiển thị thông điệp nhật ký thô không có các trường siêu dữ liệu khác.tag
: Chỉ hiển thị mức độ ưu tiên và thẻ.thread:
: Một định dạng cũ hiển thị mức độ ưu tiên, PID và TID của luồng tạo thông điệp.threadtime
(mặc định): Hiển thị ngày, thời gian gọi, mức độ ưu tiên, thẻ, PID và TID của luồng tạo thông điệp.time
: Hiển thị ngày, thời gian gọi, mức độ ưu tiên, thẻ và PID của quy trình tạo thông điệp.
Khi khởi chạy logcat
, hãy chỉ định định dạng đầu ra mà bạn muốn bằng cách sử dụng tuỳ chọn -v
:
[adb] logcat [-v <format>]
Dưới đây là ví dụ trình bày cách tạo thông điệp ở định dạng đầu ra thread
:
adb logcat -v thread
Bạn chỉ có thể chỉ định một định dạng đầu ra với tuỳ chọn -v
. Tuy nhiên, bạn có thể chỉ định số lượng tuỳ chọn sửa đổi theo ý muốn, miễn là các tuỳ chọn sửa đổi này phù hợp. logcat
bỏ qua các tuỳ chọn sửa đổi không phù hợp.
Tuỳ chọn sửa đổi định dạng
Tuỳ chọn sửa đổi định dạng sẽ thay đổi đầu ra của logcat
. Để chỉ định một tuỳ chọn sửa đổi định dạng, hãy sử dụng tuỳ chọn -v
như sau:
adb logcat -b all -v color -d
Mỗi thông điệp nhật ký trên Android đều có một thẻ và mức độ ưu tiên gắn với thẻ đó. Bạn có thể kết hợp tuỳ chọn sửa đổi định dạng với toàn bộ tuỳ chọn định dạng sau:
brief
long
process
raw
tag
thread
threadtime
time
Để định dạng các tuỳ chọn sửa đổi dưới đây, hãy nhập logcat -v --help
tại
dòng lệnh:
color
: Hiển thị mỗi mức độ ưu tiên bằng một màu riêng.descriptive
: Hiển thị phần mô tả sự kiện vùng đệm nhật ký. Tuỳ chọn sửa đổi này chỉ ảnh hưởng đến các thông điệp trong vùng đệm nhật ký sự kiện và không ảnh hưởng đến các vùng đệm phi nhị phân khác. Các phần mô tả sự kiện được lấy từ cơ sở dữ liệu thẻ-nhật ký-sự kiện (event-log-tags).epoch
: Hiển thị thời gian theo đơn vị giây kể từ ngày 1 tháng 1 năm 1970.monotonic
: Hiển thị thời gian tính bằng giây CPU tính từ lần khởi động gần đây nhất.printable
: Đảm bảo toàn bộ nội dung ghi nhật ký nhị phân đều được loại bỏ.uid
: Nếu biện pháp kiểm soát quyền truy cập cho phép, hãy hiện UID hoặc mã Android của quá trình ghi nhật ký.usec
: Hiện thời gian với độ chính xác tính bằng micrô giây.UTC
: Hiện thời gian theo giờ UTC.year
: Thêm năm vào thời gian hiển thị.zone
: Thêm múi giờ địa phương vào thời gian hiển thị.
Xem vùng đệm nhật ký thay thế
Hệ thống ghi nhật ký Android lưu trữ nhiều vùng đệm tròn cho thông điệp nhật ký. Tuy nhiên, không phải
tất cả thông điệp nhật ký đều được gửi tới vùng đệm tròn mặc định. Để xem các thông điệp nhật ký khác, bạn có thể
chạy lệnh logcat
với tuỳ chọn -b
để yêu cầu xem một
vùng đệm tròn thay thế. Bạn có thể xem mọi vùng đệm thay thế sau đây:
radio
: Xem vùng đệm chứa thông điệp liên quan đến đài/điện thoại.events
: Xem thông điệp vùng đệm sự kiện của hệ thống nhị phân được diễn giải.main
: Xem vùng đệm nhật ký chính (mặc định) không chứa thông điệp nhật ký sự cố và hệ thống.system
: Xem vùng đệm nhật ký hệ thống (mặc định).crash
: Xem vùng đệm nhật ký sự cố (mặc định).all
: Xem tất cả vùng đệm.default
: Báo cáo vùng đệmmain
,system
vàcrash
.
Cách sử dụng của tuỳ chọn -b
là:
[adb] logcat [-b <buffer>]
Dưới đây là ví dụ về cách xem vùng đệm nhật ký chứa thông điệp của đài và điện thoại:
adb logcat -b radio
Để chỉ định các cờ -b
cho tất cả vùng đệm mà bạn muốn in,
hãy nhập dòng sau:
logcat -b main -b radio -b events
Chỉ định một cờ -b
bằng danh sách các vùng đệm được phân tách bằng dấu phẩy,
ví dụ:
logcat -b main,radio,events
Ghi nhật ký trong mã
Lớp Log
cho phép bạn tạo
các mục nhập nhật ký trong mã để hiện ở công cụ logcat
. Các phương pháp ghi nhật ký phổ biến bao gồm:
Log.v(String, String)
(chi tiết)Log.d(String, String)
(gỡ lỗi)Log.i(String, String)
(thông tin)Log.w(String, String)
(nhắc nhở)Log.e(String, String)
(lỗi)
Ví dụ: sử dụng lệnh gọi sau:
Kotlin
Log.i("MyActivity", "MyClass.getView() — get item number $position")
Java
Log.i("MyActivity", "MyClass.getView() — get item number " + position);
logcat
sẽ xuất nội dung tương tự như sau:
I/MyActivity( 1557): MyClass.getView() — get item number 1