Skip to content

Commit

Permalink
Merge pull request #1948 from DataDog/mconstantin/merge-develop-branc…
Browse files Browse the repository at this point in the history
…e-into-otel

Merge develop branch
  • Loading branch information
mariusc83 authored Mar 28, 2024
2 parents c224901 + 364a08b commit 3cfe958
Show file tree
Hide file tree
Showing 261 changed files with 10,069 additions and 4,429 deletions.
5 changes: 3 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
# Copyright 2016-Present Datadog, Inc.

[*.{kt,kts}]
ktlint_code_style = ktlint_official
indent_size = unset
ktlint_code_style = android_studio
ij_kotlin_allow_trailing_comma_on_call_site = false
ij_kotlin_allow_trailing_comma = false
ij_kotlin_imports_layout=*,java.**,javax.**,kotlin.**,^
max_line_length = 120

# Code generated by KotlinPoet
[buildSrc/src/test/kotlin/com/example/model/*.kt]
Expand Down
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
# 2.7.0 / 2024-03-21

* [FEATURE] Session Replay: Add a request builder for resources. See [#1827](https://github.com/DataDog/dd-sdk-android/pull/1827)
* [FEATURE] Session Replay: Add Resources feature. See [#1840](https://github.com/DataDog/dd-sdk-android/pull/1840)
* [FEATURE] Session Replay: Implement resource capture during traversal. See [#1854](https://github.com/DataDog/dd-sdk-android/pull/1854)
* [FEATURE] Add `source_type` when sent from cross platform logs. See [#1895](https://github.com/DataDog/dd-sdk-android/pull/1895)
* [FEATURE] Session Replay: Enable Resource Endpoint by default. See [#1858](https://github.com/DataDog/dd-sdk-android/pull/1858)
* [FEATURE] Logs: Add support for global attributes on logs. See [#1900](https://github.com/DataDog/dd-sdk-android/pull/1900)
* [FEATURE] RUM: Allow setting custom error fingerprint. See [#1911](https://github.com/DataDog/dd-sdk-android/pull/1911)
* [FEATURE] RUM: Report all threads for non-fatal ANRs. See [#1912](https://github.com/DataDog/dd-sdk-android/pull/1912)
* [FEATURE] RUM: Report fatal ANRs. See [#1909](https://github.com/DataDog/dd-sdk-android/pull/1909)
* [BUGFIX] Session Replay: Avoid crash when `applicationContext` is `null`. See [#1864](https://github.com/DataDog/dd-sdk-android/pull/1864)
* [BUGFIX] Session Replay: Fix image resizing issue. See [#1897](https://github.com/DataDog/dd-sdk-android/pull/1897)
* [BUGFIX] Fix typo in source type. See [#1904](https://github.com/DataDog/dd-sdk-android/pull/1904)
* [BUGFIX] RUM: Prevent `ConcurrentModificationException` when reading feature flags. See [#1925](https://github.com/DataDog/dd-sdk-android/pull/1925)
* [IMPROVEMENT] RUM: Disable non-fatal ANR reporting by default. See [#1914](https://github.com/DataDog/dd-sdk-android/pull/1914)
* [IMPROVEMENT] RUM: Introduce `error.category` attribute for exceptions, categorize ANRs separately. See [#1918](https://github.com/DataDog/dd-sdk-android/pull/1918)
* [MAINTENANCE] Next dev iteration. See [#1861](https://github.com/DataDog/dd-sdk-android/pull/1861)
* [MAINTENANCE] Merge `release/2.6.0` in `develop`. See [#1862](https://github.com/DataDog/dd-sdk-android/pull/1862)
* [MAINTENANCE] Merge `release/2.6.1` changes into `develop` branch. See [#1868](https://github.com/DataDog/dd-sdk-android/pull/1868)
* [MAINTENANCE] Update telemetry schema. See [#1874](https://github.com/DataDog/dd-sdk-android/pull/1874)
* [MAINTENANCE] Merge Hotfix 2.6.2. See [#1890](https://github.com/DataDog/dd-sdk-android/pull/1890)
* [MAINTENANCE] Add signed commits requirement to `CONTRIBUTING.md`. See [#1905](https://github.com/DataDog/dd-sdk-android/pull/1905)
* [MAINTENANCE] Session Replay: Cleanup SR code. See [#1910](https://github.com/DataDog/dd-sdk-android/pull/1910)
* [MAINTENANCE] Session Replay: Fix integration tests post Session Replay refactoring. See [#1916](https://github.com/DataDog/dd-sdk-android/pull/1916)
* [MAINTENANCE] Session Replay: Fix `SrImageButtonsMaskUserInputTest`. See [#1920](https://github.com/DataDog/dd-sdk-android/pull/1920)
* [MAINTENANCE] Adjust `ktlint` formatting rules. See [#1919](https://github.com/DataDog/dd-sdk-android/pull/1919)
* [MAINTENANCE] Fix formatting. See [#1921](https://github.com/DataDog/dd-sdk-android/pull/1921)

# 2.6.2 / 2024-02-23

* [BUGFIX] RUM: Fix crash in frame rate vital detection. See [#1872](https://github.com/DataDog/dd-sdk-android/pull/1872)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object AndroidConfig {
const val MIN_SDK_FOR_WEAR = 23
const val BUILD_TOOLS_VERSION = "34.0.0"

val VERSION = Version(2, 7, 0, Version.Type.Snapshot)
val VERSION = Version(2, 8, 0, Version.Type.Snapshot)
}

// TODO RUM-628 Switch to Java 17 bytecode
Expand Down
15 changes: 12 additions & 3 deletions dd-sdk-android-core/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ interface com.datadog.android.api.feature.Feature
const val RUM_FEATURE_NAME: String
const val TRACING_FEATURE_NAME: String
const val SESSION_REPLAY_FEATURE_NAME: String
const val NDK_CRASH_REPORTS_FEATURE_NAME: String
interface com.datadog.android.api.feature.FeatureEventReceiver
fun onReceive(Any)
interface com.datadog.android.api.feature.FeatureScope
Expand Down Expand Up @@ -145,7 +146,11 @@ interface com.datadog.android.core.InternalSdkCore : com.datadog.android.api.fea
val rootStorageDir: java.io.File?
val isDeveloperModeEnabled: Boolean
val firstPartyHostResolver: com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
val lastViewEvent: com.google.gson.JsonObject?
val lastFatalAnrSent: Long?
fun writeLastViewEvent(ByteArray)
fun deleteLastViewEvent()
fun writeLastFatalAnrSent(Long)
fun getPersistenceExecutorService(): java.util.concurrent.ExecutorService
fun getAllFeatures(): List<com.datadog.android.api.feature.FeatureScope>
fun getDatadogContext(): com.datadog.android.api.context.DatadogContext?
Expand Down Expand Up @@ -228,9 +233,9 @@ fun java.io.File.existsSafe(com.datadog.android.api.InternalLogger): Boolean
fun java.io.File.readTextSafe(java.nio.charset.Charset = Charsets.UTF_8, com.datadog.android.api.InternalLogger): String?
fun java.io.File.readLinesSafe(java.nio.charset.Charset = Charsets.UTF_8, com.datadog.android.api.InternalLogger): List<String>?
interface com.datadog.android.core.internal.system.BuildSdkVersionProvider
fun version(): Int
class com.datadog.android.core.internal.system.DefaultBuildSdkVersionProvider : BuildSdkVersionProvider
override fun version(): Int
val version: Int
companion object
val DEFAULT: BuildSdkVersionProvider
class com.datadog.android.core.internal.thread.LoggingScheduledThreadPoolExecutor : java.util.concurrent.ScheduledThreadPoolExecutor
constructor(Int, com.datadog.android.api.InternalLogger)
override fun afterExecute(Runnable?, Throwable?)
Expand All @@ -242,9 +247,12 @@ val NULL_MAP_VALUE: Object
object com.datadog.android.core.internal.utils.JsonSerializer
fun toJsonElement(Any?): com.google.gson.JsonElement
fun Map<String, Any?>.safeMapValuesToJson(com.datadog.android.api.InternalLogger): Map<String, com.google.gson.JsonElement>
const val HEX_RADIX: Int
fun Int.toHexString(): String
fun Long.toHexString(): String
fun java.math.BigInteger.toHexString(): String
fun Thread.State.asString(): String
fun Array<StackTraceElement>.loggableStackTrace(): String
fun Throwable.loggableStackTrace(): String
interface com.datadog.android.core.persistence.PersistenceStrategy
interface Factory
Expand Down Expand Up @@ -331,6 +339,7 @@ object com.datadog.android.log.LogAttributes
const val USR_NAME: String
const val VARIANT: String
const val SOURCE_TYPE: String
const val ERROR_FINGERPRINT: String
enum com.datadog.android.privacy.TrackingConsent
- GRANTED
- NOT_GRANTED
Expand Down
21 changes: 17 additions & 4 deletions dd-sdk-android-core/api/dd-sdk-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ public final class com/datadog/android/api/context/UserInfo {
public abstract interface class com/datadog/android/api/feature/Feature {
public static final field Companion Lcom/datadog/android/api/feature/Feature$Companion;
public static final field LOGS_FEATURE_NAME Ljava/lang/String;
public static final field NDK_CRASH_REPORTS_FEATURE_NAME Ljava/lang/String;
public static final field RUM_FEATURE_NAME Ljava/lang/String;
public static final field SESSION_REPLAY_FEATURE_NAME Ljava/lang/String;
public static final field TRACING_FEATURE_NAME Ljava/lang/String;
Expand All @@ -304,6 +305,7 @@ public abstract interface class com/datadog/android/api/feature/Feature {

public final class com/datadog/android/api/feature/Feature$Companion {
public static final field LOGS_FEATURE_NAME Ljava/lang/String;
public static final field NDK_CRASH_REPORTS_FEATURE_NAME Ljava/lang/String;
public static final field RUM_FEATURE_NAME Ljava/lang/String;
public static final field SESSION_REPLAY_FEATURE_NAME Ljava/lang/String;
public static final field TRACING_FEATURE_NAME Ljava/lang/String;
Expand Down Expand Up @@ -430,14 +432,18 @@ public final class com/datadog/android/api/storage/RawBatchEvent {
}

public abstract interface class com/datadog/android/core/InternalSdkCore : com/datadog/android/api/feature/FeatureSdkCore {
public abstract fun deleteLastViewEvent ()V
public abstract fun getAllFeatures ()Ljava/util/List;
public abstract fun getDatadogContext ()Lcom/datadog/android/api/context/DatadogContext;
public abstract fun getFirstPartyHostResolver ()Lcom/datadog/android/core/internal/net/FirstPartyHostHeaderTypeResolver;
public abstract fun getLastFatalAnrSent ()Ljava/lang/Long;
public abstract fun getLastViewEvent ()Lcom/google/gson/JsonObject;
public abstract fun getNetworkInfo ()Lcom/datadog/android/api/context/NetworkInfo;
public abstract fun getPersistenceExecutorService ()Ljava/util/concurrent/ExecutorService;
public abstract fun getRootStorageDir ()Ljava/io/File;
public abstract fun getTrackingConsent ()Lcom/datadog/android/privacy/TrackingConsent;
public abstract fun isDeveloperModeEnabled ()Z
public abstract fun writeLastFatalAnrSent (J)V
public abstract fun writeLastViewEvent ([B)V
}

Expand Down Expand Up @@ -624,12 +630,12 @@ public final class com/datadog/android/core/internal/persistence/file/FileExtKt
}

public abstract interface class com/datadog/android/core/internal/system/BuildSdkVersionProvider {
public abstract fun version ()I
public static final field Companion Lcom/datadog/android/core/internal/system/BuildSdkVersionProvider$Companion;
public abstract fun getVersion ()I
}

public final class com/datadog/android/core/internal/system/DefaultBuildSdkVersionProvider : com/datadog/android/core/internal/system/BuildSdkVersionProvider {
public fun <init> ()V
public fun version ()I
public final class com/datadog/android/core/internal/system/BuildSdkVersionProvider$Companion {
public final fun getDEFAULT ()Lcom/datadog/android/core/internal/system/BuildSdkVersionProvider;
}

public final class com/datadog/android/core/internal/thread/LoggingScheduledThreadPoolExecutor : java/util/concurrent/ScheduledThreadPoolExecutor {
Expand Down Expand Up @@ -658,11 +664,17 @@ public final class com/datadog/android/core/internal/utils/MapUtilsKt {
}

public final class com/datadog/android/core/internal/utils/NumberExtKt {
public static final field HEX_RADIX I
public static final fun toHexString (I)Ljava/lang/String;
public static final fun toHexString (J)Ljava/lang/String;
public static final fun toHexString (Ljava/math/BigInteger;)Ljava/lang/String;
}

public final class com/datadog/android/core/internal/utils/ThreadExtKt {
public static final fun asString (Ljava/lang/Thread$State;)Ljava/lang/String;
public static final fun loggableStackTrace ([Ljava/lang/StackTraceElement;)Ljava/lang/String;
}

public final class com/datadog/android/core/internal/utils/ThrowableExtKt {
public static final fun loggableStackTrace (Ljava/lang/Throwable;)Ljava/lang/String;
}
Expand Down Expand Up @@ -754,6 +766,7 @@ public final class com/datadog/android/log/LogAttributes {
public static final field DD_TRACE_ID Ljava/lang/String;
public static final field DURATION Ljava/lang/String;
public static final field ENV Ljava/lang/String;
public static final field ERROR_FINGERPRINT Ljava/lang/String;
public static final field ERROR_KIND Ljava/lang/String;
public static final field ERROR_MESSAGE Ljava/lang/String;
public static final field ERROR_SOURCE_TYPE Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,10 @@ interface Feature {
* Session Replay feature name.
*/
const val SESSION_REPLAY_FEATURE_NAME: String = "session-replay"

/**
* NDK Crash Reports feature name.
*/
const val NDK_CRASH_REPORTS_FEATURE_NAME: String = "ndk-crash-reporting"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package com.datadog.android.core
import android.app.Application
import android.content.Context
import android.content.pm.ApplicationInfo
import android.os.Build
import android.util.Log
import androidx.annotation.WorkerThread
import com.datadog.android.Datadog
Expand All @@ -22,7 +23,6 @@ import com.datadog.android.api.feature.Feature
import com.datadog.android.api.feature.FeatureEventReceiver
import com.datadog.android.api.feature.FeatureScope
import com.datadog.android.api.feature.FeatureSdkCore
import com.datadog.android.api.storage.RawBatchEvent
import com.datadog.android.core.configuration.BatchSize
import com.datadog.android.core.configuration.Configuration
import com.datadog.android.core.configuration.UploadFrequency
Expand All @@ -32,14 +32,12 @@ import com.datadog.android.core.internal.SdkFeature
import com.datadog.android.core.internal.lifecycle.ProcessLifecycleCallback
import com.datadog.android.core.internal.lifecycle.ProcessLifecycleMonitor
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
import com.datadog.android.core.internal.persistence.file.FileWriter
import com.datadog.android.core.internal.persistence.file.batch.BatchFileReaderWriter
import com.datadog.android.core.internal.persistence.file.existsSafe
import com.datadog.android.core.internal.system.BuildSdkVersionProvider
import com.datadog.android.core.internal.utils.scheduleSafe
import com.datadog.android.error.internal.CrashReportsFeature
import com.datadog.android.ndk.internal.DatadogNdkCrashHandler
import com.datadog.android.ndk.internal.NdkCrashHandler
import com.datadog.android.privacy.TrackingConsent
import com.google.gson.JsonObject
import java.io.File
import java.util.Locale
import java.util.concurrent.ExecutorService
Expand All @@ -52,6 +50,7 @@ import java.util.concurrent.TimeUnit
* @param name the name of this instance
* @param internalLoggerProvider Provider for [InternalLogger] instance.
* @param persistenceExecutorServiceFactory Custom factory for persistence executor, used only in unit-tests
* @param buildSdkVersionProvider Build.VERSION.SDK_INT provider used for the test
*/
@Suppress("TooManyFunctions")
internal class DatadogCore(
Expand All @@ -60,7 +59,8 @@ internal class DatadogCore(
override val name: String,
internalLoggerProvider: (FeatureSdkCore) -> InternalLogger = { SdkInternalLogger(it) },
// only for unit tests
private val persistenceExecutorServiceFactory: ((InternalLogger) -> ExecutorService)? = null
private val persistenceExecutorServiceFactory: ((InternalLogger) -> ExecutorService)? = null,
private val buildSdkVersionProvider: BuildSdkVersionProvider = BuildSdkVersionProvider.DEFAULT
) : InternalSdkCore {

internal lateinit var coreFeature: CoreFeature
Expand All @@ -81,13 +81,6 @@ internal class DatadogCore(
internal val isActive: Boolean
get() = coreFeature.initialized.get()

private val ndkLastViewEventFileWriter: FileWriter<RawBatchEvent> by lazy {
BatchFileReaderWriter.create(
internalLogger = internalLogger,
encryption = coreFeature.localDataEncryption
)
}

private var processLifecycleMonitor: ProcessLifecycleMonitor? = null

// region SdkCore
Expand Down Expand Up @@ -183,6 +176,10 @@ internal class DatadogCore(
features.values.forEach {
it.clearAllData()
}
@Suppress("ThreadSafety") // removal of the data is done in synchronous manner
coreFeature.deleteLastViewEvent()
@Suppress("ThreadSafety") // removal of the data is done in synchronous manner
coreFeature.deleteLastFatalAnrSent()
}

/** @inheritDoc */
Expand Down Expand Up @@ -245,23 +242,41 @@ internal class DatadogCore(
override val rootStorageDir: File
get() = coreFeature.storageDir

@get:WorkerThread
override val lastViewEvent: JsonObject?
get() = coreFeature.lastViewEvent

@get:WorkerThread
override val lastFatalAnrSent: Long?
get() = coreFeature.lastFatalAnrSent

@WorkerThread
override fun writeLastViewEvent(data: ByteArray) {
// directory structure may not exist: currently it is a file which is located in NDK reports
// folder, so if NDK reporting plugin is not initialized, this NDK reports dir won't exist
// as well (and no need to write).
val lastViewEventFile = DatadogNdkCrashHandler.getLastViewEventFile(coreFeature.storageDir)
if (lastViewEventFile.parentFile?.existsSafe(internalLogger) == true) {
ndkLastViewEventFileWriter.writeData(lastViewEventFile, RawBatchEvent(data), false)
// we need to write it only if we are going to read ApplicationExitInfo (available on
// API 30+) or if there is NDK crash tracking enabled
if (buildSdkVersionProvider.version >= Build.VERSION_CODES.R ||
features.containsKey(Feature.NDK_CRASH_REPORTS_FEATURE_NAME)
) {
coreFeature.writeLastViewEvent(data)
} else {
internalLogger.log(
InternalLogger.Level.WARN,
InternalLogger.Level.INFO,
InternalLogger.Target.MAINTAINER,
{ LAST_VIEW_EVENT_DIR_MISSING_MESSAGE.format(Locale.US, lastViewEventFile.parent) }
{ NO_NEED_TO_WRITE_LAST_VIEW_EVENT }
)
}
}

@WorkerThread
override fun deleteLastViewEvent() {
coreFeature.deleteLastViewEvent()
}

@WorkerThread
override fun writeLastFatalAnrSent(anrTimestamp: Long) {
coreFeature.writeLastFatalAnrSent(anrTimestamp)
}

override fun getPersistenceExecutorService(): ExecutorService {
return coreFeature.persistenceExecutorService
}
Expand Down Expand Up @@ -487,8 +502,9 @@ internal class DatadogCore(
internal const val EVENT_RECEIVER_ALREADY_EXISTS =
"Feature \"%s\" already has event receiver registered, overwriting it."

const val LAST_VIEW_EVENT_DIR_MISSING_MESSAGE = "Directory structure %s for writing" +
" last view event doesn't exist."
internal const val NO_NEED_TO_WRITE_LAST_VIEW_EVENT =
"No need to write last RUM view event: NDK" +
" crash reports feature is not enabled and API is below 30."

internal val CONFIGURATION_TELEMETRY_DELAY_MS = TimeUnit.SECONDS.toMillis(5)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.datadog.android.api.feature.FeatureSdkCore
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
import com.datadog.android.lint.InternalApi
import com.datadog.android.privacy.TrackingConsent
import com.google.gson.JsonObject
import java.io.File
import java.util.concurrent.ExecutorService

Expand Down Expand Up @@ -54,6 +55,20 @@ interface InternalSdkCore : FeatureSdkCore {
*/
val firstPartyHostResolver: FirstPartyHostHeaderTypeResolver

/**
* Reads last known RUM view event stored.
*/
@get:WorkerThread
@InternalApi
val lastViewEvent: JsonObject?

/**
* Reads information about last fatal ANR sent.
*/
@get:WorkerThread
@InternalApi
val lastFatalAnrSent: Long?

/**
* Writes current RUM view event to the dedicated file for the needs of NDK crash reporting.
*
Expand All @@ -63,6 +78,20 @@ interface InternalSdkCore : FeatureSdkCore {
@WorkerThread
fun writeLastViewEvent(data: ByteArray)

/**
* Deletes last RUM view event written.
*/
@InternalApi
@WorkerThread
fun deleteLastViewEvent()

/**
* Writes timestamp of the last fatal ANR sent.
*/
@InternalApi
@WorkerThread
fun writeLastFatalAnrSent(anrTimestamp: Long)

/**
* Get an executor service for persistence purposes.
* @return the persistence executor to use for this SDK
Expand Down
Loading

0 comments on commit 3cfe958

Please sign in to comment.