diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ANRWatchDog.java b/sentry-android-core/src/main/java/io/sentry/android/core/ANRWatchDog.java index 549125fef..70d356389 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ANRWatchDog.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ANRWatchDog.java @@ -17,7 +17,7 @@ final class ANRWatchDog extends Thread { private final ANRListener anrListener; private final IHandler uiHandler; private final long timeoutIntervalMills; - private final ILogger logger; + private final @NotNull ILogger logger; private AtomicLong tick = new AtomicLong(0); private volatile boolean reported = false; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java index bde91c297..b6c772cb6 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java @@ -1,12 +1,11 @@ package io.sentry.android.core; -import static io.sentry.core.ILogger.logIfNotNull; - import android.content.Context; import io.sentry.core.ILogger; import io.sentry.core.SentryLevel; import io.sentry.core.SentryOptions; import java.io.File; +import org.jetbrains.annotations.NotNull; final class AndroidOptionsInitializer { private AndroidOptionsInitializer() {} @@ -15,7 +14,7 @@ static void init(SentryAndroidOptions options, Context context) { init(options, context, new AndroidLogger()); } - static void init(SentryAndroidOptions options, Context context, ILogger logger) { + static void init(SentryAndroidOptions options, Context context, final @NotNull ILogger logger) { // Firstly set the logger, if `debug=true` configured, logging can start asap. options.setLogger(logger); @@ -36,7 +35,7 @@ static void init(SentryAndroidOptions options, Context context, ILogger logger) options.setTransportGate(new AndroidTransportGate(context, options.getLogger())); } - private static void setDefaultInApp(Context context, SentryOptions options) { + private static void setDefaultInApp(Context context, final @NotNull SentryOptions options) { String packageName = context.getPackageName(); if (packageName != null && !packageName.startsWith("android.")) { options.addInAppInclude(packageName); @@ -55,8 +54,7 @@ private static void initializeCacheDirs(Context context, SentryOptions options) if (options.getOutboxPath() != null) { new File(options.getOutboxPath()).mkdirs(); } else { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "No outbox dir path is defined in options."); + options.getLogger().log(SentryLevel.WARNING, "No outbox dir path is defined in options."); } } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidSerializer.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidSerializer.java index a2e2f6aa1..0bd5bfa6f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidSerializer.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidSerializer.java @@ -26,13 +26,14 @@ import java.io.Writer; import java.util.Date; import java.util.TimeZone; +import org.jetbrains.annotations.NotNull; final class AndroidSerializer implements ISerializer { - private final ILogger logger; + private final @NotNull ILogger logger; private final Gson gson; - public AndroidSerializer(ILogger logger) { + public AndroidSerializer(final @NotNull ILogger logger) { this.logger = logger; gson = provideGson(); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransportGate.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransportGate.java index 83e241b1a..2ebbe7a11 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransportGate.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidTransportGate.java @@ -10,7 +10,7 @@ final class AndroidTransportGate implements ITransportGate { private final Context context; - private final ILogger logger; + private final @NotNull ILogger logger; AndroidTransportGate(@NotNull Context context, @NotNull ILogger logger) { this.context = context; diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java index 09e3053f2..95ac50102 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AnrIntegration.java @@ -1,7 +1,5 @@ package io.sentry.android.core; -import static io.sentry.core.ILogger.logIfNotNull; - import io.sentry.core.IHub; import io.sentry.core.ILogger; import io.sentry.core.Integration; @@ -11,6 +9,7 @@ import io.sentry.core.protocol.Mechanism; import java.io.Closeable; import java.io.IOException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; final class AnrIntegration implements Integration, Closeable { @@ -23,14 +22,15 @@ public void register(IHub hub, SentryOptions options) { } private void register(IHub hub, SentryAndroidOptions options) { - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "ANR enabled: %s", options.isAnrEnabled()); + options.getLogger().log(SentryLevel.DEBUG, "ANR enabled: %s", options.isAnrEnabled()); if (options.isAnrEnabled() && anrWatchDog == null) { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "ANR timeout in milliseconds: %d", - options.getAnrTimeoutIntervalMills()); + options + .getLogger() + .log( + SentryLevel.DEBUG, + "ANR timeout in milliseconds: %d", + options.getAnrTimeoutIntervalMills()); anrWatchDog = new ANRWatchDog( @@ -43,8 +43,8 @@ private void register(IHub hub, SentryAndroidOptions options) { } @TestOnly - void reportANR(IHub hub, ILogger logger, ApplicationNotResponding error) { - logIfNotNull(logger, SentryLevel.INFO, "ANR triggered with message: %s", error.getMessage()); + void reportANR(IHub hub, final @NotNull ILogger logger, ApplicationNotResponding error) { + logger.log(SentryLevel.INFO, "ANR triggered with message: %s", error.getMessage()); Mechanism mechanism = new Mechanism(); mechanism.setType("ANR"); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java index b912aec79..6473f6c49 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/DefaultAndroidEventProcessor.java @@ -1,7 +1,6 @@ package io.sentry.android.core; import static android.content.Context.ACTIVITY_SERVICE; -import static io.sentry.core.ILogger.logIfNotNull; import android.app.ActivityManager; import android.content.Context; @@ -81,6 +80,7 @@ public DefaultAndroidEventProcessor(Context context, SentryOptions options) { this.options = Objects.requireNonNull(options, "The SentryOptions is required."); ExecutorService executorService = Executors.newSingleThreadExecutor(); + // dont ref. to method reference, theres a bug on it contextData = executorService.submit(() -> loadContextData()); executorService.shutdown(); @@ -116,11 +116,12 @@ public SentryEvent process(SentryEvent event, @Nullable Object hint) { if (!(hint instanceof Cached)) { processNonCachedEvent(event); } else { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Event was cached so not applying data relevant to the current app execution/version: %s", - event.getEventId()); + options + .getLogger() + .log( + SentryLevel.DEBUG, + "Event was cached so not applying data relevant to the current app execution/version: %s", + event.getEventId()); } if (event.getContexts().getDevice() == null) { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java index 924a6d6b6..a3d8a75ab 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/EnvelopeFileObserver.java @@ -6,17 +6,18 @@ import io.sentry.core.SentryLevel; import io.sentry.core.util.Objects; import java.io.File; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; final class EnvelopeFileObserver extends FileObserver { private final String rootPath; private final IEnvelopeSender envelopeSender; - private final ILogger logger; + private @NotNull final ILogger logger; // The preferred overload (Taking File instead of String) is only available from API 29 @SuppressWarnings("deprecation") - EnvelopeFileObserver(String path, IEnvelopeSender envelopeSender, ILogger logger) { + EnvelopeFileObserver(String path, IEnvelopeSender envelopeSender, @NotNull ILogger logger) { super(path); this.rootPath = Objects.requireNonNull(path, "File path is required."); this.envelopeSender = Objects.requireNonNull(envelopeSender, "Envelope sender is required."); diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java index e741de958..dd89090cb 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java @@ -1,18 +1,19 @@ package io.sentry.android.core; -import static io.sentry.core.ILogger.logIfNotNull; - import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Bundle; import io.sentry.core.ILogger; import io.sentry.core.SentryLevel; +import java.util.Locale; +import org.jetbrains.annotations.NotNull; final class ManifestMetadataReader { static final String DSN_KEY = "io.sentry.dsn"; static final String DEBUG_KEY = "io.sentry.debug"; + static final String DEBUG_LEVEL = "io.sentry.debug.level"; static final String ANR_ENABLE = "io.sentry.anr.enable"; static final String ANR_REPORT_DEBUG = "io.sentry.anr.report-debug"; static final String ANR_TIMEOUT_INTERVAL_MILLS = "io.sentry.anr.timeout-interval-mills"; @@ -29,63 +30,62 @@ static void applyMetadata(Context context, SentryAndroidOptions options) { if (metadata != null) { boolean debug = metadata.getBoolean(DEBUG_KEY, options.isDebug()); - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "debug read: %s", debug); options.setDebug(debug); + options.getLogger().log(SentryLevel.DEBUG, "debug read: %s", debug); + + if (options.isDebug()) { + String level = + metadata.getString( + DEBUG_LEVEL, options.getDiagnosticLevel().name().toLowerCase(Locale.ROOT)); + options.setDiagnosticLevel(SentryLevel.valueOf(level.toUpperCase(Locale.ROOT))); + } boolean isAnrEnabled = metadata.getBoolean(ANR_ENABLE, options.isAnrEnabled()); - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "isAnrEnabled read: %s", isAnrEnabled); + options.getLogger().log(SentryLevel.DEBUG, "isAnrEnabled read: %s", isAnrEnabled); options.setAnrEnabled(isAnrEnabled); boolean isAnrReportInDebug = metadata.getBoolean(ANR_REPORT_DEBUG, options.isAnrReportInDebug()); - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "isAnrReportInDebug read: %s", - isAnrReportInDebug); + options + .getLogger() + .log(SentryLevel.DEBUG, "isAnrReportInDebug read: %s", isAnrReportInDebug); options.setAnrReportInDebug(isAnrReportInDebug); int anrTimeoutIntervalMills = metadata.getInt(ANR_TIMEOUT_INTERVAL_MILLS, options.getAnrTimeoutIntervalMills()); - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "anrTimeoutIntervalMills read: %d", - anrTimeoutIntervalMills); + options + .getLogger() + .log(SentryLevel.DEBUG, "anrTimeoutIntervalMills read: %d", anrTimeoutIntervalMills); options.setAnrTimeoutIntervalMills(anrTimeoutIntervalMills); String dsn = metadata.getString(DSN_KEY, null); if (dsn == null) { - logIfNotNull( - options.getLogger(), - SentryLevel.FATAL, - "DSN is required. Use empty string to disable SDK."); + options + .getLogger() + .log(SentryLevel.FATAL, "DSN is required. Use empty string to disable SDK."); } else if (dsn.isEmpty()) { - logIfNotNull( - options.getLogger(), SentryLevel.DEBUG, "DSN is empty, disabling sentry-android"); + options.getLogger().log(SentryLevel.DEBUG, "DSN is empty, disabling sentry-android"); } else { - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "DSN read: %s", dsn); + options.getLogger().log(SentryLevel.DEBUG, "DSN read: %s", dsn); } options.setDsn(dsn); boolean ndk = metadata.getBoolean(ENABLE_NDK, options.isEnableNdk()); - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "NDK read: %s", ndk); + options.getLogger().log(SentryLevel.DEBUG, "NDK read: %s", ndk); options.setEnableNdk(ndk); } - logIfNotNull( - options.getLogger(), - SentryLevel.INFO, - "Retrieving configuration from AndroidManifest.xml"); + options + .getLogger() + .log(SentryLevel.INFO, "Retrieving configuration from AndroidManifest.xml"); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "Failed to read configuration from android manifest metadata.", - e); + options + .getLogger() + .log( + SentryLevel.ERROR, "Failed to read configuration from android manifest metadata.", e); } } - static boolean isAutoInit(Context context, ILogger logger) { + static boolean isAutoInit(Context context, final @NotNull ILogger logger) { if (context == null) throw new IllegalArgumentException("The application context is required."); boolean autoInit = true; @@ -93,12 +93,11 @@ static boolean isAutoInit(Context context, ILogger logger) { Bundle metadata = getMetadata(context); if (metadata != null) { autoInit = metadata.getBoolean(AUTO_INIT, true); - logIfNotNull(logger, SentryLevel.DEBUG, "Auto-init: %s", autoInit); + logger.log(SentryLevel.DEBUG, "Auto-init: %s", autoInit); } - logIfNotNull(logger, SentryLevel.INFO, "Retrieving auto-init from AndroidManifest.xml"); + logger.log(SentryLevel.INFO, "Retrieving auto-init from AndroidManifest.xml"); } catch (Exception e) { - logIfNotNull( - logger, SentryLevel.ERROR, "Failed to read auto-init from android manifest metadata.", e); + logger.log(SentryLevel.ERROR, "Failed to read auto-init from android manifest metadata.", e); } return autoInit; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/ContextsDeserializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/ContextsDeserializerAdapter.java index 7c1714ef6..3f368d908 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/ContextsDeserializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/ContextsDeserializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -18,13 +16,14 @@ import io.sentry.core.protocol.SentryRuntime; import java.lang.reflect.Type; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class ContextsDeserializerAdapter implements JsonDeserializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public ContextsDeserializerAdapter(ILogger logger) { + public ContextsDeserializerAdapter(@NotNull final ILogger logger) { this.logger = logger; } @@ -78,7 +77,7 @@ public Contexts deserialize(JsonElement json, Type typeOfT, JsonDeserializationC return contexts; } } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when deserializing Contexts", e); + logger.log(SentryLevel.ERROR, "Error when deserializing Contexts", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateDeserializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateDeserializerAdapter.java index 496befbb8..1ec509810 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateDeserializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateDeserializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -12,13 +10,14 @@ import java.lang.reflect.Type; import java.util.Date; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class DateDeserializerAdapter implements JsonDeserializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public DateDeserializerAdapter(ILogger logger) { + public DateDeserializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -28,7 +27,7 @@ public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationConte try { return json == null ? null : DateUtils.getDateTime(json.getAsString()); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when deserializing Date", e); + logger.log(SentryLevel.ERROR, "Error when deserializing Date", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateSerializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateSerializerAdapter.java index fd8bf13c3..bcab18e60 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateSerializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/DateSerializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; @@ -12,13 +10,14 @@ import java.lang.reflect.Type; import java.util.Date; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class DateSerializerAdapter implements JsonSerializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public DateSerializerAdapter(ILogger logger) { + public DateSerializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -27,7 +26,7 @@ public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext try { return src == null ? null : new JsonPrimitive(DateUtils.getTimestamp(src)); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when serializing Date", e); + logger.log(SentryLevel.ERROR, "Error when serializing Date", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationDeserializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationDeserializerAdapter.java index 741c4b11e..34c10fc82 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationDeserializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationDeserializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -12,14 +10,15 @@ import java.lang.reflect.Type; import java.util.Locale; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class OrientationDeserializerAdapter implements JsonDeserializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public OrientationDeserializerAdapter(ILogger logger) { + public OrientationDeserializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -32,7 +31,7 @@ public Device.DeviceOrientation deserialize( ? null : Device.DeviceOrientation.valueOf(json.getAsString().toUpperCase(Locale.ROOT)); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when deserializing DeviceOrientation", e); + logger.log(SentryLevel.ERROR, "Error when deserializing DeviceOrientation", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationSerializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationSerializerAdapter.java index 9475851bb..534d90504 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationSerializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/OrientationSerializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; @@ -12,14 +10,15 @@ import java.lang.reflect.Type; import java.util.Locale; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class OrientationSerializerAdapter implements JsonSerializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public OrientationSerializerAdapter(ILogger logger) { + public OrientationSerializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -29,7 +28,7 @@ public JsonElement serialize( try { return src == null ? null : new JsonPrimitive(src.name().toLowerCase(Locale.ROOT)); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when serializing DeviceOrientation", e); + logger.log(SentryLevel.ERROR, "Error when serializing DeviceOrientation", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdDeserializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdDeserializerAdapter.java index 2211c92d0..494a42d43 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdDeserializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdDeserializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -11,13 +9,14 @@ import io.sentry.core.protocol.SentryId; import java.lang.reflect.Type; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class SentryIdDeserializerAdapter implements JsonDeserializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public SentryIdDeserializerAdapter(ILogger logger) { + public SentryIdDeserializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -27,7 +26,7 @@ public SentryId deserialize(JsonElement json, Type typeOfT, JsonDeserializationC try { return json == null ? null : new SentryId(json.getAsString()); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when deserializing SentryId", e); + logger.log(SentryLevel.ERROR, "Error when deserializing SentryId", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdSerializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdSerializerAdapter.java index 48230de46..7a5316546 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdSerializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryIdSerializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; @@ -11,13 +9,14 @@ import io.sentry.core.protocol.SentryId; import java.lang.reflect.Type; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class SentryIdSerializerAdapter implements JsonSerializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public SentryIdSerializerAdapter(ILogger logger) { + public SentryIdSerializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -26,7 +25,7 @@ public JsonElement serialize(SentryId src, Type typeOfSrc, JsonSerializationCont try { return src == null ? null : new JsonPrimitive(src.toString()); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when serializing SentryId", e); + logger.log(SentryLevel.ERROR, "Error when serializing SentryId", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelDeserializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelDeserializerAdapter.java index 010c647b2..6ad027630 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelDeserializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelDeserializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -11,13 +9,14 @@ import java.lang.reflect.Type; import java.util.Locale; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class SentryLevelDeserializerAdapter implements JsonDeserializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public SentryLevelDeserializerAdapter(ILogger logger) { + public SentryLevelDeserializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -27,7 +26,7 @@ public SentryLevel deserialize(JsonElement json, Type typeOfT, JsonDeserializati try { return json == null ? null : SentryLevel.valueOf(json.getAsString().toUpperCase(Locale.ROOT)); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when deserializing SentryLevel", e); + logger.log(SentryLevel.ERROR, "Error when deserializing SentryLevel", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelSerializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelSerializerAdapter.java index 7283165cb..91fe9e60f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelSerializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/SentryLevelSerializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; @@ -11,13 +9,14 @@ import java.lang.reflect.Type; import java.util.Locale; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class SentryLevelSerializerAdapter implements JsonSerializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public SentryLevelSerializerAdapter(ILogger logger) { + public SentryLevelSerializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -26,7 +25,7 @@ public JsonElement serialize(SentryLevel src, Type typeOfSrc, JsonSerializationC try { return src == null ? null : new JsonPrimitive(src.name().toLowerCase(Locale.ROOT)); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when serializing SentryLevel", e); + logger.log(SentryLevel.ERROR, "Error when serializing SentryLevel", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneDeserializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneDeserializerAdapter.java index 680de5987..82b690123 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneDeserializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneDeserializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -11,13 +9,14 @@ import java.lang.reflect.Type; import java.util.TimeZone; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class TimeZoneDeserializerAdapter implements JsonDeserializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public TimeZoneDeserializerAdapter(ILogger logger) { + public TimeZoneDeserializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -27,7 +26,7 @@ public TimeZone deserialize(JsonElement json, Type typeOfT, JsonDeserializationC try { return json == null ? null : TimeZone.getTimeZone(json.getAsString()); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when deserializing TimeZone", e); + logger.log(SentryLevel.ERROR, "Error when deserializing TimeZone", e); } return null; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneSerializerAdapter.java b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneSerializerAdapter.java index b8a6eca19..a9ab380dc 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneSerializerAdapter.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/adapters/TimeZoneSerializerAdapter.java @@ -1,7 +1,5 @@ package io.sentry.android.core.adapters; -import static io.sentry.core.ILogger.logIfNotNull; - import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; @@ -11,13 +9,14 @@ import java.lang.reflect.Type; import java.util.TimeZone; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public final class TimeZoneSerializerAdapter implements JsonSerializer { - private final ILogger logger; + private final @NotNull ILogger logger; - public TimeZoneSerializerAdapter(ILogger logger) { + public TimeZoneSerializerAdapter(final @NotNull ILogger logger) { this.logger = logger; } @@ -26,7 +25,7 @@ public JsonElement serialize(TimeZone src, Type typeOfSrc, JsonSerializationCont try { return src == null ? null : new JsonPrimitive(src.getID()); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Error when serializing TimeZone", e); + logger.log(SentryLevel.ERROR, "Error when serializing TimeZone", e); } return null; } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt index 2211c73e2..9c3eeaeb1 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/DefaultAndroidEventProcessorTest.kt @@ -110,13 +110,13 @@ class DefaultAndroidEventProcessorTest { fun `Processor won't throw exception`() { val processor = DefaultAndroidEventProcessor(context, fixture.options) processor.process(SentryEvent(), null) - verify((fixture.options.logger as DiagnosticLogger).logger, never()).log(eq(SentryLevel.ERROR), any(), any()) + verify((fixture.options.logger as DiagnosticLogger).logger, never())!!.log(eq(SentryLevel.ERROR), any(), any()) } @Test fun `Processor won't throw exception when theres a hint`() { val processor = DefaultAndroidEventProcessor(context, fixture.options) processor.process(SentryEvent(), CachedEvent()) - verify((fixture.options.logger as DiagnosticLogger).logger, never()).log(eq(SentryLevel.ERROR), any(), any()) + verify((fixture.options.logger as DiagnosticLogger).logger, never())!!.log(eq(SentryLevel.ERROR), any(), any()) } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverTest.kt index 7b128ab4e..5e0cd5eac 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/EnvelopeFileObserverTest.kt @@ -22,7 +22,7 @@ class EnvelopeFileObserverTest { private class Fixture { var path: String? = "." var envelopeSender: IEnvelopeSender = mock() - var logger: ILogger? = mock() + var logger: ILogger = mock() init { val options = SentryOptions() diff --git a/sentry-core/src/main/java/io/sentry/core/DiagnosticLogger.java b/sentry-core/src/main/java/io/sentry/core/DiagnosticLogger.java index eebacfd20..3a3f83e03 100644 --- a/sentry-core/src/main/java/io/sentry/core/DiagnosticLogger.java +++ b/sentry-core/src/main/java/io/sentry/core/DiagnosticLogger.java @@ -7,7 +7,7 @@ /** Sentry SDK internal diagnostic logger. */ public final class DiagnosticLogger implements ILogger { private final SentryOptions options; - private final ILogger logger; + private final @Nullable ILogger logger; /** * Creates a new instance of DiagnosticLogger with the wrapped ILogger. @@ -15,7 +15,7 @@ public final class DiagnosticLogger implements ILogger { * @param options a SentryOptions instance * @param logger a ILogger instance */ - public DiagnosticLogger(SentryOptions options, @Nullable ILogger logger) { + public DiagnosticLogger(final SentryOptions options, final @Nullable ILogger logger) { this.options = Objects.requireNonNull(options, "SentryOptions is required."); this.logger = logger; } @@ -26,7 +26,7 @@ public DiagnosticLogger(SentryOptions options, @Nullable ILogger logger) { * @param level The SentryLevel to test against. * @return True if a log message would be recorded for the level. Otherwise false. */ - public boolean isEnabled(SentryLevel level) { + public boolean isEnabled(final @Nullable SentryLevel level) { SentryLevel diagLevel = options.getDiagnosticLevel(); if (level == null || diagLevel == null) { return false; @@ -42,7 +42,10 @@ public boolean isEnabled(SentryLevel level) { * @param args The optional arguments to format the message. */ @Override - public void log(SentryLevel level, String message, Object... args) { + public void log( + final @Nullable SentryLevel level, + final @Nullable String message, + final @Nullable Object... args) { if (logger != null && isEnabled(level)) { logger.log(level, message, args); } @@ -56,7 +59,10 @@ public void log(SentryLevel level, String message, Object... args) { * @param throwable The throwable to log. */ @Override - public void log(SentryLevel level, String message, Throwable throwable) { + public void log( + final @Nullable SentryLevel level, + final @Nullable String message, + final @Nullable Throwable throwable) { if (logger != null && isEnabled(level)) { logger.log(level, message, throwable); } @@ -71,14 +77,18 @@ public void log(SentryLevel level, String message, Throwable throwable) { * @param args The optional arguments to format the message. */ @Override - public void log(SentryLevel level, Throwable throwable, String message, Object... args) { + public void log( + final @Nullable SentryLevel level, + final @Nullable Throwable throwable, + final @Nullable String message, + final @Nullable Object... args) { if (logger != null && isEnabled(level)) { logger.log(level, throwable, message, args); } } @TestOnly - public ILogger getLogger() { + public @Nullable ILogger getLogger() { return logger; } } diff --git a/sentry-core/src/main/java/io/sentry/core/DirectoryProcessor.java b/sentry-core/src/main/java/io/sentry/core/DirectoryProcessor.java index 368e3c44e..f113f15fd 100644 --- a/sentry-core/src/main/java/io/sentry/core/DirectoryProcessor.java +++ b/sentry-core/src/main/java/io/sentry/core/DirectoryProcessor.java @@ -1,48 +1,40 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; - import java.io.File; import org.jetbrains.annotations.NotNull; abstract class DirectoryProcessor { - private final ILogger logger; + private final @NotNull ILogger logger; - DirectoryProcessor(@NotNull ILogger logger) { + DirectoryProcessor(final @NotNull ILogger logger) { this.logger = logger; } void processDirectory(@NotNull File directory) { try { if (!directory.exists()) { - logIfNotNull( - logger, + logger.log( SentryLevel.WARNING, "Directory '%s' doesn't exist. No cached events to send.", directory.getAbsolutePath()); return; } if (!directory.isDirectory()) { - logIfNotNull( - logger, - SentryLevel.ERROR, - "Cache dir %s is not a directory.", - directory.getAbsolutePath()); + logger.log( + SentryLevel.ERROR, "Cache dir %s is not a directory.", directory.getAbsolutePath()); return; } File[] listFiles = directory.listFiles(); if (listFiles == null) { - logIfNotNull( - logger, SentryLevel.ERROR, "Cache dir %s is null.", directory.getAbsolutePath()); + logger.log(SentryLevel.ERROR, "Cache dir %s is null.", directory.getAbsolutePath()); return; } File[] filteredListFiles = directory.listFiles((d, name) -> isRelevantFileName(name)); - logIfNotNull( - logger, + logger.log( SentryLevel.DEBUG, "Processing %d items from cache dir %s", filteredListFiles != null ? filteredListFiles.length : 0, @@ -52,8 +44,7 @@ void processDirectory(@NotNull File directory) { processFile(file); } } catch (Exception e) { - logIfNotNull( - logger, SentryLevel.ERROR, e, "Failed processing '%s'", directory.getAbsolutePath()); + logger.log(SentryLevel.ERROR, e, "Failed processing '%s'", directory.getAbsolutePath()); } } diff --git a/sentry-core/src/main/java/io/sentry/core/EnvelopeSender.java b/sentry-core/src/main/java/io/sentry/core/EnvelopeSender.java index bf739254d..24dddc490 100644 --- a/sentry-core/src/main/java/io/sentry/core/EnvelopeSender.java +++ b/sentry-core/src/main/java/io/sentry/core/EnvelopeSender.java @@ -1,6 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; import static io.sentry.core.SentryLevel.ERROR; import io.sentry.core.hints.Cached; @@ -19,7 +18,6 @@ import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; @ApiStatus.Internal public final class EnvelopeSender extends DirectoryProcessor implements IEnvelopeSender { @@ -30,10 +28,13 @@ public final class EnvelopeSender extends DirectoryProcessor implements IEnvelop private final IHub hub; private final IEnvelopeReader envelopeReader; private final ISerializer serializer; - private final ILogger logger; + private final @NotNull ILogger logger; public EnvelopeSender( - IHub hub, IEnvelopeReader envelopeReader, ISerializer serializer, ILogger logger) { + IHub hub, + IEnvelopeReader envelopeReader, + ISerializer serializer, + final @NotNull ILogger logger) { super(logger); this.hub = Objects.requireNonNull(hub, "Hub is required."); this.envelopeReader = Objects.requireNonNull(envelopeReader, "Envelope reader is required."); @@ -112,8 +113,7 @@ private void processEnvelope(@NotNull SentryEnvelope envelope, @NotNull CachedEn hub.captureEvent(event, hint); logger.log(SentryLevel.DEBUG, "Item %d is being captured.", items); if (!hint.waitFlush()) { - logIfNotNull( - logger, + logger.log( SentryLevel.WARNING, "Timed out waiting for event submission: %s", event.getEventId()); @@ -147,9 +147,9 @@ private static final class CachedEnvelopeHint implements Cached, Retryable, Subm private CountDownLatch latch; private final long timeoutMills; - private final @Nullable ILogger logger; + private final @NotNull ILogger logger; - CachedEnvelopeHint(final long timeoutMills, final @Nullable ILogger logger) { + CachedEnvelopeHint(final long timeoutMills, final @NotNull ILogger logger) { this.timeoutMills = timeoutMills; this.latch = new CountDownLatch(1); this.logger = logger; @@ -159,7 +159,7 @@ boolean waitFlush() { try { return latch.await(timeoutMills, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - logIfNotNull(logger, ERROR, "Exception while awaiting on lock.", e); + logger.log(ERROR, "Exception while awaiting on lock.", e); } return false; } diff --git a/sentry-core/src/main/java/io/sentry/core/Hub.java b/sentry-core/src/main/java/io/sentry/core/Hub.java index 79b15969d..28c152e80 100644 --- a/sentry-core/src/main/java/io/sentry/core/Hub.java +++ b/sentry-core/src/main/java/io/sentry/core/Hub.java @@ -1,7 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; - import io.sentry.core.protocol.SentryId; import io.sentry.core.protocol.User; import io.sentry.core.util.Objects; @@ -80,28 +78,25 @@ public boolean isEnabled() { public @NotNull SentryId captureEvent(@NotNull SentryEvent event, @Nullable Object hint) { SentryId sentryId = SentryId.EMPTY_ID; if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'captureEvent' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, "Instance is disabled and this 'captureEvent' call is a no-op."); } else if (event == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "captureEvent called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "captureEvent called with null parameter."); } else { try { StackItem item = stack.peek(); if (item != null) { sentryId = item.client.captureEvent(event, item.scope, hint); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when captureEvent"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when captureEvent"); } } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "Error while capturing event with id: " + event.getEventId(), - e); + options + .getLogger() + .log( + SentryLevel.ERROR, "Error while capturing event with id: " + event.getEventId(), e); } } this.lastEventId = sentryId; @@ -112,25 +107,23 @@ public boolean isEnabled() { public @NotNull SentryId captureMessage(@NotNull String message, @NotNull SentryLevel level) { SentryId sentryId = SentryId.EMPTY_ID; if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'captureMessage' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureMessage' call is a no-op."); } else if (message == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "captureMessage called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "captureMessage called with null parameter."); } else { try { StackItem item = stack.peek(); if (item != null) { sentryId = item.client.captureMessage(message, level, item.scope); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when captureMessage"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when captureMessage"); } } catch (Exception e) { - logIfNotNull( - options.getLogger(), SentryLevel.ERROR, "Error while capturing message: " + message, e); + options.getLogger().log(SentryLevel.ERROR, "Error while capturing message: " + message, e); } } this.lastEventId = sentryId; @@ -141,28 +134,25 @@ public boolean isEnabled() { public @NotNull SentryId captureException(@NotNull Throwable throwable, @Nullable Object hint) { SentryId sentryId = SentryId.EMPTY_ID; if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'captureException' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'captureException' call is a no-op."); } else if (throwable == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "captureException called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "captureException called with null parameter."); } else { try { StackItem item = stack.peek(); if (item != null) { sentryId = item.client.captureException(throwable, item.scope, hint); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when captureException"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when captureException"); } } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "Error while capturing message: " + throwable.getMessage(), - e); + options + .getLogger() + .log(SentryLevel.ERROR, "Error while capturing message: " + throwable.getMessage(), e); } } this.lastEventId = sentryId; @@ -172,10 +162,9 @@ public boolean isEnabled() { @Override public void close() { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'close' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'close' call is a no-op."); } else { try { for (Integration integration : options.getIntegrations()) { @@ -189,11 +178,10 @@ public void close() { if (item != null) { item.client.close(); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was NULL when closing Hub"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was NULL when closing Hub"); } } catch (Exception e) { - logIfNotNull(options.getLogger(), SentryLevel.ERROR, "Error while closing the Hub.", e); + options.getLogger().log(SentryLevel.ERROR, "Error while closing the Hub.", e); } isEnabled = false; } @@ -202,13 +190,13 @@ public void close() { @Override public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Object hint) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'addBreadcrumb' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'addBreadcrumb' call is a no-op."); } else if (breadcrumb == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "addBreadcrumb called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "addBreadcrumb called with null parameter."); } else { StackItem item = stack.peek(); if (item != null) { @@ -220,8 +208,7 @@ public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Object hint) item.scope.addBreadcrumb(breadcrumb, false); } } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when addBreadcrumb"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when addBreadcrumb"); } } } @@ -229,16 +216,15 @@ public void addBreadcrumb(@NotNull Breadcrumb breadcrumb, @Nullable Object hint) @Override public void setLevel(@Nullable SentryLevel level) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'setLevel' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setLevel' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.setLevel(level); } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when setLevel"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when setLevel"); } } } @@ -246,17 +232,17 @@ public void setLevel(@Nullable SentryLevel level) { @Override public void setTransaction(@Nullable String transaction) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'setTransaction' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'setTransaction' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.setTransaction(transaction); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when setTransaction"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when setTransaction"); } } } @@ -264,16 +250,15 @@ public void setTransaction(@Nullable String transaction) { @Override public void setUser(@Nullable User user) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'setUser' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setUser' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.setUser(user); } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when setUser"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when setUser"); } } } @@ -281,20 +266,19 @@ public void setUser(@Nullable User user) { @Override public void setFingerprint(@NotNull List fingerprint) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'setFingerprint' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'setFingerprint' call is a no-op."); } else if (fingerprint == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "setFingerprint called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "setFingerprint called with null parameter."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.setFingerprint(fingerprint); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when setFingerprint"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when setFingerprint"); } } } @@ -302,17 +286,17 @@ public void setFingerprint(@NotNull List fingerprint) { @Override public void clearBreadcrumbs() { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'clearBreadcrumbs' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'clearBreadcrumbs' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.clearBreadcrumbs(); } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when clearBreadcrumbs"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when clearBreadcrumbs"); } } } @@ -320,18 +304,17 @@ public void clearBreadcrumbs() { @Override public void setTag(@NotNull String key, @NotNull String value) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'setTag' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setTag' call is a no-op."); } else if (key == null || value == null) { - logIfNotNull(options.getLogger(), SentryLevel.WARNING, "setTag called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "setTag called with null parameter."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.setTag(key, value); } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when setTag"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when setTag"); } } } @@ -339,19 +322,17 @@ public void setTag(@NotNull String key, @NotNull String value) { @Override public void setExtra(@NotNull String key, @NotNull String value) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'setExtra' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'setExtra' call is a no-op."); } else if (key == null || value == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "setExtra called with null parameter."); + options.getLogger().log(SentryLevel.WARNING, "setExtra called with null parameter."); } else { StackItem item = stack.peek(); if (item != null) { item.scope.setExtra(key, value); } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when setExtra"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when setExtra"); } } } @@ -363,11 +344,12 @@ public void setExtra(@NotNull String key, @NotNull String value) { try { breadcrumb = callback.execute(breadcrumb, hint); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "The BeforeBreadcrumbCallback callback threw an exception. It will be added as breadcrumb and continue.", - e); + options + .getLogger() + .log( + SentryLevel.ERROR, + "The BeforeBreadcrumbCallback callback threw an exception. It will be added as breadcrumb and continue.", + e); Map data = breadcrumb.getData(); if (breadcrumb.getData() == null) { @@ -390,10 +372,11 @@ public void setExtra(@NotNull String key, @NotNull String value) { @Override public void pushScope() { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'addBreadcrumb' call is a no-op."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Instance is disabled and this 'addBreadcrumb' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { @@ -401,18 +384,16 @@ public void pushScope() { try { clone = item.scope.clone(); } catch (CloneNotSupportedException e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "An error has occurred when cloning a Scope", - e); + options + .getLogger() + .log(SentryLevel.ERROR, "An error has occurred when cloning a Scope", e); } if (clone != null) { StackItem newItem = new StackItem(item.client, clone); stack.push(newItem); } } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was NULL when pushScope"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was NULL when pushScope"); } } } @@ -420,17 +401,16 @@ public void pushScope() { @Override public void popScope() { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'popScope' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'popScope' call is a no-op."); } else { // Don't drop the root scope synchronized (stack) { if (stack.size() != 1) { stack.pop(); } else { - logIfNotNull(options.getLogger(), SentryLevel.WARNING, "Attempt to pop the root scope."); + options.getLogger().log(SentryLevel.WARNING, "Attempt to pop the root scope."); } } } @@ -439,10 +419,9 @@ public void popScope() { @Override public void withScope(@NotNull ScopeCallback callback) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'withScope' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'withScope' call is a no-op."); } else { pushScope(); StackItem item = stack.peek(); @@ -450,11 +429,10 @@ public void withScope(@NotNull ScopeCallback callback) { try { callback.run(item.scope); } catch (Exception e) { - logIfNotNull( - options.getLogger(), SentryLevel.ERROR, "Error in the 'withScope' callback.", e); + options.getLogger().log(SentryLevel.ERROR, "Error in the 'withScope' callback.", e); } } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when withScope"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when withScope"); } popScope(); } @@ -463,22 +441,19 @@ public void withScope(@NotNull ScopeCallback callback) { @Override public void configureScope(@NotNull ScopeCallback callback) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'withScope' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'withScope' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { try { callback.run(item.scope); } catch (Exception e) { - logIfNotNull( - options.getLogger(), SentryLevel.ERROR, "Error in the 'configureScope' callback.", e); + options.getLogger().log(SentryLevel.ERROR, "Error in the 'configureScope' callback.", e); } } else { - logIfNotNull( - options.getLogger(), SentryLevel.FATAL, "Stack peek was null when configureScope"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when configureScope"); } } } @@ -486,22 +461,21 @@ public void configureScope(@NotNull ScopeCallback callback) { @Override public void bindClient(@NotNull ISentryClient client) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'bindClient' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'bindClient' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { if (client != null) { - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "New client bound to scope."); + options.getLogger().log(SentryLevel.DEBUG, "New client bound to scope."); item.client = client; } else { - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "NoOp client bound to scope."); + options.getLogger().log(SentryLevel.DEBUG, "NoOp client bound to scope."); item.client = NoOpSentryClient.getInstance(); } } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when bindClient"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when bindClient"); } } } @@ -509,20 +483,19 @@ public void bindClient(@NotNull ISentryClient client) { @Override public void flush(long timeoutMills) { if (!isEnabled()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Instance is disabled and this 'flush' call is a no-op."); + options + .getLogger() + .log(SentryLevel.WARNING, "Instance is disabled and this 'flush' call is a no-op."); } else { StackItem item = stack.peek(); if (item != null) { try { item.client.flush(timeoutMills); } catch (Exception e) { - logIfNotNull(options.getLogger(), SentryLevel.ERROR, "Error in the 'client.flush'.", e); + options.getLogger().log(SentryLevel.ERROR, "Error in the 'client.flush'.", e); } } else { - logIfNotNull(options.getLogger(), SentryLevel.FATAL, "Stack peek was null when flush"); + options.getLogger().log(SentryLevel.FATAL, "Stack peek was null when flush"); } } } @@ -530,7 +503,7 @@ public void flush(long timeoutMills) { @Override public @NotNull IHub clone() { if (!isEnabled()) { - logIfNotNull(options.getLogger(), SentryLevel.WARNING, "Disabled Hub cloned."); + options.getLogger().log(SentryLevel.WARNING, "Disabled Hub cloned."); } // Clone will be invoked in parallel Hub clone = new Hub(this.options, null); @@ -540,7 +513,7 @@ public void flush(long timeoutMills) { clonedScope = item.scope.clone(); } catch (CloneNotSupportedException e) { // TODO: Why do we need to deal with this? We must guarantee clone is possible here! - logIfNotNull(options.getLogger(), SentryLevel.ERROR, "Clone not supported"); + options.getLogger().log(SentryLevel.ERROR, "Clone not supported"); clonedScope = new Scope(options.getMaxBreadcrumbs(), options.getBeforeBreadcrumb()); } StackItem cloneItem = new StackItem(item.client, clonedScope); diff --git a/sentry-core/src/main/java/io/sentry/core/ILogger.java b/sentry-core/src/main/java/io/sentry/core/ILogger.java index 4bc5c74f8..08e8e4a2f 100644 --- a/sentry-core/src/main/java/io/sentry/core/ILogger.java +++ b/sentry-core/src/main/java/io/sentry/core/ILogger.java @@ -1,61 +1,8 @@ package io.sentry.core; -import org.jetbrains.annotations.Nullable; - /** Sentry SDK internal logging interface. */ public interface ILogger { - /** - * This method is supposed to be statically imported and provides a shortcut for logging the - * message only if logger is not null. - * - * @param logger the logger or null if none found - * @param level the log level - * @param message the message - * @param args the formatting arguments - * @see #log(SentryLevel, String, Object...) - */ - static void logIfNotNull( - @Nullable ILogger logger, SentryLevel level, String message, Object... args) { - if (logger != null) { - logger.log(level, message, args); - } - } - - /** - * This method is supposed to be statically imported and provides a shortcut for logging the - * message only if logger is not null. - * - * @param logger the logger or null if none found - * @param level the log level - * @param message the message - * @param throwable the exception to log - * @see #log(SentryLevel, String, Throwable) - */ - static void logIfNotNull(ILogger logger, SentryLevel level, String message, Throwable throwable) { - if (logger != null) { - logger.log(level, message, throwable); - } - } - - /** - * This method is supposed to be statically imported and provides a shortcut for logging the - * message only if logger is not null. - * - * @param logger the logger or null if none found - * @param level the log level - * @param throwable the exception to log - * @param message the message - * @param args the formatting arguments - * @see #log(SentryLevel, String, Throwable) - */ - static void logIfNotNull( - ILogger logger, SentryLevel level, Throwable throwable, String message, Object... args) { - if (logger != null) { - logger.log(level, throwable, message, args); - } - } - /** * Logs a message with the specified level, message and optional arguments. * diff --git a/sentry-core/src/main/java/io/sentry/core/MainEventProcessor.java b/sentry-core/src/main/java/io/sentry/core/MainEventProcessor.java index bbf59eac6..7f0c1226f 100644 --- a/sentry-core/src/main/java/io/sentry/core/MainEventProcessor.java +++ b/sentry-core/src/main/java/io/sentry/core/MainEventProcessor.java @@ -1,7 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; - import io.sentry.core.hints.Cached; import io.sentry.core.util.Objects; import org.jetbrains.annotations.ApiStatus; @@ -50,11 +48,12 @@ public SentryEvent process(SentryEvent event, @Nullable Object hint) { if (!(hint instanceof Cached)) { processNonCachedEvent(event); } else { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Event was cached so not applying data relevant to the current app execution/version: %s", - event.getEventId()); + options + .getLogger() + .log( + SentryLevel.DEBUG, + "Event was cached so not applying data relevant to the current app execution/version: %s", + event.getEventId()); } return event; diff --git a/sentry-core/src/main/java/io/sentry/core/SendCachedEvent.java b/sentry-core/src/main/java/io/sentry/core/SendCachedEvent.java index 665374fa5..2cd352f00 100644 --- a/sentry-core/src/main/java/io/sentry/core/SendCachedEvent.java +++ b/sentry-core/src/main/java/io/sentry/core/SendCachedEvent.java @@ -1,6 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; import static io.sentry.core.SentryLevel.ERROR; import io.sentry.core.cache.DiskCache; @@ -19,15 +18,15 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; final class SendCachedEvent extends DirectoryProcessor { private static final Charset UTF_8 = Charset.forName("UTF-8"); private final ISerializer serializer; private final IHub hub; - private final ILogger logger; + private final @NotNull ILogger logger; - SendCachedEvent(@NotNull ISerializer serializer, @NotNull IHub hub, @NotNull ILogger logger) { + SendCachedEvent( + @NotNull ISerializer serializer, @NotNull IHub hub, final @NotNull ILogger logger) { super(logger); this.serializer = Objects.requireNonNull(serializer, "Serializer is required."); this.hub = Objects.requireNonNull(hub, "Hub is required."); @@ -37,19 +36,17 @@ final class SendCachedEvent extends DirectoryProcessor { @Override protected void processFile(@NotNull File file) { if (!file.isFile()) { - logIfNotNull(logger, SentryLevel.DEBUG, "'%s' is not a file.", file.getAbsolutePath()); + logger.log(SentryLevel.DEBUG, "'%s' is not a file.", file.getAbsolutePath()); return; } if (!isRelevantFileName(file.getName())) { - logIfNotNull( - logger, SentryLevel.DEBUG, "File '%s' doesn't match extension expected.", file.getName()); + logger.log(SentryLevel.DEBUG, "File '%s' doesn't match extension expected.", file.getName()); return; } if (!file.getParentFile().canWrite()) { - logIfNotNull( - logger, + logger.log( SentryLevel.WARNING, "File '%s' cannot be delete so it will not be processed.", file.getName()); @@ -65,30 +62,24 @@ protected void processFile(@NotNull File file) { SentryEvent event = serializer.deserializeEvent(reader); hub.captureEvent(event, hint); if (!hint.waitFlush()) { - logIfNotNull( - logger, - SentryLevel.WARNING, - "Timed out waiting for event submission: %s", - event.getEventId()); + logger.log( + SentryLevel.WARNING, "Timed out waiting for event submission: %s", event.getEventId()); } } catch (FileNotFoundException e) { - logIfNotNull(logger, SentryLevel.ERROR, "File '%s' cannot be found.", file.getName(), e); + logger.log(SentryLevel.ERROR, "File '%s' cannot be found.", file.getName(), e); } catch (IOException e) { - logIfNotNull(logger, SentryLevel.ERROR, "I/O on file '%s' failed.", file.getName(), e); + logger.log(SentryLevel.ERROR, "I/O on file '%s' failed.", file.getName(), e); } catch (Exception e) { - logIfNotNull(logger, SentryLevel.ERROR, "Failed to capture cached event.", file.getName(), e); + logger.log(SentryLevel.ERROR, "Failed to capture cached event.", file.getName(), e); hint.setRetry(false); } finally { // Unless the transport marked this to be retried, it'll be deleted. if (!hint.getRetry()) { safeDelete(file, "after trying to capture it"); - logIfNotNull(logger, SentryLevel.DEBUG, "Deleted file %s.", file.getName()); + logger.log(SentryLevel.DEBUG, "Deleted file %s.", file.getName()); } else { - logIfNotNull( - logger, - SentryLevel.INFO, - "File not deleted since retry was marked. %s.", - file.getName()); + logger.log( + SentryLevel.INFO, "File not deleted since retry was marked. %s.", file.getName()); } } } @@ -102,12 +93,8 @@ private void safeDelete(File file, String errorMessageSuffix) { try { file.delete(); } catch (Exception e) { - logIfNotNull( - logger, - SentryLevel.ERROR, - "Failed to delete '%s' " + errorMessageSuffix, - file.getName(), - e); + logger.log( + SentryLevel.ERROR, "Failed to delete '%s' " + errorMessageSuffix, file.getName(), e); } } @@ -115,9 +102,9 @@ private static final class SendCachedEventHint implements Cached, Retryable, Sub boolean retry = false; private final CountDownLatch latch; private final long timeoutMills; - private final @Nullable ILogger logger; + private final @NotNull ILogger logger; - SendCachedEventHint(final long timeoutMills, final @Nullable ILogger logger) { + SendCachedEventHint(final long timeoutMills, final @NotNull ILogger logger) { this.timeoutMills = timeoutMills; this.latch = new CountDownLatch(1); this.logger = logger; @@ -137,7 +124,7 @@ boolean waitFlush() { try { return latch.await(timeoutMills, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - logIfNotNull(logger, ERROR, "Exception while awaiting on lock.", e); + logger.log(ERROR, "Exception while awaiting on lock.", e); } return false; } diff --git a/sentry-core/src/main/java/io/sentry/core/SendCachedEventFireAndForgetIntegration.java b/sentry-core/src/main/java/io/sentry/core/SendCachedEventFireAndForgetIntegration.java index eedb83c5c..8dd995cc5 100644 --- a/sentry-core/src/main/java/io/sentry/core/SendCachedEventFireAndForgetIntegration.java +++ b/sentry-core/src/main/java/io/sentry/core/SendCachedEventFireAndForgetIntegration.java @@ -1,7 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; - import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.jetbrains.annotations.NotNull; @@ -27,8 +25,7 @@ interface SendFireAndForgetFactory { public void register(@NotNull IHub hub, @NotNull SentryOptions options) { String cachedDir = options.getCacheDirPath(); if (cachedDir == null) { - logIfNotNull( - options.getLogger(), SentryLevel.WARNING, "No cache dir path is defined in options."); + options.getLogger().log(SentryLevel.WARNING, "No cache dir path is defined in options."); return; } @@ -40,31 +37,21 @@ public void register(@NotNull IHub hub, @NotNull SentryOptions options) { () -> { try { sender.send(); - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Finished processing cached files from %s", - cachedDir); + options + .getLogger() + .log(SentryLevel.DEBUG, "Finished processing cached files from %s", cachedDir); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "Failed trying to send cached events.", - e); + options.getLogger().log(SentryLevel.ERROR, "Failed trying to send cached events.", e); } }); - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Scheduled sending cached files from %s", - cachedDir); + options + .getLogger() + .log(SentryLevel.DEBUG, "Scheduled sending cached files from %s", cachedDir); es.shutdown(); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "Failed to call the executor. Cached events will not be sent", - e); + options + .getLogger() + .log(SentryLevel.ERROR, "Failed to call the executor. Cached events will not be sent", e); } } } diff --git a/sentry-core/src/main/java/io/sentry/core/SentryClient.java b/sentry-core/src/main/java/io/sentry/core/SentryClient.java index bb571a6b5..be6d0943d 100644 --- a/sentry-core/src/main/java/io/sentry/core/SentryClient.java +++ b/sentry-core/src/main/java/io/sentry/core/SentryClient.java @@ -1,7 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; - import io.sentry.core.cache.DiskCache; import io.sentry.core.cache.IEventCache; import io.sentry.core.hints.Cached; @@ -65,15 +63,16 @@ public SentryClient(SentryOptions options, @Nullable Connection connection) { @Override public SentryId captureEvent(SentryEvent event, @Nullable Scope scope, @Nullable Object hint) { if (!sample()) { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Event %s was dropped due to sampling decision.", - event.getEventId()); + options + .getLogger() + .log( + SentryLevel.DEBUG, + "Event %s was dropped due to sampling decision.", + event.getEventId()); return SentryId.EMPTY_ID; } - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "Capturing event: %s", event.getEventId()); + options.getLogger().log(SentryLevel.DEBUG, "Capturing event: %s", event.getEventId()); if (!(hint instanceof Cached)) { // Event has already passed through here before it was cached @@ -86,11 +85,9 @@ public SentryId captureEvent(SentryEvent event, @Nullable Scope scope, @Nullable return SentryId.EMPTY_ID; } } else { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Event was cached so not applying scope: %s", - event.getEventId()); + options + .getLogger() + .log(SentryLevel.DEBUG, "Event was cached so not applying scope: %s", event.getEventId()); } for (EventProcessor processor : options.getEventProcessors()) { @@ -107,11 +104,9 @@ public SentryId captureEvent(SentryEvent event, @Nullable Scope scope, @Nullable try { connection.send(event, hint); } catch (IOException e) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Capturing event " + event.getEventId() + " failed.", - e); + options + .getLogger() + .log(SentryLevel.WARNING, "Capturing event " + event.getEventId() + " failed.", e); } return event.getEventId(); @@ -173,11 +168,12 @@ private SentryEvent executeBeforeSend(SentryEvent event, @Nullable Object hint) try { event = beforeSend.execute(event, hint); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "The BeforeSend callback threw an exception. It will be added as breadcrumb and continue.", - e); + options + .getLogger() + .log( + SentryLevel.ERROR, + "The BeforeSend callback threw an exception. It will be added as breadcrumb and continue.", + e); Breadcrumb breadcrumb = new Breadcrumb(); breadcrumb.setMessage("BeforeSend callback failed."); @@ -197,17 +193,15 @@ private SentryEvent executeBeforeSend(SentryEvent event, @Nullable Object hint) @Override public void close() { - logIfNotNull(options.getLogger(), SentryLevel.INFO, "Closing SDK."); + options.getLogger().log(SentryLevel.INFO, "Closing SDK."); try { flush(options.getShutdownTimeout()); connection.close(); } catch (IOException e) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Failed to close the connection to the Sentry Server.", - e); + options + .getLogger() + .log(SentryLevel.WARNING, "Failed to close the connection to the Sentry Server.", e); } enabled = false; } diff --git a/sentry-core/src/main/java/io/sentry/core/SentryOptions.java b/sentry-core/src/main/java/io/sentry/core/SentryOptions.java index f806bcb81..9b2c0d927 100644 --- a/sentry-core/src/main/java/io/sentry/core/SentryOptions.java +++ b/sentry-core/src/main/java/io/sentry/core/SentryOptions.java @@ -1,7 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; - import com.jakewharton.nopen.annotation.Open; import io.sentry.core.transport.ITransport; import io.sentry.core.transport.ITransportGate; @@ -78,19 +76,16 @@ public void setDebug(boolean debug) { return logger; } - public void setLogger(@Nullable ILogger logger) { - this.logger = logger == null ? NoOpLogger.getInstance() : new DiagnosticLogger(this, logger); + public void setLogger(final @Nullable ILogger logger) { + this.logger = (logger == null) ? NoOpLogger.getInstance() : new DiagnosticLogger(this, logger); } public @NotNull SentryLevel getDiagnosticLevel() { return diagnosticLevel; } - public void setDiagnosticLevel(@Nullable SentryLevel diagnosticLevel) { - if (diagnosticLevel == null) { - diagnosticLevel = DEFAULT_DIAGNOSTIC_LEVEL; - } - this.diagnosticLevel = diagnosticLevel; + public void setDiagnosticLevel(@Nullable final SentryLevel diagnosticLevel) { + this.diagnosticLevel = (diagnosticLevel != null) ? diagnosticLevel : DEFAULT_DIAGNOSTIC_LEVEL; } public @NotNull ISerializer getSerializer() { @@ -292,10 +287,11 @@ public SentryOptions() { File cacheDir = new File(options.getCacheDirPath()); return () -> sender.processDirectory(cacheDir); } else { - logIfNotNull( - getLogger(), - SentryLevel.WARNING, - "No cache dir path is defined in options, discarding SendCachedEvent."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "No cache dir path is defined in options, discarding SendCachedEvent."); return null; } })); @@ -310,10 +306,11 @@ public SentryOptions() { File outbox = new File(options.getOutboxPath()); return () -> envelopeSender.processDirectory(outbox); } else { - logIfNotNull( - getLogger(), - SentryLevel.WARNING, - "No outbox dir path is defined in options, discarding EnvelopeSender."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "No outbox dir path is defined in options, discarding EnvelopeSender."); return null; } })); diff --git a/sentry-core/src/main/java/io/sentry/core/UncaughtExceptionHandlerIntegration.java b/sentry-core/src/main/java/io/sentry/core/UncaughtExceptionHandlerIntegration.java index 71903fd81..0e9f29809 100644 --- a/sentry-core/src/main/java/io/sentry/core/UncaughtExceptionHandlerIntegration.java +++ b/sentry-core/src/main/java/io/sentry/core/UncaughtExceptionHandlerIntegration.java @@ -1,6 +1,5 @@ package io.sentry.core; -import static io.sentry.core.ILogger.logIfNotNull; import static io.sentry.core.SentryLevel.ERROR; import io.sentry.core.exception.ExceptionMechanismException; @@ -11,7 +10,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; /** @@ -40,10 +38,11 @@ final class UncaughtExceptionHandlerIntegration @Override public void register(IHub hub, SentryOptions options) { if (registered) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - "Attempt to register a UncaughtExceptionHandlerIntegration twice."); + options + .getLogger() + .log( + SentryLevel.ERROR, + "Attempt to register a UncaughtExceptionHandlerIntegration twice."); return; } registered = true; @@ -53,10 +52,13 @@ public void register(IHub hub, SentryOptions options) { Thread.UncaughtExceptionHandler currentHandler = threadAdapter.getDefaultUncaughtExceptionHandler(); if (currentHandler != null) { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "default UncaughtExceptionHandler class='" + currentHandler.getClass().getName() + "'"); + options + .getLogger() + .log( + SentryLevel.DEBUG, + "default UncaughtExceptionHandler class='" + + currentHandler.getClass().getName() + + "'"); defaultExceptionHandler = currentHandler; } @@ -65,7 +67,7 @@ public void register(IHub hub, SentryOptions options) { @Override public void uncaughtException(Thread thread, Throwable thrown) { - logIfNotNull(options.getLogger(), SentryLevel.INFO, "Uncaught exception received."); + options.getLogger().log(SentryLevel.INFO, "Uncaught exception received."); try { UncaughtExceptionHint hint = @@ -76,20 +78,19 @@ public void uncaughtException(Thread thread, Throwable thrown) { this.hub.captureEvent(event, hint); // Block until the event is flushed to disk if (!hint.waitFlush()) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Timed out waiting to flush event to disk before crashing. Event: %s", - event.getEventId()); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Timed out waiting to flush event to disk before crashing. Event: %s", + event.getEventId()); } } catch (Exception e) { - logIfNotNull( - options.getLogger(), SentryLevel.ERROR, "Error sending uncaught exception to Sentry.", e); + options.getLogger().log(SentryLevel.ERROR, "Error sending uncaught exception to Sentry.", e); } if (defaultExceptionHandler != null) { - logIfNotNull( - options.getLogger(), SentryLevel.INFO, "Invoking inner uncaught exception handler."); + options.getLogger().log(SentryLevel.INFO, "Invoking inner uncaught exception handler."); defaultExceptionHandler.uncaughtException(thread, thrown); } } @@ -115,9 +116,9 @@ private static final class UncaughtExceptionHint implements DiskFlushNotificatio private final CountDownLatch latch; private final long timeoutMills; - private final @Nullable ILogger logger; + private final @NotNull ILogger logger; - UncaughtExceptionHint(final long timeoutMills, final @Nullable ILogger logger) { + UncaughtExceptionHint(final long timeoutMills, final @NotNull ILogger logger) { this.timeoutMills = timeoutMills; this.latch = new CountDownLatch(1); this.logger = logger; @@ -127,8 +128,7 @@ boolean waitFlush() { try { return latch.await(timeoutMills, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - logIfNotNull( - logger, ERROR, "Exception while awaiting for flush in UncaughtExceptionHint", e); + logger.log(ERROR, "Exception while awaiting for flush in UncaughtExceptionHint", e); } return false; } diff --git a/sentry-core/src/main/java/io/sentry/core/cache/DiskCache.java b/sentry-core/src/main/java/io/sentry/core/cache/DiskCache.java index 7275db708..35864c5f5 100644 --- a/sentry-core/src/main/java/io/sentry/core/cache/DiskCache.java +++ b/sentry-core/src/main/java/io/sentry/core/cache/DiskCache.java @@ -1,6 +1,5 @@ package io.sentry.core.cache; -import static io.sentry.core.ILogger.logIfNotNull; import static io.sentry.core.SentryLevel.DEBUG; import static io.sentry.core.SentryLevel.ERROR; import static io.sentry.core.SentryLevel.WARNING; @@ -55,39 +54,37 @@ public DiskCache(SentryOptions options) { @Override public void store(SentryEvent event) { if (getNumberOfStoredEvents() >= maxSize) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Disk cache full (respecting maxSize). Not storing event {}", - event); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Disk cache full (respecting maxSize). Not storing event {}", + event); return; } File eventFile = getEventFile(event); if (eventFile.exists()) { - logIfNotNull( - options.getLogger(), - WARNING, - "Not adding Event to offline storage because it already exists: %s", - eventFile.getAbsolutePath()); + options + .getLogger() + .log( + WARNING, + "Not adding Event to offline storage because it already exists: %s", + eventFile.getAbsolutePath()); return; } else { - logIfNotNull( - options.getLogger(), - DEBUG, - "Adding Event to offline storage: %s", - eventFile.getAbsolutePath()); + options + .getLogger() + .log(DEBUG, "Adding Event to offline storage: %s", eventFile.getAbsolutePath()); } try (FileOutputStream fileOutputStream = new FileOutputStream(eventFile); Writer wrt = new OutputStreamWriter(fileOutputStream, UTF8)) { serializer.serialize(event, wrt); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - ERROR, - "Error writing Event to offline storage: %s", - event.getEventId()); + options + .getLogger() + .log(ERROR, "Error writing Event to offline storage: %s", event.getEventId()); } } @@ -95,19 +92,15 @@ public void store(SentryEvent event) { public void discard(SentryEvent event) { File eventFile = getEventFile(event); if (eventFile.exists()) { - logIfNotNull( - options.getLogger(), - DEBUG, - "Discarding event from cache: %s", - eventFile.getAbsolutePath()); + options + .getLogger() + .log(DEBUG, "Discarding event from cache: %s", eventFile.getAbsolutePath()); if (!eventFile.delete()) { - logIfNotNull( - options.getLogger(), ERROR, "Failed to delete Event: %s", eventFile.getAbsolutePath()); + options.getLogger().log(ERROR, "Failed to delete Event: %s", eventFile.getAbsolutePath()); } } else { - logIfNotNull( - options.getLogger(), DEBUG, "Event was not cached: %s", eventFile.getAbsolutePath()); + options.getLogger().log(DEBUG, "Event was not cached: %s", eventFile.getAbsolutePath()); } } @@ -117,11 +110,12 @@ private int getNumberOfStoredEvents() { private boolean isDirectoryValid() { if (!directory.isDirectory() || !directory.canWrite() || !directory.canRead()) { - logIfNotNull( - options.getLogger(), - ERROR, - "The directory for caching Sentry events is inaccessible.: %s", - directory.getAbsolutePath()); + options + .getLogger() + .log( + ERROR, + "The directory for caching Sentry events is inaccessible.: %s", + directory.getAbsolutePath()); return false; } return true; @@ -143,17 +137,19 @@ private File getEventFile(SentryEvent event) { ret.add(serializer.deserializeEvent(rdr)); } catch (FileNotFoundException e) { - logIfNotNull( - options.getLogger(), - DEBUG, - "Event file '%s' disappeared while converting all cached files to events.", - f.getAbsolutePath()); + options + .getLogger() + .log( + DEBUG, + "Event file '%s' disappeared while converting all cached files to events.", + f.getAbsolutePath()); } catch (IOException e) { - logIfNotNull( - options.getLogger(), - ERROR, - format("Error while reading cached event from file %s", f.getAbsolutePath()), - e); + options + .getLogger() + .log( + ERROR, + format("Error while reading cached event from file %s", f.getAbsolutePath()), + e); } } diff --git a/sentry-core/src/main/java/io/sentry/core/transport/AsyncConnection.java b/sentry-core/src/main/java/io/sentry/core/transport/AsyncConnection.java index 7c5c644e5..a510b2bab 100644 --- a/sentry-core/src/main/java/io/sentry/core/transport/AsyncConnection.java +++ b/sentry-core/src/main/java/io/sentry/core/transport/AsyncConnection.java @@ -1,7 +1,5 @@ package io.sentry.core.transport; -import static io.sentry.core.ILogger.logIfNotNull; - import io.sentry.core.SentryEvent; import io.sentry.core.SentryLevel; import io.sentry.core.SentryOptions; @@ -101,22 +99,22 @@ public void send(SentryEvent event, @Nullable Object hint) throws IOException { @Override public void close() throws IOException { executor.shutdown(); - logIfNotNull(options.getLogger(), SentryLevel.DEBUG, "Shutting down"); + options.getLogger().log(SentryLevel.DEBUG, "Shutting down"); try { if (!executor.awaitTermination(1, TimeUnit.MINUTES)) { - logIfNotNull( - options.getLogger(), - SentryLevel.WARNING, - "Failed to shutdown the async connection async sender within 1 minute. Trying to force it now."); + options + .getLogger() + .log( + SentryLevel.WARNING, + "Failed to shutdown the async connection async sender within 1 minute. Trying to force it now."); executor.shutdownNow(); } transport.close(); } catch (InterruptedException e) { // ok, just give up then... - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Thread interrupted while closing the connection."); + options + .getLogger() + .log(SentryLevel.DEBUG, "Thread interrupted while closing the connection."); Thread.currentThread().interrupt(); } } @@ -150,23 +148,17 @@ public void run() { TransportResult result = this.failedResult; try { result = flush(); - logIfNotNull( - options.getLogger(), SentryLevel.DEBUG, "Event flushed: %s", event.getEventId()); + options.getLogger().log(SentryLevel.DEBUG, "Event flushed: %s", event.getEventId()); } catch (Exception e) { - logIfNotNull( - options.getLogger(), - SentryLevel.ERROR, - e, - "Event submission failed: %s", - event.getEventId()); + options + .getLogger() + .log(SentryLevel.ERROR, e, "Event submission failed: %s", event.getEventId()); throw e; } finally { if (hint instanceof SubmissionResult) { - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Marking event submission result: %s", - result.isSuccess()); + options + .getLogger() + .log(SentryLevel.DEBUG, "Marking event submission result: %s", result.isSuccess()); ((SubmissionResult) hint).setResult(result.isSuccess()); } } @@ -177,11 +169,9 @@ private TransportResult flush() { eventCache.store(event); if (hint instanceof DiskFlushNotification) { ((DiskFlushNotification) hint).markFlushed(); - logIfNotNull( - options.getLogger(), - SentryLevel.DEBUG, - "Disk flush event fired: %s", - event.getEventId()); + options + .getLogger() + .log(SentryLevel.DEBUG, "Disk flush event fired: %s", event.getEventId()); } if (transportGate.isSendingAllowed()) { diff --git a/sentry-core/src/main/java/io/sentry/core/transport/HttpTransport.java b/sentry-core/src/main/java/io/sentry/core/transport/HttpTransport.java index b9cb32109..c8ccb3213 100644 --- a/sentry-core/src/main/java/io/sentry/core/transport/HttpTransport.java +++ b/sentry-core/src/main/java/io/sentry/core/transport/HttpTransport.java @@ -1,6 +1,5 @@ package io.sentry.core.transport; -import static io.sentry.core.ILogger.logIfNotNull; import static io.sentry.core.SentryLevel.*; import com.jakewharton.nopen.annotation.Open; @@ -103,7 +102,7 @@ public TransportResult send(SentryEvent event) throws IOException { // need to also close the input stream of the connection connection.getInputStream().close(); - logIfNotNull(options.getLogger(), DEBUG, "Event sent %s successfully.", event.getEventId()); + options.getLogger().log(DEBUG, "Event sent %s successfully.", event.getEventId()); return TransportResult.success(); } catch (IOException e) { long retryAfterMs = 1000; // the default is 1s @@ -122,23 +121,22 @@ public TransportResult send(SentryEvent event) throws IOException { responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) { if (options.isDebug()) { - logIfNotNull( - options.getLogger(), - DEBUG, - "Event '" - + event.getEventId() - + "' was rejected by the Sentry server due to a filter."); + options + .getLogger() + .log( + DEBUG, + "Event '" + + event.getEventId() + + "' was rejected by the Sentry server due to a filter."); } } logErrorInPayload(connection); return TransportResult.error(retryAfterMs, responseCode); } catch (IOException responseCodeException) { // this should not stop us from continuing. We'll just use -1 as response code. - logIfNotNull( - options.getLogger(), - WARNING, - "Failed to obtain response code while analyzing event send failure.", - e); + options + .getLogger() + .log(WARNING, "Failed to obtain response code while analyzing event send failure.", e); } logErrorInPayload(connection); @@ -159,7 +157,7 @@ private void logErrorInPayload(HttpURLConnection connection) { errorMessage = "An exception occurred while submitting the event to the Sentry server."; } - logIfNotNull(options.getLogger(), DEBUG, errorMessage); + options.getLogger().log(DEBUG, errorMessage); } } @@ -178,10 +176,11 @@ private String getErrorMessageFromStream(InputStream errorStream) { first = false; } } catch (Exception e2) { - logIfNotNull( - options.getLogger(), - ERROR, - "Exception while reading the error message from the connection: " + e2.getMessage()); + options + .getLogger() + .log( + ERROR, + "Exception while reading the error message from the connection: " + e2.getMessage()); } return sb.toString(); } diff --git a/sentry-core/src/test/java/io/sentry/core/EnvelopeSenderTest.kt b/sentry-core/src/test/java/io/sentry/core/EnvelopeSenderTest.kt index bca7671e3..f751fe77d 100644 --- a/sentry-core/src/test/java/io/sentry/core/EnvelopeSenderTest.kt +++ b/sentry-core/src/test/java/io/sentry/core/EnvelopeSenderTest.kt @@ -34,7 +34,7 @@ class EnvelopeSenderTest { } fun getSut(): EnvelopeSender { - return EnvelopeSender(hub, envelopeReader, serializer, logger) + return EnvelopeSender(hub, envelopeReader, serializer, logger!!) } } @@ -120,6 +120,7 @@ class EnvelopeSenderTest { @Test fun `when logger is null, ctor throws`() { fixture.logger = null - assertFailsWith { fixture.getSut() } + // TODO: check how to assert IllegalArgumentException if param is @NotNull and you are calling from kotlin + assertFailsWith { fixture.getSut() } } } diff --git a/sentry-sample/src/main/AndroidManifest.xml b/sentry-sample/src/main/AndroidManifest.xml index a2a1656cc..5c6d2b0df 100644 --- a/sentry-sample/src/main/AndroidManifest.xml +++ b/sentry-sample/src/main/AndroidManifest.xml @@ -31,6 +31,9 @@ + + +