| เลือกแพลตฟอร์ม: | iOS+ Android Flutter Unity |
คุณสามารถคลิกเข้าไปดูปัญหาและรับรายงานเหตุการณ์โดยละเอียดในแดชบอร์ด DevOps & Engagement > Crashlyticsของ Firebaseคอนโซล และปรับแต่งรายงานเหล่านั้นเพื่อช่วยให้คุณเข้าใจได้ดียิ่งขึ้นว่าเกิดอะไรขึ้นในแอปและสถานการณ์รอบๆ เหตุการณ์ที่รายงานไปยัง Crashlytics
ติดตั้งเครื่องมือในแอปเพื่อบันทึกคีย์ที่กำหนดเอง, ข้อความบันทึกที่กำหนดเอง และ ตัวระบุผู้ใช้
รายงานข้อยกเว้นไปยัง Crashlytics
รับบันทึกเบรดครัมบ์โดยอัตโนมัติหากแอปใช้ Firebase SDK สำหรับ Google Analytics บันทึกเหล่านี้จะช่วยให้คุณเห็นการกระทำของผู้ใช้ที่นำไปสู่เหตุการณ์ที่ Crashlytics-รวบรวมในแอป
ปิดการรายงานข้อขัดข้องอัตโนมัติและ เปิดใช้การรายงานแบบเลือกรับสำหรับผู้ใช้ โปรดทราบว่าโดย ค่าเริ่มต้น Crashlytics จะรวบรวมรายงานข้อขัดข้องสำหรับผู้ใช้ แอปทั้งหมดโดยอัตโนมัติ
เพิ่มคีย์ที่กำหนดเอง
คีย์ที่กำหนดเองจะช่วยให้คุณทราบสถานะเฉพาะของแอปที่นำไปสู่ข้อขัดข้อง คุณสามารถเชื่อมโยงคู่คีย์-ค่าที่กำหนดเองกับรายงานข้อขัดข้อง จากนั้นใช้ คีย์ที่กำหนดเองเพื่อค้นหาและกรองรายงานข้อขัดข้องใน แดชบอร์ด DevOps และการมีส่วนร่วม > Crashlytics ของ Firebase
คุณสามารถค้นหาปัญหาที่ตรงกับคีย์ที่กำหนดเอง
เมื่อตรวจสอบปัญหาที่เฉพาะเจาะจงในคอนโซล คุณจะดูคีย์ที่กำหนดเองที่เชื่อมโยงกับเหตุการณ์แต่ละรายการ (แท็บย่อยคีย์) และกรองเหตุการณ์ตามคีย์ที่กำหนดเองได้ด้วย (เมนูตัวกรอง ที่ด้านบนของหน้า)
ใช้เมธอด 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")
Objective-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")
Objective-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)
Objective-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];
เพิ่มข้อความบันทึกที่กำหนดเอง
คุณสามารถเพิ่มบันทึก ที่กำหนดเองCrashlyticsลงในแอปเพื่อให้มีบริบทเพิ่มเติมสำหรับเหตุการณ์ที่นำไปสู่ข้อขัดข้องได้ โดยCrashlyticsจะเชื่อมโยงบันทึก กับข้อมูลข้อขัดข้องและแสดงในแท็บบันทึกเมื่อคุณดู รายละเอียดของปัญหา (ดูปัญหาทั้งหมดในแดชบอร์ดDevOps และการมีส่วนร่วม> 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
Objective-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 เอกสารอ้างอิง
ตั้งค่าตัวระบุผู้ใช้
การทราบว่าผู้ใช้รายใดพบข้อขัดข้องที่เฉพาะเจาะจงมักจะเป็นประโยชน์ในการวินิจฉัยปัญหา Crashlytics มีวิธีระบุตัวตนของผู้ใช้ใน รายงานข้อขัดข้องโดยไม่ระบุชื่อ
หากต้องการเพิ่มรหัสผู้ใช้ลงในรายงาน ให้กำหนดตัวระบุที่ไม่ซ้ำกันให้กับผู้ใช้แต่ละรายในรูปแบบหมายเลขรหัส โทเค็น หรือค่าที่แฮช
Swift
Crashlytics.crashlytics().setUserID("123456789")
Objective-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
หากต้องการล้างตัวระบุผู้ใช้หลังจากตั้งค่าแล้ว ให้รีเซ็ตค่าเป็นสตริงว่าง การล้างตัวระบุผู้ใช้จะไม่นำบันทึก Crashlytics ที่มีอยู่ออก หากต้องการลบบันทึกที่เชื่อมโยงกับรหัสผู้ใช้ โปรดติดต่อทีมสนับสนุนของ Firebase
รายงานข้อยกเว้นที่ไม่ร้ายแรง
นอกจากการรายงานข้อขัดข้องของแอปโดยอัตโนมัติแล้ว Crashlytics ยังช่วยให้ คุณบันทึกข้อยกเว้นที่ไม่ร้ายแรงและส่งข้อยกเว้นเหล่านั้นให้คุณในครั้งถัดไปที่แอป เปิดขึ้น
คุณสามารถบันทึกข้อยกเว้นที่ไม่ร้ายแรงได้โดยบันทึกออบเจ็กต์ NSError ด้วยเมธอด recordError recordError จะบันทึกสแต็กการเรียกใช้ของเทรดโดยเรียก [NSThread callStackReturnAddresses]
Swift
Crashlytics.crashlytics().record(error: error)
Objective-C
[[FIRCrashlytics crashlytics] recordError:error];
เมื่อใช้เมธอด recordError คุณจะต้องทำความเข้าใจโครงสร้าง NSError
และวิธีที่ Crashlytics ใช้ข้อมูลเพื่อจัดกลุ่มข้อขัดข้อง การใช้
เมธอด recordError อย่างไม่ถูกต้องอาจทำให้เกิดลักษณะการทำงานที่ไม่คาดคิดและอาจ
ทำให้ Crashlytics จำกัดการรายงานข้อผิดพลาดที่บันทึกไว้สำหรับแอป
ออบเจ็กต์ NSError มีอาร์กิวเมนต์ 3 รายการ ได้แก่
domain: Stringcode: IntuserInfo: [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)
Objective-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 จะบันทึกสแต็กการเรียกใช้ของเธรดปัจจุบันโดยใช้ กระบวนการที่เรียกว่าการคลายสแต็ก กระบวนการนี้อาจใช้ CPU และ I/O มาก โดยเฉพาะอย่างยิ่งในสถาปัตยกรรมที่รองรับการคลาย DWARF (arm64 และ x86)
หลังจากคลายสแต็กเสร็จแล้ว ระบบจะเขียนข้อมูลลงในดิสก์แบบซิงโครนัส
ซึ่งจะป้องกันไม่ให้ข้อมูลสูญหายหากบรรทัดถัดไปเกิดข้อขัดข้อง
แม้ว่าการเรียก API นี้ในเธรดเบื้องหลังจะปลอดภัย แต่โปรดทราบว่าการส่งการเรียกนี้ไปยังคิวอื่นจะทำให้บริบทของสแต็กเทรซปัจจุบันสูญหาย
แล้ว NSException ล่ะ
Crashlytics ไม่มีฟังก์ชันสำหรับบันทึกและบันทึก NSException
อินสแตนซ์โดยตรง โดยทั่วไปแล้ว Cocoa และ Cocoa Touch API ไม่ปลอดภัยต่อข้อยกเว้น ซึ่งหมายความว่าการใช้ @catch อาจก่อให้เกิดผลข้างเคียงที่ไม่พึงประสงค์ร้ายแรงในกระบวนการของคุณ แม้ว่าจะใช้ด้วยความระมัดระวังอย่างยิ่งก็ตาม คุณไม่ควรใช้คำสั่ง @catch ในโค้ด โปรดดู
เอกสารประกอบของ Apple
เกี่ยวกับหัวข้อนี้
ปรับแต่งสแต็กเทรซ
หากแอปทำงานในสภาพแวดล้อมที่ไม่ใช่แบบเนทีฟ (เช่น C++ หรือ Unity) คุณสามารถใช้ Exception Model API เพื่อรายงานข้อมูลเมตาของข้อขัดข้องในรูปแบบข้อยกเว้นแบบเนทีฟของแอปได้ ระบบจะทำเครื่องหมายข้อยกเว้นที่รายงานเป็นข้อยกเว้นที่ไม่ร้ายแรง
Swift
var ex = ExceptionModel(name:"FooException", reason:"There was a foo.") ex.stackTrace = [ StackFrame(symbol:"makeError", file:"handler.js", line:495), StackFrame(symbol:"then", file:"routes.js", line:102), StackFrame(symbol:"main", file:"app.js", line:12), ] crashlytics.record(exceptionModel:ex)
Objective-C
FIRExceptionModel *model = [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."]; model.stackTrace = @[ [FIRStackFrame stackFrameWithSymbol:@"makeError" file:@"handler.js" line:495], [FIRStackFrame stackFrameWithSymbol:@"then" file:@"routes.js" line:102], [FIRStackFrame stackFrameWithSymbol:@"main" file:@"app.js" line:12], ]; [[FIRCrashlytics crashlytics] recordExceptionModel:model];
นอกจากนี้ คุณยังเริ่มต้นเฟรมสแต็กที่กำหนดเองด้วยที่อยู่เท่านั้นได้ด้วย
Swift
var ex = ExceptionModel.init(name:"FooException", reason:"There was a foo.") ex.stackTrace = [ StackFrame(address:0xfa12123), StackFrame(address:12412412), StackFrame(address:194129124), ] crashlytics.record(exceptionModel:ex)
Objective-C
FIRExceptionModel *model = [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."]; model.stackTrace = @[ [FIRStackFrame stackFrameWithAddress:0xfa12123], [FIRStackFrame stackFrameWithAddress:12412412], [FIRStackFrame stackFrameWithAddress:194129124], ]; [[FIRCrashlytics crashlytics] recordExceptionModel:model];
รับบันทึกเบรดครัมบ์
บันทึกเบรดครัมบ์จะช่วยให้คุณเข้าใจได้ดียิ่งขึ้นเกี่ยวกับการโต้ตอบที่ผู้ใช้มีกับแอปที่นำไปสู่ข้อขัดข้อง เหตุการณ์ที่ไม่ร้ายแรง หรือเหตุการณ์ ANR บันทึกเหล่านี้อาจเป็นประโยชน์เมื่อพยายามจำลองและแก้ไขข้อบกพร่องของปัญหา
บันทึกเบรดครัมบ์ทำงานโดยใช้ Google Analytics ดังนั้นหากต้องการรับบันทึกเบรดครัมบ์ คุณ ต้อง เปิดใช้ Google Analytics สำหรับโปรเจ็กต์ Firebase และ เพิ่ม Firebase SDK สำหรับ Google Analytics ลงในแอป เมื่อเป็นไปตามข้อกำหนดเหล่านี้แล้ว ระบบจะรวมบันทึกเบรดครัมบ์ไว้กับข้อมูลของเหตุการณ์โดยอัตโนมัติ ในแท็บ บันทึก เมื่อคุณดูรายละเอียด ของปัญหา (ดูปัญหาทั้งหมดในแดชบอร์ด DevOps และการมีส่วนร่วม > Crashlytics แดชบอร์ดของ Firebase คอนโซล)
Analytics SDK
จะบันทึกเหตุการณ์ screen_view โดยอัตโนมัติ
ซึ่งจะช่วยให้บันทึกเบรดครัมบ์แสดงรายการหน้าจอที่ดูไปก่อนที่จะเกิด
ข้อขัดข้อง เหตุการณ์ที่ไม่ร้ายแรง หรือเหตุการณ์ ANR บันทึกเบรดครัมบ์ screen_view มีพารามิเตอร์ firebase_screen_class
นอกจากนี้ ระบบยังป้อนข้อมูลเหตุการณ์ที่กำหนดเองที่คุณบันทึกด้วยตนเองภายในเซสชันของผู้ใช้ลงในบันทึกเบรดครัมบ์ด้วย ซึ่งรวมถึงข้อมูลพารามิเตอร์ของเหตุการณ์ ข้อมูลนี้จะช่วยแสดงชุดการกระทำของผู้ใช้ที่นำไปสู่ข้อขัดข้อง เหตุการณ์ที่ไม่ร้ายแรง หรือเหตุการณ์ ANR
โปรดทราบว่าคุณสามารถ ควบคุมการเก็บรวบรวมและการใช้ข้อมูลGoogle Analyticsได้, ซึ่งรวมถึงข้อมูลที่ป้อนลงในบันทึกเบรดครัมบ์
เปิดใช้การรายงานแบบเลือกรับ
โดยค่าเริ่มต้น Crashlytics จะรวบรวมรายงานข้อขัดข้องสำหรับผู้ใช้ แอปทั้งหมดโดยอัตโนมัติ หากต้องการให้ผู้ใช้ควบคุมข้อมูลที่ส่งได้มากขึ้น คุณสามารถเปิดใช้ การรายงานแบบเลือกรับได้โดยปิดใช้การรายงานอัตโนมัติและส่งข้อมูลไปยัง Crashlytics เฉพาะเมื่อคุณเลือกที่จะส่งในโค้ด
ปิดการเก็บรวบรวมอัตโนมัติโดยเพิ่มคีย์ใหม่ลงในไฟล์
Info.plistดังนี้- คีย์:
FirebaseCrashlyticsCollectionEnabled - ค่า:
false
- คีย์:
เปิดใช้การเก็บรวบรวมสำหรับผู้ใช้ที่เลือกโดยเรียกการลบล้างการเก็บรวบรวมข้อมูล Crashlytics ในรันไทม์ ค่าการลบล้างจะยังคงอยู่ในการเปิดแอปครั้งต่อๆ ไปทั้งหมด เพื่อให้ Crashlytics รวบรวม รายงานสำหรับผู้ใช้รายนั้นได้โดยอัตโนมัติ
Swift
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
Objective-C
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
หากผู้ใช้เลือกไม่รับการเก็บรวบรวมข้อมูลในภายหลัง คุณสามารถส่ง
falseเป็นค่าการลบล้างได้ ซึ่งจะมีผลในครั้งถัดไปที่ผู้ใช้เปิดแอปและจะยังคงอยู่ในการเปิดแอปครั้งต่อๆ ไปทั้งหมดสำหรับผู้ใช้รายนั้น
จัดการข้อมูลข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้อง
ข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องจะช่วยคุณแก้ปัญหาโดยการเปรียบเทียบสแต็กเทรซที่ลบข้อมูลระบุตัวบุคคลแล้วกับเทรซจากแอป Firebase อื่นๆ และแจ้งให้คุณทราบว่าปัญหาของคุณเป็นส่วนหนึ่งของเทรนด์ที่ใหญ่ขึ้นหรือไม่ สำหรับปัญหาหลายๆ อย่าง ข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องยังมีแหล่งข้อมูลที่จะช่วยคุณแก้ไขข้อบกพร่องของข้อขัดข้องด้วย
ข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องใช้ข้อมูลข้อขัดข้องที่รวบรวมเพื่อระบุเทรนด์ความเสถียรทั่วไป หากไม่ต้องการแชร์ข้อมูลของแอป คุณสามารถเลือกไม่รับข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องได้ จากเมนู ข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้อง ที่ด้านบนของรายการปัญหาใน DevOps และการมีส่วนร่วม > Crashlytics แดชบอร์ด ของ Firebase คอนโซล
ขั้นตอนถัดไป
- ส่งออกข้อมูลไปยัง BigQuery หรือ Cloud Logging เพื่อการวิเคราะห์ขั้นสูงและฟีเจอร์ต่างๆ เช่น การค้นหาข้อมูล การสร้างแดชบอร์ดที่กำหนดเอง และการตั้งค่าการแจ้งเตือนที่กำหนดเอง