Skip to content

Commit bb0e0c7

Browse files
adinauerclaude
andauthored
fix(core): Reduce serialization log spam (#6255)
* fix(core): Reduce serialization log spam Allow serializers to suppress debug logging for individual calls and disable it while calculating serialized byte sizes. Preserve compatibility for custom serializers through a default interface implementation. Fixes #4946 Co-Authored-By: Claude <noreply@anthropic.com> * changelog --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1f0e1e0 commit bb0e0c7

7 files changed

Lines changed: 55 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@
107107
- See the [Navigation for Android docs](https://docs.sentry.io/platforms/android/integrations/navigation/) for additional details.
108108
- Report the cellular network technology generation in `device.connection_effective_type`, for example `4g` or `5g` ([#6146](https://github.com/getsentry/sentry-java/pull/6146))
109109

110+
### Fixes
111+
112+
- Avoid duplicate serialization debug logs when calculating serialized object sizes ([#6255](https://github.com/getsentry/sentry-java/pull/6255))
113+
110114
### Dependencies
111115

112116
- Bump Native SDK from v0.17.1 to v0.17.2 ([#6230](https://github.com/getsentry/sentry-java/pull/6230))

‎sentry/api/sentry.api‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,7 @@ public abstract interface class io/sentry/ISerializer {
12291229
public abstract fun deserializeEnvelope (Ljava/io/InputStream;)Lio/sentry/SentryEnvelope;
12301230
public abstract fun serialize (Lio/sentry/SentryEnvelope;Ljava/io/OutputStream;)V
12311231
public abstract fun serialize (Ljava/lang/Object;Ljava/io/Writer;)V
1232+
public fun serialize (Ljava/lang/Object;Ljava/io/Writer;Z)V
12321233
public abstract fun serialize (Ljava/util/Map;)Ljava/lang/String;
12331234
}
12341235

@@ -1446,6 +1447,7 @@ public final class io/sentry/JsonSerializer : io/sentry/ISerializer {
14461447
public fun deserializeEnvelope (Ljava/io/InputStream;)Lio/sentry/SentryEnvelope;
14471448
public fun serialize (Lio/sentry/SentryEnvelope;Ljava/io/OutputStream;)V
14481449
public fun serialize (Ljava/lang/Object;Ljava/io/Writer;)V
1450+
public fun serialize (Ljava/lang/Object;Ljava/io/Writer;Z)V
14491451
public fun serialize (Ljava/util/Map;)Ljava/lang/String;
14501452
}
14511453

‎sentry/src/main/java/io/sentry/ISerializer.java‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ public interface ISerializer {
2323

2424
<T> void serialize(@NotNull T entity, @NotNull Writer writer) throws IOException;
2525

26+
/**
27+
* Serializes an entity to a writer with optional logging control.
28+
*
29+
* @param entity the entity to serialize
30+
* @param writer the writer to serialize to
31+
* @param enableLogging whether serializer logging is enabled, if supported
32+
* @param <T> the type of entity
33+
* @throws IOException if serialization fails
34+
*/
35+
default <T> void serialize(@NotNull T entity, @NotNull Writer writer, boolean enableLogging)
36+
throws IOException {
37+
serialize(entity, writer);
38+
}
39+
2640
/**
2741
* Serializes an envelope
2842
*

‎sentry/src/main/java/io/sentry/JsonSerializer.java‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,16 @@ public JsonSerializer(@NotNull SentryOptions options) {
207207

208208
@Override
209209
public <T> void serialize(@NotNull T entity, @NotNull Writer writer) throws IOException {
210+
serialize(entity, writer, true);
211+
}
212+
213+
@Override
214+
public <T> void serialize(@NotNull T entity, @NotNull Writer writer, boolean enableLogging)
215+
throws IOException {
210216
Objects.requireNonNull(entity, "The entity is required.");
211217
Objects.requireNonNull(writer, "The Writer object is required.");
212218

213-
if (options.getLogger().isEnabled(SentryLevel.DEBUG)) {
219+
if (enableLogging && options.getLogger().isEnabled(SentryLevel.DEBUG)) {
214220
String serialized = serializeToString(entity, options.isEnablePrettySerializationOutput());
215221
options.getLogger().log(SentryLevel.DEBUG, "Serializing object: %s", serialized);
216222
}

‎sentry/src/main/java/io/sentry/util/JsonSerializationUtils.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public static long byteSizeOf(
8585
}
8686
try {
8787
final ByteCountingWriter writer = new ByteCountingWriter();
88-
serializer.serialize(serializable, writer);
88+
serializer.serialize(serializable, writer, false);
8989
return writer.getByteCount();
9090
} catch (Throwable t) {
9191
logger.log(SentryLevel.ERROR, "Could not calculate size of serializable", t);

‎sentry/src/test/java/io/sentry/JsonSerializerTest.kt‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,20 @@ class JsonSerializerTest {
15251525
.log(any(), check { assertTrue(it.startsWith("Serializing object:")) }, any<Any>())
15261526
}
15271527

1528+
@Test
1529+
fun `json serializer can disable serialization logging`() {
1530+
val logger = mock<ILogger>()
1531+
val options = SentryOptions()
1532+
options.setLogger(logger)
1533+
options.setDebug(true)
1534+
whenever(logger.isEnabled(any())).thenReturn(true)
1535+
1536+
(options.serializer as JsonSerializer).serialize(mapOf("key" to "val"), StringWriter(), false)
1537+
1538+
verify(logger, never())
1539+
.log(any(), check { assertTrue(it.startsWith("Serializing object:")) }, any<Any>())
1540+
}
1541+
15281542
@Test
15291543
fun `json serializer does not close the stream that is passed in`() {
15301544
val stream = mock<OutputStream>()

‎sentry/src/test/java/io/sentry/util/JsonSerializationUtilsTest.kt‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.sentry.util
22

33
import io.sentry.ILogger
4+
import io.sentry.ISerializer
45
import io.sentry.JsonSerializable
56
import io.sentry.JsonSerializer
67
import io.sentry.ObjectWriter
@@ -18,7 +19,9 @@ import kotlin.test.assertNull
1819
import kotlin.test.assertTrue
1920
import org.mockito.invocation.InvocationOnMock
2021
import org.mockito.kotlin.any
22+
import org.mockito.kotlin.eq
2123
import org.mockito.kotlin.mock
24+
import org.mockito.kotlin.verify
2225

2326
class JsonSerializationUtilsTest {
2427

@@ -117,6 +120,16 @@ class JsonSerializationUtilsTest {
117120
assertTrue(byteSize > 0, "byteSize should be positive")
118121
}
119122

123+
@Test
124+
fun `byteSizeOf disables serialization logging`() {
125+
val mockSerializer: ISerializer = mock()
126+
val serializable: JsonSerializable = mock()
127+
128+
JsonSerializationUtils.byteSizeOf(mockSerializer, logger, serializable)
129+
130+
verify(mockSerializer).serialize(eq(serializable), any(), eq(false))
131+
}
132+
120133
@Test
121134
fun `byteSizeOf returns 0 on serialization error`() {
122135
val serializable =

0 commit comments

Comments
 (0)