From 513fa6fc977cb2776e2e0f7e5415b3cbb3e82bba Mon Sep 17 00:00:00 2001 From: Alexandre Costanza Date: Wed, 17 Feb 2021 17:06:52 +0100 Subject: [PATCH 1/4] RUMM-1077 Make the RUMViewEvent mapper return a non-nil RUMViewEvent to disallow dropping view events --- Sources/Datadog/DatadogConfiguration.swift | 8 ++++---- Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift | 2 +- Sources/DatadogObjc/DatadogConfiguration+objc.swift | 4 ++-- .../Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift | 10 ++-------- .../DatadogObjc/DDConfigurationTests.swift | 4 +--- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Sources/Datadog/DatadogConfiguration.swift b/Sources/Datadog/DatadogConfiguration.swift index b153a1f251..81843b0010 100644 --- a/Sources/Datadog/DatadogConfiguration.swift +++ b/Sources/Datadog/DatadogConfiguration.swift @@ -454,10 +454,10 @@ extension Datadog { } /// Sets the custom mapper for `RUMViewEvent`. This can be used to modify RUM View events before they are send to Datadog. - /// - Parameter mapper: the closure taking `RUMViewEvent` as input and expecting `RUMViewEvent` or `nil` as output. - /// The implementation should obtain a mutable version of the `RUMViewEvent`, modify it and return. Returning `nil` will result - /// with dropping the RUM View event entirely, so it won't be send to Datadog. - public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent?) -> Builder { + /// - Parameter mapper: the closure taking `RUMViewEvent` as input and expecting `RUMViewEvent` as output. + /// The implementation should obtain a mutable version of the `RUMViewEvent`, modify it and return it. + /// Note that the mapper intentionally prevents from returning a `nil` to drop the `RUMViewEvent` entirely, this ensures that all `RUMViewEvent` are sent to Datadog. + public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent) -> Builder { configuration.rumViewEventMapper = mapper return self } diff --git a/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift b/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift index e64055d7a7..8882cd955f 100644 --- a/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift +++ b/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift @@ -6,7 +6,7 @@ import Foundation -internal typealias RUMViewEventMapper = (RUMViewEvent) -> RUMViewEvent? +internal typealias RUMViewEventMapper = (RUMViewEvent) -> RUMViewEvent internal typealias RUMErrorEventMapper = (RUMErrorEvent) -> RUMErrorEvent? internal typealias RUMResourceEventMapper = (RUMResourceEvent) -> RUMResourceEvent? internal typealias RUMActionEventMapper = (RUMActionEvent) -> RUMActionEvent? diff --git a/Sources/DatadogObjc/DatadogConfiguration+objc.swift b/Sources/DatadogObjc/DatadogConfiguration+objc.swift index 9cb8f426f7..2131aa0d09 100644 --- a/Sources/DatadogObjc/DatadogConfiguration+objc.swift +++ b/Sources/DatadogObjc/DatadogConfiguration+objc.swift @@ -231,10 +231,10 @@ public class DDConfigurationBuilder: NSObject { } @objc - public func setRUMViewEventMapper(_ mapper: @escaping (DDRUMViewEvent) -> DDRUMViewEvent?) { + public func setRUMViewEventMapper(_ mapper: @escaping (DDRUMViewEvent) -> DDRUMViewEvent) { _ = sdkBuilder.setRUMViewEventMapper { swiftEvent in let objcEvent = DDRUMViewEvent(swiftModel: swiftEvent) - return mapper(objcEvent)?.swiftModel + return mapper(objcEvent).swiftModel } } diff --git a/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift b/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift index 4260ddf6bd..23659761db 100644 --- a/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift @@ -88,17 +88,13 @@ class RUMEventsMapperTests: XCTestCase { } func testGivenMappersEnabled_whenDroppingEvents_itReturnsNil() { - let originalViewEvent: RUMViewEvent = .mockRandom() let originalErrorEvent: RUMErrorEvent = .mockRandom() let originalResourceEvent: RUMResourceEvent = .mockRandom() let originalActionEvent: RUMActionEvent = .mockRandom() // Given let mapper = RUMEventsMapper( - viewEventMapper: { viewEvent in - XCTAssertEqual(viewEvent, originalViewEvent, "Mapper should be called with the original event.") - return nil - }, + viewEventMapper: nil, errorEventMapper: { errorEvent in XCTAssertEqual(errorEvent, originalErrorEvent, "Mapper should be called with the original event.") return nil @@ -114,13 +110,11 @@ class RUMEventsMapperTests: XCTestCase { ) // When - let mappedViewEvent = mapper.map(event: RUMEvent.mockWith(model: originalViewEvent))?.model let mappedErrorEvent = mapper.map(event: RUMEvent.mockWith(model: originalErrorEvent))?.model let mappedResourceEvent = mapper.map(event: RUMEvent.mockWith(model: originalResourceEvent))?.model let mappedActionEvent = mapper.map(event: RUMEvent.mockWith(model: originalActionEvent))?.model // Then - XCTAssertNil(mappedViewEvent, "Mapper should return nil.") XCTAssertNil(mappedErrorEvent, "Mapper should return nil.") XCTAssertNil(mappedResourceEvent, "Mapper should return nil.") XCTAssertNil(mappedActionEvent, "Mapper should return nil.") @@ -163,7 +157,7 @@ class RUMEventsMapperTests: XCTestCase { // When let mapper = RUMEventsMapper( - viewEventMapper: { _ in nil }, + viewEventMapper: nil, errorEventMapper: { _ in nil }, resourceEventMapper: { _ in nil }, actionEventMapper: { _ in nil } diff --git a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift index ea6f4f288a..1711b439ea 100644 --- a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift +++ b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift @@ -123,7 +123,7 @@ class DDConfigurationTests: XCTestCase { objcBuilder.set(rumSessionsSamplingRate: 42.5) XCTAssertEqual(objcBuilder.build().sdkConfiguration.rumSessionsSamplingRate, 42.5) - objcBuilder.setRUMViewEventMapper { _ in nil } + objcBuilder.setRUMViewEventMapper { $0 } XCTAssertNotNil(objcBuilder.build().sdkConfiguration.rumViewEventMapper) objcBuilder.setRUMResourceEventMapper { _ in nil } @@ -212,14 +212,12 @@ class DDConfigurationTests: XCTestCase { environment: "tests" ) - objcBuilder.setRUMViewEventMapper { _ in nil } objcBuilder.setRUMResourceEventMapper { _ in nil } objcBuilder.setRUMActionEventMapper { _ in nil } objcBuilder.setRUMErrorEventMapper { _ in nil } let configuration = objcBuilder.build().sdkConfiguration - XCTAssertNil(configuration.rumViewEventMapper?(.mockRandom())) XCTAssertNil(configuration.rumResourceEventMapper?(.mockRandom())) XCTAssertNil(configuration.rumActionEventMapper?(.mockRandom())) XCTAssertNil(configuration.rumErrorEventMapper?(.mockRandom())) From 92688d2459eed1b28fc4c4a812010bb9c6a56b24 Mon Sep 17 00:00:00 2001 From: Alexandre Costanza Date: Wed, 17 Feb 2021 17:06:52 +0100 Subject: [PATCH 2/4] RUMM-1077 Make the RUMViewEvent mapper return a non-nil RUMViewEvent to disallow dropping view events --- Sources/Datadog/DatadogConfiguration.swift | 8 ++++---- Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift | 2 +- Sources/DatadogObjc/DatadogConfiguration+objc.swift | 4 ++-- .../Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift | 10 ++-------- .../DatadogObjc/DDConfigurationTests.swift | 4 +--- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Sources/Datadog/DatadogConfiguration.swift b/Sources/Datadog/DatadogConfiguration.swift index b153a1f251..81843b0010 100644 --- a/Sources/Datadog/DatadogConfiguration.swift +++ b/Sources/Datadog/DatadogConfiguration.swift @@ -454,10 +454,10 @@ extension Datadog { } /// Sets the custom mapper for `RUMViewEvent`. This can be used to modify RUM View events before they are send to Datadog. - /// - Parameter mapper: the closure taking `RUMViewEvent` as input and expecting `RUMViewEvent` or `nil` as output. - /// The implementation should obtain a mutable version of the `RUMViewEvent`, modify it and return. Returning `nil` will result - /// with dropping the RUM View event entirely, so it won't be send to Datadog. - public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent?) -> Builder { + /// - Parameter mapper: the closure taking `RUMViewEvent` as input and expecting `RUMViewEvent` as output. + /// The implementation should obtain a mutable version of the `RUMViewEvent`, modify it and return it. + /// Note that the mapper intentionally prevents from returning a `nil` to drop the `RUMViewEvent` entirely, this ensures that all `RUMViewEvent` are sent to Datadog. + public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent) -> Builder { configuration.rumViewEventMapper = mapper return self } diff --git a/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift b/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift index e64055d7a7..8882cd955f 100644 --- a/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift +++ b/Sources/Datadog/RUM/Scrubbing/RUMEventsMapper.swift @@ -6,7 +6,7 @@ import Foundation -internal typealias RUMViewEventMapper = (RUMViewEvent) -> RUMViewEvent? +internal typealias RUMViewEventMapper = (RUMViewEvent) -> RUMViewEvent internal typealias RUMErrorEventMapper = (RUMErrorEvent) -> RUMErrorEvent? internal typealias RUMResourceEventMapper = (RUMResourceEvent) -> RUMResourceEvent? internal typealias RUMActionEventMapper = (RUMActionEvent) -> RUMActionEvent? diff --git a/Sources/DatadogObjc/DatadogConfiguration+objc.swift b/Sources/DatadogObjc/DatadogConfiguration+objc.swift index 9cb8f426f7..2131aa0d09 100644 --- a/Sources/DatadogObjc/DatadogConfiguration+objc.swift +++ b/Sources/DatadogObjc/DatadogConfiguration+objc.swift @@ -231,10 +231,10 @@ public class DDConfigurationBuilder: NSObject { } @objc - public func setRUMViewEventMapper(_ mapper: @escaping (DDRUMViewEvent) -> DDRUMViewEvent?) { + public func setRUMViewEventMapper(_ mapper: @escaping (DDRUMViewEvent) -> DDRUMViewEvent) { _ = sdkBuilder.setRUMViewEventMapper { swiftEvent in let objcEvent = DDRUMViewEvent(swiftModel: swiftEvent) - return mapper(objcEvent)?.swiftModel + return mapper(objcEvent).swiftModel } } diff --git a/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift b/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift index 4260ddf6bd..23659761db 100644 --- a/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift +++ b/Tests/DatadogTests/Datadog/RUM/Scrubbing/RUMEventsMapperTests.swift @@ -88,17 +88,13 @@ class RUMEventsMapperTests: XCTestCase { } func testGivenMappersEnabled_whenDroppingEvents_itReturnsNil() { - let originalViewEvent: RUMViewEvent = .mockRandom() let originalErrorEvent: RUMErrorEvent = .mockRandom() let originalResourceEvent: RUMResourceEvent = .mockRandom() let originalActionEvent: RUMActionEvent = .mockRandom() // Given let mapper = RUMEventsMapper( - viewEventMapper: { viewEvent in - XCTAssertEqual(viewEvent, originalViewEvent, "Mapper should be called with the original event.") - return nil - }, + viewEventMapper: nil, errorEventMapper: { errorEvent in XCTAssertEqual(errorEvent, originalErrorEvent, "Mapper should be called with the original event.") return nil @@ -114,13 +110,11 @@ class RUMEventsMapperTests: XCTestCase { ) // When - let mappedViewEvent = mapper.map(event: RUMEvent.mockWith(model: originalViewEvent))?.model let mappedErrorEvent = mapper.map(event: RUMEvent.mockWith(model: originalErrorEvent))?.model let mappedResourceEvent = mapper.map(event: RUMEvent.mockWith(model: originalResourceEvent))?.model let mappedActionEvent = mapper.map(event: RUMEvent.mockWith(model: originalActionEvent))?.model // Then - XCTAssertNil(mappedViewEvent, "Mapper should return nil.") XCTAssertNil(mappedErrorEvent, "Mapper should return nil.") XCTAssertNil(mappedResourceEvent, "Mapper should return nil.") XCTAssertNil(mappedActionEvent, "Mapper should return nil.") @@ -163,7 +157,7 @@ class RUMEventsMapperTests: XCTestCase { // When let mapper = RUMEventsMapper( - viewEventMapper: { _ in nil }, + viewEventMapper: nil, errorEventMapper: { _ in nil }, resourceEventMapper: { _ in nil }, actionEventMapper: { _ in nil } diff --git a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift index ea6f4f288a..1711b439ea 100644 --- a/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift +++ b/Tests/DatadogTests/DatadogObjc/DDConfigurationTests.swift @@ -123,7 +123,7 @@ class DDConfigurationTests: XCTestCase { objcBuilder.set(rumSessionsSamplingRate: 42.5) XCTAssertEqual(objcBuilder.build().sdkConfiguration.rumSessionsSamplingRate, 42.5) - objcBuilder.setRUMViewEventMapper { _ in nil } + objcBuilder.setRUMViewEventMapper { $0 } XCTAssertNotNil(objcBuilder.build().sdkConfiguration.rumViewEventMapper) objcBuilder.setRUMResourceEventMapper { _ in nil } @@ -212,14 +212,12 @@ class DDConfigurationTests: XCTestCase { environment: "tests" ) - objcBuilder.setRUMViewEventMapper { _ in nil } objcBuilder.setRUMResourceEventMapper { _ in nil } objcBuilder.setRUMActionEventMapper { _ in nil } objcBuilder.setRUMErrorEventMapper { _ in nil } let configuration = objcBuilder.build().sdkConfiguration - XCTAssertNil(configuration.rumViewEventMapper?(.mockRandom())) XCTAssertNil(configuration.rumResourceEventMapper?(.mockRandom())) XCTAssertNil(configuration.rumActionEventMapper?(.mockRandom())) XCTAssertNil(configuration.rumErrorEventMapper?(.mockRandom())) From a194ed8bb9fb4115da5779b2dcc26b626e2ef1dc Mon Sep 17 00:00:00 2001 From: Alexandre Costanza Date: Thu, 18 Feb 2021 10:00:27 +0100 Subject: [PATCH 3/4] RUMM-1077 Update api-surface files --- api-surface-objc | 7 ++++++- api-surface-swift | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/api-surface-objc b/api-surface-objc index edfadc19b4..84a1caa307 100644 --- a/api-surface-objc +++ b/api-surface-objc @@ -56,7 +56,7 @@ public class DDConfigurationBuilder: NSObject public func trackUIKitRUMViews() public func trackUIKitRUMViews(using predicate: DDUIKitRUMViewsPredicate) public func trackUIKitActions() - public func setRUMViewEventMapper(_ mapper: @escaping (DDRUMViewEvent) -> DDRUMViewEvent?) + public func setRUMViewEventMapper(_ mapper: @escaping (DDRUMViewEvent) -> DDRUMViewEvent) public func setRUMResourceEventMapper(_ mapper: @escaping (DDRUMResourceEvent) -> DDRUMResourceEvent?) public func setRUMActionEventMapper(_ mapper: @escaping (DDRUMActionEvent) -> DDRUMActionEvent?) public func setRUMErrorEventMapper(_ mapper: @escaping (DDRUMErrorEvent) -> DDRUMErrorEvent?) @@ -186,6 +186,7 @@ public class DDRUMViewEventView: NSObject @objc public var action: DDRUMViewEventViewAction @objc public var crash: DDRUMViewEventViewCrash? @objc public var cumulativeLayoutShift: NSNumber? + @objc public var customTimings: [String: NSNumber]? @objc public var domComplete: NSNumber? @objc public var domContentLoaded: NSNumber? @objc public var domInteractive: NSNumber? @@ -200,6 +201,7 @@ public class DDRUMViewEventView: NSObject @objc public var loadingTime: NSNumber? @objc public var loadingType: DDRUMViewEventViewLoadingType @objc public var longTask: DDRUMViewEventViewLongTask? + @objc public var name: String? @objc public var referrer: String? @objc public var resource: DDRUMViewEventViewResource @objc public var timeSpent: NSNumber @@ -350,6 +352,7 @@ public class DDRUMResourceEventRUMUser: NSObject @objc public var name: String? public class DDRUMResourceEventView: NSObject @objc public var id: String + @objc public var name: String? @objc public var referrer: String? @objc public var url: String public class DDRUMActionEvent: NSObject @@ -428,6 +431,7 @@ public class DDRUMActionEventRUMUser: NSObject @objc public var name: String? public class DDRUMActionEventView: NSObject @objc public var id: String + @objc public var name: String? @objc public var referrer: String? @objc public var url: String public class DDRUMErrorEvent: NSObject @@ -529,6 +533,7 @@ public class DDRUMErrorEventRUMUser: NSObject @objc public var name: String? public class DDRUMErrorEventView: NSObject @objc public var id: String + @objc public var name: String? @objc public var referrer: String? @objc public var url: String public class DDRUMView: NSObject diff --git a/api-surface-swift b/api-surface-swift index 1d125e7961..421969d533 100644 --- a/api-surface-swift +++ b/api-surface-swift @@ -81,7 +81,7 @@ public class Datadog public func set(rumSessionsSamplingRate: Float) -> Builder public func trackUIKitRUMViews(using predicate: UIKitRUMViewsPredicate = DefaultUIKitRUMViewsPredicate()) -> Builder public func trackUIKitActions(_ enabled: Bool = true) -> Builder - public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent?) -> Builder + public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent) -> Builder public func setRUMResourceEventMapper(_ mapper: @escaping (RUMResourceEvent) -> RUMResourceEvent?) -> Builder public func setRUMActionEventMapper(_ mapper: @escaping (RUMActionEvent) -> RUMActionEvent?) -> Builder public func setRUMErrorEventMapper(_ mapper: @escaping (RUMErrorEvent) -> RUMErrorEvent?) -> Builder @@ -233,6 +233,7 @@ public struct RUMViewEvent: RUMDataModel public let action: Action public let crash: Crash? public let cumulativeLayoutShift: Double? + public let customTimings: [String: Int64]? public let domComplete: Int64? public let domContentLoaded: Int64? public let domInteractive: Int64? @@ -247,6 +248,7 @@ public struct RUMViewEvent: RUMDataModel public let loadingTime: Int64? public let loadingType: LoadingType? public let longTask: LongTask? + public var name: String? public var referrer: String? public let resource: Resource public let timeSpent: Int64 @@ -362,6 +364,7 @@ public struct RUMResourceEvent: RUMDataModel case synthetics = "synthetics" public struct View: Codable public let id: String + public var name: String? public var referrer: String? public var url: String public struct RUMActionEvent: RUMDataModel @@ -415,6 +418,7 @@ public struct RUMActionEvent: RUMDataModel case synthetics = "synthetics" public struct View: Codable public let id: String + public var name: String? public var referrer: String? public var url: String public struct RUMErrorEvent: RUMDataModel @@ -483,6 +487,7 @@ public struct RUMErrorEvent: RUMDataModel case synthetics = "synthetics" public struct View: Codable public let id: String + public var name: String? public var referrer: String? public var url: String public struct RUMConnectivity: Codable From 3625a0cbe61383fe25b3bbe85d265cb5c3f51286 Mon Sep 17 00:00:00 2001 From: Alexandre Costanza Date: Mon, 22 Feb 2021 16:30:40 +0100 Subject: [PATCH 4/4] RUMM-1077 Add reference to the UIKitRUMViewsPredicate API in doc --- Sources/Datadog/DatadogConfiguration.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/Datadog/DatadogConfiguration.swift b/Sources/Datadog/DatadogConfiguration.swift index 81843b0010..220932c81c 100644 --- a/Sources/Datadog/DatadogConfiguration.swift +++ b/Sources/Datadog/DatadogConfiguration.swift @@ -456,7 +456,10 @@ extension Datadog { /// Sets the custom mapper for `RUMViewEvent`. This can be used to modify RUM View events before they are send to Datadog. /// - Parameter mapper: the closure taking `RUMViewEvent` as input and expecting `RUMViewEvent` as output. /// The implementation should obtain a mutable version of the `RUMViewEvent`, modify it and return it. - /// Note that the mapper intentionally prevents from returning a `nil` to drop the `RUMViewEvent` entirely, this ensures that all `RUMViewEvent` are sent to Datadog. + /// + /// **NOTE** The mapper intentionally prevents from returning a `nil` to drop the `RUMViewEvent` entirely, this ensures that all `RUMViewEvent` are sent to Datadog. + /// + /// Use the `UIKitRUMViewsPredicate` API to ensure upstream consideration or filtering out of `UIViewController`/`RUMView`s. public func setRUMViewEventMapper(_ mapper: @escaping (RUMViewEvent) -> RUMViewEvent) -> Builder { configuration.rumViewEventMapper = mapper return self