سفارشی‌سازی گزارش‌های خرابی برای پلاتفرم‌های Apple

انتخاب پلاتفرم: iOS+ Android Flutter Unity


می‌توانید روی مشکلی کلیک کنید و گزارش رویداد مفصلی را در داشبورد DevOps و تعامل > Crashlytics در کنسول Firebase دریافت کنید. می‌توانید این گزارش‌ها را سفارشی‌سازی کنید تا به شما کمک کند آنچه را در برنامه‌تان اتفاق می‌افتد و شرایط پیرامون رویدادهای گزارش‌شده به Crashlytics را بهتر درک کنید.

  • برنامه‌تان را برای ثبت کلیدهای سفارشی، پیام‌های ثبت سفارشی، و شناسه‌های کاربر آماده کنید.

  • استثنائات را به Crashlytics گزارش کنید.

  • اگر برنامه‌تان از کیت توسعه نرم‌افزار Firebase برای 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 گزارش‌ها را با داده‌های خرابی شما مرتبط می‌کند و وقتی جزئیات مشکلی را مشاهده می‌کنید، آن‌ها را در برگه گزارش‌ها نمایش می‌دهد (همه مشکلاتتان را در داشبورد Crashlytics DevOps و تعامل > در کنسول 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 سه متغیر مستقل دارد:

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

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

NSExceptions چطور؟

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 برای Google Analytics را به برنامه خود اضافه کنید. پس‌از برآورده شدن این الزامات، گزارش‌های ردپای رخدادها به‌طور خودکار با داده‌های رویداد در برگه گزارش‌ها گنجانده می‌شوند وقتی جزئیات یک مشکل را مشاهده می‌کنید (همه مشکلات خود را در داشبورد DevOps و تعامل > Crashlytics در کنسول Firebase ببینید).

Analytics SDK به‌طور خودکار رویداد screen_view را ثبت می‌کند که به گزارش‌های ردپای رخدادها امکان می‌دهد فهرستی از صفحه‌های مشاهده‌شده قبل‌از خرابی، رویداد غیرکشنده، یا ANR را نشان دهد. گزارش ردپای رخدادهای screen_view حاوی پارامتر firebase_screen_class است.

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

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

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

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

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

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

    Swift

    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)

    Objective-C

    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

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

مدیریت داده‌های «اطلاعات آماری خرابی»

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

«اطلاعات آماری خرابی» از داده‌های انبوهشی خرابی برای شناسایی روندهای پایداری رایج استفاده می‌کند. اگر ترجیح می‌دهید داده‌های برنامه‌تان را هم‌رسانی نکنید، می‌توانید از منوِ اطلاعات آماری خرابی در بالای فهرست مشکل در داشبورد DevOps و تعامل > Crashlytics در کنسول Firebase از «اطلاعات آماری خرابی» انصراف دهید.

مراحل بعدی