diff --git a/embrace-android-fcm/src/main/java/io/embrace/android/embracesdk/fcm/swazzle/callback/com/android/fcm/FirebaseSwazzledHooks.java b/embrace-android-fcm/src/main/java/io/embrace/android/embracesdk/fcm/swazzle/callback/com/android/fcm/FirebaseSwazzledHooks.java index 5b643ff97..620d219c0 100644 --- a/embrace-android-fcm/src/main/java/io/embrace/android/embracesdk/fcm/swazzle/callback/com/android/fcm/FirebaseSwazzledHooks.java +++ b/embrace-android-fcm/src/main/java/io/embrace/android/embracesdk/fcm/swazzle/callback/com/android/fcm/FirebaseSwazzledHooks.java @@ -1,8 +1,7 @@ package io.embrace.android.embracesdk.fcm.swazzle.callback.com.android.fcm; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.google.firebase.messaging.RemoteMessage; @@ -18,10 +17,8 @@ private FirebaseSwazzledHooks() { @SuppressWarnings("MethodNameCheck") @InternalApi public static void _onMessageReceived(@NonNull RemoteMessage message) { - logger.logDebug("Embrace received push notification message"); - if (!Embrace.getInstance().isStarted()) { - logger.logError("Embrace received push notification data before the SDK was started"); + logError("Embrace received push notification data before the SDK was started", null); return; } @@ -37,21 +34,21 @@ private static void handleRemoteMessage(@NonNull RemoteMessage message) { try { messageId = message.getMessageId(); } catch (Exception e) { - logger.logError("Failed to capture FCM messageId", e); + logError("Failed to capture FCM messageId", e); } String topic = null; try { topic = message.getFrom(); } catch (Exception e) { - logger.logError("Failed to capture FCM topic", e); + logError("Failed to capture FCM topic", e); } Integer messagePriority = null; try { messagePriority = message.getPriority(); } catch (Exception e) { - logger.logError("Failed to capture FCM message priority", e); + logError("Failed to capture FCM message priority", e); } RemoteMessage.Notification notification = null; @@ -59,7 +56,7 @@ private static void handleRemoteMessage(@NonNull RemoteMessage message) { try { notification = message.getNotification(); } catch (Exception e) { - logger.logError("Failed to capture FCM RemoteMessage Notification", e); + logError("Failed to capture FCM RemoteMessage Notification", e); } String title = null; @@ -69,19 +66,19 @@ private static void handleRemoteMessage(@NonNull RemoteMessage message) { try { title = notification.getTitle(); } catch (Exception e) { - logger.logError("Failed to capture FCM title", e); + logError("Failed to capture FCM title", e); } try { body = notification.getBody(); } catch (Exception e) { - logger.logError("Failed to capture FCM body", e); + logError("Failed to capture FCM body", e); } try { notificationPriority = notification.getNotificationPriority(); } catch (Exception e) { - logger.logError("Failed to capture FCM notificationPriority", e); + logError("Failed to capture FCM notificationPriority", e); } } @@ -100,10 +97,17 @@ private static void handleRemoteMessage(@NonNull RemoteMessage message) { hasData ); } catch (Exception e) { - logger.logError("Failed to log push Notification", e); + logError("Failed to log push Notification", e); } } catch (Exception e) { - logger.logError("Push Notification Error", e); + logError("Push Notification Error", e); + } + } + + private static void logError(@NonNull String message, @Nullable Exception e) { + Embrace.getInstance().getInternalInterface().logError(message, null, null, false); + if (e != null) { + Embrace.getInstance().getInternalInterface().logInternalError(e); } } } diff --git a/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java b/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java index 8e2444c7f..29df31c9e 100644 --- a/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java +++ b/embrace-android-okhttp3/src/main/java/io/embrace/android/embracesdk/okhttp3/swazzle/callback/okhttp3/OkHttpClient.java @@ -1,9 +1,8 @@ package io.embrace.android.embracesdk.okhttp3.swazzle.callback.okhttp3; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import java.util.List; +import io.embrace.android.embracesdk.Embrace; import io.embrace.android.embracesdk.annotation.InternalApi; import io.embrace.android.embracesdk.okhttp3.EmbraceOkHttp3ApplicationInterceptor; import io.embrace.android.embracesdk.okhttp3.EmbraceOkHttp3NetworkInterceptor; @@ -35,13 +34,13 @@ private Builder() { */ @SuppressWarnings("MethodNameCheck") public static void _preBuild(okhttp3.OkHttpClient.Builder thiz) { - logger.logDebug("Embrace OkHTTP Wrapper; onPrebuild"); + logInfo("Embrace OkHTTP Wrapper; onPrebuild"); addEmbraceInterceptors(thiz); } @SuppressWarnings("MethodNameCheck") public static void _constructorOnPostBody(okhttp3.OkHttpClient.Builder thiz) { - logger.logDebug("Embrace OkHTTP Wrapper; onPostBody"); + logInfo("Embrace OkHTTP Wrapper; onPostBody"); addEmbraceInterceptors(thiz); } @@ -52,16 +51,15 @@ public static void _constructorOnPostBody(okhttp3.OkHttpClient.Builder thiz) { */ private static void addEmbraceInterceptors(okhttp3.OkHttpClient.Builder thiz) { try { - logger.logDebug("Embrace OkHTTP Wrapper; Adding interceptors"); + logInfo("Embrace OkHTTP Wrapper; Adding interceptors"); addInterceptor(thiz.interceptors(), new EmbraceOkHttp3ApplicationInterceptor()); addInterceptor(thiz.networkInterceptors(), new EmbraceOkHttp3NetworkInterceptor()); } catch (NoSuchMethodError exception) { // The customer may be overwriting OkHttpClient with their own implementation, and some of the // methods we use are missing. - logger.logError("Altered OkHttpClient implementation, could not add OkHttp interceptor. ", - exception); + logError("Altered OkHttpClient implementation, could not add OkHttp interceptor. ", exception); } catch (Exception exception) { - logger.logError("Could not add OkHttp interceptor. ", exception); + logError("Could not add OkHttp interceptor. ", exception); } } @@ -76,8 +74,8 @@ private static void addInterceptor(List interceptors, if (interceptors != null && !containsInstance(interceptors, interceptor.getClass())) { interceptors.add(0, interceptor); } else { - logger.logDebug( - "Not adding interceptor [" + interceptor.getClass().getSimpleName() + "]" + logInfo( + "Not adding interceptor [" + interceptor.getClass().getSimpleName() + "]" ); } } @@ -94,13 +92,22 @@ private static boolean containsInstance(List elementsList, Class clazz) { for (T classInstance : elementsList) { if (clazz.isInstance(classInstance)) { - logger.logDebug( - "[" + clazz.getSimpleName() + "] already present in list" + logInfo( + "[" + clazz.getSimpleName() + "] already present in list" ); return true; } } return false; } + + private static void logInfo(String message) { + Embrace.getInstance().getInternalInterface().logInfo(message, null); + } + + private static void logError(String message, Throwable throwable) { + Embrace.getInstance().getInternalInterface().logError(message, null, null, false); + Embrace.getInstance().getInternalInterface().logInternalError(throwable); + } } } diff --git a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/PublicApiTest.kt b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/PublicApiTest.kt index 2bbc0ce70..33da3f47f 100644 --- a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/PublicApiTest.kt +++ b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/PublicApiTest.kt @@ -4,11 +4,8 @@ import android.os.Build.VERSION_CODES.TIRAMISU import androidx.test.ext.junit.runners.AndroidJUnit4 import io.embrace.android.embracesdk.Embrace.AppFramework import io.embrace.android.embracesdk.IntegrationTestRule -import io.embrace.android.embracesdk.assertions.assertInternalErrorLogged import io.embrace.android.embracesdk.internal.ApkToolsConfig import io.embrace.android.embracesdk.internal.TraceparentGeneratorTest.Companion.validPattern -import io.embrace.android.embracesdk.internalErrorService -import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger import io.embrace.android.embracesdk.recordSession import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse @@ -139,23 +136,4 @@ internal class PublicApiTest { } } } - - @Test - fun `static logger and SDK logger instance log to the same internal error service`() { - with(testRule) { - embrace.start(harness.fakeCoreModule.context) - InternalStaticEmbraceLogger.logger.logError("not-used", RuntimeException("static"), true) - assertInternalErrorLogged( - checkNotNull(internalErrorService()).currentExceptionError, - checkNotNull(RuntimeException::class.qualifiedName), - "static" - ) - harness.initModule.logger.logError("not-used", RuntimeException("non-static"), true) - assertInternalErrorLogged( - checkNotNull(internalErrorService()).currentExceptionError, - checkNotNull(RuntimeException::class.qualifiedName), - "non-static" - ) - } - } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt index 2f8a01451..f8a12967e 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceAutomaticVerification.kt @@ -8,8 +8,6 @@ import android.net.Uri import android.os.Handler import android.os.Looper import android.widget.Toast -import io.embrace.android.embracesdk.logging.InternalEmbraceLogger -import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger import io.embrace.android.embracesdk.samples.AutomaticVerificationChecker import io.embrace.android.embracesdk.samples.VerificationActions import io.embrace.android.embracesdk.samples.VerifyIntegrationException @@ -34,8 +32,7 @@ import kotlin.system.exitProcess * */ internal class EmbraceAutomaticVerification( - private val scheduledExecutorService: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor(), - private val logger: InternalEmbraceLogger + private val scheduledExecutorService: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() ) : ActivityLifecycleListener, ProcessStateListener { private val handler = Handler(Looper.getMainLooper()) @@ -45,9 +42,9 @@ internal class EmbraceAutomaticVerification( internal lateinit var processStateService: ProcessStateService - var automaticVerificationChecker = AutomaticVerificationChecker(logger) + var automaticVerificationChecker = AutomaticVerificationChecker() - var verificationActions = VerificationActions(Embrace.getInstance(), logger, automaticVerificationChecker) + var verificationActions = VerificationActions(Embrace.getInstance(), automaticVerificationChecker) /** * This flag track if the verification result popup was displayed or not, @@ -61,7 +58,7 @@ internal class EmbraceAutomaticVerification( private const val EMBRACE_CONTACT_EMAIL = "support@embrace.io" private const val VERIFY_INTEGRATION_DELAY = 200L private const val ON_FOREGROUND_TIMEOUT = 5000L - internal val instance = EmbraceAutomaticVerification(logger = logger) + internal val instance = EmbraceAutomaticVerification() } fun verifyIntegration() { @@ -93,7 +90,7 @@ internal class EmbraceAutomaticVerification( TimeUnit.MILLISECONDS ) } catch (e: RejectedExecutionException) { - logger.logError("$TAG - Start verification rejected", e) + logInternalError(e, "Start verification rejected") } } @@ -107,23 +104,23 @@ internal class EmbraceAutomaticVerification( verificationActions.runActions() } else { // the verification was already started - logger.logInfo("$TAG Verification almost ready...") + logInfo("Verification almost ready...") handler.postDelayed({ verifyLifecycle() }, ON_FOREGROUND_TIMEOUT) } } catch (e: IOException) { - logger.logError("$TAG Embrace SDK cannot run the verification in this moment", e) + logInternalError(e, "Embrace SDK cannot run the verification in this moment") showToast(activity, activity.getString(R.string.automatic_verification_not_started)) } } else { - logger.logError("$TAG Embrace SDK cannot run the verification in this moment, Activity is not present") + logError("Embrace SDK cannot run the verification in this moment, Activity is not present") } } private fun verifyLifecycle() { if (!foregroundEventTriggered) { - logger.logError("$TAG OnForeground event was not triggered") + logError("OnForeground event was not triggered") val exceptionsService = checkNotNull(Embrace.getImpl().internalErrorService) if (verifyIfInitializerIsDisabled()) { exceptionsService.handleInternalError( @@ -141,7 +138,7 @@ internal class EmbraceAutomaticVerification( fun runEndSession() { Embrace.getInstance().endSession() - logger.logInfo("$TAG End session manually") + logInfo("End session manually") } /** @@ -150,7 +147,7 @@ internal class EmbraceAutomaticVerification( * @return true if it detects that ProcessLifecycleInitializer is disabled, false otherwise */ private fun verifyIfInitializerIsDisabled(): Boolean { - logger.logInfo("Trying to verify lifecycle annotations") + logInfo("Trying to verify lifecycle annotations") try { val appInitializerClass: Class<*>? try { @@ -173,7 +170,7 @@ internal class EmbraceAutomaticVerification( return false } } catch (e: Exception) { - logger.logWarning("$TAG Could not verify if lifecycle annotations are working: $e") + logWarning("Could not verify if lifecycle annotations are working: $e") } return false } @@ -196,7 +193,7 @@ internal class EmbraceAutomaticVerification( } exitProcess(exitStatus) } else { - logger.logError("Cannot restart app, activity is not present") + logError("Cannot restart app, activity is not present") } } @@ -212,7 +209,7 @@ internal class EmbraceAutomaticVerification( } if (isResultDisplayed) { - logger.logDebug("onForeground called but the result was already displayed") + logInfo("onForeground called but the result was already displayed") return } @@ -223,7 +220,7 @@ internal class EmbraceAutomaticVerification( automaticVerificationChecker.deleteFile() }, ON_FOREGROUND_DELAY) } else { - logger.logError("Cannot restart app, activity is not present") + logError("Cannot restart app, activity is not present") } } @@ -240,13 +237,13 @@ internal class EmbraceAutomaticVerification( automaticVerificationChecker.isVerificationCorrect()?.also { isCorrect -> if (isCorrect) { - logger.logInfo("$TAG Successful - Embrace is ready to go! 🎉") + logInfo("Successful - Embrace is ready to go! 🎉") showSuccessDialog() } else { - logger.logInfo("$TAG Error - Something is wrong with the Embrace Configuration ⚠️") + logError("Error - Something is wrong with the Embrace Configuration ⚠️") showDialogWithError() } - } ?: logger.logError("Cannot display end message") + } ?: logError("Cannot display end message") } private fun showToast(activity: Activity, message: String) { @@ -272,7 +269,7 @@ internal class EmbraceAutomaticVerification( } dialogBuilder.create().show() } else { - logger.logInfo("Verification success! - Cannot display popup") + logInfo("Verification success!") } } @@ -306,7 +303,7 @@ internal class EmbraceAutomaticVerification( } dialogBuilder.create().show() } else { - logger.logError("Verification error - Cannot display popup") + logError("Verification error - Cannot display popup") } } @@ -331,4 +328,20 @@ internal class EmbraceAutomaticVerification( errorLog += errorMessage return errorLog } + + private fun logInfo(message: String) { + Embrace.getInstance().internalInterface.logInfo("$TAG $message", null) + } + + private fun logWarning(message: String) { + Embrace.getInstance().internalInterface.logWarning("$TAG $message", null, null) + } + private fun logError(message: String) { + Embrace.getInstance().internalInterface.logError("$TAG $message", null, null, false) + } + + private fun logInternalError(t: Throwable, message: String? = null) { + message?.let { logError(message) } + Embrace.getInstance().internalInterface.logInternalError(t) + } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt index 98ca0aec0..2098e4cc5 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/EmbraceSamples.kt @@ -1,7 +1,6 @@ package io.embrace.android.embracesdk import io.embrace.android.embracesdk.annotation.InternalApi -import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger import io.embrace.android.embracesdk.samples.EmbraceCrashSamples /** @@ -15,7 +14,7 @@ import io.embrace.android.embracesdk.samples.EmbraceCrashSamples public object EmbraceSamples { private val embraceCrashSamples = EmbraceCrashSamples - private val embraceAutomaticVerification = EmbraceAutomaticVerification(logger = logger) + private val embraceAutomaticVerification = EmbraceAutomaticVerification() /** * Starts an automatic verification of the following Embrace features: diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/ViewSwazzledHooks.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/ViewSwazzledHooks.java index 1b61cba77..e7eccd014 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/ViewSwazzledHooks.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/ViewSwazzledHooks.java @@ -1,9 +1,10 @@ package io.embrace.android.embracesdk; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import android.util.Pair; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import io.embrace.android.embracesdk.annotation.InternalApi; import io.embrace.android.embracesdk.payload.TapBreadcrumb.TapBreadcrumbType; @@ -33,13 +34,19 @@ static void logOnClickEvent(android.view.View view, TapBreadcrumbType breadcrumb point = new Pair<>(0.0F, 0.0F); } Embrace.getImpl().logTap(point, viewName, breadcrumbType); - } catch (NoSuchMethodError exception) { + } catch (NoSuchMethodError error) { // The customer may be overwriting View with their own implementation, and some of the // methods we use are missing. - logger.logError("Could not log onClickEvent. Some methods are missing. ", - exception); + logError("Could not log onClickEvent. Some methods are missing. ", error); } catch (Exception exception) { - logger.logError("Could not log onClickEvent.", exception); + logError("Could not log onClickEvent.", exception); + } + } + + private static void logError(@NonNull String message, @Nullable Throwable throwable) { + Embrace.getInstance().getInternalInterface().logError(message, null, null, false); + if (throwable != null) { + Embrace.getInstance().getInternalInterface().logInternalError(throwable); } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewChromeClientSwazzledHooks.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewChromeClientSwazzledHooks.java index 72d6350cd..d679c0f31 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewChromeClientSwazzledHooks.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/WebViewChromeClientSwazzledHooks.java @@ -1,7 +1,5 @@ package io.embrace.android.embracesdk; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import android.webkit.ConsoleMessage; import androidx.annotation.NonNull; @@ -19,6 +17,6 @@ private WebViewChromeClientSwazzledHooks() { @SuppressWarnings("MethodNameCheck") public static void _preOnConsoleMessage(@NonNull ConsoleMessage consoleMessage) { - logger.logInfo("webview _preOnConsoleMessage"); + Embrace.getInstance().getInternalInterface().logInfo("webview _preOnConsoleMessage", null); } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt index fde38c151..fd8ec3d9a 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapper.kt @@ -27,7 +27,6 @@ import io.embrace.android.embracesdk.internal.utils.SystemServiceModuleSupplier import io.embrace.android.embracesdk.internal.utils.VersionChecker import io.embrace.android.embracesdk.internal.utils.WorkerThreadModuleSupplier import io.embrace.android.embracesdk.logging.InternalEmbraceLogger -import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger import io.embrace.android.embracesdk.ndk.NativeModule import io.embrace.android.embracesdk.ndk.NativeModuleImpl import io.embrace.android.embracesdk.session.properties.EmbraceSessionProperties @@ -283,7 +282,6 @@ internal class ModuleInitBootstrapper( postInit(SdkObservabilityModule::class) { serviceRegistry.registerService(sdkObservabilityModule.internalErrorService) initModule.logger.addLoggerAction(sdkObservabilityModule.reportingLoggerAction) - InternalStaticEmbraceLogger.logger.addLoggerAction(sdkObservabilityModule.reportingLoggerAction) } val sessionProperties = Systrace.traceSynchronous("session-properties-init") { diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpPathOverride.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpPathOverride.java index 85e78d9a8..ff9f5a9c3 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpPathOverride.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpPathOverride.java @@ -1,7 +1,5 @@ package io.embrace.android.embracesdk.internal.network.http; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -9,6 +7,7 @@ import java.util.Locale; import java.util.regex.Pattern; +import io.embrace.android.embracesdk.Embrace; import io.embrace.android.embracesdk.annotation.InternalApi; @InternalApi @@ -55,34 +54,38 @@ public static String getURLString(@NonNull HttpPathOverrideRequest request, @Nul private static Boolean validatePathOverride(String path) { if (path == null) { - logger.logError("URL relative path cannot be null"); + logError("URL relative path cannot be null"); return false; } if (path.isEmpty()) { - logger.logError("Relative path must have non-zero length"); + logError("Relative path must have non-zero length"); return false; } if (path.length() > RELATIVE_PATH_MAX_LENGTH) { - logger.logError(String.format(Locale.US, + logError(String.format(Locale.US, "Relative path %s is greater than the maximum allowed length of %d. It will be ignored", path, RELATIVE_PATH_MAX_LENGTH)); return false; } if (!StandardCharsets.US_ASCII.newEncoder().canEncode(path)) { - logger.logError("Relative path must not contain unicode " + + logError("Relative path must not contain unicode " + "characters. Relative path " + path + " will be ignored."); return false; } if (!path.startsWith("/")) { - logger.logError("Relative path must start with a /"); + logError("Relative path must start with a /"); return false; } if (!RELATIVE_PATH_PATTERN.matcher(path).matches()) { - logger.logError("Relative path contains invalid chars. " + + logError("Relative path contains invalid chars. " + "Relative path " + path + " will be ignored."); return false; } return true; } + + private static void logError(@NonNull String message) { + Embrace.getInstance().getInternalInterface().logError(message, null, null, false); + } } \ No newline at end of file diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpUrlConnectionOverride.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpUrlConnectionOverride.java index b7c298249..627fe97e8 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpUrlConnectionOverride.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceHttpUrlConnectionOverride.java @@ -1,7 +1,5 @@ package io.embrace.android.embracesdk.internal.network.http; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -9,6 +7,8 @@ import java.net.MalformedURLException; import java.net.URL; +import io.embrace.android.embracesdk.Embrace; + class EmbraceHttpUrlConnectionOverride implements HttpPathOverrideRequest { private final HttpURLConnection connection; @@ -30,7 +30,8 @@ public String getOverriddenURL(@NonNull String pathOverride) { return new URL(connection.getURL().getProtocol(), connection.getURL().getHost(), connection.getURL().getPort(), pathOverride + "?" + connection.getURL().getQuery()).toString(); } catch (MalformedURLException e) { - logger.logError("Failed to override path of " + connection.getURL() + " with " + pathOverride); + Embrace.getInstance().getInternalInterface().logError( + "Failed to override path of " + connection.getURL() + " with " + pathOverride, null, null, false); return connection.getURL().toString(); } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlConnectionDelegate.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlConnectionDelegate.java index 95551eb75..f83860bb0 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlConnectionDelegate.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlConnectionDelegate.java @@ -1,7 +1,6 @@ package io.embrace.android.embracesdk.internal.network.http; import static io.embrace.android.embracesdk.config.behavior.NetworkSpanForwardingBehavior.TRACEPARENT_HEADER_NAME; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; import android.annotation.TargetApi; import android.os.Build; @@ -621,7 +620,7 @@ synchronized void internalLogNetworkCall(long startTime, long endTime, boolean o ); } } catch (Exception e) { - logger.logError("Error logging native network request", e); + logError(e); } } } @@ -698,7 +697,8 @@ private void identifyTraceId() { try { traceId = getRequestProperty(embrace.getTraceIdHeader()); } catch (Exception e) { - logger.logDebug("Failed to retrieve actual trace id header. Current: " + traceId); + Embrace.getInstance().getInternalInterface().logWarning( + "Failed to retrieve actual trace id header. Current: " + traceId, null, null); } } } @@ -927,4 +927,8 @@ private boolean shouldCaptureNetworkData() { return (hasNetworkCaptureRules() && (enableWrapIoStreams || inputStreamAccessException != null)) && (networkCaptureData.get() == null || networkCaptureData.get().getCapturedResponseBody() == null); } + + private void logError(@NonNull Throwable t) { + Embrace.getInstance().getInternalInterface().logInternalError(t); + } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlStreamHandlerFactory.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlStreamHandlerFactory.java index ca628813d..b674704b8 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlStreamHandlerFactory.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/EmbraceUrlStreamHandlerFactory.java @@ -1,12 +1,15 @@ package io.embrace.android.embracesdk.internal.network.http; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.util.HashMap; import java.util.Map; +import io.embrace.android.embracesdk.Embrace; + /** * Custom implementation of URLStreamHandlerFactory that is able to return URLStreamHandlers that log network data to * Embrace. @@ -25,7 +28,7 @@ final class EmbraceUrlStreamHandlerFactory implements URLStreamHandlerFactory { handlers.put(PROTOCOL_HTTP, new EmbraceHttpUrlStreamHandler(newUrlStreamHandler(CLASS_HTTP_OKHTTP_STREAM_HANDLER))); handlers.put(PROTOCOL_HTTPS, new EmbraceHttpsUrlStreamHandler(newUrlStreamHandler(CLASS_HTTPS_OKHTTP_STREAM_HANDLER))); } catch (Exception ex) { - logger.logError("Failed initialize EmbraceUrlStreamHandlerFactory", ex); + logError("Failed initialize EmbraceUrlStreamHandlerFactory", ex); } } @@ -35,11 +38,18 @@ static URLStreamHandler newUrlStreamHandler(String className) { } catch (Exception e) { // We catch Exception here instead of the specific exceptions that can be thrown due to a change in the way some // of these exceptions are compiled on different OS versions. - logger.logError("Failed to instantiate new URLStreamHandler instance: " + className, e); + logError("Failed to instantiate new URLStreamHandler instance: " + className, e); return null; } } + private static void logError(@NonNull String message, @Nullable Throwable throwable) { + Embrace.getInstance().getInternalInterface().logError(message, null, null, false); + if (throwable != null) { + Embrace.getInstance().getInternalInterface().logInternalError(throwable); + } + } + @Override public URLStreamHandler createURLStreamHandler(String protocol) { return protocol != null ? handlers.get(protocol) : null; diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/StreamHandlerFactoryInstaller.java b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/StreamHandlerFactoryInstaller.java index fd087add1..8f5ad6492 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/StreamHandlerFactoryInstaller.java +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/network/http/StreamHandlerFactoryInstaller.java @@ -1,8 +1,7 @@ package io.embrace.android.embracesdk.internal.network.http; -import static io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.logger; - import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -16,6 +15,7 @@ import javax.net.ssl.HttpsURLConnection; +import io.embrace.android.embracesdk.Embrace; import io.embrace.android.embracesdk.utils.exceptions.Unchecked; /** @@ -48,12 +48,12 @@ static void registerFactory(Boolean enableRequestSizeCapture) { Object existingFactory = getFactoryField().get(null); if (existingFactory == null) { // No factory is registered, so we can simply register the Embrace factory - logger.logInfo("Registering EmbraceUrlStreamHandlerFactory."); + Embrace.getInstance().getInternalInterface().logInfo("Registering EmbraceUrlStreamHandlerFactory.", null); URL.setURLStreamHandlerFactory(new EmbraceUrlStreamHandlerFactory()); } else { - logger.logInfo("Existing URLStreamHandlerFactory detected " + + Embrace.getInstance().getInternalInterface().logInfo("Existing URLStreamHandlerFactory detected " + "(" + existingFactory.getClass().getName() + "). Wrapping with Embrace factory " + - "to enable network traffic interception."); + "to enable network traffic interception.", null); WrappingFactory wrappingFactory = new WrappingFactory((URLStreamHandlerFactory) existingFactory, enableRequestSizeCapture); clearFactory(); URL.setURLStreamHandlerFactory(wrappingFactory); @@ -62,11 +62,11 @@ static void registerFactory(Boolean enableRequestSizeCapture) { // Catching Throwable as URL.setURLStreamHandlerFactory throws an Error which we want to // handle, rather than kill the application if we are unable to swap the factory. String msg = "Error during wrapping of UrlStreamHandlerFactory. Will attempt to set the default Embrace factory"; - logger.logWarning(msg, ex); + logError(msg, ex); try { URL.setURLStreamHandlerFactory(new EmbraceUrlStreamHandlerFactory()); } catch (Throwable ex2) { - logger.logDebug("Failed to register EmbraceUrlStreamHandlerFactory. Network capture disabled.", ex2); + logError("Failed to register EmbraceUrlStreamHandlerFactory. Network capture disabled.", ex2); } } } @@ -104,6 +104,13 @@ private static void clearFactory() { } } + static void logError(@NonNull String message, @Nullable Throwable throwable) { + Embrace.getInstance().getInternalInterface().logError(message, null, null, false); + if (throwable != null) { + Embrace.getInstance().getInternalInterface().logInternalError(throwable); + } + } + /** * A factory which generates a {@link URLConnection}, wrapping the {@link URLConnection} provided * by the wrapped factory. The Embrace network logging is performed, then we delegate to the @@ -136,7 +143,7 @@ public URLStreamHandler createURLStreamHandler(String protocol) { parentHandler = parent.createURLStreamHandler(protocol); } catch (Exception ex) { String msg = "Exception when trying to create stream handler with parent factory for protocol: " + protocol; - logger.logDebug(msg, ex); + logError(msg, ex); return new EmbraceUrlStreamHandlerFactory().createURLStreamHandler(protocol); } if (parentHandler == null) { @@ -154,7 +161,7 @@ protected URLConnection openConnection(URL url, Proxy proxy) { return wrapConnection(parentConnection); } catch (Exception ex) { String msg = "Exception when opening connection for protocol: " + protocol + " and URL: " + url; - logger.logDebug(msg, ex); + logError(msg, ex); throw Unchecked.propagate(ex); } } @@ -168,7 +175,7 @@ protected URLConnection openConnection(URL url) { return wrapConnection(parentConnection); } catch (Exception ex) { String msg = "Exception when opening connection for protocol: " + protocol + " and URL: " + url; - logger.logDebug(msg, ex); + logError(msg, ex); throw Unchecked.propagate(ex); } } @@ -190,7 +197,7 @@ private URLConnection wrapConnection(URLConnection parentConnection) { } } else { // We do not support wrapping this connection type - logger.logDebug("Cannot wrap unsupported protocol: " + protocol); + logError("Cannot wrap unsupported protocol: " + protocol, null); return parentConnection; } } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/logging/InternalStaticEmbraceLogger.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/logging/InternalStaticEmbraceLogger.kt deleted file mode 100644 index 4f9cd3b2b..000000000 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/logging/InternalStaticEmbraceLogger.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.embrace.android.embracesdk.logging - -/** - * A version of the logger used when the SDK instance is not readily available - */ -internal object InternalStaticEmbraceLogger { - @JvmField - val logger = InternalEmbraceLogger() -} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt index 298a8a8b6..201a7e72f 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/AutomaticVerificationChecker.kt @@ -1,14 +1,12 @@ package io.embrace.android.embracesdk.samples import android.app.Activity +import io.embrace.android.embracesdk.Embrace import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer -import io.embrace.android.embracesdk.logging.InternalEmbraceLogger import java.io.File import java.io.FileNotFoundException -internal class AutomaticVerificationChecker( - private val logger: InternalEmbraceLogger -) { +internal class AutomaticVerificationChecker { private val fileName = "emb_marker_file.txt" private val verificationResult = VerificationResult() private lateinit var file: File @@ -62,7 +60,8 @@ internal class AutomaticVerificationChecker( } } } catch (e: FileNotFoundException) { - logger.logError("cannot open file", e) + Embrace.getInstance().internalInterface.logError("Cannot open file", null, null, false) + Embrace.getInstance().internalInterface.logInternalError(e) } return null } diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt index 510b0d68a..a6d4256e7 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/samples/VerificationActions.kt @@ -6,7 +6,6 @@ import io.embrace.android.embracesdk.BuildConfig import io.embrace.android.embracesdk.Embrace import io.embrace.android.embracesdk.EmbraceAutomaticVerification import io.embrace.android.embracesdk.Severity -import io.embrace.android.embracesdk.logging.InternalEmbraceLogger import org.json.JSONObject import java.io.DataOutputStream import java.net.HttpURLConnection @@ -28,7 +27,6 @@ import java.net.URL */ internal class VerificationActions( private val embraceInstance: Embrace, - private val logger: InternalEmbraceLogger, private val automaticVerificationChecker: AutomaticVerificationChecker, ) { @@ -88,7 +86,7 @@ internal class VerificationActions( * - Throw an Exception */ fun runActions() { - logger.logInfo("${EmbraceAutomaticVerification.TAG} Starting Verification...") + logInfo("${EmbraceAutomaticVerification.TAG} Starting Verification...") embraceInstance.addBreadcrumb("This is a breadcrumb") actionsToVerify.forEach { verifyAction(it.first, it.second) @@ -98,14 +96,10 @@ internal class VerificationActions( private fun verifyAction(action: () -> Unit, message: String) { currentStep++ try { - logger.logInfo( - "${EmbraceAutomaticVerification.TAG} ✓ Step $currentStep/$totalSteps: $message" - ) + logInfo(" ✓ Step $currentStep/$totalSteps: $message") action.invoke() } catch (e: Throwable) { - logger.logError( - "${EmbraceAutomaticVerification.TAG} -- $message ERROR ${e.localizedMessage}" - ) + logError("${EmbraceAutomaticVerification.TAG} -- $message ERROR ${e.localizedMessage}") automaticVerificationChecker.addException(e) } } @@ -163,7 +157,7 @@ internal class VerificationActions( val currentVersion = BuildConfig.VERSION_NAME if (ComparableVersion(currentVersion) < ComparableVersion(latestEmbraceVersion)) { - logger.logWarning( + logInfo( "${EmbraceAutomaticVerification.TAG} Note that there is a newer version of Embrace available 🙌! " + "You can read the changelog for $latestEmbraceVersion here: $embraceChangelogLink" ) @@ -192,7 +186,7 @@ internal class VerificationActions( private fun triggerAnr() { handler.post { Thread.sleep(ANR_DURATION_MILLIS) } - logger.logInfo("${EmbraceAutomaticVerification.TAG} ANR Finished") + logInfo("${EmbraceAutomaticVerification.TAG} ANR Finished") } private fun throwAnException() { @@ -200,4 +194,12 @@ internal class VerificationActions( throw VerifyIntegrationException("Forced Exception to verify integration") }, THROW_EXCEPTION_DELAY_MILLIS) } + + private fun logInfo(message: String) { + embraceInstance.internalInterface.logInfo("${EmbraceAutomaticVerification.TAG} $message", null) + } + + private fun logError(message: String) { + embraceInstance.internalInterface.logError("${EmbraceAutomaticVerification.TAG} $message", null, null, false) + } } diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt index 334f3259e..295ba3a08 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/EmbraceAutomaticVerificationTest.kt @@ -3,7 +3,7 @@ package io.embrace.android.embracesdk import android.app.Activity import io.embrace.android.embracesdk.fakes.FakeActivityTracker import io.embrace.android.embracesdk.fakes.system.mockActivity -import io.embrace.android.embracesdk.logging.InternalEmbraceLogger +import io.embrace.android.embracesdk.internal.EmbraceInternalInterface import io.mockk.clearAllMocks import io.mockk.every import io.mockk.just @@ -33,8 +33,8 @@ internal class EmbraceAutomaticVerificationTest { fun beforeClass() { mockkStatic(ScheduledExecutorService::class) mockkStatic(ExecutorService::class) - mockkStatic(EmbraceImpl::class) mockkStatic(Embrace::class) + mockkStatic(EmbraceImpl::class) } @AfterClass @@ -46,8 +46,8 @@ internal class EmbraceAutomaticVerificationTest { @Before fun setup() { - every { Embrace.getImpl() } returns mockk(relaxed = true) - embraceSamples = EmbraceAutomaticVerification(scheduledExecutorService, InternalEmbraceLogger()) + every { Embrace.getInstance().internalInterface } answers { mockk(relaxed = true) } + embraceSamples = EmbraceAutomaticVerification(scheduledExecutorService) } @After diff --git a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapperTest.kt b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapperTest.kt index 22bb18dc8..29be2d877 100644 --- a/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapperTest.kt +++ b/embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/injection/ModuleInitBootstrapperTest.kt @@ -8,10 +8,8 @@ import io.embrace.android.embracesdk.fakes.injection.FakeCoreModule import io.embrace.android.embracesdk.fakes.injection.FakeInitModule import io.embrace.android.embracesdk.fakes.injection.FakeWorkerThreadModule import io.embrace.android.embracesdk.logging.InternalEmbraceLogger -import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger import io.embrace.android.embracesdk.worker.WorkerName import io.embrace.android.embracesdk.worker.WorkerThreadModuleImpl -import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertThrows import org.junit.Assert.assertTrue @@ -86,26 +84,6 @@ internal class ModuleInitBootstrapperTest { ) } - @Test - fun `internal error service hooked up to both static and non-static SDK instance`() { - assertTrue( - moduleInitBootstrapper.init( - context = context, - enableIntegrationTesting = false, - appFramework = Embrace.AppFramework.NATIVE, - sdkStartTimeMs = 0L, - ) - ) - - InternalStaticEmbraceLogger.logger.logError("not-used", RuntimeException("static"), true) - logger.logError("not-used", RuntimeException("non-static"), true) - - assertEquals( - 2, - moduleInitBootstrapper.sdkObservabilityModule.internalErrorService.currentExceptionError?.exceptionErrors?.size - ) - } - @Test fun `async init returns normally and without failure`() { assertTrue(