From 52321477e39c764e339b342b7f8596504adf6f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 28 Jan 2025 08:16:24 +0100 Subject: [PATCH] General enhancements (#384) * Enhancing default processor factory * Canceling gate timeout tasks * Clean up * Setting global apm server connectivity config * Using context compat to test permission * Preparing to support network change for different api levels * Renaming * Delegating providing network type * Creating NetworkApi23QueryManager * Providing network capabilities * Created NetworkApi21QueryManager * Updating NetworkApi21QueryManager * Choosing proper NetworkQueryManager * Adding header * Updating docs and tests for 21 compatibility support * Setting kotlin jvm-default=all * Setting kotlin jvm-default=all for java libs * Clean up * Clean up * Updating dependencies * Replacing deprecated semconv fields --- NOTICE | 2 +- android-api/metadata/notice.properties | 2 +- android-common/metadata/notice.properties | 2 +- .../src/main/resources/META-INF/NOTICE | 1 - android-plugin/build.gradle.kts | 10 -- android-plugin/metadata/notice.properties | 2 +- .../android/plugin/ApmAndroidAgentPlugin.kt | 6 -- android-sdk/build.gradle.kts | 3 +- android-sdk/metadata/notice.properties | 2 +- .../elastic/otel/android/ElasticApmAgent.kt | 18 +++- .../attributes/CommonAttributesInterceptor.kt | 6 +- .../attributes/SpanAttributesInterceptor.kt | 10 +- .../ConnectivityConfigurationHolder.kt | 4 - .../apmserver/ApmServerConnectivityManager.kt | 5 +- .../apmserver/ApmServerExporterProvider.kt | 1 - .../CentralConfigurationManager.kt | 31 +----- .../exportergate/ExporterGateManager.kt | 16 +++- .../ElasticOpenTelemetryBuilder.kt | 46 +++++---- .../processors/DefaultProcessorFactory.kt | 29 +++++- .../services/appinfo/AppInfoService.kt | 6 +- .../backgroundwork/BackgroundWorkService.kt | 2 +- .../services/network/NetworkService.kt | 67 +++++++------ .../network/listener/NetworkChangeListener.kt | 27 ++++++ .../network/query/NetworkApi21QueryManager.kt | 92 ++++++++++++++++++ .../network/query/NetworkApi23QueryManager.kt | 95 +++++++++++++++++++ .../network/query/NetworkApi24QueryManager.kt | 62 ++++++++++++ .../network/query/NetworkQueryManager.kt | 56 +++++++++++ .../android/processors/ProcessorFactory.kt | 8 -- .../src/main/resources/META-INF/NOTICE | 2 +- .../android/integration/AttributesTest.kt | 59 +++++++++--- .../integration/ElasticApmAgentTest.kt | 4 +- .../services/network/NetworkServiceTest.kt | 6 +- android-test/build.gradle.kts | 2 +- android-test/gradle/libs.versions.toml | 14 +-- .../kotlin/elastic.android-library.gradle.kts | 1 + .../kotlin/elastic.java-library.gradle.kts | 1 + docs/setup.asciidoc | 4 +- docs/supported-technologies.asciidoc | 2 +- gradle.properties | 6 +- gradle/libs.versions.toml | 40 ++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- manual_licenses_map.txt | 6 +- 42 files changed, 569 insertions(+), 191 deletions(-) rename android-sdk/src/main/java/co/elastic/otel/android/{ => internal}/features/apmserver/ApmServerConnectivityManager.kt (89%) create mode 100644 android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/listener/NetworkChangeListener.kt create mode 100644 android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi21QueryManager.kt create mode 100644 android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi23QueryManager.kt create mode 100644 android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi24QueryManager.kt create mode 100644 android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkQueryManager.kt diff --git a/NOTICE b/NOTICE index b0d6eb794..2235e692f 100644 --- a/NOTICE +++ b/NOTICE @@ -5,9 +5,9 @@ Copyright 2018-2022 Elasticsearch B.V. This product includes software licensed under the 'Apache License Version 2.0' license from the following sources: - - Android Support Library Annotations (https://developer.android.com/jetpack/androidx/releases/annotation#1.4.0) - Byte Buddy (without dependencies) - Byte Buddy Gradle plugin + - Core (https://developer.android.com/jetpack/androidx/releases/core#1.15.0) - Kotlin Stdlib (https://kotlinlang.org/) - OpenTelemetry Java (https://github.com/open-telemetry/opentelemetry-java) - OpenTelemetry Java Contrib (https://github.com/open-telemetry/opentelemetry-java-contrib) diff --git a/android-api/metadata/notice.properties b/android-api/metadata/notice.properties index bbd51a6f7..a6ac759f7 100644 --- a/android-api/metadata/notice.properties +++ b/android-api/metadata/notice.properties @@ -1 +1 @@ -dependencies.hash=C4EDFC20A44F37F2CBB62F2446E01DA8 \ No newline at end of file +dependencies.hash=1E17F5641C5CF6F9415E423B7E4DAFF4 \ No newline at end of file diff --git a/android-common/metadata/notice.properties b/android-common/metadata/notice.properties index 8860181cb..255de3e6d 100644 --- a/android-common/metadata/notice.properties +++ b/android-common/metadata/notice.properties @@ -1 +1 @@ -dependencies.hash=067D73F0C266736CAADED6F77C2EC811 \ No newline at end of file +dependencies.hash=A88DCE3A12A459568879FBD82058DF9A \ No newline at end of file diff --git a/android-common/src/main/resources/META-INF/NOTICE b/android-common/src/main/resources/META-INF/NOTICE index 7085b1bad..bed1d97a2 100644 --- a/android-common/src/main/resources/META-INF/NOTICE +++ b/android-common/src/main/resources/META-INF/NOTICE @@ -5,7 +5,6 @@ Copyright 2018-2022 Elasticsearch B.V. This product includes software licensed under the 'Apache License Version 2.0' license from the following sources: - - Android Support Library Annotations (https://developer.android.com/jetpack/androidx/releases/annotation#1.4.0) - Kotlin Stdlib (https://kotlinlang.org/) ------------------------------------------------------------------------------- diff --git a/android-plugin/build.gradle.kts b/android-plugin/build.gradle.kts index 39113b48b..fc73d14a7 100644 --- a/android-plugin/build.gradle.kts +++ b/android-plugin/build.gradle.kts @@ -14,16 +14,6 @@ dependencies { buildConfig { packageName("${group}.generated") buildConfigField("String", "SDK_DEPENDENCY_URI", "\"$group:android-sdk:$version\"") - buildConfigField( - "String", - "OTEL_OKHTTP_LIBRARY_URI", - "\"${libs.opentelemetry.android.okhttpLib.get()}\"" - ) - buildConfigField( - "String", - "OTEL_OKHTTP_AGENT_URI", - "\"${libs.opentelemetry.android.okhttpAgent.get()}\"" - ) } licensesConfig { diff --git a/android-plugin/metadata/notice.properties b/android-plugin/metadata/notice.properties index 90964cdf6..bda992af4 100644 --- a/android-plugin/metadata/notice.properties +++ b/android-plugin/metadata/notice.properties @@ -1 +1 @@ -dependencies.hash=902A29423B971754030D7233FFCAA958 \ No newline at end of file +dependencies.hash=88FF60992EFCED0C408A073B7361D003 \ No newline at end of file diff --git a/android-plugin/src/main/java/co/elastic/otel/android/plugin/ApmAndroidAgentPlugin.kt b/android-plugin/src/main/java/co/elastic/otel/android/plugin/ApmAndroidAgentPlugin.kt index 3c26cccd8..c1b078e62 100644 --- a/android-plugin/src/main/java/co/elastic/otel/android/plugin/ApmAndroidAgentPlugin.kt +++ b/android-plugin/src/main/java/co/elastic/otel/android/plugin/ApmAndroidAgentPlugin.kt @@ -33,7 +33,6 @@ internal class ApmAndroidAgentPlugin : Plugin { Elog.init(GradleLoggerFactory()) addByteBuddyPlugin() addSdkDependency() - addInstrumentationDependency() } private fun addByteBuddyPlugin() { @@ -43,9 +42,4 @@ internal class ApmAndroidAgentPlugin : Plugin { private fun addSdkDependency() { project.dependencies.add("implementation", BuildConfig.SDK_DEPENDENCY_URI) } - - private fun addInstrumentationDependency() { - project.dependencies.add("implementation", BuildConfig.OTEL_OKHTTP_LIBRARY_URI) - project.dependencies.add("byteBuddy", BuildConfig.OTEL_OKHTTP_AGENT_URI) - } } \ No newline at end of file diff --git a/android-sdk/build.gradle.kts b/android-sdk/build.gradle.kts index 08ee1bd91..b15b46aba 100644 --- a/android-sdk/build.gradle.kts +++ b/android-sdk/build.gradle.kts @@ -30,9 +30,10 @@ dependencies { implementation(libs.stagemonitor.configuration) implementation(project(":android-common")) implementation(libs.opentelemetry.exporter.otlp) - implementation(libs.opentelemetry.semconv) + implementation(libs.bundles.opentelemetry.semconv) implementation(libs.opentelemetry.diskBuffering) implementation(libs.androidx.annotations) + implementation(libs.androidx.core) implementation(libs.dsl.json) testImplementation(libs.wireMock) testImplementation(libs.opentelemetry.testing) diff --git a/android-sdk/metadata/notice.properties b/android-sdk/metadata/notice.properties index 51a5e20e7..16aac4ffc 100644 --- a/android-sdk/metadata/notice.properties +++ b/android-sdk/metadata/notice.properties @@ -1 +1 @@ -dependencies.hash=AB9B95B767BE37A6FD85815FAEBD0F3F \ No newline at end of file +dependencies.hash=599652E88D43F2C4A92843B10443411F \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/ElasticApmAgent.kt b/android-sdk/src/main/java/co/elastic/otel/android/ElasticApmAgent.kt index c6442c221..893eec928 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/ElasticApmAgent.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/ElasticApmAgent.kt @@ -24,10 +24,11 @@ import co.elastic.otel.android.exporters.ExporterProvider import co.elastic.otel.android.exporters.configuration.ExportProtocol import co.elastic.otel.android.features.apmserver.ApmServerAuthentication import co.elastic.otel.android.features.apmserver.ApmServerConnectivity -import co.elastic.otel.android.features.apmserver.ApmServerConnectivityManager import co.elastic.otel.android.interceptor.Interceptor import co.elastic.otel.android.internal.api.ManagedElasticOtelAgent +import co.elastic.otel.android.internal.features.apmserver.ApmServerConnectivityManager import co.elastic.otel.android.internal.features.apmserver.ApmServerExporterProvider +import co.elastic.otel.android.internal.features.centralconfig.CentralConfigurationConnectivity import co.elastic.otel.android.internal.features.centralconfig.CentralConfigurationManager import co.elastic.otel.android.internal.features.clock.ElasticClockManager import co.elastic.otel.android.internal.features.conditionaldrop.ConditionalDropManager @@ -72,7 +73,20 @@ class ElasticApmAgent private constructor( return openTelemetry } - fun getApmServerConnectivityManager(): ApmServerConnectivityManager { + fun setApmServerConnectivity(connectivity: ApmServerConnectivity) { + apmServerConnectivityManager.setConnectivityConfiguration(connectivity) + val currentCentralConnectivityConfig = + centralConfigurationManager.getConnectivityConfiguration() + centralConfigurationManager.setConnectivityConfiguration( + CentralConfigurationConnectivity.fromApmServerConfig( + currentCentralConnectivityConfig.serviceName, + currentCentralConnectivityConfig.serviceDeployment, + connectivity + ) + ) + } + + internal fun getApmServerConnectivityManager(): ApmServerConnectivityManager { return apmServerConnectivityManager } diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/CommonAttributesInterceptor.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/CommonAttributesInterceptor.kt index 4a3bbc374..d9de2fac7 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/CommonAttributesInterceptor.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/CommonAttributesInterceptor.kt @@ -25,7 +25,7 @@ import co.elastic.otel.android.internal.services.network.data.NetworkType import co.elastic.otel.android.session.SessionProvider import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes -import io.opentelemetry.semconv.SemanticAttributes +import io.opentelemetry.semconv.incubating.NetworkIncubatingAttributes internal class CommonAttributesInterceptor( private val serviceManager: ServiceManager, @@ -39,13 +39,13 @@ internal class CommonAttributesInterceptor( val builder = Attributes.builder().putAll(item) val networkType = networkService.getType() - builder.put(SemanticAttributes.NETWORK_CONNECTION_TYPE, networkType.name) + builder.put(NetworkIncubatingAttributes.NETWORK_CONNECTION_TYPE, networkType.name) sessionProvider.getSession()?.getId()?.let { builder.put(SESSION_ID_ATTRIBUTE_KEY, it) } if (networkType is NetworkType.Cell) { networkType.subTypeName?.let { builder.put( - SemanticAttributes.NETWORK_CONNECTION_SUBTYPE, + NetworkIncubatingAttributes.NETWORK_CONNECTION_SUBTYPE, it ) } diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/SpanAttributesInterceptor.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/SpanAttributesInterceptor.kt index e19cb9292..7684c3534 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/SpanAttributesInterceptor.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/attributes/SpanAttributesInterceptor.kt @@ -23,7 +23,7 @@ import co.elastic.otel.android.internal.services.ServiceManager import co.elastic.otel.android.internal.services.network.NetworkService import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes -import io.opentelemetry.semconv.SemanticAttributes +import io.opentelemetry.semconv.incubating.NetworkIncubatingAttributes internal class SpanAttributesInterceptor(serviceManager: ServiceManager) : Interceptor { private val networkService: NetworkService by lazy { @@ -37,10 +37,10 @@ internal class SpanAttributesInterceptor(serviceManager: ServiceManager) : Inter builder.put(TRANSACTION_TYPE_ATTRIBUTE_KEY, TRANSACTION_TYPE_VALUE) if (carrierInfo != null) { - builder.put(SemanticAttributes.NETWORK_CARRIER_NAME, carrierInfo.name) - builder.put(SemanticAttributes.NETWORK_CARRIER_MCC, carrierInfo.mcc) - builder.put(SemanticAttributes.NETWORK_CARRIER_MNC, carrierInfo.mnc) - builder.put(SemanticAttributes.NETWORK_CARRIER_ICC, carrierInfo.icc) + builder.put(NetworkIncubatingAttributes.NETWORK_CARRIER_NAME, carrierInfo.name) + builder.put(NetworkIncubatingAttributes.NETWORK_CARRIER_MCC, carrierInfo.mcc) + builder.put(NetworkIncubatingAttributes.NETWORK_CARRIER_MNC, carrierInfo.mnc) + builder.put(NetworkIncubatingAttributes.NETWORK_CARRIER_ICC, carrierInfo.icc) } return builder.build() diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/connectivity/ConnectivityConfigurationHolder.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/connectivity/ConnectivityConfigurationHolder.kt index d4a7ce3e1..4d0458622 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/connectivity/ConnectivityConfigurationHolder.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/connectivity/ConnectivityConfigurationHolder.kt @@ -50,10 +50,6 @@ internal open class ConnectivityConfigurationHolder(initialValue: ConnectivityCo listeners.addIfAbsent(listener) } - fun removeListener(listener: Listener) = synchronized(setLock) { - listeners.remove(listener) - } - interface Listener { fun onConnectivityConfigurationChange() } diff --git a/android-sdk/src/main/java/co/elastic/otel/android/features/apmserver/ApmServerConnectivityManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerConnectivityManager.kt similarity index 89% rename from android-sdk/src/main/java/co/elastic/otel/android/features/apmserver/ApmServerConnectivityManager.kt rename to android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerConnectivityManager.kt index 665eff603..dc2fb5e10 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/features/apmserver/ApmServerConnectivityManager.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerConnectivityManager.kt @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.otel.android.features.apmserver +package co.elastic.otel.android.internal.features.apmserver +import co.elastic.otel.android.features.apmserver.ApmServerConnectivity import co.elastic.otel.android.internal.connectivity.ConnectivityConfigurationHolder -class ApmServerConnectivityManager internal constructor( +internal class ApmServerConnectivityManager internal constructor( private val connectivityConfigurationHolder: ConnectivityHolder ) { fun setConnectivityConfiguration(configuration: ApmServerConnectivity) { diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerExporterProvider.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerExporterProvider.kt index 958cb4064..4766180a8 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerExporterProvider.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/apmserver/ApmServerExporterProvider.kt @@ -21,7 +21,6 @@ package co.elastic.otel.android.internal.features.apmserver import co.elastic.otel.android.exporters.ExporterProvider import co.elastic.otel.android.exporters.configuration.ExporterConfiguration import co.elastic.otel.android.features.apmserver.ApmServerConnectivity -import co.elastic.otel.android.features.apmserver.ApmServerConnectivityManager import co.elastic.otel.android.internal.connectivity.ConnectivityConfigurationHolder import co.elastic.otel.android.internal.opentelemetry.exporters.configurable.ConfigurableExporterProvider import co.elastic.otel.android.provider.Provider diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/features/centralconfig/CentralConfigurationManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/centralconfig/CentralConfigurationManager.kt index a1af6d7f0..a5dda5f5a 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/features/centralconfig/CentralConfigurationManager.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/centralconfig/CentralConfigurationManager.kt @@ -20,8 +20,8 @@ package co.elastic.otel.android.internal.features.centralconfig import androidx.annotation.WorkerThread import co.elastic.otel.android.common.internal.logging.Elog -import co.elastic.otel.android.features.apmserver.ApmServerConnectivityManager import co.elastic.otel.android.internal.connectivity.ConnectivityConfigurationHolder +import co.elastic.otel.android.internal.features.apmserver.ApmServerConnectivityManager import co.elastic.otel.android.internal.features.exportergate.ExporterGateManager import co.elastic.otel.android.internal.services.ServiceManager import co.elastic.otel.android.internal.time.SystemTimeProvider @@ -45,7 +45,6 @@ internal class CentralConfigurationManager private constructor( } fun setConnectivityConfiguration(configuration: CentralConfigurationConnectivity) { - connectivityHolder.unlinkFromExportersConfig() connectivityHolder.set(configuration) } @@ -145,11 +144,8 @@ internal class CentralConfigurationManager private constructor( } internal class ConnectivityHolder( - connectivity: CentralConfigurationConnectivity, - private val apmServerConnectivityHolder: ApmServerConnectivityManager.ConnectivityHolder, - private val serviceName: String, - private val serviceDeployment: String? - ) : ConnectivityConfigurationHolder(connectivity), ConnectivityConfigurationHolder.Listener { + connectivity: CentralConfigurationConnectivity + ) : ConnectivityConfigurationHolder(connectivity) { companion object { fun fromApmServerConfig( @@ -157,32 +153,15 @@ internal class CentralConfigurationManager private constructor( serviceDeployment: String?, apmServerConfigurationManager: ApmServerConnectivityManager.ConnectivityHolder ): ConnectivityHolder { - val instance = ConnectivityHolder( + return ConnectivityHolder( CentralConfigurationConnectivity.fromApmServerConfig( serviceName, serviceDeployment, apmServerConfigurationManager.getConnectivityConfiguration() - ), apmServerConfigurationManager, serviceName, serviceDeployment + ) ) - apmServerConfigurationManager.addListener(instance) - return instance } } - - internal fun unlinkFromExportersConfig() { - apmServerConnectivityHolder.removeListener(this) - } - - override fun onConnectivityConfigurationChange() { - // On apm server exporters config change. - set( - CentralConfigurationConnectivity.fromApmServerConfig( - serviceName, - serviceDeployment, - apmServerConnectivityHolder.getConnectivityConfiguration() - ) - ) - } } override fun onConfigChange() { diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/ExporterGateManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/ExporterGateManager.kt index 0b6470355..ecb42e154 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/ExporterGateManager.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/ExporterGateManager.kt @@ -29,6 +29,7 @@ import io.opentelemetry.sdk.metrics.data.MetricData import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.sdk.trace.data.SpanData import io.opentelemetry.sdk.trace.export.SpanExporter +import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicBoolean @@ -60,6 +61,9 @@ internal class ExporterGateManager( private val spanGateOpen = AtomicBoolean(false) private val logGateOpen = AtomicBoolean(false) private val metricGateOpen = AtomicBoolean(false) + private var spanTimeoutTask: ScheduledFuture<*>? = null + private var logTimeoutTask: ScheduledFuture<*>? = null + private var metricTimeoutTask: ScheduledFuture<*>? = null companion object { private const val SPAN_QUEUE_ID = 1 @@ -129,6 +133,8 @@ internal class ExporterGateManager( } private fun onSpanGateOpen() { + spanTimeoutTask?.cancel(false) + spanTimeoutTask = null spanExporter.setDelegate(delegateSpanExporter) backgroundWorkService.submit { val items = spanGateQueue.getEnqueuedItems() @@ -141,6 +147,8 @@ internal class ExporterGateManager( } private fun onLogRecordGateOpen() { + logTimeoutTask?.cancel(false) + logTimeoutTask = null logRecordExporter.setDelegate(delegateLogRecordExporter) backgroundWorkService.submit { val items = logRecordGateQueue.getEnqueuedItems() @@ -153,6 +161,8 @@ internal class ExporterGateManager( } private fun onMetricGateOpen() { + metricTimeoutTask?.cancel(false) + metricTimeoutTask = null metricExporter.setDelegate(delegateMetricExporter) backgroundWorkService.submit { val items = metricGateQueue.getEnqueuedItems() @@ -165,19 +175,19 @@ internal class ExporterGateManager( } private fun onSpanQueueStarted() { - backgroundWorkService.scheduleOnce(gateLatchTimeout) { + spanTimeoutTask = backgroundWorkService.scheduleOnce(gateLatchTimeout) { spanGateQueue.forceOpenGate("Timeout") } } private fun onLogRecordQueueStarted() { - backgroundWorkService.scheduleOnce(gateLatchTimeout) { + logTimeoutTask = backgroundWorkService.scheduleOnce(gateLatchTimeout) { logRecordGateQueue.forceOpenGate("Timeout") } } private fun onMetricQueueStarted() { - backgroundWorkService.scheduleOnce(gateLatchTimeout) { + metricTimeoutTask = backgroundWorkService.scheduleOnce(gateLatchTimeout) { metricGateQueue.forceOpenGate("Timeout") } } diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/ElasticOpenTelemetryBuilder.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/ElasticOpenTelemetryBuilder.kt index 97c0ccefd..b2a10c932 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/ElasticOpenTelemetryBuilder.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/ElasticOpenTelemetryBuilder.kt @@ -25,6 +25,7 @@ import co.elastic.otel.android.interceptor.Interceptor import co.elastic.otel.android.internal.api.ManagedElasticOtelAgent import co.elastic.otel.android.internal.attributes.CommonAttributesInterceptor import co.elastic.otel.android.internal.attributes.SpanAttributesInterceptor +import co.elastic.otel.android.internal.opentelemetry.processors.DefaultProcessorFactory import co.elastic.otel.android.internal.opentelemetry.processors.logs.LogRecordAttributesProcessor import co.elastic.otel.android.internal.opentelemetry.processors.spans.SpanAttributesProcessor import co.elastic.otel.android.internal.opentelemetry.processors.spans.SpanInterceptorProcessor @@ -44,7 +45,12 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter import io.opentelemetry.sdk.resources.Resource import io.opentelemetry.sdk.trace.SdkTracerProvider import io.opentelemetry.sdk.trace.export.SpanExporter -import io.opentelemetry.semconv.ResourceAttributes +import io.opentelemetry.semconv.ServiceAttributes +import io.opentelemetry.semconv.TelemetryAttributes +import io.opentelemetry.semconv.incubating.DeploymentIncubatingAttributes +import io.opentelemetry.semconv.incubating.DeviceIncubatingAttributes +import io.opentelemetry.semconv.incubating.OsIncubatingAttributes +import io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes import java.util.UUID import java.util.concurrent.atomic.AtomicBoolean @@ -60,7 +66,7 @@ abstract class ElasticOpenTelemetryBuilder { private var spanExporterInterceptors = mutableListOf>() private var logRecordExporterInterceptors = mutableListOf>() private var metricExporterInterceptors = mutableListOf>() - private var processorFactory: ProcessorFactory = ProcessorFactory.getDefault() + private var processorFactory: ProcessorFactory? = null private var sessionProvider: SessionProvider = SessionProvider.getDefault() private var clock: Clock = Clock.getDefault() private var exporterProvider: ExporterProvider = ExporterProvider.noop() @@ -162,31 +168,33 @@ abstract class ElasticOpenTelemetryBuilder { "device_id" ) { UUID.randomUUID().toString() } } + val finalProcessorFactory = processorFactory + ?: DefaultProcessorFactory(serviceManager.getBackgroundWorkService()) val resource = Resource.builder() - .put(ResourceAttributes.SERVICE_NAME, serviceName) + .put(ServiceAttributes.SERVICE_NAME, serviceName) .put( - ResourceAttributes.SERVICE_VERSION, + ServiceAttributes.SERVICE_VERSION, serviceVersion ?: serviceManager.getAppInfoService().getVersionName() ?: "unknown" ) .put( AttributeKey.longKey("service.build"), serviceBuild ?: serviceManager.getAppInfoService().getVersionCode() ) - .put(ResourceAttributes.DEPLOYMENT_ENVIRONMENT, deploymentEnvironment) - .put(ResourceAttributes.DEVICE_ID, deviceIdProvider!!.get()) - .put(ResourceAttributes.DEVICE_MODEL_IDENTIFIER, Build.MODEL) - .put(ResourceAttributes.DEVICE_MANUFACTURER, Build.MANUFACTURER) - .put(ResourceAttributes.OS_DESCRIPTION, getOsDescription()) - .put(ResourceAttributes.OS_VERSION, Build.VERSION.RELEASE) - .put(ResourceAttributes.OS_NAME, "Android") - .put(ResourceAttributes.PROCESS_RUNTIME_NAME, "Android Runtime") + .put(DeploymentIncubatingAttributes.DEPLOYMENT_ENVIRONMENT, deploymentEnvironment) + .put(DeviceIncubatingAttributes.DEVICE_ID, deviceIdProvider!!.get()) + .put(DeviceIncubatingAttributes.DEVICE_MODEL_IDENTIFIER, Build.MODEL) + .put(DeviceIncubatingAttributes.DEVICE_MANUFACTURER, Build.MANUFACTURER) + .put(OsIncubatingAttributes.OS_DESCRIPTION, getOsDescription()) + .put(OsIncubatingAttributes.OS_VERSION, Build.VERSION.RELEASE) + .put(OsIncubatingAttributes.OS_NAME, "Android") + .put(ProcessIncubatingAttributes.PROCESS_RUNTIME_NAME, "Android Runtime") .put( - ResourceAttributes.PROCESS_RUNTIME_VERSION, + ProcessIncubatingAttributes.PROCESS_RUNTIME_VERSION, System.getProperty("java.vm.version") ) - .put(ResourceAttributes.TELEMETRY_SDK_NAME, "android") - .put(ResourceAttributes.TELEMETRY_SDK_VERSION, BuildConfig.APM_AGENT_VERSION) - .put(ResourceAttributes.TELEMETRY_SDK_LANGUAGE, "java") + .put(TelemetryAttributes.TELEMETRY_SDK_NAME, "android") + .put(TelemetryAttributes.TELEMETRY_SDK_VERSION, BuildConfig.APM_AGENT_VERSION) + .put(TelemetryAttributes.TELEMETRY_SDK_LANGUAGE, "java") .build() val openTelemetryBuilder = OpenTelemetrySdk.builder() val spanExporter = exporterProvider.getSpanExporter()?.let { @@ -198,7 +206,7 @@ abstract class ElasticOpenTelemetryBuilder { val metricExporter = exporterProvider.getMetricExporter()?.let { Interceptor.composite(metricExporterInterceptors).intercept(it) } - processorFactory.createSpanProcessor(spanExporter)?.let { + finalProcessorFactory.createSpanProcessor(spanExporter)?.let { openTelemetryBuilder.setTracerProvider( SdkTracerProvider.builder() .setClock(clock) @@ -215,7 +223,7 @@ abstract class ElasticOpenTelemetryBuilder { .build() ) } - processorFactory.createLogRecordProcessor(logRecordExporter) + finalProcessorFactory.createLogRecordProcessor(logRecordExporter) ?.let { openTelemetryBuilder.setLoggerProvider( SdkLoggerProvider.builder() @@ -232,7 +240,7 @@ abstract class ElasticOpenTelemetryBuilder { .build() ) } - processorFactory.createMetricReader(metricExporter)?.let { + finalProcessorFactory.createMetricReader(metricExporter)?.let { openTelemetryBuilder.setMeterProvider( SdkMeterProvider.builder() .setClock(clock) diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/processors/DefaultProcessorFactory.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/processors/DefaultProcessorFactory.kt index e190e5dc5..9eb053526 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/processors/DefaultProcessorFactory.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/processors/DefaultProcessorFactory.kt @@ -18,6 +18,7 @@ */ package co.elastic.otel.android.internal.opentelemetry.processors +import co.elastic.otel.android.internal.services.backgroundwork.BackgroundWorkService import co.elastic.otel.android.processors.ProcessorFactory import io.opentelemetry.sdk.logs.LogRecordProcessor import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor @@ -28,18 +29,38 @@ import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader import io.opentelemetry.sdk.trace.SpanProcessor import io.opentelemetry.sdk.trace.export.BatchSpanProcessor import io.opentelemetry.sdk.trace.export.SpanExporter +import java.time.Duration -internal class DefaultProcessorFactory : ProcessorFactory { +internal class DefaultProcessorFactory(private val backgroundWorkService: BackgroundWorkService) : + ProcessorFactory { + + companion object { + private val PROCESSING_INTERVAL = Duration.ofSeconds(2) + private val READING_INTERVAL = Duration.ofSeconds(4) + } override fun createSpanProcessor(exporter: SpanExporter?): SpanProcessor? { - return exporter?.let { BatchSpanProcessor.builder(exporter).build() } + return exporter?.let { + BatchSpanProcessor.builder(exporter) + .setScheduleDelay(PROCESSING_INTERVAL) + .build() + } } override fun createLogRecordProcessor(exporter: LogRecordExporter?): LogRecordProcessor? { - return exporter?.let { BatchLogRecordProcessor.builder(exporter).build() } + return exporter?.let { + BatchLogRecordProcessor.builder(exporter) + .setScheduleDelay(PROCESSING_INTERVAL) + .build() + } } override fun createMetricReader(exporter: MetricExporter?): MetricReader? { - return exporter?.let { PeriodicMetricReader.create(exporter) } + return exporter?.let { + PeriodicMetricReader.builder(exporter) + .setInterval(READING_INTERVAL) + .setExecutor(backgroundWorkService.executorService) + .build() + } } } \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/appinfo/AppInfoService.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/appinfo/AppInfoService.kt index ca95eb79a..4f696f192 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/appinfo/AppInfoService.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/appinfo/AppInfoService.kt @@ -26,6 +26,7 @@ import android.os.Build import android.os.storage.StorageManager import androidx.annotation.RequiresApi import androidx.annotation.WorkerThread +import androidx.core.content.ContextCompat import co.elastic.otel.android.common.internal.logging.Elog import co.elastic.otel.android.internal.services.Service import java.io.File @@ -35,7 +36,10 @@ import kotlin.math.min internal class AppInfoService(private val context: Context) : Service { fun isPermissionGranted(permissionName: String): Boolean { - return context.checkSelfPermission(permissionName) == PackageManager.PERMISSION_GRANTED + return ContextCompat.checkSelfPermission( + context, + permissionName + ) == PackageManager.PERMISSION_GRANTED } fun isInDebugMode(): Boolean { diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/backgroundwork/BackgroundWorkService.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/backgroundwork/BackgroundWorkService.kt index 6a938e373..123f360ec 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/backgroundwork/BackgroundWorkService.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/backgroundwork/BackgroundWorkService.kt @@ -25,7 +25,7 @@ import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture import java.util.concurrent.TimeUnit -internal class BackgroundWorkService private constructor(private val executorService: ScheduledExecutorService) : +internal class BackgroundWorkService private constructor(internal val executorService: ScheduledExecutorService) : Service { companion object { diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/NetworkService.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/NetworkService.kt index 1a5614ce5..0c1d16a1e 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/NetworkService.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/NetworkService.kt @@ -22,8 +22,6 @@ import android.Manifest import android.annotation.SuppressLint import android.content.Context import android.net.ConnectivityManager -import android.net.ConnectivityManager.NetworkCallback -import android.net.Network import android.net.NetworkCapabilities import android.telephony.TelephonyManager import co.elastic.otel.android.common.internal.logging.Elog @@ -32,21 +30,23 @@ import co.elastic.otel.android.internal.services.ServiceManager import co.elastic.otel.android.internal.services.appinfo.AppInfoService import co.elastic.otel.android.internal.services.network.data.CarrierInfo import co.elastic.otel.android.internal.services.network.data.NetworkType +import co.elastic.otel.android.internal.services.network.listener.NetworkChangeListener +import co.elastic.otel.android.internal.services.network.query.NetworkQueryManager import java.util.concurrent.atomic.AtomicReference internal class NetworkService internal constructor( private val appInfoService: AppInfoService, - private val connectivityManager: ConnectivityManager, - private val telephonyManager: TelephonyManager -) : NetworkCallback(), Service { + private val telephonyManager: TelephonyManager, + private val networkQueryManager: NetworkQueryManager +) : Service, NetworkChangeListener { private val type = AtomicReference(NetworkType.None) override fun start() { - connectivityManager.registerDefaultNetworkCallback(this) + networkQueryManager.start() } override fun stop() { - connectivityManager.unregisterNetworkCallback(this) + networkQueryManager.stop() } fun getType(): NetworkType { @@ -66,9 +66,12 @@ internal class NetworkService internal constructor( ) } - override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { - super.onCapabilitiesChanged(network, networkCapabilities) - type.set(getNetworkType(networkCapabilities)) + override fun onNewNetwork(capabilities: NetworkCapabilities) { + type.set(getNetworkType(capabilities)) + } + + override fun onNetworkLost() { + type.set(NetworkType.None) } private fun getNetworkType(networkCapabilities: NetworkCapabilities): NetworkType { @@ -81,23 +84,6 @@ internal class NetworkService internal constructor( } } - override fun onLost(network: Network) { - super.onLost(network) - type.set(NetworkType.None) - } - - private val simOperator: String? - get() { - if (telephonyManager.simState == TelephonyManager.SIM_STATE_READY) { - val simOperator = telephonyManager.simOperator - if (simOperator != null && simOperator.length > 3) { - return simOperator - } - } - - return null - } - @SuppressLint("MissingPermission") private fun getSubtypeName(): String? { if (!appInfoService.isPermissionGranted(Manifest.permission.READ_PHONE_STATE)) { @@ -105,7 +91,7 @@ internal class NetworkService internal constructor( return null } - return when (telephonyManager.dataNetworkType) { + return when (networkQueryManager.getNetworkType()) { TelephonyManager.NETWORK_TYPE_GPRS -> "GPRS" TelephonyManager.NETWORK_TYPE_EDGE -> "EDGE" TelephonyManager.NETWORK_TYPE_UMTS -> "UMTS" @@ -130,17 +116,36 @@ internal class NetworkService internal constructor( } } + private val simOperator: String? + get() { + if (telephonyManager.simState == TelephonyManager.SIM_STATE_READY) { + val simOperator = telephonyManager.simOperator + if (simOperator != null && simOperator.length > 3) { + return simOperator + } + } + + return null + } + companion object { fun create(context: Context, serviceManager: ServiceManager): NetworkService { val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager - return NetworkService( + + val queryManager = NetworkQueryManager.create(connectivityManager, telephonyManager) + + val service = NetworkService( serviceManager.getAppInfoService(), - connectivityManager, - telephonyManager + telephonyManager, + queryManager ) + + queryManager.setChangeListener(service) + + return service } } } \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/listener/NetworkChangeListener.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/listener/NetworkChangeListener.kt new file mode 100644 index 000000000..3f3f0c8d2 --- /dev/null +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/listener/NetworkChangeListener.kt @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.otel.android.internal.services.network.listener + +import android.net.NetworkCapabilities + +internal interface NetworkChangeListener { + fun onNewNetwork(capabilities: NetworkCapabilities) + + fun onNetworkLost() +} \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi21QueryManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi21QueryManager.kt new file mode 100644 index 000000000..c5568611e --- /dev/null +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi21QueryManager.kt @@ -0,0 +1,92 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.otel.android.internal.services.network.query + +import android.net.ConnectivityManager +import android.net.ConnectivityManager.NetworkCallback +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkRequest +import android.telephony.TelephonyManager +import androidx.annotation.GuardedBy +import co.elastic.otel.android.internal.services.network.listener.NetworkChangeListener + +internal class NetworkApi21QueryManager( + private val connectivityManager: ConnectivityManager, + private val telephonyManager: TelephonyManager +) : NetworkCallback(), NetworkQueryManager { + internal lateinit var listener: NetworkChangeListener + private val networkLock = Any() + + @GuardedBy("networkLock") + private var currentNetwork: Network? = null + + override fun setChangeListener(listener: NetworkChangeListener) { + this.listener = listener + } + + override fun getNetworkType(): Int { + return telephonyManager.networkType + } + + override fun start() { + connectivityManager.registerNetworkCallback( + NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(), this + ) + } + + override fun stop() { + connectivityManager.unregisterNetworkCallback(this) + } + + override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { + super.onCapabilitiesChanged(network, networkCapabilities) + onNetworkUpdate(network, networkCapabilities) + } + + private fun onNetworkUpdate(network: Network, capabilities: NetworkCapabilities) { + if (connectivityManager.getNetworkInfo(network) == connectivityManager.activeNetworkInfo) { + onActiveNetworkSet(network, capabilities) + } + } + + override fun onLost(network: Network) { + if (connectivityManager.activeNetworkInfo == null) { + onNetworkLost() + } + super.onLost(network) + } + + private fun onActiveNetworkSet(network: Network, capabilities: NetworkCapabilities) { + synchronized(networkLock) { + if (network != currentNetwork) { + currentNetwork = network + listener.onNewNetwork(capabilities) + } + } + } + + private fun onNetworkLost() { + synchronized(networkLock) { + currentNetwork = null + listener.onNetworkLost() + } + } +} \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi23QueryManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi23QueryManager.kt new file mode 100644 index 000000000..f301d3ccb --- /dev/null +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi23QueryManager.kt @@ -0,0 +1,95 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.otel.android.internal.services.network.query + +import android.annotation.TargetApi +import android.net.ConnectivityManager +import android.net.ConnectivityManager.NetworkCallback +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkRequest +import android.os.Build +import android.telephony.TelephonyManager +import androidx.annotation.GuardedBy +import co.elastic.otel.android.internal.services.network.listener.NetworkChangeListener + +@TargetApi(Build.VERSION_CODES.M) +internal class NetworkApi23QueryManager( + private val connectivityManager: ConnectivityManager, + private val telephonyManager: TelephonyManager +) : NetworkCallback(), NetworkQueryManager { + internal lateinit var listener: NetworkChangeListener + private val networkLock = Any() + + @GuardedBy("networkLock") + private var currentNetwork: Network? = null + + override fun setChangeListener(listener: NetworkChangeListener) { + this.listener = listener + } + + override fun getNetworkType(): Int { + return telephonyManager.networkType + } + + override fun start() { + connectivityManager.registerNetworkCallback( + NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build(), this + ) + } + + override fun stop() { + connectivityManager.unregisterNetworkCallback(this) + } + + override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { + super.onCapabilitiesChanged(network, networkCapabilities) + onNetworkUpdate(network, networkCapabilities) + } + + private fun onNetworkUpdate(network: Network, capabilities: NetworkCapabilities) { + if (network == connectivityManager.activeNetwork) { + onActiveNetworkSet(network, capabilities) + } + } + + override fun onLost(network: Network) { + if (connectivityManager.activeNetwork == null) { + onNetworkLost() + } + super.onLost(network) + } + + private fun onActiveNetworkSet(network: Network, capabilities: NetworkCapabilities) { + synchronized(networkLock) { + if (network != currentNetwork) { + currentNetwork = network + listener.onNewNetwork(capabilities) + } + } + } + + private fun onNetworkLost() { + synchronized(networkLock) { + currentNetwork = null + listener.onNetworkLost() + } + } +} \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi24QueryManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi24QueryManager.kt new file mode 100644 index 000000000..eddb4f1b1 --- /dev/null +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkApi24QueryManager.kt @@ -0,0 +1,62 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.otel.android.internal.services.network.query + +import android.annotation.TargetApi +import android.net.ConnectivityManager +import android.net.ConnectivityManager.NetworkCallback +import android.net.Network +import android.net.NetworkCapabilities +import android.os.Build +import android.telephony.TelephonyManager +import co.elastic.otel.android.internal.services.network.listener.NetworkChangeListener + +@TargetApi(Build.VERSION_CODES.N) +internal class NetworkApi24QueryManager( + private val connectivityManager: ConnectivityManager, + private val telephonyManager: TelephonyManager +) : NetworkCallback(), NetworkQueryManager { + internal lateinit var listener: NetworkChangeListener + + override fun setChangeListener(listener: NetworkChangeListener) { + this.listener = listener + } + + override fun getNetworkType(): Int { + return telephonyManager.dataNetworkType + } + + override fun start() { + connectivityManager.registerDefaultNetworkCallback(this) + } + + override fun stop() { + connectivityManager.unregisterNetworkCallback(this) + } + + override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { + super.onCapabilitiesChanged(network, networkCapabilities) + listener.onNewNetwork(networkCapabilities) + } + + override fun onLost(network: Network) { + super.onLost(network) + listener.onNetworkLost() + } +} \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkQueryManager.kt b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkQueryManager.kt new file mode 100644 index 000000000..f956f470c --- /dev/null +++ b/android-sdk/src/main/java/co/elastic/otel/android/internal/services/network/query/NetworkQueryManager.kt @@ -0,0 +1,56 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.otel.android.internal.services.network.query + +import android.net.ConnectivityManager +import android.os.Build +import android.telephony.TelephonyManager +import co.elastic.otel.android.internal.services.network.listener.NetworkChangeListener + +internal interface NetworkQueryManager { + companion object { + fun create( + connectivityManager: ConnectivityManager, + telephonyManager: TelephonyManager + ): NetworkQueryManager { + val currentApi = Build.VERSION.SDK_INT + return when { + currentApi == Build.VERSION_CODES.M -> NetworkApi23QueryManager( + connectivityManager, + telephonyManager + ) + + currentApi < Build.VERSION_CODES.M -> NetworkApi21QueryManager( + connectivityManager, + telephonyManager + ) + + else -> NetworkApi24QueryManager(connectivityManager, telephonyManager) + } + } + } + + fun setChangeListener(listener: NetworkChangeListener) + + fun getNetworkType(): Int + + fun start() + + fun stop() +} \ No newline at end of file diff --git a/android-sdk/src/main/java/co/elastic/otel/android/processors/ProcessorFactory.kt b/android-sdk/src/main/java/co/elastic/otel/android/processors/ProcessorFactory.kt index 4bd50d8ba..3ba3e98c4 100644 --- a/android-sdk/src/main/java/co/elastic/otel/android/processors/ProcessorFactory.kt +++ b/android-sdk/src/main/java/co/elastic/otel/android/processors/ProcessorFactory.kt @@ -18,7 +18,6 @@ */ package co.elastic.otel.android.processors -import co.elastic.otel.android.internal.opentelemetry.processors.DefaultProcessorFactory import io.opentelemetry.sdk.logs.LogRecordProcessor import io.opentelemetry.sdk.logs.export.LogRecordExporter import io.opentelemetry.sdk.metrics.export.MetricExporter @@ -27,13 +26,6 @@ import io.opentelemetry.sdk.trace.SpanProcessor import io.opentelemetry.sdk.trace.export.SpanExporter interface ProcessorFactory { - companion object { - @JvmStatic - fun getDefault(): ProcessorFactory { - return DefaultProcessorFactory() - } - } - fun createSpanProcessor(exporter: SpanExporter?): SpanProcessor? fun createLogRecordProcessor(exporter: LogRecordExporter?): LogRecordProcessor? diff --git a/android-sdk/src/main/resources/META-INF/NOTICE b/android-sdk/src/main/resources/META-INF/NOTICE index 20e2a2d8e..17a87b9ab 100644 --- a/android-sdk/src/main/resources/META-INF/NOTICE +++ b/android-sdk/src/main/resources/META-INF/NOTICE @@ -5,7 +5,7 @@ Copyright 2018-2022 Elasticsearch B.V. This product includes software licensed under the 'Apache License Version 2.0' license from the following sources: - - Android Support Library Annotations (https://developer.android.com/jetpack/androidx/releases/annotation#1.4.0) + - Core (https://developer.android.com/jetpack/androidx/releases/core#1.15.0) - Kotlin Stdlib (https://kotlinlang.org/) - OpenTelemetry Java (https://github.com/open-telemetry/opentelemetry-java) - OpenTelemetry Java Contrib (https://github.com/open-telemetry/opentelemetry-java-contrib) diff --git a/android-sdk/src/test/java/co/elastic/otel/android/integration/AttributesTest.kt b/android-sdk/src/test/java/co/elastic/otel/android/integration/AttributesTest.kt index 08d9921ac..bab2574b4 100644 --- a/android-sdk/src/test/java/co/elastic/otel/android/integration/AttributesTest.kt +++ b/android-sdk/src/test/java/co/elastic/otel/android/integration/AttributesTest.kt @@ -23,8 +23,12 @@ import android.content.Context import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities +import android.net.NetworkInfo import android.os.Build import android.telephony.TelephonyManager +import co.elastic.otel.android.internal.services.network.query.NetworkApi21QueryManager +import co.elastic.otel.android.internal.services.network.query.NetworkApi23QueryManager +import co.elastic.otel.android.internal.services.network.query.NetworkApi24QueryManager import co.elastic.otel.android.testutils.ElasticAgentRule import co.elastic.otel.android.testutils.ElasticAgentRule.Companion.LOG_DEFAULT_ATTRS import co.elastic.otel.android.testutils.ElasticAgentRule.Companion.SPAN_DEFAULT_ATTRS @@ -46,6 +50,7 @@ import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.Shadows import org.robolectric.annotation.Config +import org.robolectric.shadows.ShadowNetwork import org.robolectric.util.ReflectionHelpers @RunWith(RobolectricTestRunner::class) @@ -93,7 +98,7 @@ internal class AttributesTest { setVersionCode(0) } - @Config(sdk = [24, Config.NEWEST_SDK]) + @Config(sdk = [21, 23, Config.NEWEST_SDK]) @Test fun `Check resources`() { agentRule.initialize() @@ -133,7 +138,7 @@ internal class AttributesTest { assertThat(metricItems.first()).hasResource(expectedResource) } - @Config(sdk = [24, Config.NEWEST_SDK]) + @Config(sdk = [21, 23, Config.NEWEST_SDK]) @Test fun `Check resources with not provided service version`() { setVersionName("1.2.3") @@ -174,7 +179,7 @@ internal class AttributesTest { assertThat(metricItems.first()).hasResource(expectedResource) } - @Config(sdk = [24, Config.NEWEST_SDK]) + @Config(sdk = [21, 23, Config.NEWEST_SDK]) @Test fun `Check global attributes and span status`() { agentRule.initialize() @@ -190,7 +195,7 @@ internal class AttributesTest { assertThat(logItems.first()).hasAttributes(LOG_DEFAULT_ATTRS) } - @Config(sdk = [24, Config.NEWEST_SDK]) + @Config(sdk = [21, 23, Config.NEWEST_SDK]) @Test fun `Check global attributes with cellular connectivity available`() { agentRule.initialize() @@ -216,7 +221,7 @@ internal class AttributesTest { assertThat(logItems.first()).hasAttributes(expectedLogAttributes) } - @Config(sdk = [24, Config.NEWEST_SDK]) + @Config(sdk = [21, 23, Config.NEWEST_SDK]) @Test fun `Check global attributes with carrier info available`() { agentRule.initialize() @@ -295,22 +300,50 @@ internal class AttributesTest { private fun enableCellularDataAttr() { val application = RuntimeEnvironment.getApplication() - Shadows.shadowOf(application) - .grantPermissions(Manifest.permission.READ_PHONE_STATE) + Shadows.shadowOf(application).run { + grantPermissions(Manifest.permission.READ_PHONE_STATE) + grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE) + } + val connectivityManager = + application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val shadowConnectivityManager = - Shadows.shadowOf(application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?) + Shadows.shadowOf(connectivityManager) val shadowTelephonyManager = - Shadows.shadowOf(application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager?) - val callbacks = ArrayList(shadowConnectivityManager.networkCallbacks) - val defaultNetworkCallback = callbacks[0] + Shadows.shadowOf(application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager) + val defaultNetworkCallback = shadowConnectivityManager.networkCallbacks.first() + val activeNetworkInfo = mockk() + every { activeNetworkInfo.type }.returns(ConnectivityManager.TYPE_MOBILE) + shadowConnectivityManager.setActiveNetworkInfo(activeNetworkInfo) + var activeNetwork: Network = ShadowNetwork.newInstance(ConnectivityManager.TYPE_MOBILE) + + when (Build.VERSION.SDK_INT) { + in 21..22 -> { + assertThat(defaultNetworkCallback).isInstanceOf(NetworkApi21QueryManager::class.java) + shadowTelephonyManager.setNetworkType(TelephonyManager.NETWORK_TYPE_EDGE) + } + + 23 -> { + assertThat(defaultNetworkCallback).isInstanceOf(NetworkApi23QueryManager::class.java) + shadowTelephonyManager.setNetworkType(TelephonyManager.NETWORK_TYPE_EDGE) + activeNetwork = connectivityManager.activeNetwork!! + } + + else -> { + assertThat(defaultNetworkCallback).isInstanceOf(NetworkApi24QueryManager::class.java) + shadowTelephonyManager.setDataNetworkType(TelephonyManager.NETWORK_TYPE_EDGE) + activeNetwork = connectivityManager.activeNetwork!! + } + } val capabilities = mockk() every { capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) } returns true - shadowTelephonyManager.setDataNetworkType(TelephonyManager.NETWORK_TYPE_EDGE) - defaultNetworkCallback.onCapabilitiesChanged(mockk(), capabilities) + defaultNetworkCallback.onCapabilitiesChanged( + activeNetwork, + capabilities + ) } private fun enableCarrierInfoAttrs() { diff --git a/android-sdk/src/test/java/co/elastic/otel/android/integration/ElasticApmAgentTest.kt b/android-sdk/src/test/java/co/elastic/otel/android/integration/ElasticApmAgentTest.kt index 817e9c521..42a43c3c8 100644 --- a/android-sdk/src/test/java/co/elastic/otel/android/integration/ElasticApmAgentTest.kt +++ b/android-sdk/src/test/java/co/elastic/otel/android/integration/ElasticApmAgentTest.kt @@ -200,9 +200,9 @@ class ElasticApmAgentTest { metricsRequest.headers.getHeader("Authorization").firstValue() ).isEqualTo("Bearer $secretToken") - // Changing config + // Changing global config val apiKey = "api-key" - agent.getApmServerConnectivityManager().setConnectivityConfiguration( + agent.setApmServerConnectivity( ApmServerConnectivity( wireMockRule.url("/second/"), ApmServerAuthentication.ApiKey(apiKey), diff --git a/android-sdk/src/test/java/co/elastic/otel/android/internal/services/network/NetworkServiceTest.kt b/android-sdk/src/test/java/co/elastic/otel/android/internal/services/network/NetworkServiceTest.kt index 95cb708d2..40a7fa400 100644 --- a/android-sdk/src/test/java/co/elastic/otel/android/internal/services/network/NetworkServiceTest.kt +++ b/android-sdk/src/test/java/co/elastic/otel/android/internal/services/network/NetworkServiceTest.kt @@ -18,9 +18,9 @@ */ package co.elastic.otel.android.internal.services.network -import android.net.ConnectivityManager import android.telephony.TelephonyManager import co.elastic.otel.android.internal.services.appinfo.AppInfoService +import co.elastic.otel.android.internal.services.network.query.NetworkQueryManager import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK @@ -31,7 +31,7 @@ import org.junit.Test class NetworkServiceTest { @MockK - private lateinit var connectivityManager: ConnectivityManager + private lateinit var networkQueryManager: NetworkQueryManager @MockK private lateinit var telephonyManager: TelephonyManager @@ -43,7 +43,7 @@ class NetworkServiceTest { @Before fun setUp() { MockKAnnotations.init(this) - networkService = NetworkService(appInfoService, connectivityManager, telephonyManager) + networkService = NetworkService(appInfoService, telephonyManager, networkQueryManager) } @Test diff --git a/android-test/build.gradle.kts b/android-test/build.gradle.kts index 087054ee6..b05a02f4e 100644 --- a/android-test/build.gradle.kts +++ b/android-test/build.gradle.kts @@ -9,7 +9,7 @@ propertiesFile.inputStream().use { extra.apply { set("jvmCompatibility", JavaVersion.VERSION_17) - set("androidCompileSdk", 34) + set("androidCompileSdk", 35) set("androidMinSdk", 26) set("agentVersion", agentProperties["version"]) } \ No newline at end of file diff --git a/android-test/gradle/libs.versions.toml b/android-test/gradle/libs.versions.toml index 73e05d0e5..778b4f0c7 100644 --- a/android-test/gradle/libs.versions.toml +++ b/android-test/gradle/libs.versions.toml @@ -1,15 +1,15 @@ [versions] -espresso = "3.5.1" +espresso = "3.6.1" [libraries] -openTelemetry-exporter = "io.opentelemetry:opentelemetry-exporter-otlp:1.28.0" +openTelemetry-exporter = "io.opentelemetry:opentelemetry-exporter-otlp:1.46.0" junit = "junit:junit:4.13.2" espresso-idlingResource = { module = "androidx.test.espresso:espresso-idling-resource", version.ref = "espresso" } espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "espresso" } -mockito = "org.mockito:mockito-core:5.14.2" +mockito = "org.mockito:mockito-core:5.15.2" mockWebServer = "com.squareup.okhttp3:mockwebserver:4.12.0" -fragmentTesting = "androidx.fragment:fragment-testing:1.6.1" -appCompat = "androidx.appcompat:appcompat:1.5.1" -coreLib = "com.android.tools:desugar_jdk_libs:2.0.4" -robolectric = "org.robolectric:robolectric:4.12.1" \ No newline at end of file +fragmentTesting = "androidx.fragment:fragment-testing:1.8.5" +appCompat = "androidx.appcompat:appcompat:1.7.0" +coreLib = "com.android.tools:desugar_jdk_libs:2.1.4" +robolectric = "org.robolectric:robolectric:4.14.1" \ No newline at end of file diff --git a/build-tools/src/main/kotlin/elastic.android-library.gradle.kts b/build-tools/src/main/kotlin/elastic.android-library.gradle.kts index 804796544..0e9022002 100644 --- a/build-tools/src/main/kotlin/elastic.android-library.gradle.kts +++ b/build-tools/src/main/kotlin/elastic.android-library.gradle.kts @@ -20,6 +20,7 @@ android { } kotlinOptions { jvmTarget = javaVersionStr + freeCompilerArgs = listOf("-Xjvm-default=all") } } diff --git a/build-tools/src/main/kotlin/elastic.java-library.gradle.kts b/build-tools/src/main/kotlin/elastic.java-library.gradle.kts index 0c8030741..69f01d94b 100644 --- a/build-tools/src/main/kotlin/elastic.java-library.gradle.kts +++ b/build-tools/src/main/kotlin/elastic.java-library.gradle.kts @@ -14,6 +14,7 @@ java { kotlin.compilerOptions { jvmTarget.set(JvmTarget.fromTarget(javaVersionStr)) + freeCompilerArgs = listOf("-Xjvm-default=all") } tasks.withType(Test::class).configureEach { diff --git a/docs/setup.asciidoc b/docs/setup.asciidoc index 6315f9b48..d9789157d 100644 --- a/docs/setup.asciidoc +++ b/docs/setup.asciidoc @@ -25,12 +25,12 @@ Follow these steps to start reporting your Android application's performance to |7.4.0 |Android API level -|24 +|21 |=== [float] -[[minsdk-24-support]] +[[minsdk-21-support]] ==== For projects using minSdkVersion < 26 Due to Android's limited support for Java 8 features on devices with an API level < 26, or in other words, older than Android 8.0, you must add https://developer.android.com/studio/write/java8-support#library-desugaring[Java 8+ desugaring support] to apps with a `minSdkVersion` less than 26. diff --git a/docs/supported-technologies.asciidoc b/docs/supported-technologies.asciidoc index a224bac8b..bd015ff9d 100644 --- a/docs/supported-technologies.asciidoc +++ b/docs/supported-technologies.asciidoc @@ -29,7 +29,7 @@ This section lists all supported technologies. |=== |Supported versions -| API >= 24 +| API >= 21 |=== NOTE: If your minSdk version is lower than 26, then you must add https://developer.android.com/studio/write/java8-support#library-desugaring[Java 8+ desugaring support] to your application. diff --git a/gradle.properties b/gradle.properties index 1eaa5e427..e8a6d4eb9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,10 +1,10 @@ #Mon Jul 29 12:17:40 UTC 2024 -androidGradlePlugin_version=8.2.0 +androidGradlePlugin_version=8.7.3 description=APM for Android applications with the Elastic stack org.gradle.jvmargs=-XX\:MaxMetaspaceSize\=2G version=0.21.0 android.useAndroidX=true -elastic.android.minSdk=24 -elastic.android.compileSdk=34 +elastic.android.minSdk=21 +elastic.android.compileSdk=35 elastic.java.compatibility=11 group=co.elastic.apm diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 70e4f10a6..27eadafd8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,54 +1,52 @@ [versions] -opentelemetry-android = "0.5.0-alpha" -opentelemetry = "1.40.0" -opentelemetry-semconv = "1.26.0-alpha" -opentelemetry-contrib = "1.37.0-alpha" -mockito = "5.14.2" -byteBuddy = "1.14.18" -kotlin = "1.9.23" -android = "8.2.0" -junit5 = "5.11.3" +opentelemetry = "1.46.0" +opentelemetry-semconv = "1.29.0-alpha" +opentelemetry-contrib = "1.43.0-alpha" +byteBuddy = "1.16.1" +kotlin = "2.1.0" +android = "8.7.3" +junit5 = "5.11.4" [libraries] opentelemetry-sdk = { module = "io.opentelemetry:opentelemetry-sdk", version.ref = "opentelemetry" } -opentelemetry-android-okhttpLib = { module = "io.opentelemetry.android:okhttp-3.0-library", version.ref = "opentelemetry-android" } -opentelemetry-android-okhttpAgent = { module = "io.opentelemetry.android:okhttp-3.0-agent", version.ref = "opentelemetry-android" } stagemonitor-configuration = "org.stagemonitor:stagemonitor-configuration:0.89.1" -androidx-annotations = "androidx.annotation:annotation:1.4.0" +androidx-annotations = "androidx.annotation:annotation:1.9.1" +androidx-core = "androidx.core:core:1.15.0" dsl-json = "com.dslplatform:dsl-json-java8:1.10.0" -slf4j-api = "org.slf4j:slf4j-api:2.0.0" +slf4j-api = "org.slf4j:slf4j-api:2.0.7" byteBuddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byteBuddy" } opentelemetry-semconv = { module = "io.opentelemetry.semconv:opentelemetry-semconv", version.ref = "opentelemetry-semconv" } +opentelemetry-semconv-incubating = { module = "io.opentelemetry.semconv:opentelemetry-semconv-incubating", version.ref = "opentelemetry-semconv" } opentelemetry-diskBuffering = { module = "io.opentelemetry.contrib:opentelemetry-disk-buffering", version.ref = "opentelemetry-contrib" } opentelemetry-exporter-otlp = { module = "io.opentelemetry:opentelemetry-exporter-otlp", version.ref = "opentelemetry" } #Test tools -mockito = { module = "org.mockito:mockito-core", version.ref = "mockito" } junit4 = "junit:junit:4.13.2" junit5 = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit5" } junit5-vintage = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } opentelemetry-testing = { module = "io.opentelemetry:opentelemetry-sdk-testing", version.ref = "opentelemetry" } -robolectric = "org.robolectric:robolectric:4.13" -assertj = "org.assertj:assertj-core:3.26.3" -coreLib = "com.android.tools:desugar_jdk_libs:2.0.4" -mockk = "io.mockk:mockk:1.13.13" +robolectric = "org.robolectric:robolectric:4.14.1" +assertj = "org.assertj:assertj-core:3.27.3" +coreLib = "com.android.tools:desugar_jdk_libs:2.1.4" +mockk = "io.mockk:mockk:1.13.16" awaitility = "org.awaitility:awaitility-kotlin:4.2.2" wireMock = "org.wiremock:wiremock:3.10.0" #Compilation tools apache-commons-text = "org.apache.commons:commons-text:1.10.0" commons-io = "commons-io:commons-io:2.13.0" -spotless-plugin = "com.diffplug.spotless:spotless-plugin-gradle:6.24.0" +spotless-plugin = "com.diffplug.spotless:spotless-plugin-gradle:7.0.2" dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.9.0" -nexus-publish-plugin = "io.github.gradle-nexus:publish-plugin:1.3.0" +nexus-publish-plugin = "io.github.gradle-nexus:publish-plugin:2.0.0" gradle-publish-plugin = "com.gradle.publish:plugin-publish-plugin:1.2.1" gradle-shadow-plugin = "gradle.plugin.com.github.johnrengelman:shadow:7.1.2" byteBuddy-plugin = { module = "net.bytebuddy:byte-buddy-gradle-plugin", version.ref = "byteBuddy" } kotlin-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } [bundles] -mocking = ["mockito", "mockk"] +mocking = ["mockk"] junit = ["junit4", "junit5"] +opentelemetry-semconv = ["opentelemetry-semconv", "opentelemetry-semconv-incubating"] [plugins] androidApp = { id = "com.android.application", version.ref = "android" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 744c64d12..171d8761b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/manual_licenses_map.txt b/manual_licenses_map.txt index d113e42a3..1448252de 100644 --- a/manual_licenses_map.txt +++ b/manual_licenses_map.txt @@ -1,5 +1,5 @@ -net.bytebuddy:byte-buddy:1.14.18|apache_v2 -net.bytebuddy:byte-buddy-gradle-plugin:1.14.18|apache_v2 -org.slf4j:slf4j-api:2.0.0|mit +net.bytebuddy:byte-buddy:1.16.1|apache_v2 +net.bytebuddy:byte-buddy-gradle-plugin:1.16.1|apache_v2 +org.slf4j:slf4j-api:2.0.7|mit com.squareup.okhttp3:okhttp:3.11.0|apache_v2 com.github.instacart.truetime-android:library:3.5|apache_v2 \ No newline at end of file