Skip to content

Commit 1931a0b

Browse files
authoredFeb 9, 2025··
Re #142: Agrona does not like array backed buffers due to mis-alignment performance hit. It does not allow to turn off the check on arm. (#143)
1 parent aa7c6eb commit 1931a0b

File tree

16 files changed

+52
-123
lines changed

16 files changed

+52
-123
lines changed
 

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Logging should be lightweight and not interfere with main business tasks of thre
4242
Asking the logging subsystem to log a message should be as CPU efficient as possible.
4343
That's a truism. Apart from computation itself there are many other causes of jitter (varying speed of code execution).
4444
Thread can be slowed down by excessive allocations, by initialization code running in constructors of unnecessarily allocated objects,
45-
by garbage collector activity that is triggered by it. There can by configuration refresh checks on logging path, inter thread signaling etc.
45+
by garbage collector activity that is triggered by it. There can be configuration refresh checks on logging path, inter thread signaling etc.
4646

4747
To avoid these effects we strive to adhere to the following principles (and document any violations):
4848

‎core/pom.xml

-7
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,5 @@
3333
<version>4.1.17</version>
3434
<scope>provided</scope>
3535
</dependency>
36-
37-
<!-- Test dependencies -->
38-
<dependency>
39-
<groupId>org.apache.logging.log4j</groupId>
40-
<artifactId>log4j-slf4j-impl</artifactId>
41-
<scope>test</scope>
42-
</dependency>
4336
</dependencies>
4437
</project>

‎core/src/main/java/pl/tkowalcz/tjahzi/TjahziInitializer.java

+3-13
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,10 @@ public LoggingSystem createLoggingSystem(
2626
int bufferSizeBytes,
2727
long logShipperWakeupIntervalMillis,
2828
long shutdownTimeoutMillis,
29-
boolean offHeap,
3029
boolean useDaemonThreads
3130
) {
3231
bufferSizeBytes = findNearestPowerOfTwo(bufferSizeBytes);
33-
ByteBuffer javaBuffer = allocateJavaBuffer(bufferSizeBytes, offHeap);
32+
ByteBuffer javaBuffer = allocateJavaBuffer(bufferSizeBytes);
3433

3534
ManyToOneRingBuffer logBuffer = new ManyToOneRingBuffer(
3635
new UnsafeBuffer(javaBuffer)
@@ -93,17 +92,8 @@ static int findNearestPowerOfTwo(int bufferSize) {
9392
return bufferSize;
9493
}
9594

96-
private ByteBuffer allocateJavaBuffer(
97-
int bufferSize,
98-
boolean offHeap) {
95+
private ByteBuffer allocateJavaBuffer(int bufferSize) {
9996
int totalSize = bufferSize + RingBufferDescriptor.TRAILER_LENGTH;
100-
101-
if (offHeap) {
102-
return ByteBuffer.allocateDirect(totalSize)
103-
.order(ByteOrder.LITTLE_ENDIAN);
104-
}
105-
106-
return ByteBuffer.allocate(totalSize)
107-
.order(ByteOrder.LITTLE_ENDIAN);
97+
return ByteBuffer.allocateDirect(totalSize).order(ByteOrder.LITTLE_ENDIAN);
10898
}
10999
}

‎core/src/test/java/pl/tkowalcz/tjahzi/HeadersTest.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@
1414
import java.util.Map;
1515
import java.util.concurrent.TimeUnit;
1616

17-
import static com.github.tomakehurst.wiremock.client.WireMock.*;
17+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
18+
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
19+
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
20+
import static com.github.tomakehurst.wiremock.client.WireMock.post;
21+
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
22+
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
23+
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
1824
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
1925
import static org.awaitility.Awaitility.await;
2026

@@ -91,7 +97,6 @@ void shouldIncludeAdditionalHeaders() {
9197
1024 * 1024,
9298
250,
9399
10_000,
94-
false,
95100
false
96101
);
97102
loggingSystem.start();
@@ -146,7 +151,6 @@ void shouldHandleCaseWithNoAdditionalHeaders() {
146151
1024 * 1024,
147152
250,
148153
10_000,
149-
false,
150154
false
151155
);
152156
loggingSystem.start();
@@ -203,7 +207,6 @@ void shouldNotOverrideCrucialHeaders() {
203207
1024 * 1024,
204208
250,
205209
10_000,
206-
false,
207210
false
208211
);
209212
loggingSystem.start();

‎core/src/test/java/pl/tkowalcz/tjahzi/LoggingSystemSanityCheckTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ void setUp() {
6969
1024 * 1024,
7070
250,
7171
10_000,
72-
false,
7372
false
7473
);
7574

@@ -126,7 +125,7 @@ void sendData() {
126125
.body("data.result[0].stream.server", equalTo("127.0.0.1"))
127126
.body("data.result[0].stream.version", equalTo("0.43"))
128127
.body("data.result[0].stream.level", equalTo("warn"))
129-
.body("data.result[0].values[0]", hasItems("" + (timestamp * 1000_000 +882), "Test"));
128+
.body("data.result[0].values[0]", hasItems("" + (timestamp * 1000_000 + 882), "Test"));
130129
});
131130
}
132131
}

‎core/src/test/java/pl/tkowalcz/tjahzi/LoggingSystemTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ void setUp() {
7373
0,
7474
250,
7575
10_000,
76-
false,
7776
false
7877
);
7978

@@ -159,7 +158,7 @@ public boolean matches(Object o) {
159158
index--;
160159

161160
return actualTimestamp == expectedTimestamp
162-
&& actualLogLine.equals(expectedLogLine);
161+
&& actualLogLine.equals(expectedLogLine);
163162
}
164163
}));
165164
});

‎core/src/test/java/pl/tkowalcz/tjahzi/ReconnectTest.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
import java.util.Map;
1515
import java.util.concurrent.TimeUnit;
1616

17-
import static com.github.tomakehurst.wiremock.client.WireMock.*;
17+
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
18+
import static com.github.tomakehurst.wiremock.client.WireMock.post;
19+
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
20+
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
21+
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
1822
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
1923
import static org.awaitility.Awaitility.await;
2024

@@ -86,7 +90,6 @@ void shouldEventuallyReconnectIfLokiWasDownWhenStarting() {
8690
1024 * 1024,
8791
250,
8892
10_000,
89-
false,
9093
false
9194
);
9295
loggingSystem.start();
@@ -139,7 +142,6 @@ void shouldReconnectIfLokiFailed() {
139142
1024 * 1024,
140143
250,
141144
10_000,
142-
false,
143145
false
144146
);
145147
loggingSystem.start();

‎core/src/test/java/pl/tkowalcz/tjahzi/ResourcesCleanupOnCloseTest.java

-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ void shouldStopThreads() {
8282
1024 * 1024,
8383
250,
8484
10_000,
85-
false,
8685
false
8786
);
8887
loggingSystem.start();
@@ -146,7 +145,6 @@ void shouldStartThreadsAsDaemon() {
146145
1024 * 1024,
147146
250,
148147
10_000,
149-
false,
150148
true
151149
);
152150
loggingSystem.start();

‎log4j2-appender/README.md

-6
Original file line numberDiff line numberDiff line change
@@ -327,12 +327,6 @@ to retry indefinitely employing exponential backoff (initial backoff = 250ms, ma
327327

328328
Sets socket read timeout on Loki connection.
329329

330-
#### useOffHeapBuffer (optional, default = true)
331-
332-
Whether Tjahzi should allocate native buffer for `Log buffer` component. We can go into a rabbit hole of divagations
333-
what are the implications of this. Most important in our view is that having 10s or 100s of MB of space taken out of
334-
heap is not very friendly to garbage collector which might have to occasionally copy it around.
335-
336330
#### batchSize (optional, default = 10_2400)
337331

338332
Like

‎log4j2-appender/pom.xml

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
34

45
<modelVersion>4.0.0</modelVersion>
@@ -40,30 +41,4 @@
4041
<scope>test</scope>
4142
</dependency>
4243
</dependencies>
43-
44-
<profiles>
45-
<profile>
46-
<id>allocation-profiling</id>
47-
<build>
48-
<plugins>
49-
<plugin>
50-
<groupId>org.apache.maven.plugins</groupId>
51-
<artifactId>maven-surefire-plugin</artifactId>
52-
<configuration>
53-
<argLine>
54-
-javaagent:"${settings.localRepository}/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.3.0/java-allocation-instrumenter-3.3.0.jar"
55-
</argLine>
56-
</configuration>
57-
<dependencies>
58-
<dependency>
59-
<groupId>com.google.code.java-allocation-instrumenter</groupId>
60-
<artifactId>java-allocation-instrumenter</artifactId>
61-
<version>3.3.0</version>
62-
</dependency>
63-
</dependencies>
64-
</plugin>
65-
</plugins>
66-
</build>
67-
</profile>
68-
</profiles>
6944
</project>

‎log4j2-appender/src/main/java/pl/tkowalcz/tjahzi/log4j2/LokiAppenderBuilder.java

-12
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@ public class LokiAppenderBuilder<B extends LokiAppenderBuilder<B>> extends Abstr
7171
@PluginBuilderAttribute
7272
private int bufferSizeMegabytes = 32;
7373

74-
@PluginBuilderAttribute
75-
private boolean useOffHeapBuffer = true;
76-
7774
@PluginBuilderAttribute
7875
private String logLevelLabel;
7976

@@ -158,7 +155,6 @@ public LokiAppender build() {
158155
bufferSizeBytes,
159156
logShipperWakeupIntervalMillis,
160157
TimeUnit.SECONDS.toMillis(shutdownTimeoutSeconds),
161-
isUseOffHeapBuffer(),
162158
useDaemonThreads
163159
);
164160

@@ -280,14 +276,6 @@ public void setBufferSizeMegabytes(int bufferSizeMegabytes) {
280276
this.bufferSizeMegabytes = bufferSizeMegabytes;
281277
}
282278

283-
public boolean isUseOffHeapBuffer() {
284-
return useOffHeapBuffer;
285-
}
286-
287-
public void setUseOffHeapBuffer(boolean useOffHeapBuffer) {
288-
this.useOffHeapBuffer = useOffHeapBuffer;
289-
}
290-
291279
public String getLogLevelLabel() {
292280
return logLevelLabel;
293281
}

‎logback-appender/README.md

-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ or use Tjahzi optimized efficient, low allocation encoder:
281281
| MaxRetries | 3 | Maximum number of retries to perform when delivering log message to Loki. Log buffer data is delivered in order, one batch after the other, so too much retries will block delivery of subsequent log batches (on the other hand if we need to retry many times then next batches will probably fail too). |
282282
| ConnectTimeoutMillis | 5s | This configures socket connect timeout when connecting to Loki. After unsuccessful connection attempt it will continue to retry indefinitely employing exponential backoff (initial backoff = 250ms, maximum backoff = 30s, multiplier = 3). |
283283
| ReadTimeoutMillis | 60s | Sets socket read timeout on Loki connection. |
284-
| UseOffHeapBuffer | true | Whether Tjahzi should allocate native buffer for `Log buffer` component. We can go into a rabbit hole of divagations what are the implications of this. Most important in our view is that having 10s or 100s of MB of space taken out of heap is not very friendly to garbage collector which might have to occasionally copy it around. |
285284
| BatchSize | 100 KB | Like in [promtail configuration](https://grafana.com/docs/loki/latest/clients/promtail/configuration/) `maximum batch size (in bytes) of logs to accumulate before sending the batch to Loki`. |
286285
| BatchWait | 5s | Like in [promtail configuration](https://grafana.com/docs/loki/latest/clients/promtail/configuration/) `maximum amount of time to wait before sending a batch, even if that batch isn't full`. |
287286
| logShipperWakeupIntervalMillis | 10 | The agent that reads data from log buffer, compresses it and sends to Loki via http is called `LogShipper`. This property controls how often it wakes up to perform its duties. Other properties control how often the data should be sent to Loki (`batchSize`, `batchWait`) this one just control how often to wake up and check for these conditions. In versions before `0.9.17` it was left at default 1ms which caused high CPU usage on some setups. |

‎logback-appender/pom.xml

-31
Original file line numberDiff line numberDiff line change
@@ -49,35 +49,4 @@
4949
<scope>test</scope>
5050
</dependency>
5151
</dependencies>
52-
53-
<profiles>
54-
<profile>
55-
<id>allocation-profiling</id>
56-
<build>
57-
<plugins>
58-
<plugin>
59-
<groupId>org.apache.maven.plugins</groupId>
60-
<artifactId>maven-surefire-plugin</artifactId>
61-
<version>3.0.0-M5</version>
62-
<configuration>
63-
<argLine>
64-
-javaagent:"${settings.localRepository}/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.3.0/java-allocation-instrumenter-3.3.0.jar"
65-
</argLine>
66-
</configuration>
67-
<dependencies>
68-
<dependency>
69-
<groupId>
70-
com.google.code.java-allocation-instrumenter
71-
</groupId>
72-
<artifactId>
73-
java-allocation-instrumenter
74-
</artifactId>
75-
<version>3.3.0</version>
76-
</dependency>
77-
</dependencies>
78-
</plugin>
79-
</plugins>
80-
</build>
81-
</profile>
82-
</profiles>
8352
</project>

‎logback-appender/src/main/java/pl/tkowalcz/tjahzi/logback/LokiAppenderConfigurator.java

-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public abstract class LokiAppenderConfigurator extends UnsynchronizedAppenderBas
2929
private int maxRetries = 3;
3030

3131
private int bufferSizeMegabytes = 32;
32-
private boolean useOffHeapBuffer = true;
3332

3433
private String logLevelLabel;
3534
private String loggerNameLabel;
@@ -142,14 +141,6 @@ public void setBufferSizeMegabytes(int bufferSizeMegabytes) {
142141
this.bufferSizeMegabytes = bufferSizeMegabytes;
143142
}
144143

145-
public boolean isUseOffHeapBuffer() {
146-
return useOffHeapBuffer;
147-
}
148-
149-
public void setUseOffHeapBuffer(boolean useOffHeapBuffer) {
150-
this.useOffHeapBuffer = useOffHeapBuffer;
151-
}
152-
153144
public String getLogLevelLabel() {
154145
return logLevelLabel;
155146
}

‎logback-appender/src/main/java/pl/tkowalcz/tjahzi/logback/LokiAppenderFactory.java

-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ public LoggingSystem createAppender() {
9393
bufferSizeBytes,
9494
configurator.getLogShipperWakeupIntervalMillis(),
9595
TimeUnit.SECONDS.toMillis(configurator.getShutdownTimeoutSeconds()),
96-
configurator.isUseOffHeapBuffer(),
9796
configurator.isUseDaemonThreads()
9897
);
9998
}

‎pom.xml

+32-2
Original file line numberDiff line numberDiff line change
@@ -357,14 +357,44 @@
357357
<version>3.5.2</version>
358358
<configuration>
359359
<argLine>
360-
--add-opens java.base/java.net=ALL-UNNAMED
361-
--add-opens java.base/sun.net=ALL-UNNAMED
360+
--add-opens
361+
java.base/java.net=ALL-UNNAMED
362+
--add-opens
363+
java.base/sun.net=ALL-UNNAMED
362364
</argLine>
363365
</configuration>
364366
</plugin>
365367
</plugins>
366368
</pluginManagement>
367369
</build>
368370
</profile>
371+
<profile>
372+
<id>allocation-profiling</id>
373+
<build>
374+
<plugins>
375+
<plugin>
376+
<groupId>org.apache.maven.plugins</groupId>
377+
<artifactId>maven-surefire-plugin</artifactId>
378+
<version>3.0.0-M5</version>
379+
<configuration>
380+
<argLine>
381+
-javaagent:"${settings.localRepository}/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.3.0/java-allocation-instrumenter-3.3.0.jar"
382+
</argLine>
383+
</configuration>
384+
<dependencies>
385+
<dependency>
386+
<groupId>
387+
com.google.code.java-allocation-instrumenter
388+
</groupId>
389+
<artifactId>
390+
java-allocation-instrumenter
391+
</artifactId>
392+
<version>3.3.0</version>
393+
</dependency>
394+
</dependencies>
395+
</plugin>
396+
</plugins>
397+
</build>
398+
</profile>
369399
</profiles>
370400
</project>

0 commit comments

Comments
 (0)
Please sign in to comment.