From 6fe9cfeec660b329e8b4629c33a03c3434685b9a Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:24:56 +0100 Subject: [PATCH 01/34] Adding the disk buffering dependency --- gradle/libs.versions.toml | 3 ++- instrumentation/build.gradle.kts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 76e0ed807..84059f9bd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,8 @@ opentelemetry-api = { module = "io.opentelemetry:opentelemetry-api" } opentelemetry-sdk = { module = "io.opentelemetry:opentelemetry-sdk" } opentelemetry-exporter-zipkin = { module = "io.opentelemetry:opentelemetry-exporter-zipkin" } opentelemetry-exporter-logging = { module = "io.opentelemetry:opentelemetry-exporter-logging" } -zipkin-sender-okhttp3 = { module = "io.zipkin.reporter2:zipkin-sender-okhttp3", version.ref = "zipkin-reporter"} +zipkin-sender-okhttp3 = { module = "io.zipkin.reporter2:zipkin-sender-okhttp3", version.ref = "zipkin-reporter" } +opentelemetry-diskBuffering = "io.opentelemetry.contrib:opentelemetry-disk-buffering:1.31.0-alpha" #Test tools opentelemetry-sdk-testing = { module = "io.opentelemetry:opentelemetry-sdk-testing", version.ref = "opentelemetry" } diff --git a/instrumentation/build.gradle.kts b/instrumentation/build.gradle.kts index bbbaee619..6e16ce6d1 100644 --- a/instrumentation/build.gradle.kts +++ b/instrumentation/build.gradle.kts @@ -70,6 +70,7 @@ dependencies { implementation(libs.opentelemetry.exporter.logging) implementation(libs.opentelemetry.instrumentation.api) implementation(libs.opentelemetry.semconv) + implementation(libs.opentelemetry.diskBuffering) testImplementation(libs.bundles.mockito) testImplementation(libs.bundles.junit) From 88d64e695357038afa958eb11f51cd74dedb61ef Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:25:07 +0100 Subject: [PATCH 02/34] Moving OtelRumConfig --- .../ScreenAttributesSpanProcessor.java | 2 +- .../android/config/OtelRumConfig.java | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java diff --git a/instrumentation/src/main/java/io/opentelemetry/android/ScreenAttributesSpanProcessor.java b/instrumentation/src/main/java/io/opentelemetry/android/ScreenAttributesSpanProcessor.java index 57c0d411c..db86ee571 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/ScreenAttributesSpanProcessor.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/ScreenAttributesSpanProcessor.java @@ -13,7 +13,7 @@ import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SpanProcessor; -class ScreenAttributesSpanProcessor implements SpanProcessor { +public final class ScreenAttributesSpanProcessor implements SpanProcessor { private final VisibleScreenTracker visibleScreenTracker; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java new file mode 100644 index 000000000..ca3dfefca --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -0,0 +1,95 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.config; + +import java.util.function.Supplier; + +import io.opentelemetry.android.ScreenAttributesSpanProcessor; +import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; +import io.opentelemetry.api.common.Attributes; + +/** + * Configuration object for OpenTelemetry Android. The configuration items in this class will be + * used in the OpenTelemetryRumBuilder to wire up and enable/disable various mobile instrumentation + * components. + */ +public class OtelRumConfig { + + private Supplier globalAttributesSupplier = Attributes::empty; + private boolean includeNetworkAttributes = true; + private boolean generateSdkInitializationEvents = true; + private boolean includeScreenAttributes = true; + + /** + * Configures the set of global attributes to emit with every span and event. Any existing + * configured attributes will be dropped. Default = none. + */ + public OtelRumConfig setGlobalAttributes(Attributes attributes) { + return setGlobalAttributes(() -> attributes); + } + + public OtelRumConfig setGlobalAttributes(Supplier globalAttributesSupplier) { + this.globalAttributesSupplier = globalAttributesSupplier; + return this; + } + + boolean hasGlobalAttributes() { + Attributes attributes = globalAttributesSupplier.get(); + return attributes != null && !attributes.isEmpty(); + } + + Supplier getGlobalAttributesSupplier() { + return globalAttributesSupplier; + } + + /** + * Disables the collection of runtime network attributes. See {@link CurrentNetworkProvider} for + * more information. Default = true. + * + * @return this + */ + public OtelRumConfig disableNetworkAttributes() { + includeNetworkAttributes = false; + return this; + } + + /** Returns true if runtime network attributes are enabled, false otherwise. */ + public boolean shouldIncludeNetworkAttributes() { + return includeNetworkAttributes; + } + + /** + * Disables the collection of events related to the initialization of the OTel Android SDK + * itself. Default = true. + * + * @return this + */ + public OtelRumConfig disableSdkInitializationEvents() { + this.generateSdkInitializationEvents = false; + return this; + } + + /** Returns true if the SDK is configured to generate initialization events, false otherwise. */ + public boolean shouldGenerateSdkInitializationEvents() { + return generateSdkInitializationEvents; + } + + /** + * Call this to disable the collection of screen attributes. See {@link + * ScreenAttributesSpanProcessor} for more information. Default = true. + * + * @return this + */ + public OtelRumConfig disableScreenAttributes() { + this.includeScreenAttributes = false; + return this; + } + + /** Return true if the SDK should be configured to report screen attributes. */ + public boolean shouldIncludeScreenAttributes() { + return includeScreenAttributes; + } +} From 83743cce0734424368cf1b30b8df7a77f5c38c61 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:43:26 +0100 Subject: [PATCH 03/34] Creating PersistenceConfiguration --- .../android/config/OtelRumConfig.java | 27 ++++++++-- .../config/PersistenceConfiguration.java | 50 +++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index ca3dfefca..d8f5c21dc 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -22,6 +22,7 @@ public class OtelRumConfig { private boolean includeNetworkAttributes = true; private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; + private PersistenceConfiguration persistenceConfiguration; /** * Configures the set of global attributes to emit with every span and event. Any existing @@ -56,7 +57,9 @@ public OtelRumConfig disableNetworkAttributes() { return this; } - /** Returns true if runtime network attributes are enabled, false otherwise. */ + /** + * Returns true if runtime network attributes are enabled, false otherwise. + */ public boolean shouldIncludeNetworkAttributes() { return includeNetworkAttributes; } @@ -72,7 +75,9 @@ public OtelRumConfig disableSdkInitializationEvents() { return this; } - /** Returns true if the SDK is configured to generate initialization events, false otherwise. */ + /** + * Returns true if the SDK is configured to generate initialization events, false otherwise. + */ public boolean shouldGenerateSdkInitializationEvents() { return generateSdkInitializationEvents; } @@ -88,8 +93,24 @@ public OtelRumConfig disableScreenAttributes() { return this; } - /** Return true if the SDK should be configured to report screen attributes. */ + /** + * Return true if the SDK should be configured to report screen attributes. + */ public boolean shouldIncludeScreenAttributes() { return includeScreenAttributes; } + + public PersistenceConfiguration getPersistenceConfiguration() { + if (persistenceConfiguration == null) { + return PersistenceConfiguration.builder().build(); + } + return persistenceConfiguration; + } + + /** + * Sets the parameters for caching signals in disk in order to export them later. + */ + public void setPersistenceConfiguration(PersistenceConfiguration persistenceConfiguration) { + this.persistenceConfiguration = persistenceConfiguration; + } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java new file mode 100644 index 000000000..b8ff599f6 --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java @@ -0,0 +1,50 @@ +package io.opentelemetry.android.config; + +/** + * Configuration for disk buffering. + */ +public final class PersistenceConfiguration { + public final boolean enabled; + public final int maxCacheSize; + + private PersistenceConfiguration(Builder builder) { + this.enabled = builder.enabled; + this.maxCacheSize = builder.maxCacheSize; + } + + public static Builder builder() { + return new Builder(false, 60 * 1024 * 1024); + } + + public static final class Builder { + private boolean enabled; + private int maxCacheSize; + + private Builder(boolean enabled, int maxCacheSize) { + this.enabled = enabled; + this.maxCacheSize = maxCacheSize; + } + + /** + * Enables or disables disk buffering. + */ + public Builder setEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Sets the maximum amount of bytes that this tool can use to store cached signals in disk. + * A smaller amount of space will be used if there's not enough space in disk to allocate + * the value provided here. + */ + public Builder setMaxCacheSize(int maxCacheSize) { + this.maxCacheSize = maxCacheSize; + return this; + } + + public PersistenceConfiguration build() { + return new PersistenceConfiguration(this); + } + } +} From ab4052836e636483edb91f1e90208e7eabb167de Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:42:45 +0100 Subject: [PATCH 04/34] Creating DiskManager and the services it needs --- .../opentelemetry/android/OtelRumConfig.java | 93 ------------------- .../startup/InitializationEvents.java | 2 - .../startup/SdkInitializationEvents.java | 2 - .../features/persistence/DiskManager.java | 91 ++++++++++++++++++ .../internal/services/AppInfoService.java | 79 ++++++++++++++++ .../android/internal/services/Lifecycle.java | 25 +++++ .../internal/services/PreferencesService.java | 43 +++++++++ .../android/internal/services/Service.java | 10 ++ .../internal/services/ServiceManager.java | 74 +++++++++++++++ 9 files changed, 322 insertions(+), 97 deletions(-) delete mode 100644 instrumentation/src/main/java/io/opentelemetry/android/OtelRumConfig.java create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java diff --git a/instrumentation/src/main/java/io/opentelemetry/android/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/OtelRumConfig.java deleted file mode 100644 index 11d3c3fb4..000000000 --- a/instrumentation/src/main/java/io/opentelemetry/android/OtelRumConfig.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android; - -import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; -import io.opentelemetry.api.common.Attributes; -import java.util.function.Supplier; - -/** - * Configuration object for OpenTelemetry Android. The configuration items in this class will be - * used in the OpenTelemetryRumBuilder to wire up and enable/disable various mobile instrumentation - * components. - */ -public class OtelRumConfig { - - private Supplier globalAttributesSupplier = Attributes::empty; - private boolean includeNetworkAttributes = true; - private boolean generateSdkInitializationEvents = true; - private boolean includeScreenAttributes = true; - - /** - * Configures the set of global attributes to emit with every span and event. Any existing - * configured attributes will be dropped. Default = none. - */ - public OtelRumConfig setGlobalAttributes(Attributes attributes) { - return setGlobalAttributes(() -> attributes); - } - - public OtelRumConfig setGlobalAttributes(Supplier globalAttributesSupplier) { - this.globalAttributesSupplier = globalAttributesSupplier; - return this; - } - - boolean hasGlobalAttributes() { - Attributes attributes = globalAttributesSupplier.get(); - return attributes != null && !attributes.isEmpty(); - } - - Supplier getGlobalAttributesSupplier() { - return globalAttributesSupplier; - } - - /** - * Disables the collection of runtime network attributes. See {@link CurrentNetworkProvider} for - * more information. Default = true. - * - * @return this - */ - public OtelRumConfig disableNetworkAttributes() { - includeNetworkAttributes = false; - return this; - } - - /** Returns true if runtime network attributes are enabled, false otherwise. */ - public boolean shouldIncludeNetworkAttributes() { - return includeNetworkAttributes; - } - - /** - * Disables the collection of events related to the initialization of the OTel Android SDK - * itself. Default = true. - * - * @return this - */ - public OtelRumConfig disableSdkInitializationEvents() { - this.generateSdkInitializationEvents = false; - return this; - } - - /** Returns true if the SDK is configured to generate initialization events, false otherwise. */ - public boolean shouldGenerateSdkInitializationEvents() { - return generateSdkInitializationEvents; - } - - /** - * Call this to disable the collection of screen attributes. See {@link - * ScreenAttributesSpanProcessor} for more information. Default = true. - * - * @return this - */ - public OtelRumConfig disableScreenAttributes() { - this.includeScreenAttributes = false; - return this; - } - - /** Return true if the SDK should be configured to report screen attributes. */ - public boolean shouldIncludeScreenAttributes() { - return includeScreenAttributes; - } -} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java index 5fae104ca..320951ea6 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java @@ -5,8 +5,6 @@ package io.opentelemetry.android.instrumentation.startup; -import io.opentelemetry.android.OtelRumConfig; - public interface InitializationEvents { void sdkInitializationStarted(); diff --git a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java index ed20a7fc8..518d182f6 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java @@ -5,8 +5,6 @@ package io.opentelemetry.android.instrumentation.startup; -import io.opentelemetry.android.OtelRumConfig; - public class SdkInitializationEvents implements InitializationEvents { @Override diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java new file mode 100644 index 000000000..bdf7e5cab --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -0,0 +1,91 @@ +package io.opentelemetry.android.internal.features.persistence; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import io.opentelemetry.android.config.OtelRumConfig; +import io.opentelemetry.android.config.PersistenceConfiguration; +import io.opentelemetry.android.internal.services.AppInfoService; +import io.opentelemetry.android.internal.services.PreferencesService; +import io.opentelemetry.android.internal.services.Service; +import io.opentelemetry.android.internal.services.ServiceManager; + +/** + * This class is internal and not for public use. Its APIs are unstable and can change at any + * time. + */ +public final class DiskManager { + private final AppInfoService appInfoService; + private final PreferencesService preferencesService; + private final PersistenceConfiguration persistenceConfiguration; + private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; + private static final int MAX_FILE_SIZE = 1024 * 1024; + private final Logger logger = Logger.getLogger("DiskManager"); + + public static DiskManager create(OtelRumConfig config) { + ServiceManager serviceManager = ServiceManager.get(); + return new DiskManager(serviceManager.getService(Service.Type.APPLICATION_INFO), + serviceManager.getService(Service.Type.PREFERENCES), + config.getPersistenceConfiguration()); + } + + DiskManager(AppInfoService appInfoService, PreferencesService preferencesService, PersistenceConfiguration persistenceConfiguration) { + this.appInfoService = appInfoService; + this.preferencesService = preferencesService; + this.persistenceConfiguration = persistenceConfiguration; + } + + public File getSignalsCacheDir() throws IOException { + File dir = new File(appInfoService.getCacheDir(), "opentelemetry/signals"); + if (!dir.exists()) { + if (!dir.mkdirs()) { + throw new IOException("Could not create dir " + dir); + } + } + return dir; + } + + public File getTemporaryDir() throws IOException { + File dir = new File(appInfoService.getCacheDir(), "opentelemetry/temp"); + if (!dir.exists()) { + if (!dir.mkdirs()) { + throw new IOException("Could not create dir " + dir); + } + } + deleteFiles(dir); + return dir; + } + + public int getMaxFolderSize() { + int storedSize = preferencesService.retrieveInt(MAX_FOLDER_SIZE_KEY, -1); + if (storedSize != -1) { + logger.log(Level.FINER, String.format("Returning max folder size from preferences: %s", storedSize)); + return storedSize; + } + int requestedSize = persistenceConfiguration.maxCacheSize; + int availableCacheSize = (int) appInfoService.getAvailableCacheSpace(requestedSize); + int calculatedSize = (availableCacheSize / 3) - MAX_FILE_SIZE; + preferencesService.store(MAX_FOLDER_SIZE_KEY, calculatedSize); + + logger.log(Level.FINER, String.format("Requested cache size: %s, available cache size: %s, folder size: %s", requestedSize, availableCacheSize, calculatedSize)); + return calculatedSize; + } + + public int getMaxCacheFileSize() { + return MAX_FILE_SIZE; + } + + private static void deleteFiles(File dir) { + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + deleteFiles(file); + } + file.delete(); + } + } + } +} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java new file mode 100644 index 000000000..7b57dc107 --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java @@ -0,0 +1,79 @@ +package io.opentelemetry.android.internal.services; + +import android.content.Context; +import android.os.Build; +import android.os.storage.StorageManager; + +import androidx.annotation.RequiresApi; +import androidx.annotation.WorkerThread; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility to get information about the host app. + *

+ * This class is internal and not for public use. Its APIs are unstable and can change at any + * time. + */ +public class AppInfoService implements Service { + private final Context appContext; + private final Logger logger = Logger.getLogger("AppInfoService"); + + public AppInfoService(Context appContext) { + this.appContext = appContext; + } + + public File getCacheDir() { + return appContext.getCacheDir(); + } + + @WorkerThread + public long getAvailableCacheSpace(long maxSpaceNeeded) { + File cacheDir = getCacheDir(); + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) { + return getLegacyAvailableSpace(cacheDir, maxSpaceNeeded); + } + return getAvailableSpace(cacheDir, maxSpaceNeeded); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private long getAvailableSpace(File directory, long maxSpaceNeeded) { + logger.log(Level.FINER, String.format("Getting available space for %s, max needed is: %s", directory, maxSpaceNeeded)); + try { + StorageManager storageManager = appContext.getSystemService(StorageManager.class); + UUID appSpecificInternalDirUuid = storageManager.getUuidForPath(directory); + // Get the minimum amount of allocatable space. + long spaceToAllocate = Math.min(storageManager.getAllocatableBytes(appSpecificInternalDirUuid), maxSpaceNeeded); + // Ensure the space is available by asking the OS to clear stale cache if needed. + storageManager.allocateBytes(appSpecificInternalDirUuid, spaceToAllocate); + return spaceToAllocate; + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to get available space", e); + return getLegacyAvailableSpace(directory, maxSpaceNeeded); + } + } + + private long getLegacyAvailableSpace(File directory, long maxSpaceNeeded) { + logger.log(Level.FINER, String.format("Getting legacy available space for %s max needed is: %s", directory, maxSpaceNeeded)); + return Math.min(directory.getUsableSpace(), maxSpaceNeeded); + } + + @Override + public void start() { + // No operation. + } + + @Override + public void stop() { + // No operation. + } + + @Override + public Type type() { + return Type.APPLICATION_INFO; + } +} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java new file mode 100644 index 000000000..e784db023 --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java @@ -0,0 +1,25 @@ +/* + * 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 io.opentelemetry.android.internal.services; + +public interface Lifecycle { + void start(); + + void stop(); +} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java new file mode 100644 index 000000000..79f9ecc66 --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java @@ -0,0 +1,43 @@ +package io.opentelemetry.android.internal.services; + +import android.content.Context; +import android.content.SharedPreferences; + +import io.opentelemetry.android.BuildConfig; + +/** + * Utility to store and retrieve apps' preferences. + *

+ * This class is internal and not for public use. Its APIs are unstable and can change at any + * time. + */ +public class PreferencesService implements Service { + private final SharedPreferences preferences; + + public PreferencesService(Context context) { + preferences = context.getSharedPreferences(BuildConfig.LIBRARY_PACKAGE_NAME + ".prefs", Context.MODE_PRIVATE); + } + + @Override + public void start() { + // No op + } + + @Override + public void stop() { + // No op + } + + public void store(String key, int value) { + preferences.edit().putInt(key, value).apply(); + } + + public int retrieveInt(String key, int defaultValue) { + return preferences.getInt(key, defaultValue); + } + + @Override + public Type type() { + return Type.PREFERENCES; + } +} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java new file mode 100644 index 000000000..b4d6a8dbf --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java @@ -0,0 +1,10 @@ +package io.opentelemetry.android.internal.services; + +public interface Service extends Lifecycle { + + Type type(); + + enum Type { + APPLICATION_INFO, PREFERENCES + } +} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java new file mode 100644 index 000000000..4b43df262 --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -0,0 +1,74 @@ +package io.opentelemetry.android.internal.services; + +import android.content.Context; + +import androidx.annotation.RestrictTo; + +import java.util.HashMap; + +public final class ServiceManager implements Lifecycle { + + private final HashMap services = new HashMap<>(); + private static ServiceManager INSTANCE; + + private ServiceManager() { + } + + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) + public static void initialize(Context appContext) { + INSTANCE = new ServiceManager(); + INSTANCE.addService(new PreferencesService(appContext)); + } + + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) + public static ServiceManager get() { + if (INSTANCE == null) { + throw new IllegalStateException("Services haven't been initialized"); + } + return INSTANCE; + } + + public void addService(Service service) { + Service.Type type = service.type(); + verifyNotExisting(type); + services.put(type, service); + } + + @Override + public void start() { + for (Service service : services.values()) { + service.start(); + } + } + + @Override + public void stop() { + for (Service service : services.values()) { + service.stop(); + } + } + + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) + @SuppressWarnings("unchecked") + public T getService(Service.Type type) { + Service service = services.get(type); + if (service == null) { + throw new IllegalArgumentException("Service not found: " + type); + } + + return (T) service; + } + + public static void resetForTest() { + if (INSTANCE != null) { + INSTANCE.stop(); + } + INSTANCE = null; + } + + private void verifyNotExisting(Service.Type type) { + if (services.containsKey(type)) { + throw new IllegalArgumentException("Service already registered with type: " + type); + } + } +} From 2e495be5db3d535390bcbf014ba43f9329ed8e18 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:43:48 +0100 Subject: [PATCH 05/34] Addressing OtelRumConfig references --- .../instrumentation/startup/InitializationEvents.java | 11 ++++++++--- .../startup/SdkInitializationEvents.java | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java index 320951ea6..0ff2ec0ca 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java @@ -5,6 +5,8 @@ package io.opentelemetry.android.instrumentation.startup; +import io.opentelemetry.android.config.OtelRumConfig; + public interface InitializationEvents { void sdkInitializationStarted(); @@ -16,12 +18,15 @@ public interface InitializationEvents { InitializationEvents NO_OP = new InitializationEvents() { @Override - public void sdkInitializationStarted() {} + public void sdkInitializationStarted() { + } @Override - public void recordConfiguration(OtelRumConfig config) {} + public void recordConfiguration(OtelRumConfig config) { + } @Override - public void currentNetworkProviderInitialized() {} + public void currentNetworkProviderInitialized() { + } }; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java index 518d182f6..74eb1fc86 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.java @@ -5,6 +5,8 @@ package io.opentelemetry.android.instrumentation.startup; +import io.opentelemetry.android.config.OtelRumConfig; + public class SdkInitializationEvents implements InitializationEvents { @Override From 5c724d6e0b7304462679ff603ad4bd9a6a894f1b Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:44:30 +0100 Subject: [PATCH 06/34] Addressing OtelRumConfig references --- .../android/OpenTelemetryRumBuilder.java | 17 +++++++++++------ .../android/config/OtelRumConfig.java | 4 ++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java index cd9ddc27c..1da78fa05 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java @@ -8,6 +8,14 @@ import static java.util.Objects.requireNonNull; import android.app.Application; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.android.instrumentation.InstrumentedApplication; import io.opentelemetry.android.instrumentation.activity.VisibleScreenTracker; import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; @@ -30,11 +38,6 @@ import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; /** * A builder of {@link OpenTelemetryRum}. It enabled configuring the OpenTelemetry SDK and disabling @@ -243,7 +246,9 @@ public OpenTelemetryRum build() { return delegate.build(); } - /** Leverage the configuration to wire up various instrumentation components. */ + /** + * Leverage the configuration to wire up various instrumentation components. + */ private void applyConfiguration() { if (config.shouldGenerateSdkInitializationEvents()) { initializationEvents = new SdkInitializationEvents(); diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index d8f5c21dc..3e5dafec0 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -37,12 +37,12 @@ public OtelRumConfig setGlobalAttributes(Supplier globalAttributesSu return this; } - boolean hasGlobalAttributes() { + public boolean hasGlobalAttributes() { Attributes attributes = globalAttributesSupplier.get(); return attributes != null && !attributes.isEmpty(); } - Supplier getGlobalAttributesSupplier() { + public Supplier getGlobalAttributesSupplier() { return globalAttributesSupplier; } From 931d3ef4b40f72bc19210b56e956c80bef2ffc86 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:46:52 +0100 Subject: [PATCH 07/34] Addressing compilation issues --- .../android/OpenTelemetryRum.java | 8 ++++++-- .../android/config/OtelRumConfig.java | 5 ++++- .../internal/services/ServiceManager.java | 20 ++++++++++--------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java index cda839385..822a075b3 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java @@ -6,6 +6,8 @@ package io.opentelemetry.android; import android.app.Application; + +import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.logs.SdkLoggerProvider; @@ -55,7 +57,7 @@ static OpenTelemetryRumBuilder builder(Application application, OtelRumConfig co * the {@link SdkTracerProvider}, {@link SdkMeterProvider}, and {@link SdkLoggerProvider} are * configured correctly for your target RUM provider. * - * @param application The {@link Application} that is being instrumented. + * @param application The {@link Application} that is being instrumented. * @param openTelemetrySdk The {@link OpenTelemetrySdk} that the user has already created. */ static SdkPreconfiguredRumBuilder builder( @@ -63,7 +65,9 @@ static SdkPreconfiguredRumBuilder builder( return new SdkPreconfiguredRumBuilder(application, openTelemetrySdk); } - /** Returns a no-op implementation of {@link OpenTelemetryRum}. */ + /** + * Returns a no-op implementation of {@link OpenTelemetryRum}. + */ static OpenTelemetryRum noop() { return NoopOpenTelemetryRum.INSTANCE; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index 3e5dafec0..4727b0bbe 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -5,6 +5,8 @@ package io.opentelemetry.android.config; +import androidx.annotation.Nullable; + import java.util.function.Supplier; import io.opentelemetry.android.ScreenAttributesSpanProcessor; @@ -22,7 +24,8 @@ public class OtelRumConfig { private boolean includeNetworkAttributes = true; private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; - private PersistenceConfiguration persistenceConfiguration; + @Nullable + private PersistenceConfiguration persistenceConfiguration = null; /** * Configures the set of global attributes to emit with every span and event. Any existing diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 4b43df262..c049354f1 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -2,6 +2,7 @@ import android.content.Context; +import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; import java.util.HashMap; @@ -9,23 +10,24 @@ public final class ServiceManager implements Lifecycle { private final HashMap services = new HashMap<>(); - private static ServiceManager INSTANCE; + @Nullable + private static ServiceManager instance; private ServiceManager() { } @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void initialize(Context appContext) { - INSTANCE = new ServiceManager(); - INSTANCE.addService(new PreferencesService(appContext)); + instance = new ServiceManager(); + instance.addService(new PreferencesService(appContext)); } @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static ServiceManager get() { - if (INSTANCE == null) { + if (instance == null) { throw new IllegalStateException("Services haven't been initialized"); } - return INSTANCE; + return instance; } public void addService(Service service) { @@ -49,7 +51,7 @@ public void stop() { } @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) public T getService(Service.Type type) { Service service = services.get(type); if (service == null) { @@ -60,10 +62,10 @@ public T getService(Service.Type type) { } public static void resetForTest() { - if (INSTANCE != null) { - INSTANCE.stop(); + if (instance != null) { + instance.stop(); } - INSTANCE = null; + instance = null; } private void verifyNotExisting(Service.Type type) { From 7965c0ca65baed447f918cb96797e80cbb97fb3e Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:47:15 +0100 Subject: [PATCH 08/34] Spotless --- .../android/OpenTelemetryRum.java | 7 ++-- .../android/OpenTelemetryRumBuilder.java | 16 ++++----- .../android/config/OtelRumConfig.java | 23 ++++-------- .../config/PersistenceConfiguration.java | 13 +++---- .../startup/InitializationEvents.java | 9 ++--- .../features/persistence/DiskManager.java | 35 +++++++++++++------ .../internal/services/AppInfoService.java | 28 +++++++++++---- .../android/internal/services/Lifecycle.java | 19 ++-------- .../internal/services/PreferencesService.java | 14 +++++--- .../android/internal/services/Service.java | 8 ++++- .../internal/services/ServiceManager.java | 13 +++---- 11 files changed, 96 insertions(+), 89 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java index 822a075b3..c04633bf3 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRum.java @@ -6,7 +6,6 @@ package io.opentelemetry.android; import android.app.Application; - import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.OpenTelemetrySdk; @@ -57,7 +56,7 @@ static OpenTelemetryRumBuilder builder(Application application, OtelRumConfig co * the {@link SdkTracerProvider}, {@link SdkMeterProvider}, and {@link SdkLoggerProvider} are * configured correctly for your target RUM provider. * - * @param application The {@link Application} that is being instrumented. + * @param application The {@link Application} that is being instrumented. * @param openTelemetrySdk The {@link OpenTelemetrySdk} that the user has already created. */ static SdkPreconfiguredRumBuilder builder( @@ -65,9 +64,7 @@ static SdkPreconfiguredRumBuilder builder( return new SdkPreconfiguredRumBuilder(application, openTelemetrySdk); } - /** - * Returns a no-op implementation of {@link OpenTelemetryRum}. - */ + /** Returns a no-op implementation of {@link OpenTelemetryRum}. */ static OpenTelemetryRum noop() { return NoopOpenTelemetryRum.INSTANCE; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java index 1da78fa05..0421bdc5b 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java @@ -8,13 +8,6 @@ import static java.util.Objects.requireNonNull; import android.app.Application; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; - import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.android.instrumentation.InstrumentedApplication; import io.opentelemetry.android.instrumentation.activity.VisibleScreenTracker; @@ -38,6 +31,11 @@ import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; import io.opentelemetry.sdk.trace.export.SpanExporter; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; /** * A builder of {@link OpenTelemetryRum}. It enabled configuring the OpenTelemetry SDK and disabling @@ -246,9 +244,7 @@ public OpenTelemetryRum build() { return delegate.build(); } - /** - * Leverage the configuration to wire up various instrumentation components. - */ + /** Leverage the configuration to wire up various instrumentation components. */ private void applyConfiguration() { if (config.shouldGenerateSdkInitializationEvents()) { initializationEvents = new SdkInitializationEvents(); diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index 4727b0bbe..f687812eb 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -6,12 +6,10 @@ package io.opentelemetry.android.config; import androidx.annotation.Nullable; - -import java.util.function.Supplier; - import io.opentelemetry.android.ScreenAttributesSpanProcessor; import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.api.common.Attributes; +import java.util.function.Supplier; /** * Configuration object for OpenTelemetry Android. The configuration items in this class will be @@ -24,8 +22,7 @@ public class OtelRumConfig { private boolean includeNetworkAttributes = true; private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; - @Nullable - private PersistenceConfiguration persistenceConfiguration = null; + @Nullable private PersistenceConfiguration persistenceConfiguration = null; /** * Configures the set of global attributes to emit with every span and event. Any existing @@ -60,9 +57,7 @@ public OtelRumConfig disableNetworkAttributes() { return this; } - /** - * Returns true if runtime network attributes are enabled, false otherwise. - */ + /** Returns true if runtime network attributes are enabled, false otherwise. */ public boolean shouldIncludeNetworkAttributes() { return includeNetworkAttributes; } @@ -78,9 +73,7 @@ public OtelRumConfig disableSdkInitializationEvents() { return this; } - /** - * Returns true if the SDK is configured to generate initialization events, false otherwise. - */ + /** Returns true if the SDK is configured to generate initialization events, false otherwise. */ public boolean shouldGenerateSdkInitializationEvents() { return generateSdkInitializationEvents; } @@ -96,9 +89,7 @@ public OtelRumConfig disableScreenAttributes() { return this; } - /** - * Return true if the SDK should be configured to report screen attributes. - */ + /** Return true if the SDK should be configured to report screen attributes. */ public boolean shouldIncludeScreenAttributes() { return includeScreenAttributes; } @@ -110,9 +101,7 @@ public PersistenceConfiguration getPersistenceConfiguration() { return persistenceConfiguration; } - /** - * Sets the parameters for caching signals in disk in order to export them later. - */ + /** Sets the parameters for caching signals in disk in order to export them later. */ public void setPersistenceConfiguration(PersistenceConfiguration persistenceConfiguration) { this.persistenceConfiguration = persistenceConfiguration; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java index b8ff599f6..8cc460818 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java @@ -1,8 +1,11 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.android.config; -/** - * Configuration for disk buffering. - */ +/** Configuration for disk buffering. */ public final class PersistenceConfiguration { public final boolean enabled; public final int maxCacheSize; @@ -25,9 +28,7 @@ private Builder(boolean enabled, int maxCacheSize) { this.maxCacheSize = maxCacheSize; } - /** - * Enables or disables disk buffering. - */ + /** Enables or disables disk buffering. */ public Builder setEnabled(boolean enabled) { this.enabled = enabled; return this; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java index 0ff2ec0ca..707f4fc41 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.java @@ -18,15 +18,12 @@ public interface InitializationEvents { InitializationEvents NO_OP = new InitializationEvents() { @Override - public void sdkInitializationStarted() { - } + public void sdkInitializationStarted() {} @Override - public void recordConfiguration(OtelRumConfig config) { - } + public void recordConfiguration(OtelRumConfig config) {} @Override - public void currentNetworkProviderInitialized() { - } + public void currentNetworkProviderInitialized() {} }; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index bdf7e5cab..2de416e46 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -1,9 +1,9 @@ -package io.opentelemetry.android.internal.features.persistence; +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ -import java.io.File; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; +package io.opentelemetry.android.internal.features.persistence; import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.android.config.PersistenceConfiguration; @@ -11,10 +11,13 @@ import io.opentelemetry.android.internal.services.PreferencesService; import io.opentelemetry.android.internal.services.Service; import io.opentelemetry.android.internal.services.ServiceManager; +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; /** - * This class is internal and not for public use. Its APIs are unstable and can change at any - * time. + * This class is internal and not for public use. Its APIs are unstable and can change at any time. */ public final class DiskManager { private final AppInfoService appInfoService; @@ -26,12 +29,16 @@ public final class DiskManager { public static DiskManager create(OtelRumConfig config) { ServiceManager serviceManager = ServiceManager.get(); - return new DiskManager(serviceManager.getService(Service.Type.APPLICATION_INFO), + return new DiskManager( + serviceManager.getService(Service.Type.APPLICATION_INFO), serviceManager.getService(Service.Type.PREFERENCES), config.getPersistenceConfiguration()); } - DiskManager(AppInfoService appInfoService, PreferencesService preferencesService, PersistenceConfiguration persistenceConfiguration) { + DiskManager( + AppInfoService appInfoService, + PreferencesService preferencesService, + PersistenceConfiguration persistenceConfiguration) { this.appInfoService = appInfoService; this.preferencesService = preferencesService; this.persistenceConfiguration = persistenceConfiguration; @@ -61,7 +68,9 @@ public File getTemporaryDir() throws IOException { public int getMaxFolderSize() { int storedSize = preferencesService.retrieveInt(MAX_FOLDER_SIZE_KEY, -1); if (storedSize != -1) { - logger.log(Level.FINER, String.format("Returning max folder size from preferences: %s", storedSize)); + logger.log( + Level.FINER, + String.format("Returning max folder size from preferences: %s", storedSize)); return storedSize; } int requestedSize = persistenceConfiguration.maxCacheSize; @@ -69,7 +78,11 @@ public int getMaxFolderSize() { int calculatedSize = (availableCacheSize / 3) - MAX_FILE_SIZE; preferencesService.store(MAX_FOLDER_SIZE_KEY, calculatedSize); - logger.log(Level.FINER, String.format("Requested cache size: %s, available cache size: %s, folder size: %s", requestedSize, availableCacheSize, calculatedSize)); + logger.log( + Level.FINER, + String.format( + "Requested cache size: %s, available cache size: %s, folder size: %s", + requestedSize, availableCacheSize, calculatedSize)); return calculatedSize; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java index 7b57dc107..11d01cd9b 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java @@ -1,12 +1,15 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.android.internal.services; import android.content.Context; import android.os.Build; import android.os.storage.StorageManager; - import androidx.annotation.RequiresApi; import androidx.annotation.WorkerThread; - import java.io.File; import java.io.IOException; import java.util.UUID; @@ -15,8 +18,8 @@ /** * Utility to get information about the host app. - *

- * This class is internal and not for public use. Its APIs are unstable and can change at any + * + *

This class is internal and not for public use. Its APIs are unstable and can change at any * time. */ public class AppInfoService implements Service { @@ -42,12 +45,19 @@ public long getAvailableCacheSpace(long maxSpaceNeeded) { @RequiresApi(api = Build.VERSION_CODES.O) private long getAvailableSpace(File directory, long maxSpaceNeeded) { - logger.log(Level.FINER, String.format("Getting available space for %s, max needed is: %s", directory, maxSpaceNeeded)); + logger.log( + Level.FINER, + String.format( + "Getting available space for %s, max needed is: %s", + directory, maxSpaceNeeded)); try { StorageManager storageManager = appContext.getSystemService(StorageManager.class); UUID appSpecificInternalDirUuid = storageManager.getUuidForPath(directory); // Get the minimum amount of allocatable space. - long spaceToAllocate = Math.min(storageManager.getAllocatableBytes(appSpecificInternalDirUuid), maxSpaceNeeded); + long spaceToAllocate = + Math.min( + storageManager.getAllocatableBytes(appSpecificInternalDirUuid), + maxSpaceNeeded); // Ensure the space is available by asking the OS to clear stale cache if needed. storageManager.allocateBytes(appSpecificInternalDirUuid, spaceToAllocate); return spaceToAllocate; @@ -58,7 +68,11 @@ private long getAvailableSpace(File directory, long maxSpaceNeeded) { } private long getLegacyAvailableSpace(File directory, long maxSpaceNeeded) { - logger.log(Level.FINER, String.format("Getting legacy available space for %s max needed is: %s", directory, maxSpaceNeeded)); + logger.log( + Level.FINER, + String.format( + "Getting legacy available space for %s max needed is: %s", + directory, maxSpaceNeeded)); return Math.min(directory.getUsableSpace(), maxSpaceNeeded); } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java index e784db023..dbf0532e0 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java @@ -1,21 +1,8 @@ /* - * 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. + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 */ + package io.opentelemetry.android.internal.services; public interface Lifecycle { diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java index 79f9ecc66..c312d312a 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java @@ -1,21 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.android.internal.services; import android.content.Context; import android.content.SharedPreferences; - import io.opentelemetry.android.BuildConfig; /** * Utility to store and retrieve apps' preferences. - *

- * This class is internal and not for public use. Its APIs are unstable and can change at any + * + *

This class is internal and not for public use. Its APIs are unstable and can change at any * time. */ public class PreferencesService implements Service { private final SharedPreferences preferences; public PreferencesService(Context context) { - preferences = context.getSharedPreferences(BuildConfig.LIBRARY_PACKAGE_NAME + ".prefs", Context.MODE_PRIVATE); + preferences = + context.getSharedPreferences( + BuildConfig.LIBRARY_PACKAGE_NAME + ".prefs", Context.MODE_PRIVATE); } @Override diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java index b4d6a8dbf..b52becc22 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.android.internal.services; public interface Service extends Lifecycle { @@ -5,6 +10,7 @@ public interface Service extends Lifecycle { Type type(); enum Type { - APPLICATION_INFO, PREFERENCES + APPLICATION_INFO, + PREFERENCES } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index c049354f1..065dd6dfb 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -1,20 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.android.internal.services; import android.content.Context; - import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; - import java.util.HashMap; public final class ServiceManager implements Lifecycle { private final HashMap services = new HashMap<>(); - @Nullable - private static ServiceManager instance; + @Nullable private static ServiceManager instance; - private ServiceManager() { - } + private ServiceManager() {} @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void initialize(Context appContext) { From 445b4de267a0ea009f21e8a19cec3e103d8a9d67 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:52:54 +0100 Subject: [PATCH 09/34] Adding lib version for opentelemetry-contrib --- gradle/libs.versions.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 84059f9bd..383edc219 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,6 +2,7 @@ opentelemetry = "1.31.0" opentelemetry-alpha = "1.31.0-alpha" opentelemetry-semconv = "1.21.0-alpha" +opentelemetry-contrib = "1.31.0-alpha" mockito = "5.7.0" junit = "5.10.1" byteBuddy = "1.14.9" @@ -26,7 +27,7 @@ opentelemetry-sdk = { module = "io.opentelemetry:opentelemetry-sdk" } opentelemetry-exporter-zipkin = { module = "io.opentelemetry:opentelemetry-exporter-zipkin" } opentelemetry-exporter-logging = { module = "io.opentelemetry:opentelemetry-exporter-logging" } zipkin-sender-okhttp3 = { module = "io.zipkin.reporter2:zipkin-sender-okhttp3", version.ref = "zipkin-reporter" } -opentelemetry-diskBuffering = "io.opentelemetry.contrib:opentelemetry-disk-buffering:1.31.0-alpha" +opentelemetry-diskBuffering = { module = "io.opentelemetry.contrib:opentelemetry-disk-buffering", version.ref = "opentelemetry-contrib" } #Test tools opentelemetry-sdk-testing = { module = "io.opentelemetry:opentelemetry-sdk-testing", version.ref = "opentelemetry" } From 73d902d874a0374ebc78509e5acafb88bda0e2f9 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:32:38 +0100 Subject: [PATCH 10/34] Avoiding null default config param --- ...tel.android-library-conventions.gradle.kts | 6 ++++ .../android/config/OtelRumConfig.java | 29 +++++++++++-------- .../config/PersistenceConfiguration.java | 12 ++++++-- .../opentelemetry/android/package-info.java | 4 +++ 4 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 instrumentation/src/main/java/io/opentelemetry/android/package-info.java diff --git a/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts index f34b90f58..147b6a9f0 100644 --- a/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts @@ -1,4 +1,5 @@ import com.android.build.api.dsl.LibraryExtension +import gradle.kotlin.dsl.accessors._b2446c8dc207e937a199f7dceaaf23ac.implementation import org.gradle.api.publish.maven.MavenPublication plugins { @@ -25,4 +26,9 @@ android { sourceCompatibility(javaVersion) targetCompatibility(javaVersion) } +} + +val libs = extensions.getByType().named("libs") +dependencies { + implementation(libs.findLibrary("findbugs-jsr305").get()) } \ No newline at end of file diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index f687812eb..01dea10bc 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -5,11 +5,11 @@ package io.opentelemetry.android.config; -import androidx.annotation.Nullable; +import java.util.function.Supplier; + import io.opentelemetry.android.ScreenAttributesSpanProcessor; import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.api.common.Attributes; -import java.util.function.Supplier; /** * Configuration object for OpenTelemetry Android. The configuration items in this class will be @@ -22,7 +22,7 @@ public class OtelRumConfig { private boolean includeNetworkAttributes = true; private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; - @Nullable private PersistenceConfiguration persistenceConfiguration = null; + private PersistenceConfiguration persistenceConfiguration = PersistenceConfiguration.getDefault(); /** * Configures the set of global attributes to emit with every span and event. Any existing @@ -57,14 +57,16 @@ public OtelRumConfig disableNetworkAttributes() { return this; } - /** Returns true if runtime network attributes are enabled, false otherwise. */ + /** + * Returns true if runtime network attributes are enabled, false otherwise. + */ public boolean shouldIncludeNetworkAttributes() { return includeNetworkAttributes; } /** - * Disables the collection of events related to the initialization of the OTel Android SDK - * itself. Default = true. + * Disables the collection of events related to the initialization of the OTel Android SDK itself. + * Default = true. * * @return this */ @@ -73,7 +75,9 @@ public OtelRumConfig disableSdkInitializationEvents() { return this; } - /** Returns true if the SDK is configured to generate initialization events, false otherwise. */ + /** + * Returns true if the SDK is configured to generate initialization events, false otherwise. + */ public boolean shouldGenerateSdkInitializationEvents() { return generateSdkInitializationEvents; } @@ -89,19 +93,20 @@ public OtelRumConfig disableScreenAttributes() { return this; } - /** Return true if the SDK should be configured to report screen attributes. */ + /** + * Return true if the SDK should be configured to report screen attributes. + */ public boolean shouldIncludeScreenAttributes() { return includeScreenAttributes; } public PersistenceConfiguration getPersistenceConfiguration() { - if (persistenceConfiguration == null) { - return PersistenceConfiguration.builder().build(); - } return persistenceConfiguration; } - /** Sets the parameters for caching signals in disk in order to export them later. */ + /** + * Sets the parameters for caching signals in disk in order to export them later. + */ public void setPersistenceConfiguration(PersistenceConfiguration persistenceConfiguration) { this.persistenceConfiguration = persistenceConfiguration; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java index 8cc460818..c5bf00356 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java @@ -5,11 +5,17 @@ package io.opentelemetry.android.config; -/** Configuration for disk buffering. */ +/** + * Configuration for disk buffering. + */ public final class PersistenceConfiguration { public final boolean enabled; public final int maxCacheSize; + public static PersistenceConfiguration getDefault() { + return PersistenceConfiguration.builder().build(); + } + private PersistenceConfiguration(Builder builder) { this.enabled = builder.enabled; this.maxCacheSize = builder.maxCacheSize; @@ -28,7 +34,9 @@ private Builder(boolean enabled, int maxCacheSize) { this.maxCacheSize = maxCacheSize; } - /** Enables or disables disk buffering. */ + /** + * Enables or disables disk buffering. + */ public Builder setEnabled(boolean enabled) { this.enabled = enabled; return this; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/package-info.java b/instrumentation/src/main/java/io/opentelemetry/android/package-info.java new file mode 100644 index 000000000..01696396b --- /dev/null +++ b/instrumentation/src/main/java/io/opentelemetry/android/package-info.java @@ -0,0 +1,4 @@ +@ParametersAreNonnullByDefault +package io.opentelemetry.android; + +import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file From 1357e1e1c81056acc626fd25fe2881b542f202ef Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:38:19 +0100 Subject: [PATCH 11/34] Spotless --- .../android/config/OtelRumConfig.java | 26 +++++++------------ .../config/PersistenceConfiguration.java | 8 ++---- .../opentelemetry/android/package-info.java | 2 +- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index 01dea10bc..bbb0aa843 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -5,11 +5,10 @@ package io.opentelemetry.android.config; -import java.util.function.Supplier; - import io.opentelemetry.android.ScreenAttributesSpanProcessor; import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider; import io.opentelemetry.api.common.Attributes; +import java.util.function.Supplier; /** * Configuration object for OpenTelemetry Android. The configuration items in this class will be @@ -22,7 +21,8 @@ public class OtelRumConfig { private boolean includeNetworkAttributes = true; private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; - private PersistenceConfiguration persistenceConfiguration = PersistenceConfiguration.getDefault(); + private PersistenceConfiguration persistenceConfiguration = + PersistenceConfiguration.getDefault(); /** * Configures the set of global attributes to emit with every span and event. Any existing @@ -57,16 +57,14 @@ public OtelRumConfig disableNetworkAttributes() { return this; } - /** - * Returns true if runtime network attributes are enabled, false otherwise. - */ + /** Returns true if runtime network attributes are enabled, false otherwise. */ public boolean shouldIncludeNetworkAttributes() { return includeNetworkAttributes; } /** - * Disables the collection of events related to the initialization of the OTel Android SDK itself. - * Default = true. + * Disables the collection of events related to the initialization of the OTel Android SDK + * itself. Default = true. * * @return this */ @@ -75,9 +73,7 @@ public OtelRumConfig disableSdkInitializationEvents() { return this; } - /** - * Returns true if the SDK is configured to generate initialization events, false otherwise. - */ + /** Returns true if the SDK is configured to generate initialization events, false otherwise. */ public boolean shouldGenerateSdkInitializationEvents() { return generateSdkInitializationEvents; } @@ -93,9 +89,7 @@ public OtelRumConfig disableScreenAttributes() { return this; } - /** - * Return true if the SDK should be configured to report screen attributes. - */ + /** Return true if the SDK should be configured to report screen attributes. */ public boolean shouldIncludeScreenAttributes() { return includeScreenAttributes; } @@ -104,9 +98,7 @@ public PersistenceConfiguration getPersistenceConfiguration() { return persistenceConfiguration; } - /** - * Sets the parameters for caching signals in disk in order to export them later. - */ + /** Sets the parameters for caching signals in disk in order to export them later. */ public void setPersistenceConfiguration(PersistenceConfiguration persistenceConfiguration) { this.persistenceConfiguration = persistenceConfiguration; } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java index c5bf00356..d19f42ba2 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java @@ -5,9 +5,7 @@ package io.opentelemetry.android.config; -/** - * Configuration for disk buffering. - */ +/** Configuration for disk buffering. */ public final class PersistenceConfiguration { public final boolean enabled; public final int maxCacheSize; @@ -34,9 +32,7 @@ private Builder(boolean enabled, int maxCacheSize) { this.maxCacheSize = maxCacheSize; } - /** - * Enables or disables disk buffering. - */ + /** Enables or disables disk buffering. */ public Builder setEnabled(boolean enabled) { this.enabled = enabled; return this; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/package-info.java b/instrumentation/src/main/java/io/opentelemetry/android/package-info.java index 01696396b..00a72f3c7 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/package-info.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/package-info.java @@ -1,4 +1,4 @@ @ParametersAreNonnullByDefault package io.opentelemetry.android; -import javax.annotation.ParametersAreNonnullByDefault; \ No newline at end of file +import javax.annotation.ParametersAreNonnullByDefault; From afbddc9ad65fb469e1f07ed2de2ce39e7240d876 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:43:56 +0100 Subject: [PATCH 12/34] Storing default max cache size in a var --- .../android/config/PersistenceConfiguration.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java index d19f42ba2..67cdadf5d 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java @@ -5,10 +5,13 @@ package io.opentelemetry.android.config; -/** Configuration for disk buffering. */ +/** + * Configuration for disk buffering. + */ public final class PersistenceConfiguration { public final boolean enabled; public final int maxCacheSize; + private static final int DEFAULT_MAX_CACHE_SIZE = 60 * 1024 * 1024; public static PersistenceConfiguration getDefault() { return PersistenceConfiguration.builder().build(); @@ -20,7 +23,7 @@ private PersistenceConfiguration(Builder builder) { } public static Builder builder() { - return new Builder(false, 60 * 1024 * 1024); + return new Builder(false, DEFAULT_MAX_CACHE_SIZE); } public static final class Builder { @@ -32,7 +35,9 @@ private Builder(boolean enabled, int maxCacheSize) { this.maxCacheSize = maxCacheSize; } - /** Enables or disables disk buffering. */ + /** + * Enables or disables disk buffering. + */ public Builder setEnabled(boolean enabled) { this.enabled = enabled; return this; From 157c715f6ad48a8ab9a1a76640b9dd655d19439c Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:59:55 +0100 Subject: [PATCH 13/34] Renaming PersistenceConfiguration to DiskBufferingConfiguration --- ...n.java => DiskBufferingConfiguration.java} | 20 ++++++++----------- .../android/config/OtelRumConfig.java | 13 ++++++------ .../features/persistence/DiskManager.java | 12 +++++------ 3 files changed, 21 insertions(+), 24 deletions(-) rename instrumentation/src/main/java/io/opentelemetry/android/config/{PersistenceConfiguration.java => DiskBufferingConfiguration.java} (74%) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java similarity index 74% rename from instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java rename to instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java index 67cdadf5d..8f8242872 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/PersistenceConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java @@ -5,19 +5,17 @@ package io.opentelemetry.android.config; -/** - * Configuration for disk buffering. - */ -public final class PersistenceConfiguration { +/** Configuration for disk buffering. */ +public final class DiskBufferingConfiguration { public final boolean enabled; public final int maxCacheSize; private static final int DEFAULT_MAX_CACHE_SIZE = 60 * 1024 * 1024; - public static PersistenceConfiguration getDefault() { - return PersistenceConfiguration.builder().build(); + public static DiskBufferingConfiguration getDefault() { + return DiskBufferingConfiguration.builder().build(); } - private PersistenceConfiguration(Builder builder) { + private DiskBufferingConfiguration(Builder builder) { this.enabled = builder.enabled; this.maxCacheSize = builder.maxCacheSize; } @@ -35,9 +33,7 @@ private Builder(boolean enabled, int maxCacheSize) { this.maxCacheSize = maxCacheSize; } - /** - * Enables or disables disk buffering. - */ + /** Enables or disables disk buffering. */ public Builder setEnabled(boolean enabled) { this.enabled = enabled; return this; @@ -53,8 +49,8 @@ public Builder setMaxCacheSize(int maxCacheSize) { return this; } - public PersistenceConfiguration build() { - return new PersistenceConfiguration(this); + public DiskBufferingConfiguration build() { + return new DiskBufferingConfiguration(this); } } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index bbb0aa843..75844edac 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -21,8 +21,8 @@ public class OtelRumConfig { private boolean includeNetworkAttributes = true; private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; - private PersistenceConfiguration persistenceConfiguration = - PersistenceConfiguration.getDefault(); + private DiskBufferingConfiguration diskBufferingConfiguration = + DiskBufferingConfiguration.getDefault(); /** * Configures the set of global attributes to emit with every span and event. Any existing @@ -94,12 +94,13 @@ public boolean shouldIncludeScreenAttributes() { return includeScreenAttributes; } - public PersistenceConfiguration getPersistenceConfiguration() { - return persistenceConfiguration; + public DiskBufferingConfiguration getDiskBufferingConfiguration() { + return diskBufferingConfiguration; } /** Sets the parameters for caching signals in disk in order to export them later. */ - public void setPersistenceConfiguration(PersistenceConfiguration persistenceConfiguration) { - this.persistenceConfiguration = persistenceConfiguration; + public void setDiskBufferingConfiguration( + DiskBufferingConfiguration diskBufferingConfiguration) { + this.diskBufferingConfiguration = diskBufferingConfiguration; } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 2de416e46..be67ef96e 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -5,8 +5,8 @@ package io.opentelemetry.android.internal.features.persistence; +import io.opentelemetry.android.config.DiskBufferingConfiguration; import io.opentelemetry.android.config.OtelRumConfig; -import io.opentelemetry.android.config.PersistenceConfiguration; import io.opentelemetry.android.internal.services.AppInfoService; import io.opentelemetry.android.internal.services.PreferencesService; import io.opentelemetry.android.internal.services.Service; @@ -22,7 +22,7 @@ public final class DiskManager { private final AppInfoService appInfoService; private final PreferencesService preferencesService; - private final PersistenceConfiguration persistenceConfiguration; + private final DiskBufferingConfiguration diskBufferingConfiguration; private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; private static final int MAX_FILE_SIZE = 1024 * 1024; private final Logger logger = Logger.getLogger("DiskManager"); @@ -32,16 +32,16 @@ public static DiskManager create(OtelRumConfig config) { return new DiskManager( serviceManager.getService(Service.Type.APPLICATION_INFO), serviceManager.getService(Service.Type.PREFERENCES), - config.getPersistenceConfiguration()); + config.getDiskBufferingConfiguration()); } DiskManager( AppInfoService appInfoService, PreferencesService preferencesService, - PersistenceConfiguration persistenceConfiguration) { + DiskBufferingConfiguration diskBufferingConfiguration) { this.appInfoService = appInfoService; this.preferencesService = preferencesService; - this.persistenceConfiguration = persistenceConfiguration; + this.diskBufferingConfiguration = diskBufferingConfiguration; } public File getSignalsCacheDir() throws IOException { @@ -73,7 +73,7 @@ public int getMaxFolderSize() { String.format("Returning max folder size from preferences: %s", storedSize)); return storedSize; } - int requestedSize = persistenceConfiguration.maxCacheSize; + int requestedSize = diskBufferingConfiguration.maxCacheSize; int availableCacheSize = (int) appInfoService.getAvailableCacheSpace(requestedSize); int calculatedSize = (availableCacheSize / 3) - MAX_FILE_SIZE; preferencesService.store(MAX_FOLDER_SIZE_KEY, calculatedSize); From b591b15d723da7be39c3a2d61342550cd148b39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:03:55 +0100 Subject: [PATCH 14/34] Update instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> --- .../android/internal/features/persistence/DiskManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 2de416e46..06a2d14fe 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -25,7 +25,7 @@ public final class DiskManager { private final PersistenceConfiguration persistenceConfiguration; private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; private static final int MAX_FILE_SIZE = 1024 * 1024; - private final Logger logger = Logger.getLogger("DiskManager"); + private final static Logger logger = Logger.getLogger("DiskManager"); public static DiskManager create(OtelRumConfig config) { ServiceManager serviceManager = ServiceManager.get(); From 8e6f5dd079aff3b0eee3cb588fa6e7ae985fb629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:07:19 +0100 Subject: [PATCH 15/34] Update instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> --- .../opentelemetry/android/internal/services/ServiceManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 065dd6dfb..3192ef0aa 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -12,7 +12,7 @@ public final class ServiceManager implements Lifecycle { - private final HashMap services = new HashMap<>(); + private final Map services = new HashMap<>(); @Nullable private static ServiceManager instance; private ServiceManager() {} From fe360e9a0a56c169348d07ad23f803266cfe74ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:08:13 +0100 Subject: [PATCH 16/34] Update instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java Co-authored-by: jason plumb <75337021+breedx-splk@users.noreply.github.com> --- .../opentelemetry/android/internal/services/AppInfoService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java index 11d01cd9b..0bcb7087d 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java @@ -24,7 +24,7 @@ */ public class AppInfoService implements Service { private final Context appContext; - private final Logger logger = Logger.getLogger("AppInfoService"); + private final static Logger logger = Logger.getLogger("AppInfoService"); public AppInfoService(Context appContext) { this.appContext = appContext; From 066723e78dccba1bb8ad4dc1218dcfd095c7f455 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:28:06 +0100 Subject: [PATCH 17/34] Reordering DiskManager fields --- .../android/internal/features/persistence/DiskManager.java | 6 +++--- .../android/internal/services/AppInfoService.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 26495feee..ed0f34605 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -20,12 +20,12 @@ * This class is internal and not for public use. Its APIs are unstable and can change at any time. */ public final class DiskManager { + private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; + private static final int MAX_FILE_SIZE = 1024 * 1024; + private static final Logger logger = Logger.getLogger("DiskManager"); private final AppInfoService appInfoService; private final PreferencesService preferencesService; private final DiskBufferingConfiguration diskBufferingConfiguration; - private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; - private static final int MAX_FILE_SIZE = 1024 * 1024; - private final static Logger logger = Logger.getLogger("DiskManager"); public static DiskManager create(OtelRumConfig config) { ServiceManager serviceManager = ServiceManager.get(); diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java index 0bcb7087d..406e62b5b 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java @@ -24,7 +24,7 @@ */ public class AppInfoService implements Service { private final Context appContext; - private final static Logger logger = Logger.getLogger("AppInfoService"); + private static final Logger logger = Logger.getLogger("AppInfoService"); public AppInfoService(Context appContext) { this.appContext = appContext; From 6430d653b40ffcca5379f3eaffa5503753cdbd35 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:32:03 +0100 Subject: [PATCH 18/34] Renaming methods and classes --- .../features/persistence/DiskManager.java | 16 ++++++++-------- ...InfoService.java => CacheStorageService.java} | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) rename instrumentation/src/main/java/io/opentelemetry/android/internal/services/{AppInfoService.java => CacheStorageService.java} (91%) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index ed0f34605..3c8ad64d7 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -7,7 +7,7 @@ import io.opentelemetry.android.config.DiskBufferingConfiguration; import io.opentelemetry.android.config.OtelRumConfig; -import io.opentelemetry.android.internal.services.AppInfoService; +import io.opentelemetry.android.internal.services.CacheStorageService; import io.opentelemetry.android.internal.services.PreferencesService; import io.opentelemetry.android.internal.services.Service; import io.opentelemetry.android.internal.services.ServiceManager; @@ -23,7 +23,7 @@ public final class DiskManager { private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; private static final int MAX_FILE_SIZE = 1024 * 1024; private static final Logger logger = Logger.getLogger("DiskManager"); - private final AppInfoService appInfoService; + private final CacheStorageService cacheStorageService; private final PreferencesService preferencesService; private final DiskBufferingConfiguration diskBufferingConfiguration; @@ -36,16 +36,16 @@ public static DiskManager create(OtelRumConfig config) { } DiskManager( - AppInfoService appInfoService, + CacheStorageService cacheStorageService, PreferencesService preferencesService, DiskBufferingConfiguration diskBufferingConfiguration) { - this.appInfoService = appInfoService; + this.cacheStorageService = cacheStorageService; this.preferencesService = preferencesService; this.diskBufferingConfiguration = diskBufferingConfiguration; } - public File getSignalsCacheDir() throws IOException { - File dir = new File(appInfoService.getCacheDir(), "opentelemetry/signals"); + public File getSignalsBufferDir() throws IOException { + File dir = new File(cacheStorageService.getCacheDir(), "opentelemetry/signals"); if (!dir.exists()) { if (!dir.mkdirs()) { throw new IOException("Could not create dir " + dir); @@ -55,7 +55,7 @@ public File getSignalsCacheDir() throws IOException { } public File getTemporaryDir() throws IOException { - File dir = new File(appInfoService.getCacheDir(), "opentelemetry/temp"); + File dir = new File(cacheStorageService.getCacheDir(), "opentelemetry/temp"); if (!dir.exists()) { if (!dir.mkdirs()) { throw new IOException("Could not create dir " + dir); @@ -74,7 +74,7 @@ public int getMaxFolderSize() { return storedSize; } int requestedSize = diskBufferingConfiguration.maxCacheSize; - int availableCacheSize = (int) appInfoService.getAvailableCacheSpace(requestedSize); + int availableCacheSize = (int) cacheStorageService.ensureCacheSpaceAvailable(requestedSize); int calculatedSize = (availableCacheSize / 3) - MAX_FILE_SIZE; preferencesService.store(MAX_FOLDER_SIZE_KEY, calculatedSize); diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java similarity index 91% rename from instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java rename to instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java index 406e62b5b..b5e7c6efd 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/AppInfoService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java @@ -22,11 +22,11 @@ *

This class is internal and not for public use. Its APIs are unstable and can change at any * time. */ -public class AppInfoService implements Service { +public class CacheStorageService implements Service { private final Context appContext; - private static final Logger logger = Logger.getLogger("AppInfoService"); + private static final Logger logger = Logger.getLogger("CacheStorageService"); - public AppInfoService(Context appContext) { + public CacheStorageService(Context appContext) { this.appContext = appContext; } @@ -35,7 +35,7 @@ public File getCacheDir() { } @WorkerThread - public long getAvailableCacheSpace(long maxSpaceNeeded) { + public long ensureCacheSpaceAvailable(long maxSpaceNeeded) { File cacheDir = getCacheDir(); if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) { return getLegacyAvailableSpace(cacheDir, maxSpaceNeeded); From 4b5efa1364242b589b257cdd3afa1af6ea72ba51 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:39:42 +0100 Subject: [PATCH 19/34] Adding javadoc --- .../android/internal/services/CacheStorageService.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java index b5e7c6efd..02924ca45 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java @@ -34,6 +34,14 @@ public File getCacheDir() { return appContext.getCacheDir(); } + /** + * Checks for available cache space in the device and compares it to the max amount needed, if + * the available space is lower than the provided max value, the available space is returned, + * otherwise, the provided amount is returned. + * + *

On Android OS with API level 26 and above, it will also ask the OS to clear stale cache + * from the device in order to make room for the provided max value if needed. + */ @WorkerThread public long ensureCacheSpaceAvailable(long maxSpaceNeeded) { File cacheDir = getCacheDir(); From 7d8d61662eb2bf67b57fa265a31c9c5fa54aa01d Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:41:26 +0100 Subject: [PATCH 20/34] Adding Lifecycle defaults to start and stop --- .../android/internal/services/CacheStorageService.java | 10 ---------- .../android/internal/services/Lifecycle.java | 4 ++-- .../android/internal/services/PreferencesService.java | 10 ---------- .../android/internal/services/ServiceManager.java | 1 + 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java index 02924ca45..b110aa4a1 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java @@ -84,16 +84,6 @@ private long getLegacyAvailableSpace(File directory, long maxSpaceNeeded) { return Math.min(directory.getUsableSpace(), maxSpaceNeeded); } - @Override - public void start() { - // No operation. - } - - @Override - public void stop() { - // No operation. - } - @Override public Type type() { return Type.APPLICATION_INFO; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java index dbf0532e0..e4d427bb3 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Lifecycle.java @@ -6,7 +6,7 @@ package io.opentelemetry.android.internal.services; public interface Lifecycle { - void start(); + default void start() {} - void stop(); + default void stop() {} } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java index c312d312a..f15529170 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java @@ -24,16 +24,6 @@ public PreferencesService(Context context) { BuildConfig.LIBRARY_PACKAGE_NAME + ".prefs", Context.MODE_PRIVATE); } - @Override - public void start() { - // No op - } - - @Override - public void stop() { - // No op - } - public void store(String key, int value) { preferences.edit().putInt(key, value).apply(); } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 3192ef0aa..5270e51d3 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; import java.util.HashMap; +import java.util.Map; public final class ServiceManager implements Lifecycle { From ef8b89758817ab75581ea12b349abb769e36997f Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:44:01 +0100 Subject: [PATCH 21/34] Addressing constructor code smell --- .../android/internal/services/PreferencesService.java | 10 +++++++--- .../android/internal/services/ServiceManager.java | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java index f15529170..9dd20037e 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java @@ -18,10 +18,14 @@ public class PreferencesService implements Service { private final SharedPreferences preferences; - public PreferencesService(Context context) { - preferences = + public static PreferencesService create(Context context) { + return new PreferencesService( context.getSharedPreferences( - BuildConfig.LIBRARY_PACKAGE_NAME + ".prefs", Context.MODE_PRIVATE); + BuildConfig.LIBRARY_PACKAGE_NAME + ".prefs", Context.MODE_PRIVATE)); + } + + private PreferencesService(SharedPreferences sharedPreferences) { + preferences = sharedPreferences; } public void store(String key, int value) { diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 5270e51d3..03d611060 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -21,7 +21,7 @@ private ServiceManager() {} @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void initialize(Context appContext) { instance = new ServiceManager(); - instance.addService(new PreferencesService(appContext)); + instance.addService(PreferencesService.create(appContext)); } @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) From e28b306e6c5056ce020e1b5f76083dfba651616a Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 11:45:29 +0100 Subject: [PATCH 22/34] Addressing preferences negative number issue --- .../android/internal/features/persistence/DiskManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 3c8ad64d7..fce671f7c 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -67,7 +67,7 @@ public File getTemporaryDir() throws IOException { public int getMaxFolderSize() { int storedSize = preferencesService.retrieveInt(MAX_FOLDER_SIZE_KEY, -1); - if (storedSize != -1) { + if (storedSize > 0) { logger.log( Level.FINER, String.format("Returning max folder size from preferences: %s", storedSize)); From 72a6d8ab757f6a4dffee297c64f86918af312a09 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:19:59 +0100 Subject: [PATCH 23/34] Addressing negative folder cache size issue --- .../features/persistence/DiskManager.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index fce671f7c..8219cdbe3 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -65,6 +65,16 @@ public File getTemporaryDir() throws IOException { return dir; } + /** + * It checks for the available cache space in disk, then it attempts to divide by 3 in order to + * get each signal's folder max size. The resulting value is subtracted the max file size value + * in order to account for temp files used during the reading process. + * + *

+ * + * @return If the calculated size is < the max file size value, it returns 0. The calculated + * size is stored in the preferences and returned otherwise. + */ public int getMaxFolderSize() { int storedSize = preferencesService.retrieveInt(MAX_FOLDER_SIZE_KEY, -1); if (storedSize > 0) { @@ -75,7 +85,18 @@ public int getMaxFolderSize() { } int requestedSize = diskBufferingConfiguration.maxCacheSize; int availableCacheSize = (int) cacheStorageService.ensureCacheSpaceAvailable(requestedSize); + // Divides the available cache size by 3 (for each signal's folder) and then subtracts the + // size of a single file to be aware of a temp file used when reading data back from the + // disk. int calculatedSize = (availableCacheSize / 3) - MAX_FILE_SIZE; + if (calculatedSize < MAX_FILE_SIZE) { + logger.log( + Level.WARNING, + String.format( + "Insufficient folder cache size: %s, it must be at least: %s", + calculatedSize, MAX_FILE_SIZE)); + return 0; + } preferencesService.store(MAX_FOLDER_SIZE_KEY, calculatedSize); logger.log( From ece6e84f16d7976c843e2595012c3144f2b87535 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:50:31 +0100 Subject: [PATCH 24/34] Cleaning up imports --- .../src/main/kotlin/otel.android-library-conventions.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts index 147b6a9f0..07af2016a 100644 --- a/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts @@ -1,5 +1,4 @@ import com.android.build.api.dsl.LibraryExtension -import gradle.kotlin.dsl.accessors._b2446c8dc207e937a199f7dceaaf23ac.implementation import org.gradle.api.publish.maven.MavenPublication plugins { From beb930303ccad651ae50e1696f2cd7b7e2b17bae Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:04:09 +0100 Subject: [PATCH 25/34] Clean up --- .../android/config/DiskBufferingConfiguration.java | 4 ---- .../java/io/opentelemetry/android/config/OtelRumConfig.java | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java index 8f8242872..c7e22ccac 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java @@ -11,10 +11,6 @@ public final class DiskBufferingConfiguration { public final int maxCacheSize; private static final int DEFAULT_MAX_CACHE_SIZE = 60 * 1024 * 1024; - public static DiskBufferingConfiguration getDefault() { - return DiskBufferingConfiguration.builder().build(); - } - private DiskBufferingConfiguration(Builder builder) { this.enabled = builder.enabled; this.maxCacheSize = builder.maxCacheSize; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java index 75844edac..5c83d8f35 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/OtelRumConfig.java @@ -22,7 +22,7 @@ public class OtelRumConfig { private boolean generateSdkInitializationEvents = true; private boolean includeScreenAttributes = true; private DiskBufferingConfiguration diskBufferingConfiguration = - DiskBufferingConfiguration.getDefault(); + DiskBufferingConfiguration.builder().build(); /** * Configures the set of global attributes to emit with every span and event. Any existing From 64a6b29fd62c3b9e821a336b04f5ef8f74986759 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Tue, 14 Nov 2023 14:05:52 +0100 Subject: [PATCH 26/34] Fixing test compilation --- .../io/opentelemetry/android/OpenTelemetryRumBuilderTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java b/instrumentation/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java index 3e6aa556f..7324b5927 100644 --- a/instrumentation/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java +++ b/instrumentation/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java @@ -19,6 +19,7 @@ import android.app.Activity; import android.app.Application; import androidx.annotation.NonNull; +import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.android.instrumentation.ApplicationStateListener; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; From 2a9c4861902c8618d089846b16c18242f0a50eee Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:06:49 +0100 Subject: [PATCH 27/34] Renaming Service Type to CACHE_STORAGE --- .../android/internal/features/persistence/DiskManager.java | 2 +- .../android/internal/services/CacheStorageService.java | 2 +- .../io/opentelemetry/android/internal/services/Service.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 8219cdbe3..28c59b3db 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -30,7 +30,7 @@ public final class DiskManager { public static DiskManager create(OtelRumConfig config) { ServiceManager serviceManager = ServiceManager.get(); return new DiskManager( - serviceManager.getService(Service.Type.APPLICATION_INFO), + serviceManager.getService(Service.Type.CACHE_STORAGE), serviceManager.getService(Service.Type.PREFERENCES), config.getDiskBufferingConfiguration()); } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java index b110aa4a1..4fc2140e2 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java @@ -86,6 +86,6 @@ private long getLegacyAvailableSpace(File directory, long maxSpaceNeeded) { @Override public Type type() { - return Type.APPLICATION_INFO; + return Type.CACHE_STORAGE; } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java index b52becc22..521bc1164 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java @@ -10,7 +10,7 @@ public interface Service extends Lifecycle { Type type(); enum Type { - APPLICATION_INFO, + CACHE_STORAGE, PREFERENCES } } From a09c41121667d575ee366376b55e88cd81700f73 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:41:02 +0100 Subject: [PATCH 28/34] Creating DiskManagerTest --- .../config/DiskBufferingConfiguration.java | 17 ++- .../features/persistence/DiskManager.java | 12 +- .../features/persistence/DiskManagerTest.java | 111 ++++++++++++++++++ 3 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java diff --git a/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java b/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java index c7e22ccac..393ce6067 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/config/DiskBufferingConfiguration.java @@ -7,9 +7,10 @@ /** Configuration for disk buffering. */ public final class DiskBufferingConfiguration { - public final boolean enabled; - public final int maxCacheSize; + private final boolean enabled; + private final int maxCacheSize; private static final int DEFAULT_MAX_CACHE_SIZE = 60 * 1024 * 1024; + private static final int MAX_FILE_SIZE = 1024 * 1024; private DiskBufferingConfiguration(Builder builder) { this.enabled = builder.enabled; @@ -20,6 +21,18 @@ public static Builder builder() { return new Builder(false, DEFAULT_MAX_CACHE_SIZE); } + public boolean isEnabled() { + return enabled; + } + + public int getMaxCacheSize() { + return maxCacheSize; + } + + public int getMaxCacheFileSize() { + return MAX_FILE_SIZE; + } + public static final class Builder { private boolean enabled; private int maxCacheSize; diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 28c59b3db..b57b076f6 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -21,7 +21,6 @@ */ public final class DiskManager { private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; - private static final int MAX_FILE_SIZE = 1024 * 1024; private static final Logger logger = Logger.getLogger("DiskManager"); private final CacheStorageService cacheStorageService; private final PreferencesService preferencesService; @@ -83,18 +82,19 @@ public int getMaxFolderSize() { String.format("Returning max folder size from preferences: %s", storedSize)); return storedSize; } - int requestedSize = diskBufferingConfiguration.maxCacheSize; + int requestedSize = diskBufferingConfiguration.getMaxCacheSize(); int availableCacheSize = (int) cacheStorageService.ensureCacheSpaceAvailable(requestedSize); // Divides the available cache size by 3 (for each signal's folder) and then subtracts the // size of a single file to be aware of a temp file used when reading data back from the // disk. - int calculatedSize = (availableCacheSize / 3) - MAX_FILE_SIZE; - if (calculatedSize < MAX_FILE_SIZE) { + int maxCacheFileSize = getMaxCacheFileSize(); + int calculatedSize = (availableCacheSize / 3) - maxCacheFileSize; + if (calculatedSize < maxCacheFileSize) { logger.log( Level.WARNING, String.format( "Insufficient folder cache size: %s, it must be at least: %s", - calculatedSize, MAX_FILE_SIZE)); + calculatedSize, maxCacheFileSize)); return 0; } preferencesService.store(MAX_FOLDER_SIZE_KEY, calculatedSize); @@ -108,7 +108,7 @@ public int getMaxFolderSize() { } public int getMaxCacheFileSize() { - return MAX_FILE_SIZE; + return diskBufferingConfiguration.getMaxCacheFileSize(); } private static void deleteFiles(File dir) { diff --git a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java new file mode 100644 index 000000000..975f79a1d --- /dev/null +++ b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java @@ -0,0 +1,111 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.features.persistence; + +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import io.opentelemetry.android.config.DiskBufferingConfiguration; +import io.opentelemetry.android.internal.services.CacheStorageService; +import io.opentelemetry.android.internal.services.PreferencesService; +import java.io.File; +import java.io.IOException; +import java.util.Objects; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class DiskManagerTest { + + private static final String MAX_FOLDER_SIZE_KEY = "max_signal_folder_size"; + @Mock CacheStorageService cacheStorageService; + @Mock PreferencesService preferencesService; + @Mock DiskBufferingConfiguration diskBufferingConfiguration; + @TempDir File cacheDir; + private DiskManager diskManager; + + @BeforeEach + public void setUp() { + diskManager = + new DiskManager( + cacheStorageService, preferencesService, diskBufferingConfiguration); + } + + @Test + public void provideSignalBufferDir() throws IOException { + doReturn(cacheDir).when(cacheStorageService).getCacheDir(); + File expected = new File(cacheDir, "opentelemetry/signals"); + + Assertions.assertEquals(expected, diskManager.getSignalsBufferDir()); + Assertions.assertTrue(expected.exists()); + } + + @Test + public void provideTemporaryDir() throws IOException { + doReturn(cacheDir).when(cacheStorageService).getCacheDir(); + File expected = new File(cacheDir, "opentelemetry/temp"); + + Assertions.assertEquals(expected, diskManager.getTemporaryDir()); + Assertions.assertTrue(expected.exists()); + } + + @Test + public void cleanupTemporaryDirBeforeProvidingIt() throws IOException { + File dir = new File(cacheDir, "opentelemetry/temp"); + Assertions.assertTrue(dir.mkdirs()); + Assertions.assertTrue(new File(dir, "somefile.tmp").createNewFile()); + Assertions.assertTrue(new File(dir, "some_other_file.tmp").createNewFile()); + Assertions.assertTrue(new File(dir, "somedir").mkdirs()); + Assertions.assertTrue(new File(dir, "somedir/some_other_file.tmp").createNewFile()); + + File temporaryDir = diskManager.getTemporaryDir(); + + Assertions.assertTrue(temporaryDir.exists()); + Assertions.assertEquals(0, Objects.requireNonNull(temporaryDir.listFiles()).length); + } + + @Test + public void getMaxCacheFileSize() { + int persistenceSize = 1024 * 1024 * 2; + doReturn(persistenceSize).when(diskBufferingConfiguration).getMaxCacheFileSize(); + + Assertions.assertEquals(persistenceSize, diskManager.getMaxCacheFileSize()); + + verify(diskBufferingConfiguration).getMaxCacheFileSize(); + } + + @Test + public void getMaxSignalFolderSize() { + long maxCacheSize = 10 * 1024 * 1024; // 10 MB + int maxCacheFileSize = 1024 * 1024; // 1 MB + doReturn((int) maxCacheSize).when(diskBufferingConfiguration).getMaxCacheSize(); + doReturn(maxCacheFileSize).when(diskBufferingConfiguration).getMaxCacheFileSize(); + doReturn(maxCacheSize).when(cacheStorageService).ensureCacheSpaceAvailable(maxCacheSize); + doReturn(-1).when(preferencesService).retrieveInt(MAX_FOLDER_SIZE_KEY, -1); + + // Expects the size of a single signal type folder minus the size of a cache file, to use as + // temporary space for reading. + int expected = 2_446_677; + Assertions.assertEquals(expected, diskManager.getMaxFolderSize()); + verify(preferencesService).store(MAX_FOLDER_SIZE_KEY, expected); + + // On a second call, should get the value from the preferences. + clearInvocations(cacheStorageService, diskBufferingConfiguration, preferencesService); + doReturn(expected).when(preferencesService).retrieveInt(MAX_FOLDER_SIZE_KEY, -1); + Assertions.assertEquals(expected, diskManager.getMaxFolderSize()); + verify(preferencesService).retrieveInt(MAX_FOLDER_SIZE_KEY, -1); + verifyNoMoreInteractions(preferencesService); + verifyNoInteractions(cacheStorageService, diskBufferingConfiguration); + } +} From eec891fe8f893fe384c2b6ed8e849486297d2b46 Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:03:28 +0100 Subject: [PATCH 29/34] Adding test case for DiskManager --- .../features/persistence/DiskManagerTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java index 975f79a1d..2f7736b2b 100644 --- a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java +++ b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java @@ -7,6 +7,7 @@ import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -108,4 +109,20 @@ public void getMaxSignalFolderSize() { verifyNoMoreInteractions(preferencesService); verifyNoInteractions(cacheStorageService, diskBufferingConfiguration); } + + @Test + public void getMaxSignalFolderSize_whenCalculatedSizeIsNotValid() { + long maxCacheSize = 1024 * 1024; // 1 MB + int maxCacheFileSize = 1024 * 1024; // 1 MB + doReturn((int) maxCacheSize).when(diskBufferingConfiguration).getMaxCacheSize(); + doReturn(maxCacheFileSize).when(diskBufferingConfiguration).getMaxCacheFileSize(); + doReturn(maxCacheSize).when(cacheStorageService).ensureCacheSpaceAvailable(maxCacheSize); + doReturn(-1).when(preferencesService).retrieveInt(MAX_FOLDER_SIZE_KEY, -1); + + // Expects the size of a single signal type folder minus the size of a cache file, to use as + // temporary space for reading. + int expected = 0; + Assertions.assertEquals(expected, diskManager.getMaxFolderSize()); + verify(preferencesService, never()).store(MAX_FOLDER_SIZE_KEY, expected); + } } From daa28f0968f5897551f2b6a98a77ec6efa0322eb Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:20:00 +0100 Subject: [PATCH 30/34] Removing Service.Type --- .../internal/features/persistence/DiskManager.java | 5 ++--- .../internal/services/CacheStorageService.java | 5 ----- .../android/internal/services/PreferencesService.java | 5 ----- .../android/internal/services/Service.java | 10 +--------- .../android/internal/services/ServiceManager.java | 11 ++++++----- 5 files changed, 9 insertions(+), 27 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index b57b076f6..357347dab 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -9,7 +9,6 @@ import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.android.internal.services.CacheStorageService; import io.opentelemetry.android.internal.services.PreferencesService; -import io.opentelemetry.android.internal.services.Service; import io.opentelemetry.android.internal.services.ServiceManager; import java.io.File; import java.io.IOException; @@ -29,8 +28,8 @@ public final class DiskManager { public static DiskManager create(OtelRumConfig config) { ServiceManager serviceManager = ServiceManager.get(); return new DiskManager( - serviceManager.getService(Service.Type.CACHE_STORAGE), - serviceManager.getService(Service.Type.PREFERENCES), + serviceManager.getService(CacheStorageService.class), + serviceManager.getService(PreferencesService.class), config.getDiskBufferingConfiguration()); } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java index 4fc2140e2..79767ab00 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/CacheStorageService.java @@ -83,9 +83,4 @@ private long getLegacyAvailableSpace(File directory, long maxSpaceNeeded) { directory, maxSpaceNeeded)); return Math.min(directory.getUsableSpace(), maxSpaceNeeded); } - - @Override - public Type type() { - return Type.CACHE_STORAGE; - } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java index 9dd20037e..4918e89d6 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/PreferencesService.java @@ -35,9 +35,4 @@ public void store(String key, int value) { public int retrieveInt(String key, int defaultValue) { return preferences.getInt(key, defaultValue); } - - @Override - public Type type() { - return Type.PREFERENCES; - } } diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java index 521bc1164..b14f65ae0 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/Service.java @@ -5,12 +5,4 @@ package io.opentelemetry.android.internal.services; -public interface Service extends Lifecycle { - - Type type(); - - enum Type { - CACHE_STORAGE, - PREFERENCES - } -} +public interface Service extends Lifecycle {} diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 03d611060..68719521f 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -13,7 +13,7 @@ public final class ServiceManager implements Lifecycle { - private final Map services = new HashMap<>(); + private final Map, Service> services = new HashMap<>(); @Nullable private static ServiceManager instance; private ServiceManager() {} @@ -22,6 +22,7 @@ private ServiceManager() {} public static void initialize(Context appContext) { instance = new ServiceManager(); instance.addService(PreferencesService.create(appContext)); + instance.addService(new CacheStorageService(appContext)); } @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @@ -32,8 +33,8 @@ public static ServiceManager get() { return instance; } - public void addService(Service service) { - Service.Type type = service.type(); + public void addService(T service) { + Class type = service.getClass(); verifyNotExisting(type); services.put(type, service); } @@ -54,7 +55,7 @@ public void stop() { @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) - public T getService(Service.Type type) { + public T getService(Class type) { Service service = services.get(type); if (service == null) { throw new IllegalArgumentException("Service not found: " + type); @@ -70,7 +71,7 @@ public static void resetForTest() { instance = null; } - private void verifyNotExisting(Service.Type type) { + private void verifyNotExisting(Class type) { if (services.containsKey(type)) { throw new IllegalArgumentException("Service already registered with type: " + type); } From 1f6565981d912ce3f9626b25fe6b9d068e0761ea Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:24:27 +0100 Subject: [PATCH 31/34] Making DiskManager constructor private --- .../internal/features/persistence/DiskManager.java | 2 +- .../android/internal/services/ServiceManager.java | 5 +++++ .../features/persistence/DiskManagerTest.java | 13 ++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java index 357347dab..5cc0c5020 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/features/persistence/DiskManager.java @@ -33,7 +33,7 @@ public static DiskManager create(OtelRumConfig config) { config.getDiskBufferingConfiguration()); } - DiskManager( + private DiskManager( CacheStorageService cacheStorageService, PreferencesService preferencesService, DiskBufferingConfiguration diskBufferingConfiguration) { diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 68719521f..c51aec45a 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -71,6 +71,11 @@ public static void resetForTest() { instance = null; } + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) + public static void setForTest(ServiceManager serviceManager) { + instance = serviceManager; + } + private void verifyNotExisting(Class type) { if (services.containsKey(type)) { throw new IllegalArgumentException("Service already registered with type: " + type); diff --git a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java index 2f7736b2b..ed44390ae 100644 --- a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java +++ b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java @@ -7,14 +7,17 @@ import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; import io.opentelemetry.android.config.DiskBufferingConfiguration; +import io.opentelemetry.android.config.OtelRumConfig; import io.opentelemetry.android.internal.services.CacheStorageService; import io.opentelemetry.android.internal.services.PreferencesService; +import io.opentelemetry.android.internal.services.ServiceManager; import java.io.File; import java.io.IOException; import java.util.Objects; @@ -38,9 +41,13 @@ class DiskManagerTest { @BeforeEach public void setUp() { - diskManager = - new DiskManager( - cacheStorageService, preferencesService, diskBufferingConfiguration); + OtelRumConfig config = mock(OtelRumConfig.class); + ServiceManager serviceManager = mock(ServiceManager.class); + doReturn(diskBufferingConfiguration).when(config).getDiskBufferingConfiguration(); + doReturn(cacheStorageService).when(serviceManager).getService(CacheStorageService.class); + doReturn(preferencesService).when(serviceManager).getService(PreferencesService.class); + ServiceManager.setForTest(serviceManager); + diskManager = DiskManager.create(config); } @Test From e46fb953f31d35a2dab63f43796a31c0fc211f3a Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:37:59 +0100 Subject: [PATCH 32/34] Making DiskManagerTest methods package-private --- .../features/persistence/DiskManagerTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java index ed44390ae..7566a18bc 100644 --- a/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java +++ b/instrumentation/src/test/java/io/opentelemetry/android/internal/features/persistence/DiskManagerTest.java @@ -40,9 +40,9 @@ class DiskManagerTest { private DiskManager diskManager; @BeforeEach - public void setUp() { - OtelRumConfig config = mock(OtelRumConfig.class); - ServiceManager serviceManager = mock(ServiceManager.class); + void setUp() { + OtelRumConfig config = mock(); + ServiceManager serviceManager = mock(); doReturn(diskBufferingConfiguration).when(config).getDiskBufferingConfiguration(); doReturn(cacheStorageService).when(serviceManager).getService(CacheStorageService.class); doReturn(preferencesService).when(serviceManager).getService(PreferencesService.class); @@ -51,7 +51,7 @@ public void setUp() { } @Test - public void provideSignalBufferDir() throws IOException { + void provideSignalBufferDir() throws IOException { doReturn(cacheDir).when(cacheStorageService).getCacheDir(); File expected = new File(cacheDir, "opentelemetry/signals"); @@ -60,7 +60,7 @@ public void provideSignalBufferDir() throws IOException { } @Test - public void provideTemporaryDir() throws IOException { + void provideTemporaryDir() throws IOException { doReturn(cacheDir).when(cacheStorageService).getCacheDir(); File expected = new File(cacheDir, "opentelemetry/temp"); @@ -69,7 +69,7 @@ public void provideTemporaryDir() throws IOException { } @Test - public void cleanupTemporaryDirBeforeProvidingIt() throws IOException { + void cleanupTemporaryDirBeforeProvidingIt() throws IOException { File dir = new File(cacheDir, "opentelemetry/temp"); Assertions.assertTrue(dir.mkdirs()); Assertions.assertTrue(new File(dir, "somefile.tmp").createNewFile()); @@ -84,7 +84,7 @@ public void cleanupTemporaryDirBeforeProvidingIt() throws IOException { } @Test - public void getMaxCacheFileSize() { + void getMaxCacheFileSize() { int persistenceSize = 1024 * 1024 * 2; doReturn(persistenceSize).when(diskBufferingConfiguration).getMaxCacheFileSize(); @@ -94,7 +94,7 @@ public void getMaxCacheFileSize() { } @Test - public void getMaxSignalFolderSize() { + void getMaxSignalFolderSize() { long maxCacheSize = 10 * 1024 * 1024; // 10 MB int maxCacheFileSize = 1024 * 1024; // 1 MB doReturn((int) maxCacheSize).when(diskBufferingConfiguration).getMaxCacheSize(); @@ -118,7 +118,7 @@ public void getMaxSignalFolderSize() { } @Test - public void getMaxSignalFolderSize_whenCalculatedSizeIsNotValid() { + void getMaxSignalFolderSize_whenCalculatedSizeIsNotValid() { long maxCacheSize = 1024 * 1024; // 1 MB int maxCacheFileSize = 1024 * 1024; // 1 MB doReturn((int) maxCacheSize).when(diskBufferingConfiguration).getMaxCacheSize(); From b7d3993c65ab97a851de62c7fdb0e2c539171f2f Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:57:49 +0100 Subject: [PATCH 33/34] Adding tests to ServiceManager --- .../internal/services/ServiceManager.java | 4 +- .../internal/services/ServiceManagerTest.java | 80 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 instrumentation/src/test/java/io/opentelemetry/android/internal/services/ServiceManagerTest.java diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index c51aec45a..361ad1d31 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -8,6 +8,7 @@ import android.content.Context; import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; +import androidx.annotation.VisibleForTesting; import java.util.HashMap; import java.util.Map; @@ -16,7 +17,8 @@ public final class ServiceManager implements Lifecycle { private final Map, Service> services = new HashMap<>(); @Nullable private static ServiceManager instance; - private ServiceManager() {} + @VisibleForTesting + ServiceManager() {} @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static void initialize(Context appContext) { diff --git a/instrumentation/src/test/java/io/opentelemetry/android/internal/services/ServiceManagerTest.java b/instrumentation/src/test/java/io/opentelemetry/android/internal/services/ServiceManagerTest.java new file mode 100644 index 000000000..69c81ffd1 --- /dev/null +++ b/instrumentation/src/test/java/io/opentelemetry/android/internal/services/ServiceManagerTest.java @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.services; + +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ServiceManagerTest { + + private ServiceManager serviceManager; + + @BeforeEach + void setUp() { + serviceManager = new ServiceManager(); + } + + @Test + void addingServices() { + FirstService firstService = mock(); + SecondService secondService = mock(); + + serviceManager.addService(firstService); + serviceManager.addService(secondService); + + Assertions.assertEquals(firstService, serviceManager.getService(FirstService.class)); + Assertions.assertEquals(secondService, serviceManager.getService(SecondService.class)); + } + + @Test + void allowOnlyOneServicePerType() { + FirstService firstService = mock(); + FirstService anotherFirstService = mock(); + + serviceManager.addService(firstService); + + try { + serviceManager.addService(anotherFirstService); + fail(); + } catch (IllegalArgumentException ignored) { + } + } + + @Test + void delegatingStartCall() { + FirstService firstService = mock(); + SecondService secondService = mock(); + serviceManager.addService(firstService); + serviceManager.addService(secondService); + + serviceManager.start(); + + verify(firstService).start(); + verify(secondService).start(); + } + + @Test + void delegatingStopCall() { + FirstService firstService = mock(); + SecondService secondService = mock(); + serviceManager.addService(firstService); + serviceManager.addService(secondService); + + serviceManager.stop(); + + verify(firstService).stop(); + verify(secondService).stop(); + } + + private static class FirstService implements Service {} + + private static class SecondService implements Service {} +} From 00542014853d760856b21636560694fcf57fb6ea Mon Sep 17 00:00:00 2001 From: Cesar Munoz <56847527+LikeTheSalad@users.noreply.github.com> Date: Wed, 15 Nov 2023 15:05:40 +0100 Subject: [PATCH 34/34] Adding javadoc --- .../android/internal/services/ServiceManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java index 361ad1d31..bb8500b36 100644 --- a/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java +++ b/instrumentation/src/main/java/io/opentelemetry/android/internal/services/ServiceManager.java @@ -12,6 +12,9 @@ import java.util.HashMap; import java.util.Map; +/** + * This class is internal and not for public use. Its APIs are unstable and can change at any time. + */ public final class ServiceManager implements Lifecycle { private final Map, Service> services = new HashMap<>();