Skip to content

Commit 460594f

Browse files
Introduce fatal SDK logger (#4288)
* Check for mixed SDK versions * Format code * format + api * Init noops if mixed versions detected * Add BuildConfig * config entries for agentless module sdk names * Add MANIFEST.MF for JARs * Throw on startup; use manifests for backend; reuse code for otel * Format code * Format code * changelog * api * changelog * Remove duplicate addPackage calls * remove test assertion for package * Introduce fatal SDK logger * Format code * changelog * api --------- Co-authored-by: Sentry Github Bot <bot+github-bot@sentry.io>
1 parent 98fbe0e commit 460594f

File tree

9 files changed

+114
-2
lines changed

9 files changed

+114
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
- Increase http timeouts from 5s to 30s to have a better chance of events being delivered without retry ([#4276](https://github.com/getsentry/sentry-java/pull/4276))
1717
- Add `MANIFEST.MF` to Sentry JARs ([#4272](https://github.com/getsentry/sentry-java/pull/4272))
1818
- Retain baggage sample rate/rand values as doubles ([#4279](https://github.com/getsentry/sentry-java/pull/4279))
19+
- Introduce fatal SDK logger ([#4288](https://github.com/getsentry/sentry-java/pull/4288))
20+
- We use this to print out messages when there is a problem that prevents the SDK from working correctly.
21+
- One example for this is when the SDK has been configured with mixed dependency versions where we print out details, which module and version are affected.
1922

2023
### Fixes
2124

sentry-android-core/api/sentry-android-core.api

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ public final class io/sentry/android/core/AndroidDateUtils {
6363
public static fun getCurrentSentryDateTime ()Lio/sentry/SentryDate;
6464
}
6565

66+
public final class io/sentry/android/core/AndroidFatalLogger : io/sentry/ILogger {
67+
public fun <init> ()V
68+
public fun <init> (Ljava/lang/String;)V
69+
public fun isEnabled (Lio/sentry/SentryLevel;)Z
70+
public fun log (Lio/sentry/SentryLevel;Ljava/lang/String;Ljava/lang/Throwable;)V
71+
public fun log (Lio/sentry/SentryLevel;Ljava/lang/String;[Ljava/lang/Object;)V
72+
public fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
73+
}
74+
6675
public final class io/sentry/android/core/AndroidLogger : io/sentry/ILogger {
6776
public fun <init> ()V
6877
public fun <init> (Ljava/lang/String;)V
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.sentry.android.core;
2+
3+
import android.util.Log;
4+
import io.sentry.ILogger;
5+
import io.sentry.SentryLevel;
6+
import org.jetbrains.annotations.ApiStatus;
7+
import org.jetbrains.annotations.NotNull;
8+
import org.jetbrains.annotations.Nullable;
9+
10+
@ApiStatus.Internal
11+
public final class AndroidFatalLogger implements ILogger {
12+
13+
private final @NotNull String tag;
14+
15+
public AndroidFatalLogger() {
16+
this("Sentry");
17+
}
18+
19+
public AndroidFatalLogger(final @NotNull String tag) {
20+
this.tag = tag;
21+
}
22+
23+
@SuppressWarnings("AnnotateFormatMethod")
24+
@Override
25+
public void log(
26+
final @NotNull SentryLevel level,
27+
final @NotNull String message,
28+
final @Nullable Object... args) {
29+
if (args == null || args.length == 0) {
30+
Log.println(toLogcatLevel(level), tag, message);
31+
} else {
32+
Log.println(toLogcatLevel(level), tag, String.format(message, args));
33+
}
34+
}
35+
36+
@SuppressWarnings("AnnotateFormatMethod")
37+
@Override
38+
public void log(
39+
final @NotNull SentryLevel level,
40+
final @Nullable Throwable throwable,
41+
final @NotNull String message,
42+
final @Nullable Object... args) {
43+
if (args == null || args.length == 0) {
44+
log(level, message, throwable);
45+
} else {
46+
log(level, String.format(message, args), throwable);
47+
}
48+
}
49+
50+
@Override
51+
public void log(
52+
final @NotNull SentryLevel level,
53+
final @NotNull String message,
54+
final @Nullable Throwable throwable) {
55+
Log.wtf(tag, message, throwable);
56+
}
57+
58+
@Override
59+
public boolean isEnabled(@Nullable SentryLevel level) {
60+
return true;
61+
}
62+
63+
private int toLogcatLevel(final @NotNull SentryLevel sentryLevel) {
64+
return Log.ASSERT;
65+
}
66+
}

sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static void loadDefaultAndMetadataOptions(
110110

111111
// Firstly set the logger, if `debug=true` configured, logging can start asap.
112112
options.setLogger(logger);
113+
options.setFatalLogger(new AndroidFatalLogger());
113114

114115
options.setDefaultScopeType(ScopeType.CURRENT);
115116
options.setOpenTelemetryMode(SentryOpenTelemetryMode.OFF);

sentry/api/sentry.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3057,6 +3057,7 @@ public class io/sentry/SentryOptions {
30573057
public fun getEventProcessors ()Ljava/util/List;
30583058
public fun getExecutorService ()Lio/sentry/ISentryExecutorService;
30593059
public fun getExperimental ()Lio/sentry/ExperimentalOptions;
3060+
public fun getFatalLogger ()Lio/sentry/ILogger;
30603061
public fun getFlushTimeoutMillis ()J
30613062
public fun getFullyDisplayedReporter ()Lio/sentry/FullyDisplayedReporter;
30623063
public fun getGestureTargetLocators ()Ljava/util/List;
@@ -3196,6 +3197,7 @@ public class io/sentry/SentryOptions {
31963197
public fun setEnvelopeReader (Lio/sentry/IEnvelopeReader;)V
31973198
public fun setEnvironment (Ljava/lang/String;)V
31983199
public fun setExecutorService (Lio/sentry/ISentryExecutorService;)V
3200+
public fun setFatalLogger (Lio/sentry/ILogger;)V
31993201
public fun setFlushTimeoutMillis (J)V
32003202
public fun setForceInit (Z)V
32013203
public fun setFullyDisplayedReporter (Lio/sentry/FullyDisplayedReporter;)V

sentry/src/main/java/io/sentry/DefaultVersionDetector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public DefaultVersionDetector(final @NotNull SentryOptions options) {
1414

1515
@Override
1616
public boolean checkForMixedVersions() {
17-
return SentryIntegrationPackageStorage.getInstance().checkForMixedVersions(options.getLogger());
17+
return SentryIntegrationPackageStorage.getInstance()
18+
.checkForMixedVersions(options.getFatalLogger());
1819
}
1920
}

sentry/src/main/java/io/sentry/ManifestVersionDetector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public ManifestVersionDetector(final @NotNull SentryOptions options) {
1616
@Override
1717
public boolean checkForMixedVersions() {
1818
ManifestVersionReader.getInstance().readManifestFiles();
19-
return SentryIntegrationPackageStorage.getInstance().checkForMixedVersions(options.getLogger());
19+
return SentryIntegrationPackageStorage.getInstance()
20+
.checkForMixedVersions(options.getFatalLogger());
2021
}
2122
}

sentry/src/main/java/io/sentry/Sentry.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ private static void init(final @NotNull SentryOptions options, final boolean glo
292292
.getLogger()
293293
.log(SentryLevel.INFO, "GlobalHubMode: '%s'", String.valueOf(globalHubModeToUse));
294294
Sentry.globalHubMode = globalHubModeToUse;
295+
initFatalLogger(options);
295296
final boolean shouldInit =
296297
InitUtil.shouldInit(globalScope.getOptions(), options, isEnabled());
297298
if (shouldInit) {
@@ -392,6 +393,12 @@ private static void initLogger(final @NotNull SentryOptions options) {
392393
}
393394
}
394395

396+
private static void initFatalLogger(final @NotNull SentryOptions options) {
397+
if (options.getFatalLogger() instanceof NoOpLogger) {
398+
options.setFatalLogger(new SystemOutLogger());
399+
}
400+
}
401+
395402
private static void initScopesStorage(SentryOptions options) {
396403
getScopesStorage().close();
397404
if (SentryOpenTelemetryMode.OFF == options.getOpenTelemetryMode()) {

sentry/src/main/java/io/sentry/SentryOptions.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ public class SentryOptions {
127127
/** Logger interface to log useful debugging information if debug is enabled */
128128
private @NotNull ILogger logger = NoOpLogger.getInstance();
129129

130+
@ApiStatus.Experimental private @NotNull ILogger fatalLogger = NoOpLogger.getInstance();
131+
130132
/** minimum LogLevel to be used if debug is enabled */
131133
private @NotNull SentryLevel diagnosticLevel = DEFAULT_DIAGNOSTIC_LEVEL;
132134

@@ -646,6 +648,26 @@ public void setLogger(final @Nullable ILogger logger) {
646648
this.logger = (logger == null) ? NoOpLogger.getInstance() : new DiagnosticLogger(this, logger);
647649
}
648650

651+
/**
652+
* Returns the Logger interface for logging important SDK messages
653+
*
654+
* @return the logger for fatal SDK messages
655+
*/
656+
@ApiStatus.Experimental
657+
public @NotNull ILogger getFatalLogger() {
658+
return fatalLogger;
659+
}
660+
661+
/**
662+
* Sets the Logger interface for important SDK messages. If null, logger will be NoOp
663+
*
664+
* @param logger the logger for fatal SDK messages
665+
*/
666+
@ApiStatus.Experimental
667+
public void setFatalLogger(final @Nullable ILogger logger) {
668+
this.fatalLogger = (logger == null) ? NoOpLogger.getInstance() : logger;
669+
}
670+
649671
/**
650672
* Returns the minimum LogLevel
651673
*

0 commit comments

Comments
 (0)