Skip to content

Commit

Permalink
RUM-6850: Add more precision to Effective Sample Rate
Browse files Browse the repository at this point in the history
  • Loading branch information
simaoseica-dd committed Dec 17, 2024
1 parent 73b5f5c commit 6c9ac6a
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -235,27 +235,27 @@ class CoreTelemetryIntegrationTests: XCTestCase {
XCTAssertGreaterThan(usageEvents.count, 0)

let debug = try XCTUnwrap(debugEvents.first(where: { $0.telemetry.message == "Debug Telemetry" }))
XCTAssertEqual(debug.effectiveSampleRate, Int64(withNoOverflow: config.telemetrySampleRate))
XCTAssertEqual(debug.effectiveSampleRate, Double(config.telemetrySampleRate))

let error = try XCTUnwrap(errorEvents.first(where: { $0.telemetry.message == "Error Telemetry" }))
XCTAssertEqual(error.effectiveSampleRate, Int64(withNoOverflow: config.telemetrySampleRate))
XCTAssertEqual(error.effectiveSampleRate, Double(config.telemetrySampleRate))

let mobileMetric = try XCTUnwrap(debugEvents.first(where: { $0.telemetry.message == "[Mobile Metric] Metric Name" }))
XCTAssertEqual(
mobileMetric.effectiveSampleRate,
Int64(withNoOverflow: config.telemetrySampleRate.composed(with: metricsSampleRate))
Double(config.telemetrySampleRate.composed(with: metricsSampleRate))
)

let methodCalledMetric = try XCTUnwrap(debugEvents.first(where: { $0.telemetry.message == "[Mobile Metric] Method Called" }))
XCTAssertEqual(
methodCalledMetric.effectiveSampleRate,
Int64(withNoOverflow: config.telemetrySampleRate.composed(with: metricsSampleRate).composed(with: headSampleRate))
Double(config.telemetrySampleRate.composed(with: metricsSampleRate).composed(with: headSampleRate))
)

let usage = try XCTUnwrap(usageEvents.first)
XCTAssertEqual(
usage.effectiveSampleRate,
Int64(withNoOverflow: config.telemetrySampleRate.composed(with: metricsSampleRate))
Double(config.telemetrySampleRate.composed(with: metricsSampleRate))
)
}
}
2 changes: 2 additions & 0 deletions DatadogCore/Tests/Datadog/Mocks/RUMDataModelMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import TestUtilities
extension RUMUser {
static func mockRandom() -> RUMUser {
return RUMUser(
anonymousId: .mockRandom(),
email: .mockRandom(),
id: .mockRandom(),
name: .mockRandom(),
Expand Down Expand Up @@ -524,6 +525,7 @@ extension TelemetryConfigurationEvent: RandomMockable {
batchProcessingLevel: .mockRandom(),
batchSize: .mockAny(),
batchUploadFrequency: .mockAny(),
collectFeatureFlagsOn: nil,
compressIntakeRequests: nil,
defaultPrivacyLevel: .mockAny(),
forwardConsoleLogs: nil,
Expand Down
2 changes: 1 addition & 1 deletion DatadogCore/Tests/Datadog/RUM/RUMMonitorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ class RUMMonitorTests: XCTestCase {
monitor.stopView(viewController: mockView)

let rumEventMatchers = try core.waitAndReturnRUMEventMatchers()
let expectedUserInfo = RUMUser(email: "foo@bar.com", id: "abc-123", name: "Foo", usrInfo: [
let expectedUserInfo = RUMUser(anonymousId: nil, email: "foo@bar.com", id: "abc-123", name: "Foo", usrInfo: [
"str": AnyEncodable("value"),
"int": AnyEncodable(11_235),
"bool": AnyEncodable(true)
Expand Down
56 changes: 55 additions & 1 deletion DatadogObjc/Sources/RUM/RUMDataModels+objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,10 @@ public class DDRUMActionEventRUMUser: NSObject {
self.root = root
}

@objc public var anonymousId: String? {
root.swiftModel.usr!.anonymousId
}

@objc public var email: String? {
root.swiftModel.usr!.email
}
Expand Down Expand Up @@ -2381,6 +2385,10 @@ public class DDRUMErrorEventRUMUser: NSObject {
self.root = root
}

@objc public var anonymousId: String? {
root.swiftModel.usr!.anonymousId
}

@objc public var email: String? {
root.swiftModel.usr!.email
}
Expand Down Expand Up @@ -3329,6 +3337,10 @@ public class DDRUMLongTaskEventRUMUser: NSObject {
self.root = root
}

@objc public var anonymousId: String? {
root.swiftModel.usr!.anonymousId
}

@objc public var email: String? {
root.swiftModel.usr!.email
}
Expand Down Expand Up @@ -4611,6 +4623,10 @@ public class DDRUMResourceEventRUMUser: NSObject {
self.root = root
}

@objc public var anonymousId: String? {
root.swiftModel.usr!.anonymousId
}

@objc public var email: String? {
root.swiftModel.usr!.email
}
Expand Down Expand Up @@ -5525,6 +5541,10 @@ public class DDRUMViewEventRUMUser: NSObject {
self.root = root
}

@objc public var anonymousId: String? {
root.swiftModel.usr!.anonymousId
}

@objc public var email: String? {
root.swiftModel.usr!.email
}
Expand Down Expand Up @@ -6674,6 +6694,10 @@ public class DDRUMVitalEventRUMUser: NSObject {
self.root = root
}

@objc public var anonymousId: String? {
root.swiftModel.usr!.anonymousId
}

@objc public var email: String? {
root.swiftModel.usr!.email
}
Expand Down Expand Up @@ -7486,6 +7510,10 @@ public class DDTelemetryConfigurationEventTelemetryConfiguration: NSObject {
root.swiftModel.telemetry.configuration.batchUploadFrequency as NSNumber?
}

@objc public var collectFeatureFlagsOn: [Int]? {
root.swiftModel.telemetry.configuration.collectFeatureFlagsOn?.map { DDTelemetryConfigurationEventTelemetryConfigurationCollectFeatureFlagsOn(swift: $0).rawValue }
}

@objc public var compressIntakeRequests: NSNumber? {
root.swiftModel.telemetry.configuration.compressIntakeRequests as NSNumber?
}
Expand Down Expand Up @@ -7779,6 +7807,32 @@ public class DDTelemetryConfigurationEventTelemetryConfiguration: NSObject {
}
}

@objc
public enum DDTelemetryConfigurationEventTelemetryConfigurationCollectFeatureFlagsOn: Int {
internal init(swift: TelemetryConfigurationEvent.Telemetry.Configuration.CollectFeatureFlagsOn?) {
switch swift {
case nil: self = .none
case .view?: self = .view
case .error?: self = .error
case .vital?: self = .vital
}
}

internal var toSwift: TelemetryConfigurationEvent.Telemetry.Configuration.CollectFeatureFlagsOn? {
switch self {
case .none: return nil
case .view: return .view
case .error: return .error
case .vital: return .vital
}
}

case none
case view
case error
case vital
}

@objc
public class DDTelemetryConfigurationEventTelemetryConfigurationForwardConsoleLogs: NSObject {
internal let root: DDTelemetryConfigurationEvent
Expand Down Expand Up @@ -8008,4 +8062,4 @@ public class DDTelemetryConfigurationEventView: NSObject {

// swiftlint:enable force_unwrapping

// Generated from https://github.com/DataDog/rum-events-format/tree/f0fb6383cc401f2f3db120d1f3e2d95d8e03b981
// Generated from https://github.com/DataDog/rum-events-format/tree/81c3d7401cba2a2faf48b5f4c0e8aca05c759662
26 changes: 21 additions & 5 deletions DatadogRUM/Sources/DataModels/RUMDataModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3167,7 +3167,7 @@ public struct TelemetryErrorEvent: RUMDataModel {
public let date: Int64

/// The actual percentage of telemetry usage per event
public let effectiveSampleRate: Int64?
public let effectiveSampleRate: Double?

/// Enabled experimental features
public let experimentalFeatures: [String]?
Expand Down Expand Up @@ -3373,7 +3373,7 @@ public struct TelemetryDebugEvent: RUMDataModel {
public let date: Int64

/// The actual percentage of telemetry usage per event
public let effectiveSampleRate: Int64?
public let effectiveSampleRate: Double?

/// Enabled experimental features
public let experimentalFeatures: [String]?
Expand Down Expand Up @@ -3559,7 +3559,7 @@ public struct TelemetryConfigurationEvent: RUMDataModel {
public let date: Int64

/// The actual percentage of telemetry usage per event
public let effectiveSampleRate: Int64?
public let effectiveSampleRate: Double?

/// Enabled experimental features
public let experimentalFeatures: [String]?
Expand Down Expand Up @@ -3701,6 +3701,9 @@ public struct TelemetryConfigurationEvent: RUMDataModel {
/// The upload frequency of batches (in milliseconds)
public let batchUploadFrequency: Int64?

/// The list of events that include feature flags collection
public let collectFeatureFlagsOn: [CollectFeatureFlagsOn]?

/// Whether intake requests are compressed
public let compressIntakeRequests: Bool?

Expand Down Expand Up @@ -3902,6 +3905,7 @@ public struct TelemetryConfigurationEvent: RUMDataModel {
case batchProcessingLevel = "batch_processing_level"
case batchSize = "batch_size"
case batchUploadFrequency = "batch_upload_frequency"
case collectFeatureFlagsOn = "collect_feature_flags_on"
case compressIntakeRequests = "compress_intake_requests"
case dartVersion = "dart_version"
case defaultPrivacyLevel = "default_privacy_level"
Expand Down Expand Up @@ -3968,6 +3972,12 @@ public struct TelemetryConfigurationEvent: RUMDataModel {
case viewTrackingStrategy = "view_tracking_strategy"
}

public enum CollectFeatureFlagsOn: String, Codable {
case view = "view"
case error = "error"
case vital = "vital"
}

/// The console.* tracked
public enum ForwardConsoleLogs: Codable {
case stringsArray(value: [String])
Expand Down Expand Up @@ -4190,7 +4200,7 @@ public struct TelemetryUsageEvent: RUMDataModel {
public let date: Int64

/// The actual percentage of telemetry usage per event
public let effectiveSampleRate: Int64?
public let effectiveSampleRate: Double?

/// Enabled experimental features
public let experimentalFeatures: [String]?
Expand Down Expand Up @@ -4818,6 +4828,9 @@ public struct RUMSyntheticsTest: Codable {

/// User properties
public struct RUMUser: Codable {
/// Identifier of the user across sessions
public let anonymousId: String?

/// Email of the user
public let email: String?

Expand All @@ -4830,6 +4843,7 @@ public struct RUMUser: Codable {
public var usrInfo: [String: Encodable]

enum StaticCodingKeys: String, CodingKey {
case anonymousId = "anonymous_id"
case email = "email"
case id = "id"
case name = "name"
Expand All @@ -4840,6 +4854,7 @@ extension RUMUser {
public func encode(to encoder: Encoder) throws {
// Encode static properties:
var staticContainer = encoder.container(keyedBy: StaticCodingKeys.self)
try staticContainer.encodeIfPresent(anonymousId, forKey: .anonymousId)
try staticContainer.encodeIfPresent(email, forKey: .email)
try staticContainer.encodeIfPresent(id, forKey: .id)
try staticContainer.encodeIfPresent(name, forKey: .name)
Expand All @@ -4855,6 +4870,7 @@ extension RUMUser {
public init(from decoder: Decoder) throws {
// Decode static properties:
let staticContainer = try decoder.container(keyedBy: StaticCodingKeys.self)
self.anonymousId = try staticContainer.decodeIfPresent(String.self, forKey: .anonymousId)
self.email = try staticContainer.decodeIfPresent(String.self, forKey: .email)
self.id = try staticContainer.decodeIfPresent(String.self, forKey: .id)
self.name = try staticContainer.decodeIfPresent(String.self, forKey: .name)
Expand Down Expand Up @@ -4964,4 +4980,4 @@ public struct RUMTelemetryOperatingSystem: Codable {
}
}

// Generated from https://github.com/DataDog/rum-events-format/tree/f0fb6383cc401f2f3db120d1f3e2d95d8e03b981
// Generated from https://github.com/DataDog/rum-events-format/tree/81c3d7401cba2a2faf48b5f4c0e8aca05c759662
11 changes: 6 additions & 5 deletions DatadogRUM/Sources/Integrations/TelemetryReceiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ internal final class TelemetryReceiver: FeatureMessageReceiver {
action: rum?.userActionID.map { .init(id: $0) },
application: rum.map { .init(id: $0.applicationID) },
date: date.addingTimeInterval(context.serverTimeOffset).timeIntervalSince1970.toInt64Milliseconds,
effectiveSampleRate: Int64(withNoOverflow: self.sampler.samplingRate),
effectiveSampleRate: Double(self.sampler.samplingRate),
experimentalFeatures: nil,
service: "dd-sdk-ios",
session: rum.map { .init(id: $0.sessionID) },
Expand Down Expand Up @@ -158,7 +158,7 @@ internal final class TelemetryReceiver: FeatureMessageReceiver {
action: rum?.userActionID.map { .init(id: $0) },
application: rum.map { .init(id: $0.applicationID) },
date: date.addingTimeInterval(context.serverTimeOffset).timeIntervalSince1970.toInt64Milliseconds,
effectiveSampleRate: Int64(withNoOverflow: self.sampler.samplingRate),
effectiveSampleRate: Double(self.sampler.samplingRate),
experimentalFeatures: nil,
service: "dd-sdk-ios",
session: rum.map { .init(id: $0.sessionID) },
Expand Down Expand Up @@ -189,7 +189,7 @@ internal final class TelemetryReceiver: FeatureMessageReceiver {
action: rum?.userActionID.map { .init(id: $0) },
application: rum.map { .init(id: $0.applicationID) },
date: date.addingTimeInterval(context.serverTimeOffset).timeIntervalSince1970.toInt64Milliseconds,
effectiveSampleRate: Int64(withNoOverflow: usage.sampleRate.composed(with: self.sampler.samplingRate)),
effectiveSampleRate: Double(usage.sampleRate.composed(with: self.sampler.samplingRate)),
experimentalFeatures: nil,
service: "dd-sdk-ios",
session: rum.map { .init(id: $0.sessionID) },
Expand Down Expand Up @@ -229,7 +229,7 @@ internal final class TelemetryReceiver: FeatureMessageReceiver {
action: rum?.userActionID.map { .init(id: $0) },
application: rum.map { .init(id: $0.applicationID) },
date: date.addingTimeInterval(context.serverTimeOffset).timeIntervalSince1970.toInt64Milliseconds,
effectiveSampleRate: Int64(withNoOverflow: self.configurationExtraSampler.samplingRate.composed(with: self.sampler.samplingRate)),
effectiveSampleRate: Double(self.configurationExtraSampler.samplingRate.composed(with: self.sampler.samplingRate)),
experimentalFeatures: nil,
service: "dd-sdk-ios",
session: rum.map { .init(id: $0.sessionID) },
Expand Down Expand Up @@ -270,7 +270,7 @@ internal final class TelemetryReceiver: FeatureMessageReceiver {
action: rum?.userActionID.map { .init(id: $0) },
application: rum.map { .init(id: $0.applicationID) },
date: date.addingTimeInterval(context.serverTimeOffset).timeIntervalSince1970.toInt64Milliseconds,
effectiveSampleRate: Int64(withNoOverflow: effectiveSampleRate),
effectiveSampleRate: Double(effectiveSampleRate),
experimentalFeatures: nil,
service: "dd-sdk-ios",
session: sessionID.map { .init(id: $0) },
Expand Down Expand Up @@ -376,6 +376,7 @@ private extension TelemetryConfigurationEvent.Telemetry.Configuration {
batchProcessingLevel: configuration.batchProcessingLevel,
batchSize: configuration.batchSize,
batchUploadFrequency: configuration.batchUploadFrequency,
collectFeatureFlagsOn: nil,
compressIntakeRequests: nil,
dartVersion: configuration.dartVersion,
defaultPrivacyLevel: nil,
Expand Down
1 change: 1 addition & 0 deletions DatadogRUM/Sources/RUMEvent/RUMUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extension RUMUser {

init(userInfo: UserInfo) {
self.init(
anonymousId: nil,
email: userInfo.email,
id: userInfo.id,
name: userInfo.name,
Expand Down
2 changes: 2 additions & 0 deletions DatadogRUM/Tests/Mocks/RUMDataModelMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal func randomRUMEvent() -> RUMDataModel {
extension RUMUser: RandomMockable {
public static func mockRandom() -> RUMUser {
return RUMUser(
anonymousId: .mockRandom(),
email: .mockRandom(),
id: .mockRandom(),
name: .mockRandom(),
Expand Down Expand Up @@ -542,6 +543,7 @@ extension TelemetryConfigurationEvent: RandomMockable {
batchProcessingLevel: .mockRandom(),
batchSize: .mockAny(),
batchUploadFrequency: .mockRandom(),
collectFeatureFlagsOn: nil,
compressIntakeRequests: nil,
defaultPrivacyLevel: .mockRandom(),
forwardConsoleLogs: nil,
Expand Down
Loading

0 comments on commit 6c9ac6a

Please sign in to comment.