Catch up on everthing we announced at this year's Firebase Summit. Learn more

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

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

เพิ่มคีย์แบบกำหนดเอง

คีย์ที่กำหนดเองจะช่วยให้คุณทราบสถานะเฉพาะของแอปที่นำไปสู่การขัดข้องได้ คุณสามารถเชื่อมโยงคู่คีย์/ค่าที่กำหนดเองกับรายงานข้อขัดข้อง จากนั้นใช้คีย์ที่กำหนดเองเพื่อค้นหาและกรองรายงานข้อขัดข้องในคอนโซล Firebase

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

ใช้ 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];

เพิ่มข้อความบันทึกที่กำหนดเอง

เพื่อให้ตัวคุณเองมีบริบทมากขึ้นสำหรับเหตุการณ์ที่นำไปสู่การขัดข้อง คุณสามารถเพิ่มบันทึก 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 เอกสารอ้างอิง

ตั้งค่าตัวระบุผู้ใช้

ในการวินิจฉัยปัญหา มักจะเป็นประโยชน์ที่จะทราบว่าผู้ใช้รายใดของคุณประสบปัญหา Crashlytics มีวิธีระบุผู้ใช้โดยไม่ระบุตัวตนในรายงานข้อขัดข้องของคุณ

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

Swift

Crashlytics.crashlytics().setUserID("123456789")

วัตถุประสงค์-C

[[FIRCrashlytics crashlytics] setUserID:@"123456789"];

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

รายงานข้อยกเว้นที่ไม่ร้ายแรง

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

คุณสามารถบันทึกข้อยกเว้นที่ไม่ร้ายแรงโดยการบันทึก NSError วัตถุกับ recordError วิธี recordError จับเรียกกองเธรดโดยการเรียก [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 , app ไม่ได้ทันทียุติ เพราะ 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 งบในรหัสของคุณ โปรดดู เอกสารแอปเปิ้ล ในหัวข้อ

ปรับแต่งการติดตามสแต็ก

หากแอปของคุณทำงานในสภาพแวดล้อมที่ไม่ใช่เจ้าของภาษา (เช่น 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)

วัตถุประสงค์-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)

วัตถุประสงค์-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];

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

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

  1. ปิดคอลเลกชันอัตโนมัติโดยการเพิ่มคีย์ใหม่ที่คุณ Info.plist ไฟล์:

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

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

    Swift

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    วัตถุประสงค์-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

จัดการข้อมูล Crash Insights

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

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