Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

"Используем MetricKit в бою" / Марина Звягина (Vivid Money)

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Prochain SlideShare
Coding matlab
Coding matlab
Chargement dans…3
×

Consultez-les par la suite

1 sur 34 Publicité

"Используем MetricKit в бою" / Марина Звягина (Vivid Money)

Télécharger pour lire hors ligne

Этот доклад будет максимально прикладным. Насколько MetricKit
хорош? Какие данные действительно помогут оптимизировать работу приложения? Как подружить MetricKit с другими метриками?
В приложении Vivid используется MetricKit и мы уже решили эти вопросы и многие другие.

Этот доклад будет максимально прикладным. Насколько MetricKit
хорош? Какие данные действительно помогут оптимизировать работу приложения? Как подружить MetricKit с другими метриками?
В приложении Vivid используется MetricKit и мы уже решили эти вопросы и многие другие.

Publicité
Publicité

Plus De Contenu Connexe

Diaporamas pour vous (19)

Similaire à "Используем MetricKit в бою" / Марина Звягина (Vivid Money) (20)

Publicité

Plus récents (20)

"Используем MetricKit в бою" / Марина Звягина (Vivid Money)

  1. 1. 1
  2. 2. Марина Звягина Vivid Money Используем MetricKit в бою
  3. 3. План 3 1 MetricKit - основные сущности и как с ними работать 2 Примеры и истории из нашей практики 3 Итоги
  4. 4. 4 MXMetricManager MXMetricManagerSubscriber MXMetricPayload MXDiagnosticPayload MXAppLaunchMetric MXAppResponsivenessMetric MXDiskIOMetric MXMemoryMetric MXDisplayMetric MXAnimationMetric MXAppExitMetric MXSignpostMetric MXMetaData MXCPUExceptionDiagnostic MXDiskWriteExceptionDiagnostic MXHangDiagnostic MXCrashDiagnostic MetricKit MXHistogram MXMetric
  5. 5. 5 MXMetricManager let metrikManager = MXMetricManager.shared metrikManager.add(self) open func add(_ subscriber: MXMetricManagerSubscriber) open func remove(_ subscriber: MXMetricManagerSubscriber) @available(iOS 13.0, *) open var pastPayloads: [MXMetricPayload] { get } open var pastDiagnosticPayloads: [MXDiagnosticPayload] { get } @available(iOS 14.0, *) What’s New in MetricKit
  6. 6. 6 MXMetricManagerSubscriber optional func didReceive(_ payloads: [MXMetricPayload]) optional func didReceive(_ payloads: [MXDiagnosticPayload])
  7. 7. MXMetricPayload includesMultipleApplicationVersions Bool latestApplicationVersion NSTaggedPointerString "1.77.0" metaData MXMetaData regionFormat NSTaggedPointerString @"RU" osVersion NSCFString @"iPhone OS 15.2 (19C56)" deviceType NSCFString @"iPhone 13,4" applicationBuildVersion NSTaggedPointerString @"1" platformArchitecture NSTaggedPointerString @"arm64e" timeStampBegin NSTaggedDate 2022-02-03 21:00:00 UTC timeStampEnd NSTaggedDate 2022-02-04 21:00:00 UTC 🤩
  8. 8. MXMetricPayload applicationResponsivenessMetrics MXAppResponsivenessMetric histogrammedAppHangTime (buckets) diskIOMetrics MXDiskIOMetric cumulativeLogicalWrites "1300kB" locationActivityMetrics MXLocationActivityMetric cumulativeBestAccuracyTime "20 sec" cumulativeBastAccuracyForNavigationTime cumulativeNearestTenMetersAccuracyTime cumulativeHundredMetersAccuracyTime cumulativeKilometerAccuracyTime cumulativeThreeKilometersAccuracyTime 🤩 Improving Your App's Performance AnyHashable("applicationResponsivenessMetrics"): { histogrammedAppHangTime = { histogramNumBuckets = 3; histogramValue = { 0 = { bucketCount = 50; bucketEnd = "100 ms"; bucketStart = "0 ms"; }; 1 = { bucketCount = 60; bucketEnd = "400 ms"; bucketStart = "100 ms"; }; 2 = { bucketCount = 30; bucketEnd = "700 ms"; bucketStart = "400 ms"; }; }; }; }
  9. 9. 9 MXMetricPayload 🤩 applicationLaunchMetrics MXAppLaunchMetric histogrammedTimeToFirstDraw histogrammedApplicationResumeTime histogrammedOptimizedTimeToFirstDraw What’s New in MetricKit
  10. 10. 10 @available(iOS 14.0, *) Нормальный выход Вытеснено другим приложением в foreground Переходы между стейтами занимают больше 20 секунд MXMetricPayload 🤩 cumulativeBadAccessExitCount cumulativeIllegalInstructionExitCount cumulativeAbnormalExitCount cumulativeCPUResourceLimitExitCount cumulativeMemoryResourceLimitExitCount cumulativePressureExitCount cumulativeSuspendedWithLockedFileExitCount cumulativeAppWatchdogExitCount cumulativeBackgroundTaskAssertionTimeoutExitCount cumulativeNormalExitCount Crashes Segmentation fault Illegal instruction Asserts and uncaught exceptions Understanding Crashes and Crash Logs Why is my app getting killed MXBackgroundExitData Рассмотрим вместе с MXDiagnosticPayload
  11. 11. 11 MXMetricPayload 🤔 cellularConditionMetrics MXCellularConditionMetric cellConditionTime = { histogramNumBuckets = 3; histogramValue = { 0 = { bucketCount = 20; bucketEnd = "1 bars"; bucketStart = "1 bars"; }; 1 = { bucketCount = 30; bucketEnd = "2 bars"; bucketStart = "2 bars"; }; 2 = { bucketCount = 50; bucketEnd = "3 bars"; bucketStart = "3 bars"; }; }; };
  12. 12. Custom Metric 12 let logHandle = MXMetricManager.makeLogHandle(category: "HomeScreen") mxSignpost(.begin, log: logHandle, name: "homeScreenLaunching") mxSignpost(.end, log: logHandle, name: "homeScreenLaunching") MXSignpostMetric histogram count mxSignpost(.event, log: logHandle, name: "homeScreenLaunching") os_signpost
  13. 13. 13 mxSignpost vs os_signpost 1.29ms vs 1.17ms
  14. 14. 14 MXDiagnosticPayload cpuExceptionDiagnostics: [MXCPUExceptionDiagnostic]? cpuMetrics diskWriteExceptionDiagnostics: [MXDickWriteExceptionDiagnostic]? diskIOMetrics hangDiagnostics: [MXHangDiagnostic]? applicationResponsivenessMetrics crashDiagnostics: [MXCrashDiagnostic]? applicationExitMetrics
  15. 15. 15 MXCPUExceptionDiagnostic CPU Exception, or a "high CPU usage termination" 80% CPU over a period of one minute (on background execution) Why is my app getting killed Solving CPU Usage Crashes with Xcode's Energy Organizer cumulativeCPUResourceLimitExitCount Чтобы избежать этого exception'а: move work into BGProcessingTask MXBackgroundExitData
  16. 16. 16 MXDiskWriteExceptionDiagnostic "diskIOMetrics": { cumulativeLogicalWrites = "1300 kB" } Генерируется, если количество записей > 1 ГБ в день "callStackTree" : { "callStacks" : [ { "callStackRootFrames" : [ { … "sampleCount" : 20 "diagnosticMetaData" : { … "regionFormat" : "GB", "writesCaused" : "2,000 byte" … } A disk write exception occurs when the app writes an excessive amount of data to the disk. diskIOMetrics MXDiskIOMetric cumulativeLogicalWrites "1300kB"
  17. 17. 17 MXCrashDiagnostic MXBackgroundExitData cumulativeBadAccessExitCount cumulativeIllegalInstructionExitCount cumulativeAbnormalExitCount MXCrashDiagnostic • Stack trace • Signal • Exception code • Termination reason
  18. 18. 18 MXHangDiagnostic Eliminate animation hitches with XCTest Все данные unsymbolicated - можно использовать утилиту ATOS cd ~/Library/Developer/Xcode/Archives/2022-01-26/Vivid 26.01.2022, 20.43.xcarchive/dSYMs/Vivid.app.dSYM/Contents/Resources/DWARF/ atos -arch arm64 -o myApp 0x4329526096 Identify trends with the Power and Performance API An object representing a diagnostic report for an app that is too busy to handle user input responsively applicationResponsivenessMetrics MXAppResponsivenessMetric histogrammedAppHangTime (buckets)
  19. 19. 19 MXMetricPayload Test payloads
  20. 20. План 20 1 MetricKit - основные сущности и как с ними работать 2 Примеры и истории из нашей практики 3 Итоги ✅
  21. 21. 21 reality + + In fl ux data input format Telegraf VictoriaMetrics Grafana vivid
  22. 22. 22
  23. 23. reality.code 23 struct PerformanceMeasure { var callTime: TimeInterval let type: PerformanceMeasureType let concreteName: String? var stopTime: TimeInterval? } struct TelegrafEvent { let name: String let time: TimeInterval let tags: [String: String] let metricType: TelegrafMetricType } let time = measure.stopTime - measure.callTime Date().timeIntervalSince1970 vivid
  24. 24. 24 App launch metric func measureAppStartUpTime() -> (Double, Double) { var kinfo = kinfo_proc() var size = MemoryLayout<kinfo_proc>.stride var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] sysctl(&mib, u_int(mib.count), &kinfo, &size, nil, 0) let startTime = kinfo.kp_proc.p_starttime var time = timeval(tv_sec: 0, tv_usec: 0) gettimeofday(&time, nil) let currentTimeMilliseconds = (Double(Int64(time.tv_sec) * 1_000) + Double(time.tv_usec) / 1_000.0) / 1_000.0 let processTimeMilliseconds = (Double(Int64(startTime.tv_sec) * 1_000) + Double(startTime.tv_usec) / 1_000.0) / 1_000.0 return (processTimeMilliseconds, currentTimeMilliseconds) } vivid
  25. 25. 25
  26. 26. 26 MetricKit @available(iOS 13.0, *) func didReceive(_ payloads: [MXMetricPayload]) { payloads.forEach { payload in print(payload.dictionaryRepresentation()) var currentSaveValues: [String] = payloadsStored.get() ?? [] currentSaveValues.append("MXMetricPayload = (payload.dictionaryRepresentation().description)") payloadsStored.set(value: currentSaveValues) let firstDrawBuckets: [MXHistogramBucket] = (payload.applicationLaunchMetrics?.histogrammedTimeToFirstDraw.bucketEnumerator.allObjects as? [MXHistogramBucket<Unit>]) .rescue([]) firstDrawBuckets.forEach { bucket in addMetricsIfNeeded(bucket: bucket, measureType: .appLaunchMetricsTime) } let resumeBackets: [MXHistogramBucket] = (payload.applicationLaunchMetrics?.histogrammedApplicationResumeTime.bucketEnumerator.allObjects as? [MXHistogramBucket<Unit>]) .rescue([]) resumeBackets.forEach { bucket in addMetricsIfNeeded(bucket: bucket, measureType: .appResumeMetricsTime) } } } vivid
  27. 27. 27
  28. 28. 28 struct PerformanceNewMeasure { var callTime: TimeInterval let type: PerformanceMeasureType let concreteName: String? var stopTime: TimeInterval? } struct TelegrafEvent { let name: String let time: TimeInterval let tags: [String: String] let metricType: TelegrafMetricType } let time = measure.stopTime - measure.callTime Date().timeIntervalSince1970 Date().timeIntervalSince1970 event.time.multiply(1_000) Ответ Date().timeIntervalSince1970 vivid reality.code
  29. 29. 29 histogrammedTimeToFirstDrawKey = { histogramNumBuckets = 3; histogramValue = { 0 = { bucketCount = 50; bucketEnd = "1010 ms"; bucketStart = "1000 ms"; }; 1 = { bucketCount = 60; bucketEnd = "2010 ms"; bucketStart = "2000 ms"; }; 2 = { bucketCount = 30; bucketEnd = "3010 ms"; bucketStart = "3000 ms"; }; }; }; "time_obtain_short_i,name=BeforeApp,env=stable,ver=1.77.0 ms=682.904005050659" vivid reality.code
  30. 30. 30 @available(iOS 13.0, *) func addMetricsIfNeeded(bucket: MXHistogramBucket<Unit>, measureType: PerformanceMeasureType) { let bucketEnd = bucket.bucketEnd let bucketStart = bucket.bucketStart let countOfEvents = bucket.bucketCount if bucketEnd.unit.symbol == "ms" && bucketStart.unit.symbol == "ms" { let averageValue = (bucketEnd.value.plus(bucketStart.value)) / 2 let appLaunchEvent = performanceTracker.getEvent(with: .fastRequestLoading) guard countOfEvents > 0 else { return } for _ in 1...countOfEvents { appLaunchEvent.addMeasure(callTime: 0, stopTime: averageValue, measureType: measureType, kind: .simple) } } } vivid reality.code
  31. 31. reality Grafana 31 vivid
  32. 32. План 32 1 MetricKit - основные сущности и как с ними работать 2 Примеры и истории из нашей практики 3 Итоги ✅ ✅
  33. 33. 33 💚 MetricKit легко добавить 💚 MetricKit можно использовать вместе с остальными метриками, но есть 2 нюанса: - Нужно учитывать, в каком они формате (их 3 - бакеты, количество и длительность) - Следить за единицами измерения 💚 Удобно использовать метрики в связке с Pro fi ler и с Organizer - они позволяют смотреть в моменте и регресс, а MetricKit позволяет смотреть в динамике от сборки к сборке 💚 Сопоставление MXMetricPayload vs MXDiagnosticPayload ❌ MXDiagnostic не доступен без dSYMs - не получится в реальном времени отслеживать данные ❌ Не все метрики кажутся полезными ❌ Perf tests Итоги
  34. 34. MetricKit What’s New in MetricKit Improving Your App's Performance Understanding Crashes and Crash Logs Why is my app getting killed Solving CPU Usage Crashes with Xcode's Energy Organizer Eliminate animation hitches with XCTest Identify trends with the Power and Performance API Telegraf VictoriaMetrics Grafana https://stackoverflow.com/questions/64378095/metrickit-mxdiagnostic-symbolication https://swiftrocks.com/debug-cpu-exceptions-xcode-energy-reports https://medium.com/naukri-engineering/overview-of-dsym-crashlytics-in-ios-dfd72eae8b58 iOS Performance Engineer Android Performance Engineer https://jobs.vivid.money/jobs/Careers/33579000004386184/iOS-developer-Performance-team-?source=CareerSite https://jobs.vivid.money/jobs/Careers/33579000004386170/Android-developer-Performance-team-?source=CareerSite

×