I tried logback but it created a ton of garbage. Does anyone heard about a good one for real-time Java?
@Bernie: I did a loop logging 1M cached messages and the GC went crazy.
I have a library which can log text or binary data in under a micro-second without creating garbage or even a system call.
https://github.com/peter-lawrey/Java-Chronicle
The log can also be read in real time by any number of reading processes, giving you a persisted queue which can handle over 5 million messages per second.
You can take a look on CoralLog designed by Coral Blocks (with which I am affiliated) that produces zero garbage and has an average latency of 53 nanoseconds when logging a 64-byte message. In terms of throughput, it can log 2.6 million 64-byte messages per second with timestamps and 3.5 million 64-byte messages per second without timestamps. The complete benchmark results can be seen here.
If you reduce the message size to 16 bytes then you can log 5.2 million messages per second without timestamps.
Below is a simple throughput test:
package com.coralblocks.corallog.bench;
import java.io.File;
import java.nio.ByteBuffer;
import com.coralblocks.corallog.AsyncThread;
import com.coralblocks.corallog.Log;
import com.coralblocks.corallog.Logger;
public class PerformanceTest4 {
public static void main(String[] args) throws Exception {
int batchSize = Integer.parseInt(args[0]);
int passes = Integer.parseInt(args[1]);
int msgSize = Integer.parseInt(args[2]);
byte[] msgBytes = new byte[msgSize];
// build a dummy message:
for(int i = 0; i < msgBytes.length; i++) {
msgBytes[i] = (byte) String.valueOf(i % 10).charAt(0);
}
ByteBuffer bb = ByteBuffer.wrap(msgBytes);
Log.setIncludeTopHeader(false);
String dir = ".";
String filename = "throughput.log";
Logger logger;
boolean isMmap = System.getProperty("logMemoryMappedFile", "true").equals("true");
if (isMmap) {
logger = Log.createMemoryMappedLogger(dir, filename, null /* no timestamps */, false /* not synchronized */, true /* asynchronous */);
} else {
logger = Log.createLogger(dir, filename, null, false, true);
}
int count = 0;
while(count < passes) {
long start = System.nanoTime();
for(int i = 0; i < batchSize; i++) {
bb.position(0);
logger.log(bb);
}
long time = System.nanoTime() - start;
double seconds = (((double) time) / 1000000000L);
System.out.println("Batch " + (count + 1) + " took: " + seconds + " s");
count++;
}
logger.drainCloseAndWait();
boolean deleteFile = System.getProperty("deleteFile", "true").equals("true");
if (deleteFile) {
File f = new File(dir, filename);
f.delete();
}
AsyncThread.drainAndDie(); // just so the vm will exit... (async thread is not daemon)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With