Skip to content
Draft
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
- Fix attachments being duplicated on native events that carry scope attachments ([#5548](https://github.com/getsentry/sentry-java/pull/5548))
- Fix performance collector scheduling many tasks in a row ([#5524](https://github.com/getsentry/sentry-java/pull/5524))

### Internal

- Reduce writer buffer size from 8192 to 512 ([#5544](https://github.com/getsentry/sentry-java/pull/5544))
- Remove redundant event map copies ([#5536](https://github.com/getsentry/sentry-java/pull/5536))

## 8.43.2

### Improvements
Expand Down
5 changes: 4 additions & 1 deletion sentry/src/main/java/io/sentry/JsonSerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public final class JsonSerializer implements ISerializer {
@SuppressWarnings("CharsetObjectCanBeUsed")
private static final Charset UTF_8 = Charset.forName("UTF-8");

private static final int WRITER_BUFFER_SIZE = 512;

/** the SentryOptions */
private final @NotNull SentryOptions options;

Expand Down Expand Up @@ -233,7 +235,8 @@ public void serialize(@NotNull SentryEnvelope envelope, @NotNull OutputStream ou

// we do not want to close these as we would also close the stream that was passed in
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
final Writer writer = new BufferedWriter(new OutputStreamWriter(bufferedOutputStream, UTF_8));
final Writer writer =
new BufferedWriter(new OutputStreamWriter(bufferedOutputStream, UTF_8), WRITER_BUFFER_SIZE);

try {
envelope
Expand Down
3 changes: 1 addition & 2 deletions sentry/src/main/java/io/sentry/MainEventProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -191,7 +190,7 @@ private void setSdk(final @NotNull SentryBaseEvent event) {

private void setTags(final @NotNull SentryBaseEvent event) {
if (event.getTags() == null) {
event.setTags(new HashMap<>(options.getTags()));
event.setTags(options.getTags());
} else {
for (Map.Entry<String, String> item : options.getTags().entrySet()) {
if (!event.getTags().containsKey(item.getKey())) {
Expand Down
9 changes: 4 additions & 5 deletions sentry/src/main/java/io/sentry/SentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -1425,7 +1424,7 @@ public void captureBatchedMetricsEvents(final @NotNull SentryMetricsEvents metri
event.setUser(scope.getUser());
}
if (event.getTags() == null) {
event.setTags(new HashMap<>(scope.getTags()));
event.setTags(scope.getTags());
} else {
for (Map.Entry<String, String> item : scope.getTags().entrySet()) {
if (!event.getTags().containsKey(item.getKey())) {
Expand Down Expand Up @@ -1483,7 +1482,7 @@ public void captureBatchedMetricsEvents(final @NotNull SentryMetricsEvents metri
replayEvent.setUser(scope.getUser());
}
if (replayEvent.getTags() == null) {
replayEvent.setTags(new HashMap<>(scope.getTags()));
replayEvent.setTags(scope.getTags());
} else {
for (Map.Entry<String, String> item : scope.getTags().entrySet()) {
if (!replayEvent.getTags().containsKey(item.getKey())) {
Expand Down Expand Up @@ -1523,7 +1522,7 @@ public void captureBatchedMetricsEvents(final @NotNull SentryMetricsEvents metri
sentryBaseEvent.setUser(scope.getUser());
}
if (sentryBaseEvent.getTags() == null) {
sentryBaseEvent.setTags(new HashMap<>(scope.getTags()));
sentryBaseEvent.setTags(scope.getTags());
} else {
for (Map.Entry<String, String> item : scope.getTags().entrySet()) {
if (!sentryBaseEvent.getTags().containsKey(item.getKey())) {
Expand All @@ -1537,7 +1536,7 @@ public void captureBatchedMetricsEvents(final @NotNull SentryMetricsEvents metri
sortBreadcrumbsByDate(sentryBaseEvent, scope.getBreadcrumbs());
}
if (sentryBaseEvent.getExtras() == null) {
sentryBaseEvent.setExtras(new HashMap<>(scope.getExtras()));
sentryBaseEvent.setExtras(scope.getExtras());
} else {
for (Map.Entry<String, Object> item : scope.getExtras().entrySet()) {
if (!sentryBaseEvent.getExtras().containsKey(item.getKey())) {
Expand Down
41 changes: 31 additions & 10 deletions sentry/src/main/java/io/sentry/SentryEnvelopeItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public final class SentryEnvelopeItem {
@SuppressWarnings("CharsetObjectCanBeUsed")
private static final Charset UTF_8 = Charset.forName("UTF-8");

private static final int WRITER_BUFFER_SIZE = 512;

private final SentryEnvelopeItemHeader header;
// Either dataFactory is set or data needs to be set.
private final @Nullable Callable<byte[]> dataFactory;
Expand Down Expand Up @@ -85,7 +87,9 @@ public final class SentryEnvelopeItem {
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(session, writer);
return stream.toByteArray();
}
Expand Down Expand Up @@ -119,7 +123,9 @@ public final class SentryEnvelopeItem {
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(event, writer);
return stream.toByteArray();
}
Expand Down Expand Up @@ -179,7 +185,9 @@ public static SentryEnvelopeItem fromUserFeedback(
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(userFeedback, writer);
return stream.toByteArray();
}
Expand All @@ -206,7 +214,9 @@ public static SentryEnvelopeItem fromCheckIn(
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(checkIn, writer);
return stream.toByteArray();
}
Expand Down Expand Up @@ -344,7 +354,9 @@ private static void ensureAttachmentSizeLimit(
}

try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(profileChunk, writer);
return stream.toByteArray();
} catch (IOException e) {
Expand Down Expand Up @@ -403,7 +415,9 @@ private static void ensureAttachmentSizeLimit(
profilingTraceData.readDeviceCpuFrequencies();

try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(profilingTraceData, writer);
return stream.toByteArray();
} catch (IOException e) {
Expand Down Expand Up @@ -437,7 +451,9 @@ private static void ensureAttachmentSizeLimit(
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(clientReport, writer);
return stream.toByteArray();
}
Expand Down Expand Up @@ -481,7 +497,8 @@ public static SentryEnvelopeItem fromReplay(
try {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer =
new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
// relay expects the payload to be in this exact order: [event,rrweb,video]
final Map<String, byte[]> replayPayload = new LinkedHashMap<>();
// first serialize replay event json bytes
Expand Down Expand Up @@ -541,7 +558,9 @@ public static SentryEnvelopeItem fromLogs(
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(logEvents, writer);
return stream.toByteArray();
}
Expand Down Expand Up @@ -571,7 +590,9 @@ public static SentryEnvelopeItem fromMetrics(
new CachedItem(
() -> {
try (final ByteArrayOutputStream stream = new ByteArrayOutputStream();
final Writer writer = new BufferedWriter(new OutputStreamWriter(stream, UTF_8))) {
final Writer writer =
new BufferedWriter(
new OutputStreamWriter(stream, UTF_8), WRITER_BUFFER_SIZE)) {
serializer.serialize(metricsEvents, writer);
return stream.toByteArray();
}
Expand Down
13 changes: 13 additions & 0 deletions sentry/src/test/java/io/sentry/MainEventProcessorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,19 @@ class MainEventProcessorTest {
}
}

@Test
fun `options tags are copied when applied to event`() {
val sut = fixture.getSut(tags = mapOf("tag1" to "value1"))
val event = SentryEvent()

sut.process(event, Hint())
val eventTags = event.tags!!

fixture.sentryOptions.setTag("tag2", "value2")

assertFalse(eventTags.containsKey("tag2"))
}

@Test
fun `when event has a tag set with the same name as SentryOptions tags, the tag value from the event is retained`() {
val sut = fixture.getSut(tags = mapOf("tag1" to "value1", "tag2" to "value2"))
Expand Down
18 changes: 18 additions & 0 deletions sentry/src/test/java/io/sentry/SentryClientTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,24 @@ class SentryClientTest {
assertNotNull(event.request) { assertEquals("post", it.method) }
}

@Test
fun `when captureEvent applies scope tags and extras, event map containers are copied`() {
val event = SentryEvent()
val scope = createScope()

val sut = fixture.getSut()

sut.captureEvent(event, scope)
val eventTags = event.tags!!
val eventExtras = event.extras!!

scope.setTag("newTag", "newValue")
scope.setExtra("newExtra", "newValue")

assertFalse(eventTags.containsKey("newTag"))
assertFalse(eventExtras.containsKey("newExtra"))
}

@Test
fun `when breadcrumbs are not empty, sort them out by date`() {
val b1 = Breadcrumb(DateUtils.getDateTime("2020-03-27T08:52:58.001Z"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.sentry.SentryBaseEvent
import io.sentry.SentryIntegrationPackageStorage
import io.sentry.vendor.gson.stream.JsonToken
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import org.junit.After
import org.junit.Before
import org.junit.Test
Expand Down Expand Up @@ -102,4 +103,26 @@ class SentryBaseEventSerializationTest {

assertEquals(expectedJson, actualJson)
}

@Test
fun `setTags copies source map`() {
val source = mutableMapOf("a" to "1")
val sut = Sut()

sut.tags = source
source["b"] = "2"

assertFalse(sut.tags!!.containsKey("b"))
}

@Test
fun `setExtras copies source map`() {
val source = mutableMapOf<String, Any>("a" to "1")
val sut = Sut()

sut.setExtras(source)
source["b"] = "2"

assertFalse(sut.extras!!.containsKey("b"))
}
}
Loading