Công cụ dòng lệnh logcat

Logcat là một công cụ dòng lệnh tạo nhật ký thông điệp hệ thống, bao gồm dấu vết ngăn xếp khi thiết bị tạo ra lỗi và thông điệp mà bạn đã viết từ ứng dụng của mình với lớp Log.

Trang này giới thiệu về công cụ logcat dòng lệnh, nhưng bạn cũng có thể xem 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ý từ Android Studio, hãy xem phần Viết và xem nhật ký với 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 khắc phục và xác định. Các tệp phù hợp nhất là: main, có chức năng lưu trữ hầu hết nhật ký ứng dụng, system, dùng để lưu trữ tin nhắn bắt nguồn từ hệ điều hành Android và crash, nơi 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 trong VERBOSE, DEBUG, INFO, WARNING, ERROR hoặc FATAL), 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 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. Tất cả các phương thức ghi nhật ký theo ngôn ngữ 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 ổ cắm. Bắt đầu từ API cấp 30, bạn có thể thay đổi chức năng ghi nhật ký bằng cách gọi __android_set_log_writer. Bạn có thể tìm thêm thông tin trong tài liệu về NDK.

Nhật ký do adb logcat hiển thị sẽ trải qua 4 cấp độ lọc:

  1. Lọc 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.
  2. Lọc 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ới logd. Nếu nhật ký của bạn có thẻ MyApp, thì các thuộc tính sau sẽ được kiểm tra và dự kiến sẽ 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ặc S để vô hiệu hoá tất cả nhật ký:
    • log.tag.MyApp
    • persist.log.tag.MyApp
    • log.tag
    • persist.log.tag
  3. Lọc ứng dụng: Nếu không có thuộc tính nào được đặt, liblog sẽ sử dụng mức độ ưu tiên tối thiểu do __android_log_set_minimum_priority đặt. Chế độ cài đặt mặc định là INFO.
  4. Lọc 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ý hiển thị từ logd. Vui lòng xem chi tiết bên dưới.

Cú pháp dòng lệnh

Để chạy logcat thông qua shell adb, cách sử dụng chung là:

[adb] logcat [<option>] ... [<filter-spec>] ...

Bạn có thể chạy logcat dưới dạng một lệnh adb hoặc trực tiếp trong lời nhắc shell của trình mô phỏng hoặc thiết bị mà bạn đã kết nối. Để xem đầu ra của nhật ký bằng adb, hãy chuyển đến thư mục SDK của platform-tools/ và thực thi:

adb logcat

Để được trợ giúp trực tuyến về logcat, hãy khởi động một thiết bị rồi thực thi:

adb logcat --help

Bạn có thể tạo kết nối shell với một thiết bị và thực thi:

$ adb shell
# logcat

Các tuỳ chọn

Bảng sau mô tả các tuỳ chọn dòng lệnh của logcat.

Tuỳ chọn Mô tả
-b <buffer> Tải vùng đệm nhật ký thay thế để xem, chẳng hạn như events hoặc radio. Nhóm vùng đệm main, systemcrash được sử dụng theo mặc định. Hãy xem phần Xem vùng đệm nhật ký thay thế.
-c, --clear Xoá (đẩy dữ liệu) vùng đệm đã chọn và thoát. Vùng đệm mặc định là main, systemcrash. Để xoá tất cả các vùng đệm, hãy sử dụng -b all -c.
-e <expr>, --regex=<expr> Chỉ những dòng in mà thông điệp nhật ký khớp với <expr>, trong đó <expr> là một biểu thức chính quy.
-m <count>, --max-count=<count> Thoát sau khi in số dòng của <count>. Giá trị này dự kiến sẽ được ghép nối với --regex, nhưng sẽ hoạt động riêng.
--print Đã ghép nối với --regex--max-count để cho phép nội dung bỏ qua bộ lọc biểu thức chính quy nhưng vẫn dừng ở số lượng kết quả phù hợp.
-d Ghi nhật ký vào màn hình và thoát.
-f <filename> Ghi kết quả của thông điệp nhật ký vào <filename>. Giá trị mặc định là stdout.
-g, --buffer-size In kích thước của vùng đệm nhật ký được chỉ định và thoát.
-n <count> Đặt số lượng nhật ký xoay vòng tối đa thành <count>. Giá trị mặc định là 4. Yêu cầu tuỳ chọn -r.
-r <kbytes> Xoay tệp nhật ký mỗi <kbytes> của đầu ra. Giá trị mặc định là 16. Yêu cầu tuỳ chọn -f.
-s Tương đương với biểu thức lọc '*:S', dùng để đặt mức độ ưu tiên cho tất cả các thẻ thành ẩn và dùng để đứng trước danh sách các biểu thức lọc có thêm nội dung. Để tìm hiểu thêm, hãy chuyển đến phần về cách lọc đầu ra nhật ký.
-v <format> Đặt định dạng đầu ra cho thông điệp nhật ký. Vị trí mặc định là định dạng threadtime. Để biết danh sách các định dạng được hỗ trợ, hãy chuyển đến phần về Kiểm soát định dạng đầu ra của nhật ký.
-D, --dividers In các bộ chia giữa mỗi vùng đệm nhật ký.
-c Xoá toàn bộ nhật ký và thoát.
-t <count> Chỉ in số dòng gần đây nhất. Tuỳ chọn này bao gồm chức năng của -d.
-t '<time>' In các dòng gần đây nhất kể từ thời gian đã chỉ định. Tuỳ chọn này bao gồm chức năng của -d. Hãy xem tuỳ chọn -P để biết thông tin về cách trích dẫn thông số có dấu cách được nhúng.

adb logcat -t '01-26 20:52:41.820'
-T <count> In số dòng gần đây nhất kể từ thời gian được chỉ định. Tuỳ chọn này không bao gồm chức năng của -d
-T '<time>' In các dòng gần đây nhất kể từ thời gian đã chỉ định. Tuỳ chọn này không bao gồm chức năng của -d. Hãy xem tuỳ chọn -P để biết thông tin về cách trích dẫn thông số có dấu cách được nhúng.

adb logcat -t '01-26 20:52:41.820'
-L, --last Hãy kết xuất nhật ký trước khi khởi động lại lần cuối.
-B, --binary Xuất nhật ký ở dạng tệp nhị phân.
-S, --statistics Đưa số liệu thống kê vào trong đầu ra để giúp bạn xác định và nhắm đến những người gửi nội dung không liên quan đến nhật ký.
-G <size> Đặt kích thước của vùng đệm vòng nhật ký. Có thể thêm K hoặc M ở cuối để cho biết số kilobyte hoặc megabyte.
-p, --prune In (đọc) danh sách cho phép và danh sách từ chối đồng thời không nhận đối số nào như sau:

adb logcat -p
-P '<list> ...'
--prune '<list> ...' -P '<allowlist_and_denylist>'
Viết (đặt) danh sách cho phép và danh sách từ chối để điều chỉnh nội dung ghi nhật ký cho một mục đích cụ thể. Bạn cung cấp nội dung hỗn hợp gồm các mục danh sách được phép và bị từ chối, trong đó <allowlist> hoặc <denylist> có thể là UID, UID/PID hoặc /PID. Với hướng dẫn từ số liệu thống kê logcat (logcat -S), người dùng có thể xem xét việc điều chỉnh danh sách cho phép và danh sách từ chối đối với các mục đích như:
  • Đặt thời gian tồn tại dài nhất cho nội dung ghi nhật ký cụ thể thông qua các lựa chọn UID.
  • Không cho ai đó (UID) hoặc nội dung nào đó (PID) dùng các tài nguyên này để giúp tăng khoảng thời gian ghi nhật ký nhằm giúp bạn nắm rõ hơn các vấn đề mà bạn đang chẩn đoán.

Theo mặc định, hệ thống ghi nhật ký sẽ tự động ngăn chặn mục vi phạm nghiêm trọng nhất trong số liệu thống kê nhật ký để tạo không gian cho thông điệp nhật ký mới. Khi đã thử nghiệm được các phương pháp phỏng đoán, hệ thống sẽ cắt bớt các mục cũ nhất để tạo không gian cho các thông điệp mới.

Việc thêm một danh sách cho phép sẽ giúp bảo vệ Số nhận dạng Android (AID) của bạn, nghĩa là ngăn không để AID và GID của các quy trình bị công bố là mục vi phạm, đồng thời thêm danh sách từ chối để giúp giải phóng dung lượng trước khi những mục vi phạm nghiêm trọng nhất được xem xét. Bạn có thể chọn mức độ chủ động của việc lược bớt và có thể tắt tính năng lược bớt để chỉ xóa nội dung khỏi các mục cũ nhất trong mỗi vùng đệm nhật ký.

Trích dẫn

adb logcat không giữ nguyên dấu ngoặc kép nên cú pháp để xác định danh sách cho phép và danh sách từ chối sẽ như sau:


$ adb logcat -P '"<allowlist_and_denylist>"'

or

adb shell
$ logcat -P '<allowlist_and_denylist>'

Ví dụ sau đây chỉ định danh sách cho phép có PID 32676 và UID 675, đồng thời chỉ định danh sách từ chối có PID 32677 và UID 897. PID 32677 trong danh sách từ chối sẽ có trọng số để được lược bớt nhanh hơn.


adb logcat -P '"/32676 675 ~/32677 897"'

Các biến thể khác của danh sách cho phép và danh sách từ chối mà bạn có thể sử dụng như sau:


~! worst uid denylist
~1000/! worst pid in system (1000)
--pid=<pid> ... Chỉ in nhật ký từ PID được cấp.
--wrap Ngủ trong 2 giờ hoặc khi vùng đệm sắp gói, tuỳ theo điều kiện nào đến trước. Cải thiện hiệu quả của tính năng kiểm tra vòng bằng cách cung cấp phương thức đánh thức chuẩn bị gói.

Lọc kết quả 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ụ: "Xem" cho hệ thống xem).
  • Mức độ ưu tiên là một trong những giá trị ký tự sau đây, đượ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ỗi
    • I: Thông tin
    • W: Cảnh báo
    • E: Lỗi
    • F: Nghiêm trọng
    • S: Ẩn (mức độ ưu tiên cao nhất, khi đó không có nội dung nào được in)

Bạn có thể lấy danh sách các thẻ dùng trong hệ thống, có các mức độ ưu tiên, bằng cách chạy logcat và quan sát 2 cột đầu tiên của mỗi thông điệp, được cung cấp dưới dạng <priority>/<tag>.

Sau đây là ví dụ về đầu ra ngắn gọn của logcat thu được bằng lệnh logcat -v brief output. Đầu ra này cho biết rằng 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ý được, bạn có thể 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 cho phép bạn cho hệ thống biết các kiểu kết hợp mức độ ưu tiên thẻ mà bạn 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 ... này, trong đó tag cho biết thẻ quan tâm và priority cho biết mức độ ưu tiên tối thiểu để báo cáo cho thẻ đó. Thông báo cho thẻ đó ở mức ưu tiên hoặc cao hơn mức ưu tiên được chỉ định được ghi vào nhật ký. Bạn có thể cung cấp số lượng quy cách tag:priority bất kỳ trong một biểu thức lọc. Chuỗi quy cách đượ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 mọi thông điệp nhật ký ngoại trừ những thông điệp có thẻ "ActivityManager", có mức độ ưu tiên "Thông tin trở lên và tất cả thông điệp nhật ký có 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 tất cả các thẻ thành "ẩn", để đảm bảo chỉ những thông điệp nhật ký có thẻ "ActivityManager" và "MyApp" mới hiển thị. Sử dụng *:S là cách hiệu quả để đảm bảo rằng đầu ra nhật ký sẽ chỉ bị hạn chế đối với các bộ lọc mà bạn đã chỉ định rõ ràng. Chế độ này cho phép các bộ lọc của bạn đóng vai trò như một danh sách cho phép cho đầu ra nhật ký.

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 trên tất cả các thẻ:

adb logcat *:W

Nếu đang chạy logcat từ máy tính phát triển (thay vì chạy trên shell adb từ xa), bạn cũng 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"

Xin lưu ý rằng bộ lọc ANDROID_LOG_TAGS không được xuất sang phiên bản trình mô phỏng/thiết bị, nếu bạn đang chạy logcat từ 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ể sửa đổi định dạng đầu ra của các thông điệp để chúng xuất hiện trong một trường siêu dữ liệu cụ thể. Để làm việc này, bạn hãy dùng tuỳ chọn -v và chỉ định một trong các định dạng đầu ra được hỗ trợ nêu bên dưới.

  • 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ả các trường siêu dữ liệu và thông điệp riêng biệt 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ũ thể hiện 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 động logcat, bạn có thể chỉ định định dạng đầu ra mà mình muốn bằng cách sử dụng tuỳ chọn -v:

[adb] logcat [-v <format>]

Dưới đây là ví dụ cho thấy cách tạo thông điệp ở định dạng đầu ra thread:

adb logcat -v thread

Xin lưu ý rằng bạn chỉ có thể chỉ định một định dạng đầu ra bằng tuỳ chọn -v, nhưng bạn có thể chỉ định tuỳ chọn sửa đổi có ý nghĩa với số lượng tuỳ ý. Logcat bỏ qua các tùy chọn sửa đổi không phù hợp.

Tùy chọn sửa đổi định dạng

Các tuỳ chọn sửa đổi định dạng sẽ thay đổi đầu ra logcat theo bất kỳ cách kết hợp nào của một hoặc nhiều tuỳ chọn sửa đổi sau đây. Để 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ẻmức độ ưu tiên gắn với thẻ đó. Bạn có thể kết hợp tùy chọn sửa đổi định dạng với bất kỳ tùy chọn định dạng nào sau đây: brief, long, process, raw, tag, thread, threadtimetime.

Bạn có thể xem thông tin chi tiết về tuỳ chọn sửa đổi định dạng bằng cách nhập logcat -v --help vào dòng lệnh.

  • color: Hiển thị mỗi mức độ ưu tiên bằng một màu khác nhau.
  • 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.
  • epoch: Thời gian hiển thị tính bằng giây kể từ ngày 1 tháng 1 năm 1970.
  • monotonic: Thời gian hiển thị tính bằng giây CPU tính từ lần khởi động gần đây nhất.
  • printable: Đảm bảo rằng mọi 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 thị UID hoặc mã Android của quá trình đã ghi nhật ký.
  • usec: Hiển thị thời gian với độ chính xác đến từng micrô giây.
  • UTC: Hiển thị 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ý và không phải toàn bộ 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 bất kỳ vùng đệm thay thế nào 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ả các vùng đệm.
  • default: Báo cáo vùng đệm main, systemcrash.

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 qua đài và điện thoại:

adb logcat -b radio

Bạn cũng có thể chỉ định nhiều cờ -b cho tất cả các vùng đệm mà bạn muốn in như sau:

logcat -b main -b radio -b events

Bạn có thể chỉ định một cờ -b bằng một 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ý từ mã

Lớp Log cho phép bạn tạo các mục nhập nhật ký trong mã để hiển thị trong công cụ logcat. Các phương pháp ghi nhật ký phổ biến bao gồm:

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 xuất ra những nội dung như:

I/MyActivity( 1557): MyClass.getView() — get item number 1