Reputation: 4038
I am using java logging(the one provided by default)in the java environment.
I wanted to ask how I could aggregate my readings and log lets say once every second instead of more often(I seem to be logging 20 times a second). How can that be done?
Is there any setting that I can use where it pushes data to file less often? I have never logged before so I am not sure if it is possible.Thank you.
EDIT: I am logging response time, throughput and stuff like that. Since my program is heavy I want jul to buffer and log less often.
Upvotes: 0
Views: 890
Reputation: 1654
To customize logging with JUL you can write your own Handler implementation. If you want to log to a file you should extend FileHandler. An implementation using ConsoleHandler could look like this:
package my.logging;
import java.util.Queue;
import java.util.concurrent.*;
import java.util.logging.ConsoleHandler;
import java.util.logging.LogRecord;
public class BufferingHandler extends ConsoleHandler implements AutoCloseable {
private final Queue<LogRecord> logRecordsFifo = new ConcurrentLinkedQueue<>();
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public BufferingHandler(final int delay, final TimeUnit timeUnit) {
super();
scheduler.scheduleWithFixedDelay(() -> handleLogs(), delay, delay, timeUnit);
}
private void handleLogs() {
while (!logRecordsFifo.isEmpty()) {
// sync is required to preserve logs order when flushing
synchronized (logRecordsFifo) {
final LogRecord log = logRecordsFifo.poll();
if (log != null) super.publish(log);
}
}
}
@Override
public void publish(final LogRecord record) {
if (!isLoggable(record)) return;
logRecordsFifo.add(record);
}
@Override
public void flush() {
handleLogs();
super.flush();
}
@Override
public void close() {
scheduler.shutdown();
flush();
super.close();
}
}
Usage of this handler could look like this:
import my.logging.BufferingHandler;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
public class App {
public static void main(String[] args) throws InterruptedException {
final Logger logger = Logger.getLogger(App.class.getName());
try (final BufferingHandler bufferingHandler = new BufferingHandler(1, TimeUnit.SECONDS)) {
logger.addHandler(bufferingHandler);
for (int i = 0; i < 30; ++i) {
Thread.sleep(200);
logger.info("some info: " + i);
}
}
}
}
Upvotes: 2