Logcat เป็นเครื่องมือพื้นฐานที่สำคัญต่อการทำงานของนักพัฒนาแอนดรอยด์ที่มีมานานตั้งแต่อดีตกาล หรือเรียกได้ว่าก่อนที่จะมี Android Studio ด้วยซ้ำ
เผื่อคนที่เกิดไม่ทัน : ก่อน Android Studio จะเกิดขึ้นมา นักพัฒนาในยุคนั้นใช้ Eclipse กันน่ะ
Logcat เป็นหนึ่งในเครื่องมือที่อยู่ใน adb
(ที่อยู่ใน Platform Tools ของ Android SDK) ที่จะช่วยให้นักพัฒนาสามารถ Dump Log ที่อยู่ในอุปกรณ์แอนดรอยด์ออกมาดูได้
โดยทีมพัฒนา Android Studio ก็ได้ทำแถบเครื่องมือสำหรับ Logcat ไว้ใน Android Studio ด้วย เพื่อให้นักพัฒนาสามารถใช้งานได้ง่าย และกลายเป็นเครื่องมือที่เราใช้งานกันมาจนทุกวันนี้นั่นเอง
และนับจาก Android Studio Dolphin เป็นต้นมา ทีมพัฒนาก็ได้ปรับปรุงหน้าต่าง Logcat ใหม่ทั้งหมดจนกลายออกมาเป็น Logcat v2 ที่มีรูปแบบการใช้งานแตกต่างไปจากเดิมพอสมควร
ซึ่งนั่นคือที่มาของบทความนี้ที่จะมาเล่าให้ฟังกันว่า Logcat v2 มีอะไรให้ใช้งานกันบ้าง
แต่ถ้ายังไม่เคยทำความรู้จักกับ Logcat มาก่อน ขอแนะนำให้อ่านบทความ Logcat พื้นฐานสำคัญที่ Android Developer ต้องรู้จัก ก่อนที่จะอ่านต่อนะ
เกี่ยวกับ Logcat v2
- ทดลองใช้งานบน Android Studio Dolphin ได้
- บังคับให้ใช้งานใน Android Studio Electric Eel เป็นต้นไป
- เน้นไปที่ความยืดหยุ่นในการแสดง Log ให้มากกว่าเดิม
เจ้าของบล็อกขออธิบายการใช้งาน Logcat v2 โดยแบ่งเป็น 2 ส่วนด้วยกันคือ "ความสามารถ" หลักกับ "ความสามารถอื่น ๆ"
ความสามารถหลักใน Logcat v2
จะประกอบไปด้วย 3 ส่วนด้วยกัน
- (A) ช่องเลือกอุปกรณ์แอนดรอยด์ที่ต้องการดู Logcat โดยอุปกรณ์แอนดรอยด์จะต้องเปิดใช้งาน USB/Wireless Debugging และเชื่อมต่อกับคอมพิวเตอร์ผ่าน ADB
- (B) ช่อง Query เพื่อค้นหา Log ที่ต้องการ ซึ่งจะขออธิบายในหัวข้อ "วิธีการใช้งาน Query ใน Logcat" แทน
- (C) หน้าต่างแสดง Log ของอุปกรณ์ที่เลือก และจะแสดง Log บางตัวตามที่กำหนดไว้ในช่อง Query ด้วย
ความสามารถอื่น ๆ ใน Logcat v2
ความสามารถเหล่านี้เป็นส่วนเสริมที่จะช่วยให้นักพัฒนาใช้งาน Logcat เพื่อทำอย่างอื่นได้ง่ายขึ้น
- (D) เพิ่ม Tab ของ Logcat ทำให้นักพัฒนาสามารถเปิด Tab ของ Logcat ได้หลาย ๆ ตัวและสลับไปมาระหว่างแต่ละ Tab ได้
- (E) ลบ Log ของเก่าที่แสดงอยู่ในหน้าต่าง Logcat ทิ้งทั้งหมด
- (F) เลื่อนหน้าต่างแสดง Log ลงข้างล่างสุดเสมอเมื่อมี Log เพิ่มเข้ามาใหม่
- (G) ให้ข้อความใน Log ตัดขึ้นบรรทัดใหม่ เมื่อข้อความยาวเกินความกว้างของหน้าต่าง Logcat
- (H) ตั้งค่ารูปแบบการแสดงผลของ Logcat โดยจะอธิบายในหัวข้อ "การตั้งค่ารูปแบบการแสดงผลของ Log"
- (I) บันทึกภาพของอุปกรณ์แอนดรอยด์ที่เลือกอยู่ โดยจะอธิบายในหัวข้อ "การบันทึกภาพจากอุปกรณ์แอนดรอยด์"
- (J) บันทึกวีดีโอของอุปกรณ์แอนดรอยด์ที่เลือกอยู่ โดยจะอธิบายในหัวข้อ "การบันทึกวีดีโอจากอุปกรณ์แอนดรอยด์"
การใช้งาน Query ใน Logcat v2
ในการค้นหา Log ใด ๆ ผ่านช่อง Query ใน Logcat จะพิมพ์ค้นหาด้วย Keyword โดยตรง หรือจะพิมพ์เป็น Syntax ตามที่ Logcat กำหนดไว้ก็ได้
ยกตัวอย่างเช่น Log ทั้งหมดที่มีใน Logcat เป็นแบบนี้
Level | Message
---------------
D Compat change id reported: 171979766; UID 10258; state: DISABLED
V ANGLE Developer option for 'com.akexorcist.devfest2022' set to: 'default'
V ANGLE GameManagerService for com.akexorcist.devfest2022: false
V Updatable production driver is not supported on the device.
D No Network Security Config specified, using platform default
D No Network Security Config specified, using platform default
D Compat change id reported: 210923482; UID 10258; state: DISABLED
D Compat change id reported: 37756858; UID 10258; state: ENABLED
W Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (unsupported, reflection, allowed)
V Sleeping For Less
D Sleeping For Less
I QUALCOMM build : 85da404, I46ff5fc46f
Build Date : 11/30/20
OpenGL ES Shader Compiler Version: EV031.31.04.01
Local Branch : promo490_3_Google
Remote Branch :
Remote Branch :
Reconstruct Branch :
I Build Config : S P 10.0.4 AArch64
I Driver Path : /vendor/lib64/egl/libGLESv2_adreno.so
I PFP: 0x016ee190, ME: 0x00000000
W <ReadGpuID_from_sysfs:197>: Failed to open /sys/class/kgsl/kgsl-3d0/gpu_model
W <ReadGpuID:221>: Failed to read chip ID from gpu_model. Fallback to use the GSL path
W Expecting binder but got null!
W A resource failed to call close.
เมื่อใส่ Keyword เป็นคำว่า Sleeping For
เข้าไปในช่อง Query ก็จะเหลือ Log แค่นี้แทน
Level | Message
---------------
V Sleeping For Less
D Sleeping For Less
แต่ในกรณีที่ต้องการใช้ Syntax เพื่อช่วยค้นหาด้วย ใน Logcat v2 ก็จะมี Key ที่สำคัญต่อการ Query ด้วย Syntax ดังนี้
package
เพื่อแสดง Log ของแอปที่มี Package Name ตามที่กำหนดlevel
เพื่อแสดงเฉพาะ Log Level ตามที่กำหนดและ Log Level ที่สูงกว่าtag
เพื่อแสดงเฉพาะ Log ที่มี Tag ที่ตรงกับ Keyword ตามที่กำหนดmessage
เพื่อแสดงเฉพาะ Log ทีมี Message ที่ตรงกับ Keyword ตามที่กำหนดage
เพื่อแสดงเฉพาะ Log ที่มีอายุไม่เกินช่วงเวลาตามที่กำหนด
จริง ๆ มี line
ด้วย แต่ไม่ค่อยจำเป็น จึงขอตัดออกไป
โดย Key แต่ละตัวสามารถผสมกับ Key ตัวเดียวกันหรือตัวอื่นก็ได้ ขึ้นอยู่กับความต้องการของนักพัฒนา เช่น package:mine level:ERROR message:Unexpected message:Incorrect
จากตัวอย่าง Query นี้คือการแสดง Log เฉพาะแอปมาจากโปรเจคบน Android Studio โดยจะแสดงเฉพาะ Error Log ที่ Message มีคำว่า "Unexpexted" หรือ "Incorrect" อยู่ในนั้น
ดังนั้นเพื่อให้ผลลัพธ์จากการ Query ตรงกับที่นักพัฒนาต้องการ มาดูกันว่า Key แต่ละตัวมีหน้าที่และจุดประสงค์อะไรบ้าง
Package (package
)
โดยปกติแล้ว Logcat จะมี Default Query เป็น package:mine
อยู่เสมอ ซึ่งหมายความว่าแสดง Log ทุกตัวที่มาจากแอปของโปรเจคที่เปิดอยู่บน Android Studio จึงทำให้ทุกครั้งเวลาที่นักพัฒนากด Run app ในหน้าต่างของ Logcat ก็จะแสดง Log ที่มาจากแอปนั้นให้โดยทันที
แต่ในกรณีที่ต้องการให้แสดง Log จากแอปตัวอื่นด้วย นักพัฒนาก็สามารถกำหนด Package Name ของแอปนั้น ๆ โดยตรงได้เช่นกัน
package:com.akexorcist.sleepingforless
และระหว่างพิมพ์ Package Name จะมี Suggest สำหรับ Debug App ที่ติดตั้งและทำงานอยู่ในเครื่องให้เลือกได้ทันทีด้วย
Level (level
)
การกำหนด Query ด้วย level
จะเป็นการแสดง Log Level นั้น ๆ หรือสูงกว่า โดย Log Level ที่มีบนแอนดรอยด์จะมีทั้งหมดดังนี้
- Verbose (
VERBOSE
) - Debug (
DEBUG
) - Info (
INFO
) - Warn (
WARN
) - Error (
ERROR
) - Assert (
ASSERT
)
ยกตัวอย่างเช่น level:INFO
ในการกำหนด Log Level จะไม่ได้แสดงเฉพาะ Log ของ Level นั้น ๆ เพียงอย่างเดียว แต่รวมไปถึง Log ที่มี Level ที่สูงกว่าด้วย โดยจะมีลำดับตามนี้
VERBOSE = ASSERT + ERROR + WARN + INFO + DEBUG + VERBOSE
DEBUG = ASSERT + ERROR + WARN + INFO + DEBUG
INFO = ASSERT + ERROR + WARN + INFO
WARN = ASSERT + ERROR + WARN
ERROR = ASSERT + ERROR
ASSERT = ASSERT
ด้วยเงื่อนไขดังกล่าวจึงทำให้การกำหนด level
ใน Query จะนิยมกำหนดแค่เพียงตัวเดียว
Tag (tag
)
โดยปกติแล้วนักพัฒนาสามารถกำหนด Tag และ Message ให้กับ Log ได้ จึงทำให้ใน Query สามารถแสดงเฉพาะ Tag ได้ด้วยการใช้ tag
แต่จะค้นหาคำที่มีเว้นวรรคอยู่ระหว่างคำไม่ได้
ยกตัวอย่างเช่น tag:MainActivity
และในระหว่างพิมพ์ Tag จะมี Suggest สำหรับ Tag ที่มีอยู่ ณ ตอนนั้นให้ด้วย
Message (message
)
ในกรณีที่ต้องการหาคำที่อยู่ใน Message ของ Log โดยตรง สามารถใช้ message
ได้เลย แต่จะค้นหาคำที่มีเว้นวรรคอยู่ระหว่างคำไม่ได้
ยกตัวอย่างเช่น message:GameManagerService
สำหรับการค้นหาด้วยประโยค ก็ให้ใส่เป็น Keyword ลงไปตรง ๆ ไม่ต้องใช้ message
package:mine "ANGLE GameManagerService"
เราสามารถใช้ "
คลุมทั้งประโยคได้ด้วยนะ เห็นมั้ย
Age (age
)
สำหรับการแสดง Log เฉพาะช่วงเวลาที่กำหนดจนถึงล่าสุด นักพัฒนาสามารถใช้ age
พร้อมกับระบุระยะเวลาของ Log ได้เลย เช่น
age:10s
- 10 วินาทีที่แล้วจนถึงปัจจุบันage:5m
- 5 นาทีที่แล้วจนถึงปัจจุบันage:1h
- 1 ชั่วโมงที่แล้วจนถึงปัจจุบัน
การ Exclude Log ด้วยเครื่องหมาย -
กรณีที่ต้องการกรองค่าด้วย Key บางอย่างออก นักพัฒนาสามารถใส่เครื่องหมาย -
ที่ข้างหน้า package
, tag
, หรือ message
ได้
เช่น -message:error
เพื่อแสดง Message ที่ไม่มีคำว่า "error"
การใช้งาน Regular Expression
ถ้าต้องการ Query แบบ Regular Expression ให้ใส่เครื่องหมาย ~
ต่อท้าย package
, tag
, หรือ message
ได้
เช่น message~:^[0-9]{8}$
เพื่อค้นหาเฉพาะ Log ที่มี Message เป็นตัวเลข 8 หลัก
หรือจะใช้ร่วมกับ Exclude Log ก็ได้นะ เช่น -message~:[0-9]{2}
Key ทุกตัวสามารถใช้ร่วมกันได้ บางตัวก็ใช้ซ้ำได้
เพื่อให้การ Query นั้นยืดหยุ่นและได้ผลลัพธ์เป็น Log ที่ต้องการจริง ๆ นักพัฒนาสามารถใช้ Key หลาย ๆ ตัวร่วมกันได้ตามใจชอบ
package:mine message:fatal message:exception age:1m
และการใช้ Key เดียวกันจะส่งผลต่างกัน โดยขึ้นกับว่าเป็น Include หรือ Exclude
message:fatal message:exception
- Log ที่มี Message เป็นคำว่า "fatal" หรือ "exception" ก็ได้ ("fatal" or "exception")message:fatal -message:exception
- Log ที่มี Message เป็นคำว่า "fatal" และไม่มีคำสั่ง "exception" อยู่ในนั้น ("fatal" and not "exception")
นอกจากนี้ Query ยังรองรับ Operation อย่าง &
และ |
อีกด้วย โดยให้ครอบทั้งหมดด้วยเครื่องหมายวงเล็บ
tag:mainactivity (message:user & message:profile & age:5m)
- Log ที่มี Tag เป็น "mainactivity" และมี Message ที่มีทั้งคำว่า "user" กับ "profile" และเป็น Log ที่มีอายุไม่เกิน 5 นาที
Query ด้วยตัวอักษรพิมพ์เล็กหรือพิมพ์ใหญ่ก็ได้
เพราะการ Query จะไม่สนใจว่าเป็น Uppercase หรือ Lowercase ดังนั้นจะพิมพ์แบบไหนก็ถือว่ามีค่าเท่ากัน
กดดู History ของ Query ก่อนหน้าก็ได้
เมื่อกดปุ่มที่อยู่ข้างหน้าสุดของช่อง Query จะเป็นการแสดง History ของ Query ที่ผ่านมาทั้งหมด
และจะเห็นว่าใน History จะมีเลขอยู่ข้างหลัง Query แต่ละตัวด้วย เป็นการบอกว่าในเครื่อง ณ ตอนนั้นมี Log อยู่กี่ตัวที่ตรงกับ Query นั้น ๆ
ดังนั้นถ้าเคย Query อะไรไป แล้วจำไม่ได้ก็สามารถกลับมาย้อนดูผ่าน History ได้นะ
จะบันทึกเก็บไว้เป็น Favorite Query ก็ได้นะ
ถ้า Query ตัวไหนใช้งานบ่อย ก็สามารถกดเครื่องหมายดาวที่อยู่ด้านหลังช่อง Query เพื่อบันทึกเก็บไว้เป็น Favorite Query ได้เช่นกัน
โดย Favorite Query จะแสดงอยู่ใน History นั่นเอง
กดคีย์ลัดเพื่อแสดง Key ทั้งหมดได้นะ
เมื่อนึกไม่ออกว่ามี Key อะไรให้ใช้บ้าง ให้ลองกด Control + Space ในช่อง Query เพื่อดู Key ทั้งหมดที่มีให้ใช้งาน
การตั้งค่ารูปแบบการแสดงผลของ Log
ถ้ารู้สึกว่ารูปแบบการแสดงผลของ Log ยังไม่ถูกใจซักเท่าไร ไม่ต้องการดูข้อมูลบางอย่าง หรือข้อมูลบางอย่างแสดงเยอะเกินไป ก็สามารถกดปุ่มตั้งค่าการแสดงผลของ Log ที่อยู่แถบซ้ายมือของหน้าต่าง Logcat ได้
จะเลือกรูปแบบที่มีอยู่แล้วก็ได้ หรือจะ Custom เองก็ทำได้เช่นกัน
ในกรณีที่ Custom แล้ว แต่หน้าต่าง Log ไม่เปลี่ยนตาม ให้ลองปิด Tab ของ Logcat (กดปุ่มกากบาทตรง Tab) แล้วเปิดใหม่อีกครั้ง
การบันทึกภาพจากอุปกรณ์แอนดรอยด์
เมื่อต้องการบันทึกภาพหน้าจอของอุปกรณ์แอนดรอยด์ผ่านคอมพิวเตอร์ สามารถกดปุ่ม Screen Capture ที่อยู่ในหน้าต่าง Logcat ของ Android Studio ได้เลย
โดยวิธีนี้จะไม่ต้องเสียเวลาโอนไฟล์ภาพจากอุปกรณ์แอนดรอยด์เข้าคอมพิวเตอร์ เพราะไฟล์ภาพที่ได้จะบันทึกลงในเครื่องคอมพิวเตอร์ได้เลย
การบันทึกวีดีโอจากอุปกรณ์แอนดรอยด์
เช่นเดียวกับการบันทึกภาพหน้าจอ ถ้าต้องการบันทึกเป็นวีดีโอก็ให้กดปุ่ม Screen Record แทน โดยนักพัฒนาสามารถกำหนด Resolution, Bitrate และกำหนดได้ว่าจะให้แสดงตำแหน่งการแตะบนหน้าจอด้วยหรือไม่
ถ้าบันทึกวีดีโอจาก Physical Device จะได้เป็นไฟล์ MP4 แต่ถ้าบันทึกวีดีโอจาก Android Emulator จะได้เป็นไฟล์ WebM แทน
สรุป
จะเห็นว่าการเปลี่ยนแปลงใน Logcat ครั้งนี้จะเป็นการเปลี่ยนจาก Filter มาใช้เป็น Query แทน ที่จะช่วยให้นักพัฒนาค้นหา Log ตามที่ต้องการได้อย่างอิสระมากขึ้น และทำผ่านช่อง Query แค่ที่เดียว
แต่ถึงกระนั้น นักพัฒนาที่เคยใช้แบบเก่ามาก่อน ก็อาจจะต้องปรับตัวกันเล็กน้อยนะ แต่บอกเลยว่าสะดวกกว่าของเดิม