ปรับแต่งรายงานข้อขัดข้องของ Firebase Crashlytics

ในหน้าแดชบอร์ด Crashlytics คุณสามารถคลิกที่ปัญหาและดูรายละเอียด รายงานเหตุการณ์ คุณสามารถปรับแต่งรายงานเหล่านั้นเพื่อช่วยให้คุณเข้าใจมากขึ้น เกิดอะไรขึ้นในแอปและสถานการณ์ที่เกี่ยวข้องกับเหตุการณ์ที่รายงานไปยัง Crashlytics

  • รับบันทึกเบรดครัมบ์โดยอัตโนมัติหากแอปของคุณใช้ Firebase SDK สำหรับ Google Analytics บันทึกเหล่านี้ช่วยให้คุณทราบถึง การดำเนินการของผู้ใช้ที่นำไปสู่เหตุการณ์ที่รวบรวม 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")

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 ที่มีค่า NSDพจนานุกรม เป็นพารามิเตอร์เดียว ดังนี้

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 จะเชื่อมโยงบันทึก ด้วยข้อมูลข้อขัดข้องและแสดงในหน้า 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 มีวิธีระบุผู้ใช้ใน รายงานข้อขัดข้อง

หากต้องการเพิ่ม User-ID ลงในรายงาน ให้กำหนดตัวระบุที่ไม่ซ้ำกันให้ผู้ใช้แต่ละรายใน รูปแบบของหมายเลขรหัส โทเค็น หรือค่าที่แฮช ดังนี้

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: 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)

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 กับแอปของคุณ เมื่อมีคุณสมบัติตามข้อกำหนดเหล่านี้ บันทึกเบรดครัมบ์จะ รวมกับข้อมูลของเหตุการณ์ภายในแท็บบันทึกเมื่อคุณดูรายละเอียด ของปัญหา

Analytics SDK บันทึกเหตุการณ์ screen_view โดยอัตโนมัติ ซึ่งจะทำให้บันทึกเบรดครัมบ์แสดงรายการหน้าจอที่มีการดูก่อน เหตุการณ์ข้อขัดข้อง ไม่ร้ายแรง หรือ ANR บันทึกเบรดครัมบ์ screen_view ประกอบด้วย พารามิเตอร์ firebase_screen_class

นอกจากนี้ บันทึกเบรดครัมบ์ยังมีการเติมข้อมูลด้วย เหตุการณ์ที่กำหนดเองซึ่งคุณบันทึกด้วยตนเองภายในแท็ก ซึ่งรวมถึงข้อมูลพารามิเตอร์ของเหตุการณ์ ข้อมูลนี้จะช่วยแสดงชุดหนังสือ ของการดำเนินการของผู้ใช้ที่นำไปสู่เหตุการณ์ข้อขัดข้อง ไม่ร้ายแรง หรือ ANR

โปรดทราบว่าคุณสามารถ ควบคุมการเก็บรวบรวมและใช้ข้อมูล Google Analytics ซึ่งมีข้อมูลที่สร้างบันทึกเบรดครัมบ์

เปิดใช้การรายงานการเลือกใช้

โดยค่าเริ่มต้น Crashlytics จะรวบรวมรายงานข้อขัดข้องโดยอัตโนมัติสำหรับ ผู้ใช้แอป เพื่อให้ผู้ใช้ควบคุมข้อมูลที่ส่งได้มากขึ้น ให้เปิดใช้ การเลือกใช้การรายงานโดยปิดการใช้งานการรายงานอัตโนมัติและส่งข้อมูลไปที่ Crashlytics เมื่อคุณเลือกใช้ในโค้ด

  1. ปิดการรวบรวมอัตโนมัติโดยเพิ่มคีย์ใหม่ลงในไฟล์ Info.plist ดังนี้

    • คีย์: FirebaseCrashlyticsCollectionEnabled
    • ค่า: false
  2. เปิดใช้การรวบรวมสำหรับผู้ใช้ที่เลือกโดยการเรียกใช้ข้อมูล Crashlytics การลบล้างคอลเล็กชันขณะรันไทม์ ค่าการลบล้างจะยังคงอยู่ เปิดตัวแอปได้เพื่อให้ Crashlytics รวบรวมรายงานได้โดยอัตโนมัติ

    หากต้องการเลือกไม่ใช้การรายงานข้อขัดข้องอัตโนมัติ ให้ส่ง false เป็นค่าการลบล้าง เมื่อตั้งค่าเป็น false ค่าใหม่จะไม่มีผลจนกว่าจะมีการเรียกใช้ แอป

    Swift

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    Objective-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

จัดการข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้อง

ข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องช่วยคุณแก้ไขปัญหาด้วยการเปรียบเทียบสแต็กที่มีการลบข้อมูลระบุตัวบุคคลของคุณ การติดตามไปยังการติดตามจากแอป Firebase อื่นๆ และแจ้งให้คุณทราบหากปัญหาที่พบ อยู่ในเทรนด์ที่ใหญ่กว่า สำหรับปัญหาจำนวนมาก Crash Insights มีแหล่งข้อมูล เพื่อช่วยแก้ไขข้อบกพร่องของข้อขัดข้อง

Crash Insights ใช้ข้อมูลข้อขัดข้องที่รวบรวมไว้เพื่อระบุแนวโน้มความเสถียรที่พบบ่อย หากไม่ต้องการแชร์ข้อมูลของแอป คุณสามารถเลือกไม่ใช้ข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องได้ จากเมนูข้อมูลเชิงลึกเกี่ยวกับข้อขัดข้องที่ด้านบนของรายการปัญหาของ Crashlytics ในคอนโซล Firebase