Skip to content

fix(logging): Reduce debug logs verbosity #4341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Fixes

- Fix TTFD measurement when API called too early ([#4297](https://github.com/getsentry/sentry-java/pull/4297))
- Reduce debug logs verbosity ([#4341](https://github.com/getsentry/sentry-java/pull/4341))
- Fix unregister `SystemEventsBroadcastReceiver` when entering background ([#4338](https://github.com/getsentry/sentry-java/pull/4338))
- This should reduce ANRs seen with this class in the stack trace for Android 14 and above

Expand Down
76 changes: 76 additions & 0 deletions scripts/toggle-codec-logs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/bash

# --- Functions ---

print_usage() {
echo "Usage: $0 [enable|disable]"
exit 1
}

# Check for adb
if ! command -v adb &> /dev/null; then
echo "❌ adb not found. Please install Android Platform Tools and ensure adb is in your PATH."
exit 1
fi

# Check for connected device
DEVICE_COUNT=$(adb devices | grep -w "device" | wc -l)
if [ "$DEVICE_COUNT" -eq 0 ]; then
echo "❌ No device connected. Please connect a device and enable USB debugging."
exit 1
fi

# --- Handle Argument ---

ACTION=$(echo "$1" | tr '[:upper:]' '[:lower:]')

case "$ACTION" in
enable)
echo "✅ Enabling native logs (DEBUG)..."
adb shell setprop log.tag.MPEG4Writer D
adb shell setprop log.tag.CCodec D
adb shell setprop log.tag.VQApply D
adb shell setprop log.tag.ColorUtils D
adb shell setprop log.tag.MediaCodec D
adb shell setprop log.tag.MediaCodecList D
adb shell setprop log.tag.MediaWriter D
adb shell setprop log.tag.CCodecConfig D
adb shell setprop log.tag.Codec2Client D
adb shell setprop log.tag.CCodecBufferChannel D
adb shell setprop log.tag.CodecProperties D
adb shell setprop log.tag.CodecSeeding D
adb shell setprop log.tag.C2Store D
adb shell setprop log.tag.C2NodeImpl D
adb shell setprop log.tag.GraphicBufferSource D
adb shell setprop log.tag.BufferQueueProducer D
adb shell setprop log.tag.ReflectedParamUpdater D
adb shell setprop log.tag.hw-BpHwBinder D
echo "✅ Logs ENABLED"
;;
disable)
echo "🚫 Disabling native logs (SILENT)..."
adb shell setprop log.tag.MPEG4Writer SILENT
adb shell setprop log.tag.CCodec SILENT
adb shell setprop log.tag.VQApply SILENT
adb shell setprop log.tag.ColorUtils SILENT
adb shell setprop log.tag.MediaCodec SILENT
adb shell setprop log.tag.MediaCodecList SILENT
adb shell setprop log.tag.MediaWriter SILENT
adb shell setprop log.tag.CCodecConfig SILENT
adb shell setprop log.tag.Codec2Client SILENT
adb shell setprop log.tag.CCodecBufferChannel SILENT
adb shell setprop log.tag.CodecProperties SILENT
adb shell setprop log.tag.CodecSeeding SILENT
adb shell setprop log.tag.C2Store SILENT
adb shell setprop log.tag.C2NodeImpl SILENT
adb shell setprop log.tag.GraphicBufferSource SILENT
adb shell setprop log.tag.BufferQueueProducer SILENT
adb shell setprop log.tag.ReflectedParamUpdater SILENT
adb shell setprop log.tag.hw-BpHwBinder SILENT
echo "🚫 Logs DISABLED"
;;
*)
echo "❓ Unknown or missing argument: '$1'"
print_usage
;;
esac
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ final class ManifestMetadataReader {

static final String REPLAYS_MASK_ALL_IMAGES = "io.sentry.session-replay.mask-all-images";

static final String REPLAYS_DEBUG = "io.sentry.session-replay.debug";

static final String FORCE_INIT = "io.sentry.force-init";

static final String MAX_BREADCRUMBS = "io.sentry.max-breadcrumbs";
Expand Down Expand Up @@ -452,6 +454,8 @@ static void applyMetadata(
.getSessionReplay()
.setMaskAllImages(readBool(metadata, logger, REPLAYS_MASK_ALL_IMAGES, true));

options.getSessionReplay().setDebug(readBool(metadata, logger, REPLAYS_DEBUG, false));

options.setIgnoredErrors(readList(metadata, logger, IGNORED_ERRORS));

final @Nullable List<String> includes = readList(metadata, logger, IN_APP_INCLUDES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public AssetsDebugMetaLoader(final @NotNull Context context, final @NotNull ILog
properties.load(is);
return Collections.singletonList(properties);
} catch (FileNotFoundException e) {
logger.log(SentryLevel.INFO, e, "%s file was not found.", DEBUG_META_PROPERTIES_FILENAME);
logger.log(SentryLevel.INFO, "%s file was not found.", DEBUG_META_PROPERTIES_FILENAME);
} catch (IOException e) {
logger.log(SentryLevel.ERROR, "Error getting Proguard UUIDs.", e);
} catch (RuntimeException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ public class ReplayIntegration(
} catch (e: Throwable) {
options.logger.log(
INFO,
"ComponentCallbacks is not available, orientation changes won't be handled by Session replay",
e
"ComponentCallbacks is not available, orientation changes won't be handled by Session replay"
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ internal class ScreenshotRecorder(

fun capture() {
if (!isCapturing.get()) {
options.logger.log(DEBUG, "ScreenshotRecorder is paused, not capturing screenshot")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "ScreenshotRecorder is paused, not capturing screenshot")
}
return
}

if (!contentChanged.get() && lastCaptureSuccessful.get()) {
options.logger.log(DEBUG, "Content hasn't changed, repeating last known frame")

screenshotRecorderCallback?.onScreenshotRecorded(screenshot)
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,12 @@ internal class SessionCaptureStrategy(
}

override fun captureReplay(isTerminating: Boolean, onSegmentSent: (Date) -> Unit) {
options.logger.log(DEBUG, "Replay is already running in 'session' mode, not capturing for event")
if (options.sessionReplay.isDebug) {
options.logger.log(
DEBUG,
"Replay is already running in 'session' mode, not capturing for event"
)
}
this.isTerminating.set(isTerminating)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,13 @@ internal class SimpleVideoEncoder(
* Borrows heavily from https://bigflake.com/mediacodec/EncodeAndMuxTest.java.txt
*/
private fun drainCodec(endOfStream: Boolean) {
options.logger.log(DEBUG, "[Encoder]: drainCodec($endOfStream)")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: drainCodec($endOfStream)")
}
if (endOfStream) {
options.logger.log(DEBUG, "[Encoder]: sending EOS to encoder")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: sending EOS to encoder")
}
mediaCodec.signalEndOfInputStream()
}
var encoderOutputBuffers: Array<ByteBuffer?>? = mediaCodec.outputBuffers
Expand All @@ -193,7 +197,7 @@ internal class SimpleVideoEncoder(
// no output available yet
if (!endOfStream) {
break // out of while
} else {
} else if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: no output available, spinning to await EOS")
}
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
Expand All @@ -205,35 +209,48 @@ internal class SimpleVideoEncoder(
throw RuntimeException("format changed twice")
}
val newFormat: MediaFormat = mediaCodec.outputFormat
options.logger.log(DEBUG, "[Encoder]: encoder output format changed: $newFormat")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: encoder output format changed: $newFormat")
}

// now that we have the Magic Goodies, start the muxer
frameMuxer.start(newFormat)
} else if (encoderStatus < 0) {
options.logger.log(DEBUG, "[Encoder]: unexpected result from encoder.dequeueOutputBuffer: $encoderStatus")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: unexpected result from encoder.dequeueOutputBuffer: $encoderStatus")
}
// let's ignore it
} else {
val encodedData = encoderOutputBuffers?.get(encoderStatus)
?: throw RuntimeException("encoderOutputBuffer $encoderStatus was null")
if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG != 0) {
// The codec config data was pulled out and fed to the muxer when we got
// the INFO_OUTPUT_FORMAT_CHANGED status. Ignore it.
options.logger.log(DEBUG, "[Encoder]: ignoring BUFFER_FLAG_CODEC_CONFIG")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: ignoring BUFFER_FLAG_CODEC_CONFIG")
}
bufferInfo.size = 0
}
if (bufferInfo.size != 0) {
if (!frameMuxer.isStarted()) {
throw RuntimeException("muxer hasn't started")
}
frameMuxer.muxVideoFrame(encodedData, bufferInfo)
options.logger.log(DEBUG, "[Encoder]: sent ${bufferInfo.size} bytes to muxer")
if (options.sessionReplay.isDebug) {
options.logger.log(DEBUG, "[Encoder]: sent ${bufferInfo.size} bytes to muxer")
}
}
mediaCodec.releaseOutputBuffer(encoderStatus, false)
if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0) {
if (!endOfStream) {
options.logger.log(DEBUG, "[Encoder]: reached end of stream unexpectedly")
} else {
options.logger.log(DEBUG, "[Encoder]: end of stream reached")
if (options.sessionReplay.isDebug) {
if (!endOfStream) {
options.logger.log(
DEBUG,
"[Encoder]: reached end of stream unexpectedly"
)
} else {
options.logger.log(DEBUG, "[Encoder]: end of stream reached")
}
}
break // out of while
}
Expand Down
58 changes: 58 additions & 0 deletions sentry-samples/sentry-samples-android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.variant.impl.VariantImpl
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.internal.extensions.stdlib.capitalized

plugins {
id("com.android.application")
kotlin("android")
Expand Down Expand Up @@ -109,6 +114,22 @@ android {
it.enable = !Config.Android.shouldSkipDebugVariant(it.buildType)
}

androidComponents.onVariants { variant ->
val taskName = "toggle${variant.name.capitalized()}NativeLogging"
val toggleNativeLoggingTask = project.tasks.register<ToggleNativeLoggingTask>(taskName) {
mergedManifest.set(variant.artifacts.get(SingleArtifact.MERGED_MANIFEST))
rootDir.set(project.rootDir.absolutePath)
}
project.afterEvaluate {
(variant as? VariantImpl<*>)?.taskContainer?.assembleTask?.configure {
finalizedBy(toggleNativeLoggingTask)
}
(variant as? VariantImpl<*>)?.taskContainer?.installTask?.configure {
finalizedBy(toggleNativeLoggingTask)
}
}
}

@Suppress("UnstableApiUsage")
packagingOptions {
jniLibs {
Expand Down Expand Up @@ -155,3 +176,40 @@ dependencies {

debugImplementation(Config.Libs.leakCanary)
}

abstract class ToggleNativeLoggingTask : Exec() {

@get:Input
abstract val rootDir: Property<String>

@get:InputFile
abstract val mergedManifest: RegularFileProperty

override fun exec() {
isIgnoreExitValue = true
val manifestFile = mergedManifest.get().asFile
val manifestContent = manifestFile.readText()
val match = regex.find(manifestContent)

if (match != null) {
val value = match.groupValues[1].toBooleanStrictOrNull()
if (value != null) {
val args = mutableListOf<String>()
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
args.add(0, "cmd")
args.add(1, "/c")
}
args.add("${rootDir.get()}/scripts/toggle-codec-logs.sh")
args.add(if (value) "enable" else "disable")
commandLine(args)
super.exec()
}
}
}

companion object {
private val regex = Regex(
"""<meta-data\s+[^>]*android:name="io\.sentry\.session-replay\.debug"[^>]*android:value="([^"]+)""""
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
<!-- how to enable Sentry's debug mode-->
<meta-data android:name="io.sentry.debug" android:value="${sentryDebug}" />

<!-- how to disable verbose logging of the session replay feature-->
<meta-data android:name="io.sentry.session-replay.debug" android:value="false" />

<!-- how to set a custom debug level-->
<!-- <meta-data android:name="io.sentry.debug.level" android:value="info" />-->

Expand Down
8 changes: 8 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,7 @@ public final class io/sentry/JsonObjectWriter : io/sentry/ObjectWriter {
public synthetic fun endArray ()Lio/sentry/ObjectWriter;
public fun endObject ()Lio/sentry/JsonObjectWriter;
public synthetic fun endObject ()Lio/sentry/ObjectWriter;
public fun getIndent ()Ljava/lang/String;
public fun jsonValue (Ljava/lang/String;)Lio/sentry/ObjectWriter;
public fun name (Ljava/lang/String;)Lio/sentry/JsonObjectWriter;
public synthetic fun name (Ljava/lang/String;)Lio/sentry/ObjectWriter;
Expand Down Expand Up @@ -1854,9 +1855,11 @@ public abstract interface class io/sentry/ObjectWriter {
public abstract fun beginObject ()Lio/sentry/ObjectWriter;
public abstract fun endArray ()Lio/sentry/ObjectWriter;
public abstract fun endObject ()Lio/sentry/ObjectWriter;
public abstract fun getIndent ()Ljava/lang/String;
public abstract fun jsonValue (Ljava/lang/String;)Lio/sentry/ObjectWriter;
public abstract fun name (Ljava/lang/String;)Lio/sentry/ObjectWriter;
public abstract fun nullValue ()Lio/sentry/ObjectWriter;
public abstract fun setIndent (Ljava/lang/String;)V
public abstract fun setLenient (Z)V
public abstract fun value (D)Lio/sentry/ObjectWriter;
public abstract fun value (J)Lio/sentry/ObjectWriter;
Expand Down Expand Up @@ -3420,9 +3423,11 @@ public final class io/sentry/SentryReplayOptions {
public fun getSessionSegmentDuration ()J
public fun getUnmaskViewClasses ()Ljava/util/Set;
public fun getUnmaskViewContainerClass ()Ljava/lang/String;
public fun isDebug ()Z
public fun isSessionReplayEnabled ()Z
public fun isSessionReplayForErrorsEnabled ()Z
public fun isTrackOrientationChange ()Z
public fun setDebug (Z)V
public fun setMaskAllImages (Z)V
public fun setMaskAllText (Z)V
public fun setMaskViewContainerClass (Ljava/lang/String;)V
Expand Down Expand Up @@ -6522,11 +6527,13 @@ public final class io/sentry/util/MapObjectWriter : io/sentry/ObjectWriter {
public fun endArray ()Lio/sentry/util/MapObjectWriter;
public synthetic fun endObject ()Lio/sentry/ObjectWriter;
public fun endObject ()Lio/sentry/util/MapObjectWriter;
public fun getIndent ()Ljava/lang/String;
public fun jsonValue (Ljava/lang/String;)Lio/sentry/ObjectWriter;
public synthetic fun name (Ljava/lang/String;)Lio/sentry/ObjectWriter;
public fun name (Ljava/lang/String;)Lio/sentry/util/MapObjectWriter;
public synthetic fun nullValue ()Lio/sentry/ObjectWriter;
public fun nullValue ()Lio/sentry/util/MapObjectWriter;
public fun setIndent (Ljava/lang/String;)V
public fun setLenient (Z)V
public synthetic fun value (D)Lio/sentry/ObjectWriter;
public fun value (D)Lio/sentry/util/MapObjectWriter;
Expand Down Expand Up @@ -6770,6 +6777,7 @@ public class io/sentry/vendor/gson/stream/JsonWriter : java/io/Closeable, java/i
public fun endArray ()Lio/sentry/vendor/gson/stream/JsonWriter;
public fun endObject ()Lio/sentry/vendor/gson/stream/JsonWriter;
public fun flush ()V
public fun getIndent ()Ljava/lang/String;
public final fun getSerializeNulls ()Z
public final fun isHtmlSafe ()Z
public fun isLenient ()Z
Expand Down
9 changes: 8 additions & 1 deletion sentry/src/main/java/io/sentry/JsonObjectWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,14 @@ public void setLenient(final boolean lenient) {
jsonWriter.setLenient(lenient);
}

public void setIndent(final @NotNull String indent) {
@Override
public void setIndent(final @Nullable String indent) {
jsonWriter.setIndent(indent);
}

@Override
@Nullable
public String getIndent() {
return jsonWriter.getIndent();
}
}
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/ObjectWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ ObjectWriter value(final @NotNull ILogger logger, final @Nullable Object object)
throws IOException;

void setLenient(boolean lenient);

void setIndent(final @Nullable String indent);

@Nullable
String getIndent();
}
Loading
Loading