Skip to content

Commit 2365d34

Browse files
authored
fix(logging): Reduce debug logs verbosity (#4341)
1 parent d9ab996 commit 2365d34

File tree

20 files changed

+255
-23
lines changed

20 files changed

+255
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
### Fixes
1010

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

scripts/toggle-codec-logs.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/bin/bash
2+
3+
# --- Functions ---
4+
5+
print_usage() {
6+
echo "Usage: $0 [enable|disable]"
7+
exit 1
8+
}
9+
10+
# Check for adb
11+
if ! command -v adb &> /dev/null; then
12+
echo "❌ adb not found. Please install Android Platform Tools and ensure adb is in your PATH."
13+
exit 1
14+
fi
15+
16+
# Check for connected device
17+
DEVICE_COUNT=$(adb devices | grep -w "device" | wc -l)
18+
if [ "$DEVICE_COUNT" -eq 0 ]; then
19+
echo "❌ No device connected. Please connect a device and enable USB debugging."
20+
exit 1
21+
fi
22+
23+
# --- Handle Argument ---
24+
25+
ACTION=$(echo "$1" | tr '[:upper:]' '[:lower:]')
26+
27+
case "$ACTION" in
28+
enable)
29+
echo "✅ Enabling native logs (DEBUG)..."
30+
adb shell setprop log.tag.MPEG4Writer D
31+
adb shell setprop log.tag.CCodec D
32+
adb shell setprop log.tag.VQApply D
33+
adb shell setprop log.tag.ColorUtils D
34+
adb shell setprop log.tag.MediaCodec D
35+
adb shell setprop log.tag.MediaCodecList D
36+
adb shell setprop log.tag.MediaWriter D
37+
adb shell setprop log.tag.CCodecConfig D
38+
adb shell setprop log.tag.Codec2Client D
39+
adb shell setprop log.tag.CCodecBufferChannel D
40+
adb shell setprop log.tag.CodecProperties D
41+
adb shell setprop log.tag.CodecSeeding D
42+
adb shell setprop log.tag.C2Store D
43+
adb shell setprop log.tag.C2NodeImpl D
44+
adb shell setprop log.tag.GraphicBufferSource D
45+
adb shell setprop log.tag.BufferQueueProducer D
46+
adb shell setprop log.tag.ReflectedParamUpdater D
47+
adb shell setprop log.tag.hw-BpHwBinder D
48+
echo "✅ Logs ENABLED"
49+
;;
50+
disable)
51+
echo "🚫 Disabling native logs (SILENT)..."
52+
adb shell setprop log.tag.MPEG4Writer SILENT
53+
adb shell setprop log.tag.CCodec SILENT
54+
adb shell setprop log.tag.VQApply SILENT
55+
adb shell setprop log.tag.ColorUtils SILENT
56+
adb shell setprop log.tag.MediaCodec SILENT
57+
adb shell setprop log.tag.MediaCodecList SILENT
58+
adb shell setprop log.tag.MediaWriter SILENT
59+
adb shell setprop log.tag.CCodecConfig SILENT
60+
adb shell setprop log.tag.Codec2Client SILENT
61+
adb shell setprop log.tag.CCodecBufferChannel SILENT
62+
adb shell setprop log.tag.CodecProperties SILENT
63+
adb shell setprop log.tag.CodecSeeding SILENT
64+
adb shell setprop log.tag.C2Store SILENT
65+
adb shell setprop log.tag.C2NodeImpl SILENT
66+
adb shell setprop log.tag.GraphicBufferSource SILENT
67+
adb shell setprop log.tag.BufferQueueProducer SILENT
68+
adb shell setprop log.tag.ReflectedParamUpdater SILENT
69+
adb shell setprop log.tag.hw-BpHwBinder SILENT
70+
echo "🚫 Logs DISABLED"
71+
;;
72+
*)
73+
echo "❓ Unknown or missing argument: '$1'"
74+
print_usage
75+
;;
76+
esac

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ final class ManifestMetadataReader {
109109

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

112+
static final String REPLAYS_DEBUG = "io.sentry.session-replay.debug";
113+
112114
static final String FORCE_INIT = "io.sentry.force-init";
113115

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

457+
options.getSessionReplay().setDebug(readBool(metadata, logger, REPLAYS_DEBUG, false));
458+
455459
options.setIgnoredErrors(readList(metadata, logger, IGNORED_ERRORS));
456460

457461
final @Nullable List<String> includes = readList(metadata, logger, IN_APP_INCLUDES);

sentry-android-core/src/main/java/io/sentry/android/core/internal/debugmeta/AssetsDebugMetaLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public AssetsDebugMetaLoader(final @NotNull Context context, final @NotNull ILog
4141
properties.load(is);
4242
return Collections.singletonList(properties);
4343
} catch (FileNotFoundException e) {
44-
logger.log(SentryLevel.INFO, e, "%s file was not found.", DEBUG_META_PROPERTIES_FILENAME);
44+
logger.log(SentryLevel.INFO, "%s file was not found.", DEBUG_META_PROPERTIES_FILENAME);
4545
} catch (IOException e) {
4646
logger.log(SentryLevel.ERROR, "Error getting Proguard UUIDs.", e);
4747
} catch (RuntimeException e) {

sentry-android-replay/src/main/java/io/sentry/android/replay/ReplayIntegration.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ public class ReplayIntegration(
151151
} catch (e: Throwable) {
152152
options.logger.log(
153153
INFO,
154-
"ComponentCallbacks is not available, orientation changes won't be handled by Session replay",
155-
e
154+
"ComponentCallbacks is not available, orientation changes won't be handled by Session replay"
156155
)
157156
}
158157
}

sentry-android-replay/src/main/java/io/sentry/android/replay/ScreenshotRecorder.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ internal class ScreenshotRecorder(
7272

7373
fun capture() {
7474
if (!isCapturing.get()) {
75-
options.logger.log(DEBUG, "ScreenshotRecorder is paused, not capturing screenshot")
75+
if (options.sessionReplay.isDebug) {
76+
options.logger.log(DEBUG, "ScreenshotRecorder is paused, not capturing screenshot")
77+
}
7678
return
7779
}
7880

7981
if (!contentChanged.get() && lastCaptureSuccessful.get()) {
80-
options.logger.log(DEBUG, "Content hasn't changed, repeating last known frame")
81-
8282
screenshotRecorderCallback?.onScreenshotRecorded(screenshot)
8383
return
8484
}

sentry-android-replay/src/main/java/io/sentry/android/replay/capture/SessionCaptureStrategy.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ internal class SessionCaptureStrategy(
6767
}
6868

6969
override fun captureReplay(isTerminating: Boolean, onSegmentSent: (Date) -> Unit) {
70-
options.logger.log(DEBUG, "Replay is already running in 'session' mode, not capturing for event")
70+
if (options.sessionReplay.isDebug) {
71+
options.logger.log(
72+
DEBUG,
73+
"Replay is already running in 'session' mode, not capturing for event"
74+
)
75+
}
7176
this.isTerminating.set(isTerminating)
7277
}
7378

sentry-android-replay/src/main/java/io/sentry/android/replay/video/SimpleVideoEncoder.kt

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,13 @@ internal class SimpleVideoEncoder(
181181
* Borrows heavily from https://bigflake.com/mediacodec/EncodeAndMuxTest.java.txt
182182
*/
183183
private fun drainCodec(endOfStream: Boolean) {
184-
options.logger.log(DEBUG, "[Encoder]: drainCodec($endOfStream)")
184+
if (options.sessionReplay.isDebug) {
185+
options.logger.log(DEBUG, "[Encoder]: drainCodec($endOfStream)")
186+
}
185187
if (endOfStream) {
186-
options.logger.log(DEBUG, "[Encoder]: sending EOS to encoder")
188+
if (options.sessionReplay.isDebug) {
189+
options.logger.log(DEBUG, "[Encoder]: sending EOS to encoder")
190+
}
187191
mediaCodec.signalEndOfInputStream()
188192
}
189193
var encoderOutputBuffers: Array<ByteBuffer?>? = mediaCodec.outputBuffers
@@ -193,7 +197,7 @@ internal class SimpleVideoEncoder(
193197
// no output available yet
194198
if (!endOfStream) {
195199
break // out of while
196-
} else {
200+
} else if (options.sessionReplay.isDebug) {
197201
options.logger.log(DEBUG, "[Encoder]: no output available, spinning to await EOS")
198202
}
199203
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
@@ -205,35 +209,48 @@ internal class SimpleVideoEncoder(
205209
throw RuntimeException("format changed twice")
206210
}
207211
val newFormat: MediaFormat = mediaCodec.outputFormat
208-
options.logger.log(DEBUG, "[Encoder]: encoder output format changed: $newFormat")
212+
if (options.sessionReplay.isDebug) {
213+
options.logger.log(DEBUG, "[Encoder]: encoder output format changed: $newFormat")
214+
}
209215

210216
// now that we have the Magic Goodies, start the muxer
211217
frameMuxer.start(newFormat)
212218
} else if (encoderStatus < 0) {
213-
options.logger.log(DEBUG, "[Encoder]: unexpected result from encoder.dequeueOutputBuffer: $encoderStatus")
219+
if (options.sessionReplay.isDebug) {
220+
options.logger.log(DEBUG, "[Encoder]: unexpected result from encoder.dequeueOutputBuffer: $encoderStatus")
221+
}
214222
// let's ignore it
215223
} else {
216224
val encodedData = encoderOutputBuffers?.get(encoderStatus)
217225
?: throw RuntimeException("encoderOutputBuffer $encoderStatus was null")
218226
if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG != 0) {
219227
// The codec config data was pulled out and fed to the muxer when we got
220228
// the INFO_OUTPUT_FORMAT_CHANGED status. Ignore it.
221-
options.logger.log(DEBUG, "[Encoder]: ignoring BUFFER_FLAG_CODEC_CONFIG")
229+
if (options.sessionReplay.isDebug) {
230+
options.logger.log(DEBUG, "[Encoder]: ignoring BUFFER_FLAG_CODEC_CONFIG")
231+
}
222232
bufferInfo.size = 0
223233
}
224234
if (bufferInfo.size != 0) {
225235
if (!frameMuxer.isStarted()) {
226236
throw RuntimeException("muxer hasn't started")
227237
}
228238
frameMuxer.muxVideoFrame(encodedData, bufferInfo)
229-
options.logger.log(DEBUG, "[Encoder]: sent ${bufferInfo.size} bytes to muxer")
239+
if (options.sessionReplay.isDebug) {
240+
options.logger.log(DEBUG, "[Encoder]: sent ${bufferInfo.size} bytes to muxer")
241+
}
230242
}
231243
mediaCodec.releaseOutputBuffer(encoderStatus, false)
232244
if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0) {
233-
if (!endOfStream) {
234-
options.logger.log(DEBUG, "[Encoder]: reached end of stream unexpectedly")
235-
} else {
236-
options.logger.log(DEBUG, "[Encoder]: end of stream reached")
245+
if (options.sessionReplay.isDebug) {
246+
if (!endOfStream) {
247+
options.logger.log(
248+
DEBUG,
249+
"[Encoder]: reached end of stream unexpectedly"
250+
)
251+
} else {
252+
options.logger.log(DEBUG, "[Encoder]: end of stream reached")
253+
}
237254
}
238255
break // out of while
239256
}

sentry-samples/sentry-samples-android/build.gradle.kts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import com.android.build.api.artifact.SingleArtifact
2+
import com.android.build.api.variant.impl.VariantImpl
3+
import org.apache.tools.ant.taskdefs.condition.Os
4+
import org.gradle.internal.extensions.stdlib.capitalized
5+
16
plugins {
27
id("com.android.application")
38
kotlin("android")
@@ -109,6 +114,22 @@ android {
109114
it.enable = !Config.Android.shouldSkipDebugVariant(it.buildType)
110115
}
111116

117+
androidComponents.onVariants { variant ->
118+
val taskName = "toggle${variant.name.capitalized()}NativeLogging"
119+
val toggleNativeLoggingTask = project.tasks.register<ToggleNativeLoggingTask>(taskName) {
120+
mergedManifest.set(variant.artifacts.get(SingleArtifact.MERGED_MANIFEST))
121+
rootDir.set(project.rootDir.absolutePath)
122+
}
123+
project.afterEvaluate {
124+
(variant as? VariantImpl<*>)?.taskContainer?.assembleTask?.configure {
125+
finalizedBy(toggleNativeLoggingTask)
126+
}
127+
(variant as? VariantImpl<*>)?.taskContainer?.installTask?.configure {
128+
finalizedBy(toggleNativeLoggingTask)
129+
}
130+
}
131+
}
132+
112133
@Suppress("UnstableApiUsage")
113134
packagingOptions {
114135
jniLibs {
@@ -155,3 +176,40 @@ dependencies {
155176

156177
debugImplementation(Config.Libs.leakCanary)
157178
}
179+
180+
abstract class ToggleNativeLoggingTask : Exec() {
181+
182+
@get:Input
183+
abstract val rootDir: Property<String>
184+
185+
@get:InputFile
186+
abstract val mergedManifest: RegularFileProperty
187+
188+
override fun exec() {
189+
isIgnoreExitValue = true
190+
val manifestFile = mergedManifest.get().asFile
191+
val manifestContent = manifestFile.readText()
192+
val match = regex.find(manifestContent)
193+
194+
if (match != null) {
195+
val value = match.groupValues[1].toBooleanStrictOrNull()
196+
if (value != null) {
197+
val args = mutableListOf<String>()
198+
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
199+
args.add(0, "cmd")
200+
args.add(1, "/c")
201+
}
202+
args.add("${rootDir.get()}/scripts/toggle-codec-logs.sh")
203+
args.add(if (value) "enable" else "disable")
204+
commandLine(args)
205+
super.exec()
206+
}
207+
}
208+
}
209+
210+
companion object {
211+
private val regex = Regex(
212+
"""<meta-data\s+[^>]*android:name="io\.sentry\.session-replay\.debug"[^>]*android:value="([^"]+)""""
213+
)
214+
}
215+
}

sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@
7272
<!-- how to enable Sentry's debug mode-->
7373
<meta-data android:name="io.sentry.debug" android:value="${sentryDebug}" />
7474

75+
<!-- how to disable verbose logging of the session replay feature-->
76+
<meta-data android:name="io.sentry.session-replay.debug" android:value="false" />
77+
7578
<!-- how to set a custom debug level-->
7679
<!-- <meta-data android:name="io.sentry.debug.level" android:value="info" />-->
7780

0 commit comments

Comments
 (0)