Skip to content

Commit

Permalink
Merge pull request #1520 from DataDog/release/2.4.0
Browse files Browse the repository at this point in the history
Release 2.4.0
  • Loading branch information
ncreated authored Oct 18, 2023
2 parents 101fe09 + 93a47bb commit 506d662
Show file tree
Hide file tree
Showing 128 changed files with 2,883 additions and 2,065 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Unreleased

# 2.3.0 / 27-09-2023
# 2.4.0 / 18-10-2023

- [FEATURE] WebView Log events can be now sampled. See [#1515][]
- [BUGFIX] WebView RUM events are now dropped if mobile RUM session is not sampled. See [#1502][]
- [BUGFIX] Fix `os.name` in Log events. See [#1493][]

# 2.3.0 / 02-10-2023

- [IMPROVEMENT] Add UIBackgroundTask for uploading jobs. See [#1412][]
- [IMPROVEMENT] Report Build Number in Logs and RUM. See [#1465][]
Expand Down Expand Up @@ -533,8 +539,11 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[#1464]: https://github.com/DataDog/dd-sdk-ios/pull/1464
[#1412]: https://github.com/DataDog/dd-sdk-ios/pull/1412
[#1488]: https://github.com/DataDog/dd-sdk-ios/pull/1488
[#1502]: https://github.com/DataDog/dd-sdk-ios/pull/1502
[#1515]: https://github.com/DataDog/dd-sdk-ios/pull/1515
[#1465]: https://github.com/DataDog/dd-sdk-ios/pull/1465
[#1498]: https://github.com/DataDog/dd-sdk-ios/pull/1498
[#1493]: https://github.com/DataDog/dd-sdk-ios/pull/1493
[@00fa9a]: https://github.com/00FA9A
[@britton-earnin]: https://github.com/Britton-Earnin
[@hengyu]: https://github.com/Hengyu
Expand Down
188 changes: 121 additions & 67 deletions Datadog/Datadog.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

139 changes: 139 additions & 0 deletions Datadog/IntegrationUnitTests/Public/WebLogIntegrationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2019-Present Datadog, Inc.
*/

import XCTest

#if !os(tvOS)
import WebKit
import DatadogLogs
@testable import DatadogRUM
import DatadogWebViewTracking

class WebLogIntegrationTests: XCTestCase {
// swiftlint:disable implicitly_unwrapped_optional
private var core: DatadogCoreProxy! // swiftlint:disable:this implicitly_unwrapped_optional
private var controller: WKUserContentControllerMock!
// swiftlint:enable implicitly_unwrapped_optional

override func setUp() {
core = DatadogCoreProxy(
context: .mockWith(
env: "test",
version: "1.1.1",
serverTimeOffset: 123
)
)

controller = WKUserContentControllerMock()
let configuration = WKWebViewConfiguration()
configuration.userContentController = controller
let webView = WKWebView(frame: .zero, configuration: configuration)
WebViewTracking.enable(webView: webView, in: core)
}

override func tearDown() {
core.flushAndTearDown()
core = nil
controller = nil
}

func testWebLogIntegration() throws {
// Given
Logs.enable(in: core)

let body = """
{
"eventType": "log",
"event": {
"date" : \(1635932927012),
"status": "debug",
"message": "message",
"session_id": "0110cab4-7471-480e-aa4e-7ce039ced355",
"view": {
"referrer": "",
"url": "https://datadoghq.dev/browser-sdk-test-playground"
}
}
}
"""

// When
controller.send(body: body)
controller.flush()

// Then
let logMatcher = try XCTUnwrap(core.waitAndReturnLogMatchers().first)
try logMatcher.assertItFullyMatches(jsonString: """
{
"date": \(1_635_932_927_012 + 123.toInt64Milliseconds),
"ddtags": "version:1.1.1,env:test",
"message": "message",
"session_id": "0110cab4-7471-480e-aa4e-7ce039ced355",
"status": "debug",
"view": {
"referrer": "",
"url": "https://datadoghq.dev/browser-sdk-test-playground"
},
}
"""
)
}

func testWebLogWithRUMIntegration() throws {
// Given
let randomApplicationID: String = .mockRandom()
let randomUUID: UUID = .mockRandom()

Logs.enable(in: core)
RUM.enable(with: .mockWith(applicationID: randomApplicationID) {
$0.uuidGenerator = RUMUUIDGeneratorMock(uuid: randomUUID)
}, in: core)

let body = """
{
"eventType": "log",
"event": {
"date" : \(1635932927012),
"status": "debug",
"message": "message",
"session_id": "0110cab4-7471-480e-aa4e-7ce039ced355",
"view": {
"referrer": "",
"url": "https://datadoghq.dev/browser-sdk-test-playground"
}
}
}
"""

// When
RUMMonitor.shared(in: core).startView(key: "web-view")
controller.send(body: body)
controller.flush()

// Then
let expectedUUID = randomUUID.uuidString.lowercased()
let logMatcher = try XCTUnwrap(core.waitAndReturnLogMatchers().first)
try logMatcher.assertItFullyMatches(jsonString: """
{
"date": \(1_635_932_927_012 + 123.toInt64Milliseconds),
"ddtags": "version:1.1.1,env:test",
"message": "message",
"application_id": "\(randomApplicationID)",
"session_id": "\(expectedUUID)",
"view.id": "\(expectedUUID)",
"status": "debug",
"view": {
"referrer": "",
"url": "https://datadoghq.dev/browser-sdk-test-playground"
},
}
"""
)
}
}

#endif

4 changes: 2 additions & 2 deletions DatadogAlamofireExtension.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "DatadogAlamofireExtension"
s.version = "2.3.0"
s.version = "2.4.0"
s.summary = "An Official Extensions of Datadog Swift SDK for Alamofire."

s.homepage = "https://www.datadoghq.com"
Expand All @@ -14,7 +14,7 @@ Pod::Spec.new do |s|
"Maciej Burda" => "[email protected]"
}

s.swift_version = '5.8.0'
s.swift_version = '5.7.1'
s.ios.deployment_target = '11.0'
s.tvos.deployment_target = '11.0'

Expand Down
4 changes: 2 additions & 2 deletions DatadogCore.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "DatadogCore"
s.version = "2.3.0"
s.version = "2.4.0"
s.summary = "Official Datadog Swift SDK for iOS."

s.homepage = "https://www.datadoghq.com"
Expand All @@ -14,7 +14,7 @@ Pod::Spec.new do |s|
"Maciej Burda" => "[email protected]"
}

s.swift_version = '5.8.0'
s.swift_version = '5.7.1'
s.ios.deployment_target = '11.0'
s.tvos.deployment_target = '11.0'

Expand Down
22 changes: 6 additions & 16 deletions DatadogCore/Sources/Core/DatadogCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ extension DatadogCore: DatadogCoreProtocol {
/// A Feature can also communicate to other Features by sending message on the bus that is managed by the core.
///
/// - Parameter feature: The Feature instance.
/* public */ func register<T>(feature: T) throws where T: DatadogFeature {
func register<T>(feature: T) throws where T: DatadogFeature {
let featureDirectories = try directory.getFeatureDirectories(forFeatureNamed: T.name)

let performancePreset: PerformancePreset
Expand Down Expand Up @@ -274,11 +274,11 @@ extension DatadogCore: DatadogCoreProtocol {
/// - name: The Feature's name.
/// - type: The Feature instance type.
/// - Returns: The Feature if any.
/* public */ func get<T>(feature type: T.Type = T.self) -> T? where T: DatadogFeature {
func get<T>(feature type: T.Type = T.self) -> T? where T: DatadogFeature {
features[T.name] as? T
}

/* public */ func scope(for feature: String) -> FeatureScope? {
func scope(for feature: String) -> FeatureScope? {
guard let storage = stores[feature]?.storage else {
return nil
}
Expand All @@ -290,21 +290,11 @@ extension DatadogCore: DatadogCoreProtocol {
)
}

/* public */ func set(feature: String, attributes: @escaping () -> FeatureBaggage) {
contextProvider.write { $0.featuresAttributes[feature] = attributes() }
func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) {
contextProvider.write { $0.baggages[key] = baggage() }
}

func update(feature: String, attributes: @escaping () -> FeatureBaggage) {
contextProvider.write {
if $0.featuresAttributes[feature] != nil {
$0.featuresAttributes[feature]?.merge(with: attributes())
} else {
$0.featuresAttributes[feature] = attributes()
}
}
}

/* public */ func send(message: FeatureMessage, else fallback: @escaping () -> Void) {
func send(message: FeatureMessage, else fallback: @escaping () -> Void) {
bus.send(message: message, else: fallback)
}
}
Expand Down
28 changes: 20 additions & 8 deletions DatadogCore/Sources/Core/Storage/FeatureStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,25 +120,37 @@ extension FeatureStorage {
encryption: DataEncryption?,
telemetry: Telemetry
) {
let trackName = BatchMetric.trackValue(for: featureName)

if trackName == nil {
DD.logger.error("Can't determine track name for feature named '\(featureName)'")
}

let authorizedFilesOrchestrator = FilesOrchestrator(
directory: directories.authorized,
performance: performance,
dateProvider: dateProvider,
telemetry: telemetry,
metricsData: {
guard let trackName = BatchMetric.trackValue(for: featureName) else {
DD.logger.error("Can't determine track name for feature named '\(featureName)'")
return nil
}
return FilesOrchestrator.MetricsData(trackName: trackName, uploaderPerformance: performance)
}()
metricsData: trackName.map { trackName in
return FilesOrchestrator.MetricsData(
trackName: trackName,
consentLabel: BatchMetric.consentGrantedValue,
uploaderPerformance: performance
)
}
)
let unauthorizedFilesOrchestrator = FilesOrchestrator(
directory: directories.unauthorized,
performance: performance,
dateProvider: dateProvider,
telemetry: telemetry,
metricsData: nil // do not send metrics for unauthorized orchestrator
metricsData: trackName.map { trackName in
return FilesOrchestrator.MetricsData(
trackName: trackName,
consentLabel: BatchMetric.consentPendingValue,
uploaderPerformance: performance
)
}
)

self.init(
Expand Down
4 changes: 4 additions & 0 deletions DatadogCore/Sources/Core/Storage/FilesOrchestrator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ internal class FilesOrchestrator: FilesOrchestratorType {
struct MetricsData {
/// The name of the track reported for this orchestrator.
let trackName: String
/// The label indicating the value of tracking consent that this orchestrator manages files for.
let consentLabel: String
/// The preset for uploader performance in this feature to include in metric.
let uploaderPerformance: UploadPerformancePreset
}
Expand Down Expand Up @@ -252,6 +254,7 @@ internal class FilesOrchestrator: FilesOrchestratorType {
BatchDeletedMetric.uploaderDelayMinKey: metricsData.uploaderPerformance.minUploadDelay.toMilliseconds,
BatchDeletedMetric.uploaderDelayMaxKey: metricsData.uploaderPerformance.maxUploadDelay.toMilliseconds,
],
BatchMetric.consentKey: metricsData.consentLabel,
BatchDeletedMetric.uploaderWindowKey: performance.uploaderWindow.toMilliseconds,
BatchDeletedMetric.batchAgeKey: batchAge.toMilliseconds,
BatchDeletedMetric.batchRemovalReasonKey: deletionReason.toString(),
Expand All @@ -276,6 +279,7 @@ internal class FilesOrchestrator: FilesOrchestratorType {
attributes: [
BatchMetric.typeKey: BatchClosedMetric.typeValue,
BatchMetric.trackKey: metricsData.trackName,
BatchMetric.consentKey: metricsData.consentLabel,
BatchClosedMetric.uploaderWindowKey: performance.uploaderWindow.toMilliseconds,
BatchClosedMetric.batchSizeKey: lastWritableFileApproximatedSize,
BatchClosedMetric.batchEventsCountKey: lastWritableFileObjectsCount,
Expand Down
7 changes: 7 additions & 0 deletions DatadogCore/Sources/Utils/CoreMetrics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ internal enum BatchMetric {
default: return nil
}
}
/// Consent label key.
/// It is added to differentiate telemetries for batches handled in `pending` and `granted` consents.
static let consentKey = "consent"
/// "granted" consent value.
static let consentGrantedValue = "granted"
/// "pending" consent value.
static let consentPendingValue = "pending"
}

/// Definition of "Batch Deleted" telemetry.
Expand Down
2 changes: 1 addition & 1 deletion DatadogCore/Sources/Versioning.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// GENERATED FILE: Do not edit directly

internal let __sdkVersion = "2.3.0"
internal let __sdkVersion = "2.4.0"
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ class FilesOrchestrator_MetricsTests: XCTestCase {
performance: PerformancePreset.combining(storagePerformance: storage, uploadPerformance: upload),
dateProvider: dateProvider,
telemetry: telemetry,
metricsData: .init(trackName: "track name", uploaderPerformance: upload)
metricsData: FilesOrchestrator.MetricsData(
trackName: "track name",
consentLabel: "consent value",
uploaderPerformance: upload
)
)
}

Expand All @@ -57,6 +61,7 @@ class FilesOrchestrator_MetricsTests: XCTestCase {
DDAssertReflectionEqual(metric.attributes, [
"metric_type": "batch deleted",
"track": "track name",
"consent": "consent value",
"uploader_delay": [
"min": upload.minUploadDelay.toMilliseconds,
"max": upload.maxUploadDelay.toMilliseconds
Expand Down Expand Up @@ -85,6 +90,7 @@ class FilesOrchestrator_MetricsTests: XCTestCase {
DDAssertReflectionEqual(metric.attributes, [
"metric_type": "batch deleted",
"track": "track name",
"consent": "consent value",
"uploader_delay": [
"min": upload.minUploadDelay.toMilliseconds,
"max": upload.maxUploadDelay.toMilliseconds
Expand Down Expand Up @@ -116,6 +122,7 @@ class FilesOrchestrator_MetricsTests: XCTestCase {
DDAssertReflectionEqual(metric.attributes, [
"metric_type": "batch deleted",
"track": "track name",
"consent": "consent value",
"uploader_delay": [
"min": upload.minUploadDelay.toMilliseconds,
"max": upload.maxUploadDelay.toMilliseconds
Expand Down Expand Up @@ -150,6 +157,7 @@ class FilesOrchestrator_MetricsTests: XCTestCase {
DDAssertReflectionEqual(metric.attributes, [
"metric_type": "batch closed",
"track": "track name",
"consent": "consent value",
"uploader_window": storage.uploaderWindow.toMilliseconds,
"batch_size": expectedWrites.reduce(0, +),
"batch_events_count": expectedWrites.count,
Expand Down Expand Up @@ -180,6 +188,7 @@ class FilesOrchestrator_MetricsTests: XCTestCase {
DDAssertReflectionEqual(metric.attributes, [
"metric_type": "batch closed",
"track": "track name",
"consent": "consent value",
"uploader_window": storage.uploaderWindow.toMilliseconds,
"batch_size": expectedWrites.reduce(0, +),
"batch_events_count": expectedWrites.count,
Expand Down
Loading

0 comments on commit 506d662

Please sign in to comment.