Skip to content

Commit

Permalink
Added FXIOS-7558 [v119] metric kit large disk write exception (backport
Browse files Browse the repository at this point in the history
#16826) (#16860)

* Added FXIOS-7558 [v119] metric kit large disk write exception (#16826)

* Add initial recording

* Add glean test

* Update Client/metrics.yaml

Co-authored-by: lmarceau <[email protected]>

---------

Co-authored-by: lmarceau <[email protected]>
(cherry picked from commit a8f0fb7)

* Fix conflict

* Fix lint issue

---------

Co-authored-by: OrlaM <[email protected]>
  • Loading branch information
mergify[bot] and OrlaM authored Oct 16, 2023
1 parent d79c2e0 commit 7c9c164
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
5A292129295CA8A900242235 /* ThemableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A96C4B828F9DD8700B75884 /* ThemableTests.swift */; };
5A29212A295CAA1700242235 /* XCTestCaseRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A96C4BA28F9E7B300B75884 /* XCTestCaseRootViewController.swift */; };
5A31275828906422001F30FA /* RecentlySavedDelegateMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31275728906422001F30FA /* RecentlySavedDelegateMock.swift */; };
5A32C2B62AD8517200A9B5A4 /* MetricKitWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A32C2B52AD8517200A9B5A4 /* MetricKitWrapper.swift */; };
5A37861429A2BFB9006B3A34 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 5A37861329A2BFB9006B3A34 /* Common */; };
5A37861929A2C337006B3A34 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 5A37861829A2C337006B3A34 /* Sentry */; };
5A37861D29A2C37C006B3A34 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 5A37861C29A2C37C006B3A34 /* Common */; };
Expand Down Expand Up @@ -4445,6 +4446,7 @@
5A1D409EB92D8E6AB8FC8813 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/ClearPrivateData.strings; sourceTree = "<group>"; };
5A271ABC2860B0D700471CE4 /* WebServerUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebServerUtil.swift; sourceTree = "<group>"; };
5A31275728906422001F30FA /* RecentlySavedDelegateMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlySavedDelegateMock.swift; sourceTree = "<group>"; };
5A32C2B52AD8517200A9B5A4 /* MetricKitWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricKitWrapper.swift; sourceTree = "<group>"; };
5A3A2A0C287F742C00B79EAC /* BackgroundSyncUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundSyncUtility.swift; sourceTree = "<group>"; };
5A3A7DCD2886F7880065F81A /* RecentlySavedDataAdaptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlySavedDataAdaptor.swift; sourceTree = "<group>"; };
5A3A7DD52889CF3D0065F81A /* RecentlySavedDataAdaptorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlySavedDataAdaptorTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -8026,6 +8028,14 @@
path = Theme;
sourceTree = "<group>";
};
5A32C2B42AD8515F00A9B5A4 /* MetricKit */ = {
isa = PBXGroup;
children = (
5A32C2B52AD8517200A9B5A4 /* MetricKitWrapper.swift */,
);
path = MetricKit;
sourceTree = "<group>";
};
5A3A7DD42889CF140065F81A /* RecentlySaved */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -10422,6 +10432,7 @@
E69DB0B91E97E301008A67E6 /* Telemetry */ = {
isa = PBXGroup;
children = (
5A32C2B42AD8515F00A9B5A4 /* MetricKit */,
8A359EF42A1FD4CF004A5BB7 /* Wrapper */,
43175DB726B87D2C00C41C31 /* AdsTelemetryHelper.swift */,
8AABBCFB2A0010900089941E /* GleanWrapper.swift */,
Expand Down Expand Up @@ -12997,6 +13008,7 @@
E13E9AB42AAB0FB5001A0E9D /* FakespotCoordinator.swift in Sources */,
E1442FD1294782D9003680B0 /* UIModalPresentationStyle+Photon.swift in Sources */,
5A8E7B6F29B8E5E500BF060F /* UIButton+Extensions.swift in Sources */,
5A32C2B62AD8517200A9B5A4 /* MetricKitWrapper.swift in Sources */,
D3FEC38D1AC4B42F00494F45 /* AutocompleteTextField.swift in Sources */,
8A19ACAE2A329058001C2147 /* PasswordManagerSetting.swift in Sources */,
AB03032C2AB47AF300DCD8EF /* FakespotOptInCardViewModel.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Client/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
private var backgroundWorkUtility: BackgroundFetchAndProcessingUtility?
private var widgetManager: TopSitesWidgetManager?
private var menuBuilderHelper: MenuBuilderHelper?
private var metricKitWrapper = MetricKitWrapper()

/// Tracking active status of the application.
private var isActive = false
Expand Down
40 changes: 40 additions & 0 deletions Client/Telemetry/MetricKit/MetricKitWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/

import Foundation
import MetricKit

class MetricKitWrapper: NSObject, MXMetricManagerSubscriber {
private let telemetryWrapper: TelemetryWrapperProtocol
private let measurementFormatter: MeasurementFormatter

init(telemetryWrapper: TelemetryWrapperProtocol = TelemetryWrapper.shared) {
self.telemetryWrapper = telemetryWrapper

self.measurementFormatter = MeasurementFormatter()
self.measurementFormatter.locale = Locale(identifier: "en_US")
self.measurementFormatter.unitOptions = .providedUnit

super.init()
MXMetricManager.shared.add(self)
}

func didReceive(_ payloads: [MXDiagnosticPayload]) {
payloads.forEach { payload in
payload.diskWriteExceptionDiagnostics?.forEach({ exception in
self.handleDiskWriteException(exception)
})
}
}

private func handleDiskWriteException(_ exception: MXDiskWriteExceptionDiagnostic) {
let size = Int32(measurementFormatter.string(from: exception.totalWritesCaused)) ?? -1
let eventExtra = [TelemetryWrapper.EventExtraKey.size.rawValue: size]
telemetryWrapper.recordEvent(category: .information,
method: .error,
object: .app,
value: .largeFileWrite,
extras: eventExtra)
}
}
10 changes: 10 additions & 0 deletions Client/Telemetry/TelemetryWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ extension TelemetryWrapper {
case invertColors = "invert-colors"
case switchControl = "switch-control"
case dynamicTextSize = "dynamic-text-size"
case error = "error"
}

public enum EventObject: String {
Expand Down Expand Up @@ -648,6 +649,7 @@ extension TelemetryWrapper {
case searchSuggestion = "search-suggestion"
case searchHighlights = "search-highlights"
case awesomebarShareTap = "awesomebar-share-tap"
case largeFileWrite = "large-file-write"
}

public enum EventExtraKey: String, CustomStringConvertible {
Expand All @@ -659,6 +661,7 @@ extension TelemetryWrapper {
case tabsQuantity = "tabsQuantity"
case isRestoreTabsStarted = "is-restore-tabs-started"
case awesomebarSearchTapType = "awesomebarSearchTapType"
case size = "size"

case preference = "pref"
case preferenceChanged = "to"
Expand Down Expand Up @@ -1651,6 +1654,13 @@ extension TelemetryWrapper {
GleanMetrics.ShareSheet.pocketActionTapped.record()
case (.action, .tap, .shareSheet, .shareSaveToPocket, _):
GleanMetrics.ShareSheet.saveToPocketTapped.record()

// MARK: - App Errors
case(.information, .error, .app, .largeFileWrite, let extras):
if let quantity = extras?[EventExtraKey.size.rawValue] as? Int32 {
let properties = GleanMetrics.AppErrors.LargeFileWriteExtra(size: quantity)
GleanMetrics.AppErrors.largeFileWrite.record(properties)
}
default:
recordUninstrumentedMetrics(category: category, method: method, object: object, value: value, extras: extras)
}
Expand Down
18 changes: 18 additions & 0 deletions Client/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4392,3 +4392,21 @@ baseline.validation:
expires: 2023-12-31
data_sensitivity:
- interaction

app_errors:
large_file_write:
type: event
description: |
Recorded when a very large file is written to disk
extra_keys:
size:
description: |
The size of the file that was written
type: quantity
bugs:
- https://mozilla-hub.atlassian.net/browse/FXIOS-7558
data_reviews:
- https://github.com/mozilla-mobile/firefox-ios/pull/16826
notification_emails:
- [email protected]
expires: never
13 changes: 13 additions & 0 deletions Tests/ClientTests/TelemetryWrapperTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,19 @@ class TelemetryWrapperTests: XCTestCase {
// TelemetryWrapper.recordEvent(category: .firefoxAccount, method: .view, object: .fxaLoginCompleteWebpage, value: nil)
// XCTAssertTrue(try Experiments.shared.createMessageHelper().evalJexl(expression: "'sync.login_completed_view'|eventSum('Days', 1, 0) > 0"))
}

// MARK: - App Errors

func test_error_largeFileWriteIsCalled() {
let eventExtra = [TelemetryWrapper.EventExtraKey.size.rawValue: Int32(1000)]
TelemetryWrapper.recordEvent(category: .information,
method: .error,
object: .app,
value: .largeFileWrite,
extras: eventExtra)

testEventMetricRecordingSuccess(metric: GleanMetrics.AppErrors.largeFileWrite)
}
}

// MARK: - Helper functions to test telemetry
Expand Down

0 comments on commit 7c9c164

Please sign in to comment.