การเขียนแอพฯบนโทรศัพท์มือถือที่มีข้อจำกัดทางด้าน Hardware ค่อนข้างมาก ไม่ว่าจะเป็น CPU, RAM รวมถึงแบตเตอรี่ ทำให้ระบบถูกออกแบบมาให้ทำงานแบบ Strict มาก หากนักพัฒนาเขียนโปรแกรมแบบไม่รอบคอบหรือไม่ถูกสุขลักษณะของระบบปฏิบัติการแล้วหละก็ โอกาสที่แอพฯจะ Crash นั้นมีสูงมาก และนั่นไม่ส่งผลดีเลย จากผลการวิจัยพบว่า
แอพฯ Crash เป็นปัญหาที่ถูกบ่นจาก User มากที่สุดของ Mobile Application
นอกจากนั้น
หากมีการ Crash ของแอพฯติดต่อกัน 3 ครั้ง จะมีผู้ใช้ถึงประมาณครึ่งหนึ่ง ตัดสินใจลบแอพฯนั้นๆทิ้งไปเลย
ระบบ Crash Tracking จึงถือกำเนิดขึ้นเพื่อให้นักพัฒนาสามารถตรวจจับ Crash จากเครื่อง User ได้โดยตรง ทำให้รู้ได้เลยว่าแอพฯ Crash ตอนไหน เกิดจากอะไร ที่ดังสุดตอนนี้ก็มี Crashlytics และ Parse Crash Reporting ที่เป็นบริการฟรี ให้ผู้ใช้สามารถเอาไปฝังในแอพฯและเริ่มใช้งานได้ทันที หากมีการ Crash เกิดขึ้น ระบบก็จะส่ง Crash Log มาให้เราดูผ่านระบบหลังบ้านเพื่อทำการแก้ไขและอัพเดตเวอร์ชั่นใหม่ จนสุดท้ายกลายเป็น Crash-Free Application ได้ในที่สุด
อย่างไรก็ตาม ระบบเหล่านี้มีการเก็บข้อมูลไว้ที่ Server ของบริษัทผู้ให้บริการ เช่นของ Crashlytics ก็เก็บไว้ที่ Twitter ส่วน Parse ก็เก็บไว้ที่ Facebook ดังนั้นพอบริษัทใหญ่จะเอาไปใช้ก็มักจะขัดกับ Policy อยู่เสมอ ก็เลยไม่สามารถใช้งานได้
ถามว่ามีระบบไหนที่เราสามารถตั้ง Server เองได้มั้ย ข้อมูลจะได้ไม่รั่วไหล? ขอตอบว่ามีครับ และติดตั้งไม่ยากเท่าไหร่ด้วย วันนี้เราจึงขอนำระบบ Application Crash Reporting on Android หรือ ACRA ซึ่งเป็นระบบ Crash Tracking สำหรับแอนดรอยด์แบบตั้ง Server เองมานำเสนอออออ เผื่อจะมีประโยชน์กับบริษัทต่างๆที่มี Concern เรื่องข้างต้นครับ
งั้นเรามาเริ่มกันเลยดีกว่า
ติดตั้งระบบฝั่ง Server
ก่อนจะไปฝังโค้ดฝั่ง Client ได้ ก็ต้องทำ Server ให้เสร็จเรียบร้อยก่อน
เนื่องจาก ACRA ทำระบบมาค่อนข้างดีให้คนเอาไปต่อยอดทำ Server ของตัวเองได้ แต่พอไปค้นๆดู แต่ละตัวก็ยังไม่ค่อยโอเคเท่าไหร่ จนกระทั่งต้องกลับไปลองตัวที่ชื่อว่า Acralyzer ซึ่งทาง ACRA ทำขึ้นมาเองและเค้าแนะนำให้ใช้ (แต่ดูติดตั้งยากตอนแรกก็เลยขี้เกียจ) โดยตัว Acralyzer นี้ทำงานบน Apache CouchDB ไม่ต้องลงอย่างอื่นเพิ่ม สำหรับคนที่ไม่ค่อยคุ้นชินกับ CouchDB ก็อาจจะรู้สึกว่าติดตั้งยากนิดหน่อย แต่ถ้าคุ้นเคยกับมันแล้ว ก็จะทำเสร็จในไม่กี่นาทีได้ครับ
ซึ่ง Acralyzer ตัวนี้ทำออกมาดูดีเลยทีเดียว ไม่ว่าจะเป็นการรวม Stack Trace ที่คล้ายๆกันให้กลายเป็นอันเดียวกันเพื่อการดูง่าย รวมถึงการปิด Issue ก็ทำได้เช่นกัน แถมยังทำงานแบบ Real Time ด้วย เมื่อมี Crash ใหม่มาก็จะขึ้นให้เห็นทันทีโดยไม่ต้อง Refresh เว็บ น่าจะครบทุกสิ่งที่ต้องการแล้วหละ เสียอย่างเดียว หน้าตา Geek ไปหน่อย ... อยากได้สวยๆแบบ Crashlytics หงะ ไม่มีหรอ T_T
เนื่องจากทำสำเร็จแล้ว เลยขอเอาวิธีติดตั้งบน Ubuntu มาเขียนให้อ่าน เผื่อมีใครจะทำตามครับ
เริ่มต้นด้วยลง couchdb ให้เรียบร้อย
apt-get install couchdb
ลองทดสอบว่าใช้งานได้รึเปล่าด้วยคำสั่ง
curl http://127.0.0.1:5984
หากถูกต้องจะ Return กลับมาว่า
{"couchdb":"Welcome","version":"1.2.0"}
แก้ไขไฟล์ /etc/couchdb/local.ini เพื่อให้เราสามารถเข้าถึง CouchDB ผ่าน External IP ได้ (โดย Default มันจะเข้าได้จาก 127.0.0.1 เท่านั้น) ด้วยการ Uncomment สองบรรทัดนี้
;port = 5984
;bind_address = 127.0.0.1
แล้วเปลี่ยนจนเป็นแบบนี้
port = 5984
bind_address = 0.0.0.0
จากนั้นในไฟล์เดียวกัน เราต้องเพิ่ม Admin Username/Password เพื่อให้เราสามารถเข้าถึง CouchDB แบบลึกๆได้ โดยให้มองหาบรรทัดที่เขียนว่า
[admins]
แล้วใส่ Username/Password ในบรรทัดถัดไปในรูปแบบ username = password เช่น
nuuneoi = 12345
ไม่ต้องกลัวว่า Password จะไม่ปลอดภัย เพราะหลังจากที่เราสั่ง Restart CouchDB แล้ว ตัว Password ดิบนี้จะถูก Hash ไว้โดยอัตโนมัติ ไม่มีใครสามารถอ่านออกได้อีกต่อไป
จากนั้น Save ให้เรียบร้อยและทำการ Restart CouchDB ผ่าน Command Line
curl -X POST http://localhost:5984/_restart -H"Content-Type: application/json"
หลังจากนั้นเราจะสามารถเรียกใช้งาน CouchDB ผ่านทาง Web Browser แล้ว โดยสิ่งที่เราสนใจคือ Futon ระบบ UI Backend ของตัว CouchDB นั่นเอง วิธีการเข้าก็ง่ายๆ เปิด Browser แล้วจิ้ม URL ดังนี้
http://<YOUR_SERVER_IP>:5984/_utils
จะปรากฎเป็นหน้าเว็บ Futon แบบนี้
ให้ Login ตรงลิงค์ด้านขวาล่างให้เรียบร้อยด้วย Username/Password ที่ตั้งไว้ก่อนหน้านี้
จากนั้นกด Replicator จากเมนูด้านขวา แล้วทำการติดตั้ง acro-storage (ตัว Storage Endpoint ของระบบ Acralyzer) ด้วยการกรอก from Remote Database และ to Local Database ดังนี้
from Remote Database: http://get.acralyzer.com/distrib-acra-storage
to Local Database: acra-myapp
แล้วก็กด Replicate จนมันเสร็จ
จากนั้นติดตั้งตัว Acralyzer ด้วยวิธีเดียวกัน แต่เปลี่ยนค่าเป็นดังนี้
from Remote Database: http://get.acralyzer.com/distrib-acralyzer
to Local Database: acralyzer
กด Replicate อีกเช่นกันเพื่อติดตั้ง
หากทำถูกต้อง จะมี Database โผล่เพิ่มขึ้นมาสองตัวชื่อว่า acra-myapp และ acralyzer
เกือบเสร็จแล้ว ! ต่อไปต้องสร้าง User สำหรับส่งจาก Client โดยเข้าไปที่ลิงค์นี้ผ่าน Web Browser
http://<YOUR_SERVER_IP>:5984/acralyzer/_design/acralyzer/index.html
แล้วกดที่ไป Admin ตามด้วย Users
กำหนด Username/Password ตามที่ต้องการ แล้วกด Create User จะปรากฎหน้าแบบนี้ออกมา
ให้ก็อปปี้ไว้ให้หมด แปะเก็บไว้สักที่นึง เดี๋ยวจะได้ใช้ในส่วนของ Client ครับ
จะเสร็จละๆ อย่างสุดท้ายคือต้อง Protect ตัว acra-myapp ไว้ไม่ให้ใครก็ได้เข้ามาอ่านได้ วิธีก็คือกดเข้าไปที่ acra-myapp แล้วกดที่ Securities กรอกช่อง Roles ในส่วนของ Members ไปว่า
["reader"]
ดังนี้
เสร็จเรียบร้อย !!
หลังจากนี้ให้เข้าไปดู Dashboard ของสถานะนี้ได้จากลิงค์เดิมครับ
http://<YOUR_SERVER_IP>:5984/acralyzer/_design/acralyzer/index.html
และ acro-myapp นี่สำหรับ 1 แอพฯเท่านั้น หากต้องการจะทำ Crash Tracking สำหรับแอพฯอื่นอีก ให้ Replicate acro-storage ตามขั้นตอนด้านบนขึ้นมาอีกหนึ่งอัน โดยมีเงื่อนไขว่าต้องขึ้นต้นด้วย acro- เท่านั้น ส่วน myapp เปลี่ยนไปตามต้องการได้เลยครับ
ถ้ามีมากกว่า 1 แอพฯ มันจะมี Drop Down ให้เลือกในหน้า Acralyzer ด้านซ้ายบน ลองเล่นดูได้ก๊ะ
ติดตั้ง ACRA ฝั่ง Client
ฝั่ง Client ทำค่อนข้างง่าย ก่อนอื่นก็ Add Dependency ACRA ลงใน build.gradle ก่อนเลย
compile 'ch.acra:acra:4.6.1'
Sync Gradle ให้เรียบร้อย แล้วก็ Create Application ของตัวเองขึ้นมา + ผูกกับ AndroidManifest.xml ให้เรียบร้อย (ไม่สอนนะตรงนี้ คนเขียนแอนดรอยด์ต้องทำเองเป็นแล้วแหละ)
จากนั้นให้ใส่ Annotation @ReportCrashes ลงไปตามนี้เหนือคลาส Application ที่สร้างมา (ในที่นี้เนยใช้ชื่อว่า MainApplication)
import android.app.Application;
import org.acra.ACRA;
import org.acra.annotation.ReportsCrashes;
import org.acra.sender.HttpSender;
/**
* Created by nuuneoi on 2/19/2015.
*/
@ReportsCrashes(
)
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ACRA.init(this);
}
}
แล้วก็อปปี้ข้อความที่ก็อปไว้ตอนสร้าง User ในส่วน Server มาแปะไว้ใน @ReportsCrashes ดังนี้
@ReportsCrashes(
httpMethod = HttpSender.Method.PUT,
reportType = HttpSender.Type.JSON,
formUri = "http://YOUR_SERVER_IP:5984/acra-myapp/_design/acra-storage/_update/report",
formUriBasicAuthLogin = "tester",
formUriBasicAuthPassword = "12345"
)
สุดท้ายอย่าลืมใส่ Permission INTERNET ให้กับแอพฯในส่วนของ AndroidManifest.xml ด้วย
<uses-permission android:name="android.permission.INTERNET"/>
เรียบร้อยคร้าบผม !
ทดสอบ
ลองทำแอพฯให้ Crash ใน Activity ประมาณนี้
TextView tvHello;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvHello.setText("Test Crash");
}
เสร็จแล้วก็รัน แล้วเปลี่ยนดูสัก 2-3 แบบ หน้า Dashboard ก็มีข้อมูลเพิ่มขึ้นมาดังนี้
กดเข้าไปดูก็จะเป็นลิสต์ของทุก Crash แบบเดียวกัน แต่รายละเอียดต่างๆกันไปตามเครื่องที่เกิด (เผอิญที่ลองครั้งนี้ทดสอบด้วยเครื่องเดียวกัน ข้อมูลเลยเหมือนกัน)
พอกดเข้าไปดู Stack trace ก็ได้ออกมาแบบนี้ครับ
พร้อมกับข้อมูลยาวไปอีก 7 หน้า PageDown ... ก็คือข้อมูลครบเลยแหละ ครบจนเกินเลยมั้ง -_-
แล้วถ้าแก้ไขเสร็จแล้วก็ทำการกดปิดบั๊กให้เรียบร้อยตรงนี้
ก็หวังว่าบทความนี้จะมีประโยชน์โดยเฉพาะกับบริษัทใหญ่ๆที่มีความต้องการ Track Crash บนแอนดรอยด์แต่กลัวเรื่องข้อมูลรั่วไหลไป Server คนอื่น เรื่องนี้น่าจะช่วยได้มากครับ ^_^
ทั้งนี้ทั้งนั้น ตัว ACRA มีฟังก์ชั่นให้เล่นอีกหลายอย่าง เช่น ถ้ามี Crash ให้เด้ง Toast หรือเด้ง Dialog Report เด้งแอพฯให้ส่งเมลยันทำ Reporter เองก็ได้ ลูกเล่นเยอะมาก ลองไปอ่านเพิ่มเติมดูได้จากเว็บของ ACRA ครับ
เช่นเดียวกับ Acralytics ที่สามารถส่งเมลมาบอกได้ด้วย ยังไงลองไปเล่นเพิ่มเติมกันได้ครับ ในเว็บของ Acralyzer มีให้อ่านอีกเยอะ =)
See ya again next blog ! =)
ผู้เขียน: nuuneoi (Android GDE, CTO & CEO at The Cheese Factory) นักพัฒนาแบบ Full-Stack ที่มีประสบการณ์ในการพัฒนาแอพฯแอนดรอยด์มากว่า 6 ปีและอยู่ในวงการพัฒนาแอพฯมือถือมากว่า 12 ปี มีความสนใจทางด้าน Infrastucture, Service Side, Design, UI&UX, Hardware, Optimization, Cooking, Photographing, Blogging, Training, Public Speaking และรักที่จะแชร์เรื่องราวให้ผู้คนได้อ่านได้ฟังกันผ่าน Blog
|