Skip to content

Commit 8e4cd93

Browse files
committed
Reduce debug logs verbosity
1 parent 084562d commit 8e4cd93

File tree

18 files changed

+255
-23
lines changed

18 files changed

+255
-23
lines changed

scripts/toggle-codec-logs.sh

+76
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

+4
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

+1-1
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

+1-2
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

+3-3
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

+6-1
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

+28-11
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

+64
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,23 @@ 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+
output.set(project.layout.buildDirectory.dir("intermediates/$taskName"))
122+
rootDir.set(project.rootDir.absolutePath)
123+
}
124+
project.afterEvaluate {
125+
(variant as? VariantImpl<*>)?.taskContainer?.assembleTask?.configure {
126+
finalizedBy(toggleNativeLoggingTask)
127+
}
128+
(variant as? VariantImpl<*>)?.taskContainer?.installTask?.configure {
129+
finalizedBy(toggleNativeLoggingTask)
130+
}
131+
}
132+
}
133+
112134
@Suppress("UnstableApiUsage")
113135
packagingOptions {
114136
jniLibs {
@@ -155,3 +177,45 @@ dependencies {
155177

156178
debugImplementation(Config.Libs.leakCanary)
157179
}
180+
181+
abstract class ToggleNativeLoggingTask : Exec() {
182+
183+
// In order for the task to be up-to-date when the inputs have not changed,
184+
// the task must declare an output, even if it's not used. Tasks with no
185+
// output are always run regardless of whether the inputs changed
186+
@get:OutputDirectory
187+
abstract val output: DirectoryProperty
188+
189+
@get:Input
190+
abstract val rootDir: Property<String>
191+
192+
@get:InputFile
193+
abstract val mergedManifest: RegularFileProperty
194+
195+
override fun exec() {
196+
val manifestFile = mergedManifest.get().asFile
197+
val manifestContent = manifestFile.readText()
198+
val match = regex.find(manifestContent)
199+
200+
if (match != null) {
201+
val value = match.groupValues[1].toBooleanStrictOrNull()
202+
if (value != null) {
203+
val args = mutableListOf<String>()
204+
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
205+
args.add(0, "cmd")
206+
args.add(1, "/c")
207+
}
208+
args.add("${rootDir.get()}/scripts/toggle-codec-logs.sh")
209+
args.add(if (value) "enable" else "disable")
210+
commandLine(args)
211+
super.exec()
212+
}
213+
}
214+
}
215+
216+
companion object {
217+
private val regex = Regex(
218+
"""<meta-data\s+[^>]*android:name="io\.sentry\.session-replay\.debug"[^>]*android:value="([^"]+)""""
219+
)
220+
}
221+
}

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

+3
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

sentry/api/sentry.api

+8
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,7 @@ public final class io/sentry/JsonObjectWriter : io/sentry/ObjectWriter {
11971197
public synthetic fun endArray ()Lio/sentry/ObjectWriter;
11981198
public fun endObject ()Lio/sentry/JsonObjectWriter;
11991199
public synthetic fun endObject ()Lio/sentry/ObjectWriter;
1200+
public fun getIndent ()Ljava/lang/String;
12001201
public fun jsonValue (Ljava/lang/String;)Lio/sentry/ObjectWriter;
12011202
public fun name (Ljava/lang/String;)Lio/sentry/JsonObjectWriter;
12021203
public synthetic fun name (Ljava/lang/String;)Lio/sentry/ObjectWriter;
@@ -1854,9 +1855,11 @@ public abstract interface class io/sentry/ObjectWriter {
18541855
public abstract fun beginObject ()Lio/sentry/ObjectWriter;
18551856
public abstract fun endArray ()Lio/sentry/ObjectWriter;
18561857
public abstract fun endObject ()Lio/sentry/ObjectWriter;
1858+
public abstract fun getIndent ()Ljava/lang/String;
18571859
public abstract fun jsonValue (Ljava/lang/String;)Lio/sentry/ObjectWriter;
18581860
public abstract fun name (Ljava/lang/String;)Lio/sentry/ObjectWriter;
18591861
public abstract fun nullValue ()Lio/sentry/ObjectWriter;
1862+
public abstract fun setIndent (Ljava/lang/String;)V
18601863
public abstract fun setLenient (Z)V
18611864
public abstract fun value (D)Lio/sentry/ObjectWriter;
18621865
public abstract fun value (J)Lio/sentry/ObjectWriter;
@@ -3420,9 +3423,11 @@ public final class io/sentry/SentryReplayOptions {
34203423
public fun getSessionSegmentDuration ()J
34213424
public fun getUnmaskViewClasses ()Ljava/util/Set;
34223425
public fun getUnmaskViewContainerClass ()Ljava/lang/String;
3426+
public fun isDebug ()Z
34233427
public fun isSessionReplayEnabled ()Z
34243428
public fun isSessionReplayForErrorsEnabled ()Z
34253429
public fun isTrackOrientationChange ()Z
3430+
public fun setDebug (Z)V
34263431
public fun setMaskAllImages (Z)V
34273432
public fun setMaskAllText (Z)V
34283433
public fun setMaskViewContainerClass (Ljava/lang/String;)V
@@ -6522,11 +6527,13 @@ public final class io/sentry/util/MapObjectWriter : io/sentry/ObjectWriter {
65226527
public fun endArray ()Lio/sentry/util/MapObjectWriter;
65236528
public synthetic fun endObject ()Lio/sentry/ObjectWriter;
65246529
public fun endObject ()Lio/sentry/util/MapObjectWriter;
6530+
public fun getIndent ()Ljava/lang/String;
65256531
public fun jsonValue (Ljava/lang/String;)Lio/sentry/ObjectWriter;
65266532
public synthetic fun name (Ljava/lang/String;)Lio/sentry/ObjectWriter;
65276533
public fun name (Ljava/lang/String;)Lio/sentry/util/MapObjectWriter;
65286534
public synthetic fun nullValue ()Lio/sentry/ObjectWriter;
65296535
public fun nullValue ()Lio/sentry/util/MapObjectWriter;
6536+
public fun setIndent (Ljava/lang/String;)V
65306537
public fun setLenient (Z)V
65316538
public synthetic fun value (D)Lio/sentry/ObjectWriter;
65326539
public fun value (D)Lio/sentry/util/MapObjectWriter;
@@ -6770,6 +6777,7 @@ public class io/sentry/vendor/gson/stream/JsonWriter : java/io/Closeable, java/i
67706777
public fun endArray ()Lio/sentry/vendor/gson/stream/JsonWriter;
67716778
public fun endObject ()Lio/sentry/vendor/gson/stream/JsonWriter;
67726779
public fun flush ()V
6780+
public fun getIndent ()Ljava/lang/String;
67736781
public final fun getSerializeNulls ()Z
67746782
public final fun isHtmlSafe ()Z
67756783
public fun isLenient ()Z

sentry/src/main/java/io/sentry/JsonObjectWriter.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,14 @@ public void setLenient(final boolean lenient) {
114114
jsonWriter.setLenient(lenient);
115115
}
116116

117-
public void setIndent(final @NotNull String indent) {
117+
@Override
118+
public void setIndent(final @Nullable String indent) {
118119
jsonWriter.setIndent(indent);
119120
}
121+
122+
@Override
123+
@Nullable
124+
public String getIndent() {
125+
return jsonWriter.getIndent();
126+
}
120127
}

sentry/src/main/java/io/sentry/ObjectWriter.java

+5
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@ ObjectWriter value(final @NotNull ILogger logger, final @Nullable Object object)
3535
throws IOException;
3636

3737
void setLenient(boolean lenient);
38+
39+
void setIndent(final @Nullable String indent);
40+
41+
@Nullable
42+
String getIndent();
3843
}

0 commit comments

Comments
 (0)