Skip to content

Commit 6b896b1

Browse files
author
Oliver Hsu
authored
CT-163 Optimize Event.estimatedSerializedBytes (#40)
* Change `Event.countJsonEscapedCharacters` from stream to for loop for performance * Use Jackson `SerializedString` for Event message
1 parent fc57855 commit 6b896b1

File tree

5 files changed

+48
-11
lines changed

5 files changed

+48
-11
lines changed

src/main/java/com/scalyr/integrations/kafka/AddEventsClient.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,11 @@ public void serialize(Event event, JsonGenerator jsonGenerator, SerializerProvid
519519
*/
520520
private void writeEventAttrs(Event event, JsonGenerator jsonGenerator) throws IOException {
521521
jsonGenerator.writeObjectFieldStart("attrs");
522-
jsonGenerator.writeStringField("message", event.getMessage());
522+
if (event.getSerializedMessage() != null) {
523+
jsonGenerator.writeFieldName("message");
524+
byte[] quotedMsg = event.getSerializedMessage().asQuotedUTF8();
525+
jsonGenerator.writeRawUTF8String(quotedMsg, 0, quotedMsg.length);
526+
}
523527

524528
// Write additional attrs
525529
if (event.getAdditionalAttrs() != null) {

src/main/java/com/scalyr/integrations/kafka/Event.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616

1717
package com.scalyr.integrations.kafka;
1818

19+
import com.fasterxml.jackson.core.io.SerializedString;
1920
import com.google.common.base.Strings;
2021
import com.google.common.collect.ImmutableSet;
2122

2223
import java.util.HashMap;
2324
import java.util.Map;
2425
import java.util.Objects;
2526
import java.util.Set;
26-
import java.util.stream.IntStream;
2727

2828
/**
2929
* Abstraction for a Scalyr Event.
@@ -48,7 +48,7 @@ public class Event {
4848

4949
// Event level fields
5050
private long timestamp;
51-
private String message;
51+
private SerializedString message;
5252
private Map<String, Object> additionalAttrs;
5353

5454
// Cached estimated event size
@@ -107,7 +107,7 @@ public Event setTimestamp(long timestamp) {
107107
}
108108

109109
public Event setMessage(String message) {
110-
this.message = message;
110+
this.message = message == null ? null : new SerializedString(message);
111111
return this;
112112
}
113113

@@ -170,7 +170,9 @@ public long getTimestamp() {
170170
return timestamp;
171171
}
172172

173-
public String getMessage() {
173+
public String getMessage() { return message == null ? null : message.getValue(); }
174+
175+
public SerializedString getSerializedMessage() {
174176
return message;
175177
}
176178

@@ -187,7 +189,7 @@ public int estimatedSerializedBytes() {
187189
return estimatedSizeBytes;
188190
}
189191

190-
int size = Strings.isNullOrEmpty(getMessage()) ? 0 : estimateEscapedStringSize(getMessage());
192+
int size = Strings.isNullOrEmpty(getMessage()) ? 0 : getSerializedMessage().asQuotedUTF8().length;
191193
size += getTopic().length();
192194
size += EVENT_SERIALIZATION_OVERHEAD_BYTES;
193195

@@ -222,11 +224,14 @@ private int estimateEscapedStringSize(String s) {
222224
return s.length();
223225
}
224226

225-
private int countJsonEscapedCharacters(String s) {
226-
return (int)IntStream.range(0, s.length())
227-
.mapToObj(s::charAt)
228-
.filter(JSON_ESCAPED_CHARS::contains)
229-
.count();
227+
public int countJsonEscapedCharacters(String s) {
228+
int escapedChars = 0;
229+
for (int i = 0; i < s.length(); i++) {
230+
if (JSON_ESCAPED_CHARS.contains(s.charAt(i))) {
231+
escapedChars++;
232+
}
233+
}
234+
return escapedChars;
230235
}
231236

232237
/**

src/test/java/com/scalyr/integrations/kafka/AddEventsClientTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ public void addEventsRequestTest() throws IOException {
121121
addEventsRequestTest(100, 5, 3, 2);
122122
}
123123

124+
/**
125+
* Verify JSON in Event message serialization
126+
*/
127+
@Test
128+
public void jsonMessageTest() throws IOException {
129+
final String jsonMsg = "{\"k1\":\"v1\", \"k2\":\"v2\", \"k3\": 1.0, \"k4\": {\"k1\":\"v1\", \"k2\":\"v2\"}}";
130+
List<Event> events = TestUtils.createTestEvents(10, jsonMsg, 1, 1, 1);
131+
createAndVerifyAddEventsRequest(events);
132+
}
133+
124134
/**
125135
* Create `numEvents` with the specified `numServers`, `numLogFiles`, `numParsers`
126136
* and verify the AddEventsRequest is serialized correctly to JSON.

src/test/java/com/scalyr/integrations/kafka/EventBufferTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ public void testJsonEventMsg() throws Exception {
6262
assertEquals(actualSerializedBytes, estimatedSerializedBytes, actualSerializedBytes * deltaPercent);
6363
}
6464

65+
/**
66+
* Test add events payload estimate with no message attribute.
67+
*/
68+
@Test
69+
public void testNullMessage() throws Exception {
70+
final int numEvents = 1000;
71+
EventBuffer eventBuffer = new EventBuffer();
72+
TestUtils.createTestEvents(numEvents, null, 100, 1, 1)
73+
.forEach(eventBuffer::addEvent);
74+
75+
final int estimatedSerializedBytes = eventBuffer.estimatedSerializedBytes();
76+
final int actualSerializedBytes = actualSerializedSize(eventBuffer.getEvents());
77+
// message field is not included in serialized payload when null, although estimates still include `message`
78+
// allow bigger delta to account for this
79+
assertEquals(actualSerializedBytes, estimatedSerializedBytes, actualSerializedBytes * deltaPercent * 2);
80+
}
81+
6582
/**
6683
* Calculate add events payload serialized size.
6784
*/

src/test/java/com/scalyr/integrations/kafka/TestUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ public static Stream<Event> createTestEventStream(int numEvents, String msg, int
138138
.addAdditionalAttr("app", "test")
139139
.addAdditionalAttr("isTest", true)
140140
.addAdditionalAttr("version", 2.3)
141+
.addAdditionalAttr("jsonAttr", "{\"k1\":\"v1\"}")
141142
.setEnrichmentAttrs(TestValues.ENRICHMENT_VALUE_MAP);
142143
});
143144
}

0 commit comments

Comments
 (0)