Skip to content

Commit

Permalink
Merge pull request #377 from DataDog/ncreated/RUMM-924-add-data-scrub…
Browse files Browse the repository at this point in the history
…bing-and-gdpr-docs

RUMM-924 Add Data Scrubbing and GDPR docs
  • Loading branch information
ncreated authored Mar 4, 2021
2 parents 9f18bea + 1d65b6d commit abf6bc8
Show file tree
Hide file tree
Showing 41 changed files with 969 additions and 214 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tools:
@echo "OK 👌"

# The release version of `dd-sdk-swift-testing` to use for tests instrumentation.
DD_SDK_SWIFT_TESTING_VERSION = 0.5.1
DD_SDK_SWIFT_TESTING_VERSION = 0.6.0

define DD_SDK_TESTING_XCCONFIG_CI
FRAMEWORK_SEARCH_PATHS=$$(inherited) $$(SRCROOT)/../instrumented-tests/DatadogSDKTesting.xcframework/ios-arm64_x86_64-simulator/\n
Expand Down
8 changes: 8 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ let package = Package(
name: "DatadogObjc",
type: .dynamic,
targets: ["DatadogObjc"]),
.library(
name: "DatadogStatic",
type: .static,
targets: ["Datadog"]),
.library(
name: "DatadogStaticObjc",
type: .static,
targets: ["DatadogObjc"]),
],
dependencies: [
.package(url: "https://github.com/lyft/Kronos.git", .upToNextMinor(from: "4.1.0"))
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ See [Datadog iOS Trace Collection](https://docs.datadoghq.com/tracing/setup/ios/

![Datadog iOS Log Collection](docs/images/tracing.png)

### RUM Events Collection

See [Datadog iOS RUM Collection](https://docs.datadoghq.com/real_user_monitoring/ios/?tab=us) documentation to try it out.

![Datadog iOS RUM Collection](docs/images/rum.png)

## Integrations

### Alamofire
Expand Down
20 changes: 1 addition & 19 deletions Sources/Datadog/Core/Utils/JSONEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,7 @@ extension JSONEncoder {
try container.encode(formatted)
}
if #available(iOS 13.0, OSX 10.15, *) {
// NOTE: The `.sortedKeys` option was added in RUMM-776 after discovering an issue
// with backend processing of the RUM View payloads. The custom timings encoding for
// RUM views requires following structure:
//
// ```
// {
// view: { /* serialized, auto-generated RUM view event */ },
// view.custom_timings.<custom-timing-1-name>: <custom-timing-value>,
// view.custom_timings.<custom-timing-2-name>: <custom-timing-value>
// ...
// }
// ```
//
// To guarantee proper backend-side processing, the `view.custom_timings` keys must be
// encoded after the `view` object. Using `.sortedKeys` enforces this order.
//
encoder.outputFormatting = [.withoutEscapingSlashes, .sortedKeys]
} else {
encoder.outputFormatting = [.sortedKeys]
encoder.outputFormatting = [.withoutEscapingSlashes]
}
return encoder
}
Expand Down
22 changes: 21 additions & 1 deletion Sources/Datadog/RUM/DataModels/RUMDataModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ public struct RUMViewEvent: RUMDataModel {
/// Total layout shift score that occured on the view
public let cumulativeLayoutShift: Double?

/// User custom timings of the view. As timing name is used as facet path, it must contain only letters, digits, or the characters - _ . @ $
public let customTimings: [String: Int64]?

/// Duration in ns to the complete parsing and loading of the document and its sub resources
public let domComplete: Int64?

Expand Down Expand Up @@ -150,6 +153,9 @@ public struct RUMViewEvent: RUMDataModel {
/// Properties of the long tasks of the view
public let longTask: LongTask?

/// User defined name of the view
public var name: String?

/// URL that linked to the initial view of the page
public var referrer: String?

Expand All @@ -166,6 +172,7 @@ public struct RUMViewEvent: RUMDataModel {
case action = "action"
case crash = "crash"
case cumulativeLayoutShift = "cumulative_layout_shift"
case customTimings = "custom_timings"
case domComplete = "dom_complete"
case domContentLoaded = "dom_content_loaded"
case domInteractive = "dom_interactive"
Expand All @@ -180,6 +187,7 @@ public struct RUMViewEvent: RUMDataModel {
case loadingTime = "loading_time"
case loadingType = "loading_type"
case longTask = "long_task"
case name = "name"
case referrer = "referrer"
case resource = "resource"
case timeSpent = "time_spent"
Expand Down Expand Up @@ -562,6 +570,9 @@ public struct RUMResourceEvent: RUMDataModel {
/// UUID of the view
public let id: String

/// User defined name of the view
public var name: String?

/// URL that linked to the initial view of the page
public var referrer: String?

Expand All @@ -570,6 +581,7 @@ public struct RUMResourceEvent: RUMDataModel {

enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case referrer = "referrer"
case url = "url"
}
Expand Down Expand Up @@ -769,6 +781,9 @@ public struct RUMActionEvent: RUMDataModel {
/// UUID of the view
public let id: String

/// User defined name of the view
public var name: String?

/// URL that linked to the initial view of the page
public var referrer: String?

Expand All @@ -777,6 +792,7 @@ public struct RUMActionEvent: RUMDataModel {

enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case referrer = "referrer"
case url = "url"
}
Expand Down Expand Up @@ -990,6 +1006,9 @@ public struct RUMErrorEvent: RUMDataModel {
/// UUID of the view
public let id: String

/// User defined name of the view
public var name: String?

/// URL that linked to the initial view of the page
public var referrer: String?

Expand All @@ -998,6 +1017,7 @@ public struct RUMErrorEvent: RUMDataModel {

enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case referrer = "referrer"
case url = "url"
}
Expand Down Expand Up @@ -1083,4 +1103,4 @@ public enum RUMMethod: String, Codable {
case patch = "PATCH"
}

// Generated from https://github.com/DataDog/rum-events-format/tree/8b955a03d0fe0b2f032a02d6800c61ef3fc9fada
// Generated from https://github.com/DataDog/rum-events-format/tree/a37c41a4ac1aa3bfdc8d1fcecb35e4d1e07adddc
6 changes: 2 additions & 4 deletions Sources/Datadog/RUM/RUMEvent/RUMEventBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ internal class RUMEventBuilder {

func createRUMEvent<DM: RUMDataModel>(
with model: DM,
attributes: [String: Encodable],
customTimings: [String: Int64]? = nil
attributes: [String: Encodable]
) -> RUMEvent<DM> {
return RUMEvent(
model: model,
attributes: attributes,
userInfoAttributes: userInfoProvider.value.extraInfo,
customViewTimings: customTimings
userInfoAttributes: userInfoProvider.value.extraInfo
)
}
}
6 changes: 0 additions & 6 deletions Sources/Datadog/RUM/RUMEvent/RUMEventEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ internal struct RUMEvent<DM: RUMDataModel>: Encodable {
var attributes: [String: Encodable]
var userInfoAttributes: [String: Encodable]

/// Custom View timings (only available if `DM` is a RUM View model)
var customViewTimings: [String: Int64]?

func encode(to encoder: Encoder) throws {
let sanitizedEvent = RUMEventSanitizer().sanitize(event: self)
try RUMEventEncoder().encode(sanitizedEvent, to: encoder)
Expand All @@ -45,9 +42,6 @@ internal struct RUMEventEncoder {
try event.userInfoAttributes.forEach { attributeName, attributeValue in
try attributesContainer.encode(EncodableValue(attributeValue), forKey: DynamicCodingKey("context.usr.\(attributeName)"))
}
try event.customViewTimings?.forEach { timingName, timingDuration in
try attributesContainer.encode(timingDuration, forKey: DynamicCodingKey("view.custom_timings.\(timingName)"))
}

// Encode `RUMDataModel`
try event.model.encode(to: encoder)
Expand Down
14 changes: 3 additions & 11 deletions Sources/Datadog/RUM/RUMEvent/RUMEventSanitizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,24 @@ internal struct RUMEventSanitizer {

func sanitize<DM: RUMDataModel>(event: RUMEvent<DM>) -> RUMEvent<DM> {
// Sanitize attribute names
var sanitizedTimings = event.customViewTimings.flatMap { attributesSanitizer.sanitizeKeys(for: $0) }
var sanitizedUserExtraInfo = attributesSanitizer.sanitizeKeys(for: event.userInfoAttributes)
var sanitizedAttributes = attributesSanitizer.sanitizeKeys(for: event.attributes)

// Limit to max number of attributes.
// If any attributes need to be removed, we first reduce number of
// event attributes, then user info extra attributes, then custom timings.
sanitizedTimings = sanitizedTimings.flatMap { timings in
attributesSanitizer.limitNumberOf(
attributes: timings,
to: AttributesSanitizer.Constraints.maxNumberOfAttributes
)
}
// event attributes, then user info extra attributes.
sanitizedUserExtraInfo = attributesSanitizer.limitNumberOf(
attributes: sanitizedUserExtraInfo,
to: AttributesSanitizer.Constraints.maxNumberOfAttributes - (sanitizedTimings?.count ?? 0)
to: AttributesSanitizer.Constraints.maxNumberOfAttributes
)
sanitizedAttributes = attributesSanitizer.limitNumberOf(
attributes: sanitizedAttributes,
to: AttributesSanitizer.Constraints.maxNumberOfAttributes - (sanitizedTimings?.count ?? 0) - sanitizedUserExtraInfo.count
to: AttributesSanitizer.Constraints.maxNumberOfAttributes - sanitizedUserExtraInfo.count
)

var sanitizedEvent = event
sanitizedEvent.attributes = sanitizedAttributes
sanitizedEvent.userInfoAttributes = sanitizedUserExtraInfo
sanitizedEvent.customViewTimings = sanitizedTimings
return sanitizedEvent
}
}
3 changes: 2 additions & 1 deletion Sources/Datadog/RUM/RUMMonitor/Scopes/RUMViewScope.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider {
action: .init(count: actionsCount.toInt64),
crash: nil,
cumulativeLayoutShift: nil,
customTimings: customTimings,
domComplete: nil,
domContentLoaded: nil,
domInteractive: nil,
Expand All @@ -291,7 +292,7 @@ internal class RUMViewScope: RUMScope, RUMContextProvider {
)
)

let event = dependencies.eventBuilder.createRUMEvent(with: eventData, attributes: attributes, customTimings: customTimings)
let event = dependencies.eventBuilder.createRUMEvent(with: eventData, attributes: attributes)
dependencies.eventOutput.write(rumEvent: event)
}

Expand Down
26 changes: 25 additions & 1 deletion Sources/DatadogObjc/RUM/RUMDataModels+objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ public class DDRUMViewEventView: NSObject {
root.swiftModel.view.cumulativeLayoutShift as NSNumber?
}

@objc public var customTimings: [String: NSNumber]? {
root.swiftModel.view.customTimings as [String: NSNumber]?
}

@objc public var domComplete: NSNumber? {
root.swiftModel.view.domComplete as NSNumber?
}
Expand Down Expand Up @@ -327,6 +331,11 @@ public class DDRUMViewEventView: NSObject {
root.swiftModel.view.longTask != nil ? DDRUMViewEventViewLongTask(root: root) : nil
}

@objc public var name: String? {
set { root.swiftModel.view.name = newValue }
get { root.swiftModel.view.name }
}

@objc public var referrer: String? {
set { root.swiftModel.view.referrer = newValue }
get { root.swiftModel.view.referrer }
Expand Down Expand Up @@ -1056,6 +1065,11 @@ public class DDRUMResourceEventView: NSObject {
root.swiftModel.view.id
}

@objc public var name: String? {
set { root.swiftModel.view.name = newValue }
get { root.swiftModel.view.name }
}

@objc public var referrer: String? {
set { root.swiftModel.view.referrer = newValue }
get { root.swiftModel.view.referrer }
Expand Down Expand Up @@ -1461,6 +1475,11 @@ public class DDRUMActionEventView: NSObject {
root.swiftModel.view.id
}

@objc public var name: String? {
set { root.swiftModel.view.name = newValue }
get { root.swiftModel.view.name }
}

@objc public var referrer: String? {
set { root.swiftModel.view.referrer = newValue }
get { root.swiftModel.view.referrer }
Expand Down Expand Up @@ -1949,6 +1968,11 @@ public class DDRUMErrorEventView: NSObject {
root.swiftModel.view.id
}

@objc public var name: String? {
set { root.swiftModel.view.name = newValue }
get { root.swiftModel.view.name }
}

@objc public var referrer: String? {
set { root.swiftModel.view.referrer = newValue }
get { root.swiftModel.view.referrer }
Expand All @@ -1962,4 +1986,4 @@ public class DDRUMErrorEventView: NSObject {

// swiftlint:enable force_unwrapping

// Generated from https://github.com/DataDog/rum-events-format/tree/8b955a03d0fe0b2f032a02d6800c61ef3fc9fada
// Generated from https://github.com/DataDog/rum-events-format/tree/a37c41a4ac1aa3bfdc8d1fcecb35e4d1e07adddc
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class RUMStorageBenchmarkTests: XCTestCase {
action: .init(count: .mockAny()),
crash: .init(count: .mockAny()),
cumulativeLayoutShift: nil,
customTimings: .mockAny(),
domComplete: nil,
domContentLoaded: nil,
domInteractive: nil,
Expand All @@ -120,8 +121,7 @@ class RUMStorageBenchmarkTests: XCTestCase {
)
),
attributes: ["attribute": "value"],
userInfoAttributes: ["str": "value", "int": 11_235, "bool": true],
customViewTimings: nil
userInfoAttributes: ["str": "value", "int": 11_235, "bool": true]
)
}
}
27 changes: 0 additions & 27 deletions Tests/DatadogTests/Datadog/Core/Utils/JSONEncoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,4 @@ class JSONEncoderTests: XCTestCase {
XCTAssertEqual(encodedURL.utf8String, #"{"value":"https:\/\/example.com\/foo"}"#)
}
}

func testWhenEncoding_thenKeysFollowLexicographicOrder() throws {
struct Foo: Codable {
var one = 1
var two = 1
var three = 1
var four = 1
var five = 1

enum CodingKeys: String, CodingKey {
case one = "aaaaaa"
case two = "bb"
case three = "aaa"
case four = "bbb"
case five = "aaa.aaa"
}
}

// When
let encodedFoo = try jsonEncoder.encode(Foo())

// Then
XCTAssertEqual(
encodedFoo.utf8String,
#"{"aaa":1,"aaa.aaa":1,"aaaaaa":1,"bb":1,"bbb":1}"#
)
}
}
1 change: 1 addition & 0 deletions Tests/DatadogTests/Datadog/Mocks/RUMDataModelMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ extension RUMViewEvent {
action: .init(count: .mockRandom()),
crash: .init(count: .mockRandom()),
cumulativeLayoutShift: .mockRandom(),
customTimings: .mockAny(),
domComplete: .mockRandom(),
domContentLoaded: .mockRandom(),
domInteractive: .mockRandom(),
Expand Down
Loading

0 comments on commit abf6bc8

Please sign in to comment.