گزارش‌های خرابی Firebase Crashlytics خود را سفارشی کنید


در داشبورد Crashlytics ، می‌توانید روی یک مشکل کلیک کنید و گزارش دقیقی از رویداد دریافت کنید. می‌توانید این گزارش‌ها را سفارشی کنید تا به شما در درک بهتر اتفاقات برنامه‌تان و شرایط پیرامون رویدادهای گزارش‌شده به Crashlytics کمک کند.

  • اگر برنامه شما از Firebase SDK برای Google Analytics استفاده می‌کند، به طور خودکار گزارش‌های breadcrumb را دریافت کنید. این گزارش‌ها به شما امکان مشاهده اقدامات کاربر را می‌دهند که منجر به یک رویداد جمع‌آوری‌شده توسط Crashlytics در برنامه شما می‌شود.

  • گزارش خودکار خرابی را غیرفعال کنید و گزارش اختیاری را برای کاربران خود فعال کنید . توجه داشته باشید که به طور پیش‌فرض، Crashlytics به طور خودکار گزارش‌های خرابی را برای همه کاربران برنامه شما جمع‌آوری می‌کند.

اضافه کردن کلیدهای سفارشی

کلیدهای سفارشی به شما کمک می‌کنند تا وضعیت خاص برنامه خود را قبل از خرابی دریافت کنید. می‌توانید جفت‌های کلید/مقدار دلخواه را با گزارش‌های خرابی خود مرتبط کنید، سپس از کلیدهای سفارشی برای جستجو و فیلتر کردن گزارش‌های خرابی در کنسول Firebase استفاده کنید.

  • در داشبورد Crashlytics ، می‌توانید مشکلاتی را که با یک کلید سفارشی مطابقت دارند، جستجو کنید.
  • وقتی در حال بررسی یک مشکل خاص در کنسول هستید، می‌توانید کلیدهای سفارشی مرتبط با هر رویداد را مشاهده کنید (زیربرگه کلیدها ) و حتی رویدادها را بر اساس کلیدهای سفارشی فیلتر کنید (منوی فیلتر در بالای صفحه).

از متد setCustomValue برای تنظیم جفت‌های کلید/مقدار استفاده کنید. برای مثال:

سویفت

// Set int_key to 100.
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set str_key to "hello".
Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")

هدف-سی

هنگام تنظیم اعداد صحیح، بولی یا اعشاری، مقدار را به صورت @( 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"];

همچنین می‌توانید با فراخوانی کلید و تنظیم مقدار متفاوت برای آن، مقدار یک کلید موجود را تغییر دهید. برای مثال:

سویفت

Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set int_key to 50 from 100.
Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")

هدف-سی

[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set int_key to 50 from 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];

با استفاده از متد setCustomKeysAndValues ​​و تنها پارامتر NSDictionary، جفت‌های کلید/مقدار را به صورت گروهی اضافه کنید:

سویفت

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)

هدف-سی

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 ، در زیر تب Logs نمایش می‌دهد.

سویفت

برای کمک به شناسایی مشکلات، از 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 مراجعه کنید.

هدف-سی

برای کمک به شناسایی مشکلات 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 روشی برای شناسایی ناشناس کاربران در گزارش‌های خرابی شما ارائه می‌دهد.

برای افزودن شناسه‌های کاربری به گزارش‌های خود، به هر کاربر یک شناسه منحصر به فرد در قالب شماره شناسه، توکن یا مقدار هش شده اختصاص دهید:

سویفت

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

هدف-سی

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

اگر پس از تنظیم شناسه کاربری، نیاز به پاک کردن آن داشتید، مقدار آن را به یک رشته خالی تنظیم مجدد کنید. پاک کردن شناسه کاربری، رکوردهای موجود Crashlytics را حذف نمی‌کند. اگر نیاز به حذف رکوردهای مرتبط با شناسه کاربری دارید، با پشتیبانی Firebase تماس بگیرید .

گزارش استثنائات غیرمهلک

علاوه بر گزارش خودکار خرابی‌های برنامه، Crashlytics به شما امکان می‌دهد استثنائات غیرمهلک را ثبت کنید و دفعه بعد که برنامه شما راه‌اندازی می‌شود، آنها را برای شما ارسال کند.

شما می‌توانید با ضبط اشیاء NSError با استفاده از متد recordError خطاهای غیرمهلک (non-fatal exceptions) را ثبت کنید. recordError با فراخوانی [NSThread callStackReturnAddresses] پشته فراخوانی نخ را ثبت می‌کند.

سویفت

Crashlytics.crashlytics().record(error: error)

هدف-سی

[[FIRCrashlytics crashlytics] recordError:error];

هنگام استفاده از متد recordError ، درک ساختار NSError و نحوه استفاده Crashlytics از داده‌ها برای گروه‌بندی خرابی‌ها بسیار مهم است. استفاده نادرست از متد recordError می‌تواند باعث رفتار غیرقابل پیش‌بینی شود و ممکن است باعث شود Crashlytics گزارش خطاهای ثبت شده برای برنامه شما را محدود کند.

یک شیء NSError سه آرگومان دارد:

  • domain: String
  • code: Int
  • userInfo: [AnyHashable : Any]? = nil

برخلاف خرابی‌های مهلک که از طریق تحلیل ردیابی پشته گروه‌بندی می‌شوند، خطاهای ثبت‌شده بر اساس domain و code گروه‌بندی می‌شوند. این یک تمایز مهم بین خرابی‌های مهلک و خطاهای ثبت‌شده است. برای مثال:

سویفت

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)

هدف-سی

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 در یک نخ پس‌زمینه بی‌خطر است، به یاد داشته باشید که ارسال این فراخوانی به صف دیگر، زمینه‌ی ردیابی پشته فعلی را از دست می‌دهد.

در مورد NSExceptions چطور؟

Crashlytics امکانی برای ثبت و ضبط مستقیم موارد NSException ارائه نمی‌دهد. به طور کلی، APIهای Cocoa و Cocoa Touch در برابر خطا ایمن نیستند. این بدان معناست که استفاده از @catch می‌تواند عوارض جانبی ناخواسته بسیار جدی در فرآیند شما داشته باشد، حتی اگر با نهایت دقت استفاده شود. هرگز نباید از دستورات @catch در کد خود استفاده کنید. لطفاً به مستندات اپل در مورد این موضوع مراجعه کنید.

سفارشی‌سازی ردپاهای پشته

اگر برنامه شما در یک محیط غیربومی (مانند C++ یا Unity) اجرا می‌شود، می‌توانید از API مدل استثنا برای گزارش ابرداده‌های خرابی در قالب استثنای بومی برنامه خود استفاده کنید. استثناهای گزارش شده به عنوان غیرفاجعه‌آمیز علامت‌گذاری می‌شوند.

سویفت

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)

هدف-سی

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];

فریم‌های پشته سفارشی را می‌توان فقط با آدرس‌ها مقداردهی اولیه کرد:

سویفت

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)

هدف-سی

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];

دریافت گزارش‌های breadcrumb

لاگ‌های Breadcrumb درک بهتری از تعاملاتی که یک کاربر با برنامه شما داشته است، تا زمان وقوع یک کرش، خطای غیرمهلک یا رویداد ANR، به شما می‌دهند. این لاگ‌ها می‌توانند هنگام تلاش برای بازتولید و اشکال‌زدایی یک مشکل مفید باشند.

گزارش‌های Breadcrumb توسط Google Analytics پشتیبانی می‌شوند، بنابراین برای دریافت گزارش‌های Breadcrumb، باید Google Analytics را برای پروژه Firebase خود فعال کنید و Firebase SDK را برای Google Analytics به برنامه خود اضافه کنید . پس از برآورده شدن این الزامات، گزارش‌های Breadcrumb به طور خودکار هنگام مشاهده جزئیات یک مشکل، به همراه داده‌های یک رویداد در برگه Logs قرار می‌گیرند.

کیت توسعه نرم‌افزار (SDK) مربوط به Analytics به طور خودکار رویداد screen_view را ثبت می‌کند که به گزارش‌های breadcrumb امکان می‌دهد فهرستی از صفحات مشاهده شده قبل از رویداد crash، non-fatal یا ANR را نمایش دهند. گزارش breadcrumb screen_view حاوی پارامتر firebase_screen_class است.

لاگ‌های Breadcrumb همچنین با هر رویداد سفارشی که شما به صورت دستی در جلسه کاربر ثبت می‌کنید، از جمله داده‌های پارامتر رویداد، پر می‌شوند. این داده‌ها می‌توانند به نمایش مجموعه‌ای از اقدامات کاربر که منجر به یک رویداد خرابی، غیرمهلک یا ANR می‌شوند، کمک کنند.

توجه داشته باشید که می‌توانید جمع‌آوری و استفاده از داده‌های Google Analytics را کنترل کنید ، که شامل داده‌هایی است که لاگ‌های breadcrumb را پر می‌کنند.

گزارش‌دهی عضویت را فعال کنید

به طور پیش‌فرض، Crashlytics به طور خودکار گزارش‌های خرابی را برای همه کاربران برنامه شما جمع‌آوری می‌کند. برای اینکه کاربران کنترل بیشتری بر داده‌هایی که ارسال می‌کنند داشته باشند، می‌توانید با غیرفعال کردن گزارش خودکار، گزارش اختیاری را فعال کنید و فقط زمانی که در کد خود انتخاب می‌کنید، داده‌ها را به Crashlytics ارسال کنید.

  1. با اضافه کردن یک کلید جدید به فایل Info.plist خود، جمع‌آوری خودکار را غیرفعال کنید:

    • کلید: FirebaseCrashlyticsCollectionEnabled
    • مقدار: false
  2. با فراخوانی لغو جمع‌آوری داده‌های Crashlytics در زمان اجرا، جمع‌آوری را برای کاربران منتخب فعال کنید. مقدار لغو شده در تمام راه‌اندازی‌های بعدی برنامه شما باقی می‌ماند تا Crashlytics بتواند به‌طور خودکار گزارش‌ها را برای آن کاربر جمع‌آوری کند.

    سویفت

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    هدف-سی

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

    اگر کاربر بعداً از جمع‌آوری داده‌ها انصراف دهد، می‌توانید false به عنوان مقدار جایگزین ارسال کنید که دفعه‌ی بعدی که کاربر برنامه را اجرا می‌کند اعمال می‌شود و در تمام اجراهای بعدی برای آن کاربر ادامه خواهد داشت.

مدیریت داده‌های Crash Insights

Crash Insights با مقایسه‌ی ردپاهای پشته‌ی ناشناس‌شده‌ی شما با ردپاهای سایر برنامه‌های Firebase و اطلاع‌رسانی به شما در مورد اینکه آیا مشکل شما بخشی از یک روند بزرگ‌تر است یا خیر، به شما در حل مشکلات کمک می‌کند. برای بسیاری از مشکلات، Crash Insights حتی منابعی را برای کمک به شما در اشکال‌زدایی از خرابی ارائه می‌دهد.

Crash Insights از داده‌های خرابی تجمیع‌شده برای شناسایی روندهای پایداری رایج استفاده می‌کند. اگر ترجیح می‌دهید داده‌های برنامه خود را به اشتراک نگذارید، می‌توانید از منوی Crash Insights در بالای لیست مشکلات Crashlytics خود در کنسول Firebase ، از Crash Insights انصراف دهید.