| בחירת פלטפורמה: | iOS+ Android Flutter Unity |
אפשר ללחוץ על בעיה מסוימת ולקבל דוח אירועים מפורט במרכז הבקרה של DevOps ומעורבות > Crashlytics במסוף Firebase. אתם יכולים להתאים אישית את הדוחות האלה כדי להבין טוב יותר מה קורה באפליקציה ואת הנסיבות שקשורות לאירועים שמדווחים ל-Crashlytics.
מגדירים את האפליקציה כך שתתעד מפתחות בהתאמה אישית, הודעות בהתאמה אישית ביומן ומזהי משתמשים.
דיווח על חריגים אל Crashlytics.
אם האפליקציה משתמשת ב-Firebase SDK ל-Google Analytics, אתם מקבלים באופן אוטומטי יומני פעולות משתמש. היומנים האלה מאפשרים לכם לראות את פעולות המשתמשים שהובילו לאירוע שנאסף על ידי Crashlytics באפליקציה.
משביתים את הדיווח האוטומטי על קריסות ומפעילים דיווח בהצטרפות למשתמשים. שימו לב שכברירת מחדל, Crashlytics אוסף באופן אוטומטי דוחות קריסה מכל משתמשי האפליקציה.
הוספת מפתחות בהתאמה אישית
מפתחות בהתאמה אישית עוזרים לכם לקבל את המצב הספציפי של האפליקציה לפני הקריסה. אתם יכולים לשייך צמדים שרירותיים של מפתח/ערך לדוחות הקריסה, ואז להשתמש במפתחות בהתאמה אישית כדי לחפש ולסנן דוחות קריסה במרכז הבקרה של DevOps ומעורבות > Crashlytics במסוף Firebase.
אתם יכולים לחפש בעיות שתואמות למפתח מותאם אישית.
כשבודקים בעיה ספציפית במסוף, אפשר לראות את המפתחות המותאמים אישית שמשויכים לכל אירוע (כרטיסיית המשנה Keys) ואפילו לסנן את האירועים לפי מפתחות מותאמים אישית (התפריט Filter בחלק העליון של הדף).
משתמשים ב-method 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"];
כדי להוסיף צמדי מפתח/ערך בכמות גדולה, משתמשים ב-method 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 כולל דרך לזהות משתמשים באופן אנונימי בדוחות הקריסה.
כדי להוסיף מזהי משתמשים לדוחות, צריך להקצות לכל משתמש מזהה ייחודי בצורת מספר מזהה, אסימון או ערך גיבוב (hash):
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 יש שלושה ארגומנטים:
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 מתעד את סטאק הביצוע של השרשור הנוכחי באמצעות תהליך שנקרא stack unwinding. התהליך הזה יכול להיות אינטנסיבי למעבד (CPU) ול-I/O, במיוחד בארכיטקטורות שתומכות ב-DWARF unwinding (arm64 ו-x86).
אחרי שההתרה מסתיימת, המידע נכתב בדיסק באופן סינכרוני.
כך אפשר למנוע אובדן נתונים אם השורה הבאה תקרוס.
אפשר לשלוח קריאה ל-API הזה בשרשור ברקע, אבל חשוב לזכור שאם שולחים את הקריאה הזו לתור אחר, ההקשר של דוח הקריסות הנוכחי אובד.
מה לגבי NSExceptions?
ב-Crashlytics אין אפשרות לרשום ביומן ולתעד מופעים של NSException באופן ישיר. באופן כללי, ממשקי ה-API של Cocoa ו-Cocoa Touch לא בטוחים מפני חריגות. כלומר, השימוש ב-@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).
ערכת ה-SDK של Analytics מתעדת באופן אוטומטי את האירוע 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בתור ערך ההחרגה. הערך הזה יחול בפעם הבאה שהמשתמש יפעיל את האפליקציה, ויישאר בתוקף בכל ההפעלות הבאות של האפליקציה על ידי המשתמש הזה.
ניהול הנתונים של Crash Insights
התכונה "תובנות לגבי קריסות" עוזרת לפתור בעיות על ידי השוואה בין דוחות הקריסות האנונימיים שלכם לבין דוחות של אפליקציות Firebase אחרות, ומאפשרת לכם לדעת אם הבעיה שלכם היא חלק ממגמה רחבה יותר. במקרים רבים, התובנות לגבי קריסות כוללות גם מקורות מידע שיעזרו לכם לנפות באגים בקריסה.
התכונה "תובנות לגבי קריסות" משתמשת בנתוני קריסות נצברים כדי לזהות מגמות נפוצות שקשורות ליציבות. אם אתם מעדיפים לא לשתף את נתוני האפליקציה, אתם יכולים לבטל את ההצטרפות לתובנות לגבי קריסות בתפריט תובנות לגבי קריסות שבחלק העליון של רשימת הבעיות בלוח הבקרה DevOps ומעורבות > Crashlytics במסוף Firebase.
השלבים הבאים
- ייצוא הנתונים אל BigQuery או אל Cloud Logging לניתוח מתקדם ושימוש בתכונות כמו שאילתות על הנתונים, יצירת מרכזי בקרה בהתאמה אישית והגדרת התראות בהתאמה אישית.