คู่มือนี้อธิบายวิธีปรับแต่งรายงานข้อขัดข้องโดยใช้ Firebase Crashlytics SDK ตามค่าเริ่มต้น Crashlytics จะรวบรวมรายงานข้อขัดข้องสำหรับผู้ใช้แอปทั้งหมดของคุณ (คุณสามารถปิดการรายงานข้อขัดข้องอัตโนมัติและ เปิดใช้งานการรายงานการเลือกรับ สำหรับผู้ใช้ของคุณแทน) Crashlytics มีกลไกการบันทึกสี่แบบตั้งแต่แกะกล่อง: คีย์ ที่กำหนดเอง บันทึกที่กำหนดเอง ตัวระบุผู้ใช้ และ ข้อยกเว้น ที่ตรวจพบ
เพิ่มคีย์แบบกำหนดเอง
คีย์ที่กำหนดเองจะช่วยให้คุณทราบสถานะเฉพาะของแอปที่นำไปสู่การขัดข้องได้ คุณสามารถเชื่อมโยงคู่คีย์/ค่าที่กำหนดเองกับรายงานข้อขัดข้อง จากนั้นใช้คีย์ที่กำหนดเองเพื่อค้นหาและกรองรายงานข้อขัดข้องในคอนโซล Firebase
- ใน แดชบอร์ด Crashlytics คุณสามารถค้นหาปัญหาที่ตรงกับคีย์ที่กำหนดเองได้
- เมื่อคุณตรวจสอบปัญหาเฉพาะในคอนโซล คุณสามารถดูคีย์ที่กำหนดเองที่เกี่ยวข้องสำหรับแต่ละเหตุการณ์ (แท็บย่อยของ คีย์ ) และแม้กระทั่งกรองเหตุการณ์ด้วยคีย์ที่กำหนดเอง (เมนู ตัวกรอง ที่ด้านบนสุดของหน้า)
ใช้เมธอด setCustomValue
เพื่อตั้งค่าคู่คีย์/ค่า ตัวอย่างเช่น:
Swift
// Set int_key to 100. Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key") // Set str_key to "hello". Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")
วัตถุประสงค์-C
เมื่อตั้งค่าจำนวนเต็ม บูลีน หรือทศนิยม ให้ใส่กล่องค่าเป็น @( value )
// Set int_key to 100. [[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"]; // Set str_key to "hello". [[FIRCrashlytics crashlytics] setCustomValue:@"hello" forKey:@"str_key"];
คุณยังสามารถแก้ไขค่าของคีย์ที่มีอยู่ได้โดยการเรียกคีย์และตั้งค่าให้เป็นค่าอื่น ตัวอย่างเช่น:
Swift
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key") // Set int_key to 50 from 100. Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")
วัตถุประสงค์-C
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"]; // Set int_key to 50 from 100. [[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];
เพิ่มคู่คีย์/ค่าจำนวนมากโดยใช้เมธอด setCustomKeysAndValues
โดยมี NSDictionary เป็นพารามิเตอร์เดียว:
Swift
let keysAndValues = [ "string key" : "string value", "string key 2" : "string value 2", "boolean key" : true, "boolean key 2" : false, "float key" : 1.01, "float key 2" : 2.02 ] as [String : Any] Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)
วัตถุประสงค์-C
NSDictionary *keysAndValues = @{@"string key" : @"string value", @"string key 2" : @"string value 2", @"boolean key" : @(YES), @"boolean key 2" : @(NO), @"float key" : @(1.01), @"float key 2" : @(2.02)}; [[FIRCrashlytics crashlytics] setCustomKeysAndValues: keysAndValues];
เพิ่มข้อความบันทึกที่กำหนดเอง
ตัวยึดตำแหน่ง92เพื่อให้ตัวคุณเองมีบริบทมากขึ้นสำหรับเหตุการณ์ที่นำไปสู่การขัดข้อง คุณสามารถเพิ่มบันทึก Crashlytics ที่กำหนดเองลงในแอปของคุณ Crashlytics เชื่อมโยงบันทึกกับข้อมูลข้อขัดข้องของคุณและแสดงในหน้า Crashlytics ของ คอนโซล Firebase ใต้แท็บ บันทึก
Swift
ใช้ log()
หรือ log(format:, arguments:)
เพื่อช่วยระบุปัญหา หากคุณต้องการได้ผลลัพธ์บันทึกที่มีประโยชน์พร้อมข้อความ ออบเจ็กต์ที่คุณส่งไปยัง log()
จะต้องสอดคล้องกับคุณสมบัติ CustomStringConvertible
log()
ส่งคืนคุณสมบัติคำอธิบายที่คุณกำหนดสำหรับวัตถุ ตัวอย่างเช่น:
Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")
.log(format:, arguments:)
รูปแบบค่าที่ส่งคืนจากการเรียก getVaList()
ตัวอย่างเช่น:
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีใช้ log()
หรือ log(format:, arguments:)
โปรดดู เอกสารอ้างอิง ของ Crashlytics
วัตถุประสงค์-C
ใช้ log
หรือ logWithFormat
เพื่อช่วยระบุปัญหา โปรดทราบว่าหากคุณต้องการรับเอาต์พุตบันทึกที่มีประโยชน์พร้อมข้อความ อ็อบเจ็กต์ที่คุณส่งไปยังวิธีใดวิธีหนึ่งจะต้องแทนที่คุณสมบัติอินสแตนซ์ description
ตัวอย่างเช่น:
[[FIRCrashlytics crashlytics] log:@"Simple string message"]; [[FIRCrashlytics crashlytics] logWithFormat:@"Higgs-Boson detected! Bailing out... %@", attributesDict]; [[FIRCrashlytics crashlytics] logWithFormat:@"Logging a variable argument list %@" arguments:va_list_arg];
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีใช้ log
และ logWithFormat
โปรดดู เอกสารอ้างอิง ของ Crashlytics
ตั้งค่าตัวระบุผู้ใช้
ตัวยึดตำแหน่ง96ในการวินิจฉัยปัญหา มักจะเป็นประโยชน์ที่จะทราบว่าผู้ใช้รายใดของคุณประสบปัญหา Crashlytics มีวิธีระบุผู้ใช้โดยไม่ระบุตัวตนในรายงานข้อขัดข้องของคุณ
ในการเพิ่ม ID ผู้ใช้ในรายงานของคุณ ให้กำหนดตัวระบุที่ไม่ซ้ำกันให้กับผู้ใช้แต่ละคนในรูปแบบของหมายเลข ID โทเค็น หรือค่าที่แฮช:
Swift
Crashlytics.crashlytics().setUserID("123456789")
วัตถุประสงค์-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
หากคุณต้องการล้างตัวระบุผู้ใช้หลังจากตั้งค่าแล้ว ให้รีเซ็ตค่าเป็นสตริงว่าง การล้างตัวระบุผู้ใช้ไม่ได้ลบระเบียน Crashlytics ที่มีอยู่ หากคุณต้องการลบบันทึกที่เชื่อมโยงกับ ID ผู้ใช้ โปรด ติดต่อฝ่ายสนับสนุนของ Firebase
รายงานข้อยกเว้นที่ไม่ร้ายแรง
ตัวยึดตำแหน่ง102นอกเหนือจากการรายงานข้อขัดข้องของแอปโดยอัตโนมัติแล้ว Crashlytics ยังช่วยให้คุณบันทึกข้อยกเว้นที่ไม่ร้ายแรง และส่งถึงคุณในครั้งถัดไปที่แอปของคุณเปิดตัว
คุณสามารถบันทึกข้อยกเว้นที่ไม่ร้ายแรงได้โดยการบันทึกวัตถุ NSError
ด้วยเมธอด recordError
recordError
จับ call stack ของ thread โดยการเรียก [NSThread callStackReturnAddresses]
Swift
Crashlytics.crashlytics().record(error: error)
วัตถุประสงค์-C
[[FIRCrashlytics crashlytics] recordError:error];
เมื่อใช้วิธี recordError
สิ่งสำคัญคือต้องเข้าใจโครงสร้าง NSError
และวิธีที่ Crashlytics ใช้ข้อมูลเพื่อจัดกลุ่มข้อขัดข้อง การใช้วิธีการ recordError
อย่างไม่ถูกต้องอาจทำให้เกิดพฤติกรรมที่คาดเดาไม่ได้ และอาจทำให้ Crashlytics จำกัดการรายงานข้อผิดพลาดที่บันทึกไว้สำหรับแอปของคุณ
วัตถุ NSError
มีสามอาร์กิวเมนต์:
-
domain: String
-
code: Int
-
userInfo: [AnyHashable : Any]? = nil
ข้อผิดพลาดที่บันทึกไว้จะถูกจัดกลุ่มตาม domain
และ code
ต่างจากข้อขัดข้องร้ายแรงซึ่งจัดกลุ่มผ่านการวิเคราะห์การติดตามสแต็ก นี่เป็นข้อแตกต่างที่สำคัญระหว่างข้อขัดข้องที่ร้ายแรงและข้อผิดพลาดที่บันทึกไว้ ตัวอย่างเช่น:
Swift
let userInfo = [ NSLocalizedDescriptionKey: NSLocalizedString("The request failed.", comment: ""), NSLocalizedFailureReasonErrorKey: NSLocalizedString("The response returned a 404.", comment: ""), NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString("Does this page exist?", comment: ""), "ProductID": "123456", "View": "MainView" ] let error = NSError.init(domain: NSCocoaErrorDomain, code: -1001, userInfo: userInfo)
วัตถุประสงค์-C
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"The request failed.", nil), NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The response returned a 404.", nil), NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Does this page exist?", nil), @"ProductID": @"123456", @"View": @"MainView", }; NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:-1001 userInfo:userInfo];
เมื่อคุณบันทึกข้อผิดพลาดข้างต้น จะสร้างปัญหาใหม่ที่จัดกลุ่มโดย NSSomeErrorDomain
และ -1001
ข้อผิดพลาดที่บันทึกไว้เพิ่มเติมที่ใช้โดเมนและค่ารหัสเดียวกันจะถูกจัดกลุ่มภายใต้ปัญหาเดียวกัน ข้อมูลที่อยู่ในออบเจ็กต์ userInfo
จะถูกแปลงเป็นคู่คีย์-ค่า และแสดงในส่วนคีย์/บันทึกภายในปัญหาแต่ละรายการ
บันทึกและคีย์ที่กำหนดเอง
เช่นเดียวกับรายงานข้อขัดข้อง คุณสามารถฝังบันทึกและคีย์ที่กำหนดเองเพื่อเพิ่มบริบทให้กับ NSError
อย่างไรก็ตาม บันทึกที่แนบกับข้อขัดข้องกับข้อผิดพลาดที่บันทึกไว้มีความแตกต่างกัน เมื่อเกิดการขัดข้องและเปิดแอปขึ้นมาใหม่ บันทึกที่ Crashlytics ดึงมาจากดิสก์คือบันทึกที่เขียนขึ้นจนถึงเวลาที่เกิดปัญหา เมื่อคุณบันทึก NSError
แอปจะไม่ยุติทันที เนื่องจาก Crashlytics จะส่งรายงานข้อผิดพลาดที่บันทึกไว้ในการเปิดแอปครั้งถัดไปเท่านั้น และต้องจำกัดจำนวนพื้นที่ที่จัดสรรสำหรับบันทึกบนดิสก์ จึงสามารถบันทึกได้เพียงพอหลังจากบันทึก NSError
เพื่อให้บันทึกที่เกี่ยวข้องทั้งหมดจะถูกหมุนเวียนออกตามเวลาที่ Crashlytics ส่ง รายงานจากเครื่อง คำนึงถึงความสมดุลนี้เมื่อบันทึก NSErrors
และใช้บันทึกและคีย์ที่กำหนดเองในแอปของคุณ
ข้อควรพิจารณาด้านประสิทธิภาพ
โปรดทราบว่าการบันทึก NSError
อาจมีราคาแพงพอสมควร ในขณะที่คุณโทรออก Crashlytics จะดักจับ call stack ของเธรดปัจจุบันโดยใช้กระบวนการที่เรียกว่า stack คลี่คลาย กระบวนการนี้สามารถใช้ CPU และ I/O อย่างเข้มข้น โดยเฉพาะอย่างยิ่งในสถาปัตยกรรมที่รองรับการคลาย DWARF (arm64 และ x86) หลังจากที่คลี่คลายเสร็จสิ้น ข้อมูลจะถูกเขียนลงดิสก์แบบซิงโครนัส เพื่อป้องกันข้อมูลสูญหายหากเกิดข้อผิดพลาดในบรรทัดถัดไป
แม้ว่าการเรียก API นี้บนเธรดพื้นหลังจะปลอดภัย แต่อย่าลืมว่าการส่งการเรียกไปยังคิวอื่นจะสูญเสียบริบทของการติดตามสแต็กปัจจุบัน
แล้ว NSExceptions ล่ะ?
Crashlytics ไม่มีสิ่งอำนวยความสะดวกสำหรับการบันทึกและบันทึกอินสแตนซ์ NSException
โดยตรง โดยทั่วไปแล้ว Cocoa และ Cocoa Touch API นั้นไม่มีข้อยกเว้นที่ปลอดภัย นั่นหมายความว่าการใช้ @catch
อาจมีผลข้างเคียงที่ร้ายแรงโดยไม่ได้ตั้งใจในกระบวนการของคุณ แม้ว่าจะใช้งานด้วยความระมัดระวังอย่างยิ่งก็ตาม คุณไม่ควรใช้คำสั่ง @catch
ในโค้ดของคุณ โปรดดู เอกสารของ Apple ในหัวข้อ
เปิดใช้งานการรายงานการเลือกรับ
โดยค่าเริ่มต้น Crashlytics จะรวบรวมรายงานข้อขัดข้องสำหรับผู้ใช้แอปของคุณทั้งหมด เพื่อให้ผู้ใช้ควบคุมข้อมูลที่ส่งได้มากขึ้น คุณสามารถเปิดใช้งานการรายงานการเลือกรับโดยปิดใช้งานการรายงานอัตโนมัติและส่งข้อมูลไปยัง Crashlytics เมื่อคุณเลือกในโค้ดของคุณเท่านั้น:
ปิดการรวบรวมอัตโนมัติโดยการเพิ่มคีย์ใหม่ให้กับไฟล์
Info.plist
ของคุณ:- คีย์:
FirebaseCrashlyticsCollectionEnabled
- ค่า:
false
- คีย์:
เปิดใช้งานการรวบรวมสำหรับผู้ใช้ที่เลือกโดยเรียกใช้การแทนที่การรวบรวมข้อมูล Crashlytics ณ รันไทม์ ค่าการแทนที่จะคงอยู่ตลอดการเปิดตัวแอปของคุณ ดังนั้น Crashlytics จึงสามารถรวบรวมรายงานได้โดยอัตโนมัติ
หากต้องการเลือกไม่ใช้การรายงานข้อขัดข้องอัตโนมัติ ให้ส่งค่า
false
เป็นค่าแทนที่ เมื่อตั้งค่าfalse
ค่าใหม่จะไม่มีผลจนกว่าจะมีการเรียกใช้แอปครั้งถัดไปSwift
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
วัตถุประสงค์-C
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
จัดการข้อมูล Crash Insights
Crash Insights ช่วยคุณแก้ไขปัญหาโดยการเปรียบเทียบสแต็กเทรซที่ไม่ระบุตัวตนกับการติดตามจากแอป Firebase อื่นๆ และแจ้งให้คุณทราบว่าปัญหาของคุณเป็นส่วนหนึ่งของเทรนด์ที่ใหญ่กว่าหรือไม่ สำหรับปัญหาหลายๆ อย่าง Crash Insights ยังมีแหล่งข้อมูลเพื่อช่วยคุณแก้ไขจุดบกพร่องอีกด้วย
Crash Insights ใช้ข้อมูลข้อขัดข้องที่รวบรวมมาเพื่อระบุแนวโน้มความเสถียรทั่วไป หากคุณไม่ต้องการแชร์ข้อมูลของแอป คุณสามารถเลือกไม่ใช้ Crash Insights ได้จากเมนู Crash Insights ที่ด้านบนของรายการปัญหา Crashlytics ใน คอนโซล Firebase