diff options
| author | Paul Buetow <paul@buetow.org> | 2026-01-09 23:26:31 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-01-09 23:26:31 +0200 |
| commit | 15ea7f40cd7302b9bf9f0aea0d85a970a8a7c07f (patch) | |
| tree | 897055fcb651cae1f5e96e14c966243325e95286 /src | |
Add Log4j2 benchmark tool
- Configurable thread count, duration, message size
- Multiple logging configurations: sync-immediate, sync-buffered
- AsyncLogger variants: 1k, 4k, 10k, 1m ring buffer sizes
- AsyncAppender variants: 1k, 4k, 10k, 1m buffer sizes
- Subprocess isolation for proper async logger initialization
- Cache dropping between tests for accurate benchmarks
- CSV output support
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/java/bench/BenchConfig.java | 48 | ||||
| -rw-r--r-- | src/main/java/bench/BenchRunner.java | 153 | ||||
| -rw-r--r-- | src/main/java/bench/LogWorker.java | 51 | ||||
| -rw-r--r-- | src/main/java/bench/Main.java | 185 | ||||
| -rw-r--r-- | src/main/java/bench/SingleBench.java | 84 | ||||
| -rw-r--r-- | src/main/resources/log4j2-async-10k.xml | 19 | ||||
| -rw-r--r-- | src/main/resources/log4j2-async-1k.xml | 19 | ||||
| -rw-r--r-- | src/main/resources/log4j2-async-1m.xml | 16 | ||||
| -rw-r--r-- | src/main/resources/log4j2-async-4k.xml | 19 | ||||
| -rw-r--r-- | src/main/resources/log4j2-asyncapp-10k.xml | 16 | ||||
| -rw-r--r-- | src/main/resources/log4j2-asyncapp-1k.xml | 16 | ||||
| -rw-r--r-- | src/main/resources/log4j2-asyncapp-1m.xml | 16 | ||||
| -rw-r--r-- | src/main/resources/log4j2-asyncapp-4k.xml | 16 | ||||
| -rw-r--r-- | src/main/resources/log4j2-sync-buffered.xml | 13 | ||||
| -rw-r--r-- | src/main/resources/log4j2-sync-immediate.xml | 13 |
15 files changed, 684 insertions, 0 deletions
diff --git a/src/main/java/bench/BenchConfig.java b/src/main/java/bench/BenchConfig.java new file mode 100644 index 0000000..cc73444 --- /dev/null +++ b/src/main/java/bench/BenchConfig.java @@ -0,0 +1,48 @@ +package bench; + +import java.util.List; + +public class BenchConfig { + public enum Mode { DURATION, EVENTS } + + private int threads = 10; + private Mode mode = Mode.DURATION; + private long durationSeconds = 10; + private long totalEvents = 1_000_000; + private long warmupSeconds = 3; + private int messageSize = 100; + private List<String> configs = List.of( + "sync-immediate", "sync-buffered", + "async-1k", "async-4k", "async-10k", + "asyncapp-1k", "asyncapp-4k", "asyncapp-10k" + ); + private String outputFile = null; + + public int getThreads() { return threads; } + public void setThreads(int threads) { this.threads = threads; } + + public Mode getMode() { return mode; } + public void setMode(Mode mode) { this.mode = mode; } + + public long getDurationSeconds() { return durationSeconds; } + public void setDurationSeconds(long durationSeconds) { this.durationSeconds = durationSeconds; } + + public long getTotalEvents() { return totalEvents; } + public void setTotalEvents(long totalEvents) { this.totalEvents = totalEvents; } + + public long getWarmupSeconds() { return warmupSeconds; } + public void setWarmupSeconds(long warmupSeconds) { this.warmupSeconds = warmupSeconds; } + + public int getMessageSize() { return messageSize; } + public void setMessageSize(int messageSize) { this.messageSize = messageSize; } + + public List<String> getConfigs() { return configs; } + public void setConfigs(List<String> configs) { this.configs = configs; } + + public String getOutputFile() { return outputFile; } + public void setOutputFile(String outputFile) { this.outputFile = outputFile; } + + public String generateMessage() { + return "X".repeat(messageSize); + } +} diff --git a/src/main/java/bench/BenchRunner.java b/src/main/java/bench/BenchRunner.java new file mode 100644 index 0000000..5312266 --- /dev/null +++ b/src/main/java/bench/BenchRunner.java @@ -0,0 +1,153 @@ +package bench; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.Configurator; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +public class BenchRunner { + private final BenchConfig config; + + public BenchRunner(BenchConfig config) { + this.config = config; + } + + public BenchResult run(String configName) throws Exception { + dropCaches(); + reconfigure(configName); + + Logger logger = LogManager.getLogger("bench"); + String message = config.generateMessage(); + int messageBytes = message.getBytes().length; + + CountDownLatch startLatch = new CountDownLatch(1); + AtomicBoolean running = new AtomicBoolean(true); + AtomicLong eventCounter = new AtomicLong(0); + AtomicLong targetEvents = new AtomicLong(config.getTotalEvents()); + + List<Thread> threads = new ArrayList<>(); + for (int i = 0; i < config.getThreads(); i++) { + Thread t = new Thread(new LogWorker( + logger, message, startLatch, running, eventCounter, targetEvents, config.getMode() + )); + t.start(); + threads.add(t); + } + + // Warmup phase + if (config.getWarmupSeconds() > 0) { + startLatch.countDown(); + Thread.sleep(config.getWarmupSeconds() * 1000); + eventCounter.set(0); + } else { + startLatch.countDown(); + } + + long startTime = System.nanoTime(); + + if (config.getMode() == BenchConfig.Mode.DURATION) { + Thread.sleep(config.getDurationSeconds() * 1000); + running.set(false); + } else { + while (eventCounter.get() < targetEvents.get()) { + Thread.sleep(10); + } + running.set(false); + } + + long endTime = System.nanoTime(); + + for (Thread t : threads) { + t.join(5000); + } + + long events = eventCounter.get(); + double durationSec = (endTime - startTime) / 1_000_000_000.0; + double eventsPerSec = events / durationSec; + double bytesPerSec = (events * messageBytes) / durationSec; + double mbPerSec = bytesPerSec / (1024 * 1024); + + // Shutdown log4j context to flush and release resources + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + ctx.stop(); + + return new BenchResult(configName, config.getThreads(), events, durationSec, eventsPerSec, mbPerSec); + } + + private void dropCaches() { + try { + ProcessBuilder pb = new ProcessBuilder("sh", "-c", "sync; echo 3 > /proc/sys/vm/drop_caches"); + pb.inheritIO(); + Process p = pb.start(); + int exitCode = p.waitFor(); + if (exitCode != 0) { + System.err.println("Warning: Failed to drop caches (exit code " + exitCode + "). Run as root for accurate benchmarks."); + } + } catch (Exception e) { + System.err.println("Warning: Could not drop caches: " + e.getMessage()); + } + } + + private void reconfigure(String configName) throws Exception { + // Fully shutdown existing context + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + ctx.stop(); + + // Set async ring buffer size via system property (must be set before reconfigure) + if (configName.startsWith("async-")) { + String size = configName.substring(6); // e.g., "1k", "4k", "10k" + int bufferSize = switch (size) { + case "1k" -> 1024; + case "4k" -> 4096; + case "10k" -> 10240; + default -> 4096; + }; + System.setProperty("log4j2.asyncLoggerRingBufferSize", String.valueOf(bufferSize)); + System.setProperty("log4j2.contextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); + } else { + System.clearProperty("log4j2.asyncLoggerRingBufferSize"); + System.clearProperty("log4j2.contextSelector"); + } + + String resourcePath = "log4j2-" + configName + ".xml"; + URI uri = getClass().getClassLoader().getResource(resourcePath).toURI(); + Configurator.reconfigure(uri); + } + + public static class BenchResult { + public final String configName; + public final int threads; + public final long events; + public final double durationSec; + public final double eventsPerSec; + public final double mbPerSec; + + public BenchResult(String configName, int threads, long events, + double durationSec, double eventsPerSec, double mbPerSec) { + this.configName = configName; + this.threads = threads; + this.events = events; + this.durationSec = durationSec; + this.eventsPerSec = eventsPerSec; + this.mbPerSec = mbPerSec; + } + + public String toCsv() { + return String.format("%s,%d,%d,%.2f,%.0f,%.2f", + configName, threads, events, durationSec, eventsPerSec, mbPerSec); + } + + @Override + public String toString() { + return String.format("%-16s | %3d threads | %,12d events | %.2fs | %,.0f events/s | %.2f MB/s", + configName, threads, events, durationSec, eventsPerSec, mbPerSec); + } + } +} diff --git a/src/main/java/bench/LogWorker.java b/src/main/java/bench/LogWorker.java new file mode 100644 index 0000000..5a9edfc --- /dev/null +++ b/src/main/java/bench/LogWorker.java @@ -0,0 +1,51 @@ +package bench; + +import org.apache.logging.log4j.Logger; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +public class LogWorker implements Runnable { + private final Logger logger; + private final String message; + private final CountDownLatch startLatch; + private final AtomicBoolean running; + private final AtomicLong eventCounter; + private final AtomicLong targetEvents; + private final BenchConfig.Mode mode; + + public LogWorker(Logger logger, String message, CountDownLatch startLatch, + AtomicBoolean running, AtomicLong eventCounter, + AtomicLong targetEvents, BenchConfig.Mode mode) { + this.logger = logger; + this.message = message; + this.startLatch = startLatch; + this.running = running; + this.eventCounter = eventCounter; + this.targetEvents = targetEvents; + this.mode = mode; + } + + @Override + public void run() { + try { + startLatch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + + if (mode == BenchConfig.Mode.DURATION) { + while (running.get()) { + logger.info(message); + eventCounter.incrementAndGet(); + } + } else { + while (running.get() && eventCounter.get() < targetEvents.get()) { + logger.info(message); + eventCounter.incrementAndGet(); + } + } + } +} diff --git a/src/main/java/bench/Main.java b/src/main/java/bench/Main.java new file mode 100644 index 0000000..0ce0f3c --- /dev/null +++ b/src/main/java/bench/Main.java @@ -0,0 +1,185 @@ +package bench; + +import picocli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +import java.io.FileWriter; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; + +@Command(name = "log4jbench", mixinStandardHelpOptions = true, version = "1.0", + description = "Benchmark Log4j2 logging throughput with various configurations") +public class Main implements Callable<Integer> { + + @Option(names = {"-t", "--threads"}, description = "Number of concurrent threads (default: 10)") + private int threads = 10; + + @Option(names = {"-m", "--mode"}, description = "Test mode: duration or events (default: duration)") + private String mode = "duration"; + + @Option(names = {"-d", "--duration"}, description = "Test duration in seconds (default: 10)") + private long duration = 10; + + @Option(names = {"-e", "--events"}, description = "Total events to log in events mode (default: 1000000)") + private long events = 1_000_000; + + @Option(names = {"-w", "--warmup"}, description = "Warmup duration in seconds (default: 3)") + private long warmup = 3; + + @Option(names = {"-s", "--msg-size"}, description = "Message size in characters (default: 100)") + private int msgSize = 100; + + @Option(names = {"-c", "--configs"}, description = "Comma-separated list of configs to test (default: all)") + private String configs = null; + + @Option(names = {"-o", "--output"}, description = "Output CSV file (default: stdout only)") + private String outputFile = null; + + @Option(names = {"--flush"}, description = "Call LogManager.shutdown() to flush at end of each test (default: false)") + private boolean flush = false; + + public static void main(String[] args) { + // Must set context selector before ANY Log4j initialization + // We'll set it dynamically per-config in BenchRunner instead + int exitCode = new CommandLine(new Main()).execute(args); + System.exit(exitCode); + } + + @Override + public Integer call() throws Exception { + BenchConfig config = new BenchConfig(); + config.setThreads(threads); + config.setMode("events".equalsIgnoreCase(mode) ? BenchConfig.Mode.EVENTS : BenchConfig.Mode.DURATION); + config.setDurationSeconds(duration); + config.setTotalEvents(events); + config.setWarmupSeconds(warmup); + config.setMessageSize(msgSize); + config.setOutputFile(outputFile); + + if (configs != null && !configs.isBlank()) { + config.setConfigs(Arrays.asList(configs.split(","))); + } + + System.out.println("=== Log4j2 Benchmark ==="); + System.out.printf("Threads: %d | Mode: %s | Message size: %d chars | flush: %s%n", + config.getThreads(), config.getMode(), config.getMessageSize(), flush); + if (config.getMode() == BenchConfig.Mode.DURATION) { + System.out.printf("Duration: %ds | Warmup: %ds%n", config.getDurationSeconds(), config.getWarmupSeconds()); + } else { + System.out.printf("Target events: %,d | Warmup: %ds%n", config.getTotalEvents(), config.getWarmupSeconds()); + } + System.out.printf("Configs: %s%n", config.getConfigs()); + System.out.println(); + + PrintWriter csvWriter = null; + if (outputFile != null) { + csvWriter = new PrintWriter(new FileWriter(outputFile)); + csvWriter.println("config,threads,events,duration_sec,events_per_sec,mb_per_sec"); + } + + String jarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); + String javaHome = System.getProperty("java.home"); + String javaBin = javaHome + "/bin/java"; + + for (String configName : config.getConfigs()) { + System.out.printf("Running: %s ...%n", configName); + try { + // Drop caches before each test + dropCaches(); + + // Build command with appropriate system properties + List<String> cmd = new ArrayList<>(); + cmd.add(javaBin); + + // Set async properties if needed + if (configName.startsWith("async-")) { + String size = configName.substring(6); + int bufferSize = switch (size) { + case "1k" -> 1024; + case "4k" -> 4096; + case "10k" -> 10240; + case "1m" -> 1048576; + default -> 4096; + }; + cmd.add("-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"); + cmd.add("-Dlog4j2.asyncLoggerRingBufferSize=" + bufferSize); + } + + // Set log4j config file (use classpath reference) + cmd.add("-Dlog4j2.configurationFile=classpath:log4j2-" + configName + ".xml"); + + // Pass flush setting + cmd.add("-Dbench.flush=" + flush); + + cmd.add("-cp"); + cmd.add(jarPath); + cmd.add("bench.SingleBench"); + cmd.add(configName); + cmd.add(String.valueOf(config.getThreads())); + cmd.add(String.valueOf(config.getDurationSeconds())); + cmd.add(String.valueOf(config.getWarmupSeconds())); + cmd.add(String.valueOf(config.getMessageSize())); + + ProcessBuilder pb = new ProcessBuilder(cmd); + pb.redirectErrorStream(true); + Process p = pb.start(); + + long pid = p.pid(); + System.out.printf(" [PID: %d]%n", pid); + + String output = new String(p.getInputStream().readAllBytes()); + int exitCode = p.waitFor(); + + if (exitCode == 0 && !output.isBlank()) { + String[] parts = output.trim().split(","); + if (parts.length >= 6) { + String resultLine = String.format("%-16s | %3d threads | %,12d events | %.2fs | %,.0f events/s | %.2f MB/s", + parts[0], Integer.parseInt(parts[1]), Long.parseLong(parts[2]), + Double.parseDouble(parts[3]), Double.parseDouble(parts[4]), Double.parseDouble(parts[5])); + System.out.println(resultLine); + if (csvWriter != null) { + csvWriter.println(output.trim()); + csvWriter.flush(); + } + } else { + System.out.println(output); + } + } else { + System.err.printf("Error (exit %d): %s%n", exitCode, output); + } + } catch (Exception e) { + System.err.printf("Error running config %s: %s%n", configName, e.getMessage()); + e.printStackTrace(); + } + System.out.println(); + } + + if (csvWriter != null) { + csvWriter.close(); + System.out.printf("Results written to: %s%n", outputFile); + } + + return 0; + } + + private void dropCaches() { + try { + System.out.print(" Dropping caches... "); + System.out.flush(); + ProcessBuilder pb = new ProcessBuilder("sh", "-c", "sync; echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null"); + Process p = pb.start(); + int exitCode = p.waitFor(); + if (exitCode == 0) { + System.out.println("done"); + } else { + System.out.println("failed (exit code " + exitCode + "). Ensure sudo is available."); + } + } catch (Exception e) { + System.out.println("failed: " + e.getMessage()); + } + } +} diff --git a/src/main/java/bench/SingleBench.java b/src/main/java/bench/SingleBench.java new file mode 100644 index 0000000..2ce39eb --- /dev/null +++ b/src/main/java/bench/SingleBench.java @@ -0,0 +1,84 @@ +package bench; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +public class SingleBench { + + public static void main(String[] args) throws Exception { + if (args.length < 5) { + System.err.println("Usage: SingleBench <configName> <threads> <durationSec> <warmupSec> <msgSize>"); + System.exit(1); + } + + String configName = args[0]; + int threadCount = Integer.parseInt(args[1]); + long durationSec = Long.parseLong(args[2]); + long warmupSec = Long.parseLong(args[3]); + int msgSize = Integer.parseInt(args[4]); + + String message = "X".repeat(msgSize); + int messageBytes = message.getBytes().length; + + Logger logger = LogManager.getLogger("bench"); + + CountDownLatch startLatch = new CountDownLatch(1); + AtomicBoolean running = new AtomicBoolean(true); + AtomicLong eventCounter = new AtomicLong(0); + + List<Thread> threads = new ArrayList<>(); + for (int i = 0; i < threadCount; i++) { + Thread t = new Thread(() -> { + try { + startLatch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + while (running.get()) { + logger.info(message); + eventCounter.incrementAndGet(); + } + }); + t.start(); + threads.add(t); + } + + // Warmup phase + startLatch.countDown(); + if (warmupSec > 0) { + Thread.sleep(warmupSec * 1000); + eventCounter.set(0); + } + + long startTime = System.nanoTime(); + Thread.sleep(durationSec * 1000); + running.set(false); + long endTime = System.nanoTime(); + + for (Thread t : threads) { + t.join(5000); + } + + long events = eventCounter.get(); + double duration = (endTime - startTime) / 1_000_000_000.0; + double eventsPerSec = events / duration; + double mbPerSec = (events * messageBytes) / duration / (1024 * 1024); + + // Output CSV line: config,threads,events,duration,events_per_sec,mb_per_sec + System.out.printf("%s,%d,%d,%.2f,%.0f,%.2f%n", + configName, threadCount, events, duration, eventsPerSec, mbPerSec); + + // Only flush/shutdown if requested (default: no flush for max perf) + boolean doFlush = Boolean.getBoolean("bench.flush"); + if (doFlush) { + LogManager.shutdown(); + } + } +} diff --git a/src/main/resources/log4j2-async-10k.xml b/src/main/resources/log4j2-async-10k.xml new file mode 100644 index 0000000..b2d26a9 --- /dev/null +++ b/src/main/resources/log4j2-async-10k.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="false" bufferSize="8192"> + <PatternLayout pattern="[ASYNC-10K] %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + </Appenders> + <Loggers> + <AsyncLogger name="bench" level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </AsyncLogger> + <Root level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </Root> + </Loggers> + <Properties> + <Property name="log4j2.asyncLoggerRingBufferSize">10240</Property> + </Properties> +</Configuration> diff --git a/src/main/resources/log4j2-async-1k.xml b/src/main/resources/log4j2-async-1k.xml new file mode 100644 index 0000000..66389fe --- /dev/null +++ b/src/main/resources/log4j2-async-1k.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="false" bufferSize="8192"> + <PatternLayout pattern="[ASYNC-1K] %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + </Appenders> + <Loggers> + <AsyncLogger name="bench" level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </AsyncLogger> + <Root level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </Root> + </Loggers> + <Properties> + <Property name="log4j2.asyncLoggerRingBufferSize">1024</Property> + </Properties> +</Configuration> diff --git a/src/main/resources/log4j2-async-1m.xml b/src/main/resources/log4j2-async-1m.xml new file mode 100644 index 0000000..596d3d5 --- /dev/null +++ b/src/main/resources/log4j2-async-1m.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="true"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + </Appenders> + <Loggers> + <AsyncLogger name="bench" level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </AsyncLogger> + <Root level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/log4j2-async-4k.xml b/src/main/resources/log4j2-async-4k.xml new file mode 100644 index 0000000..9e51895 --- /dev/null +++ b/src/main/resources/log4j2-async-4k.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="false" bufferSize="8192"> + <PatternLayout pattern="[ASYNC-4K] %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + </Appenders> + <Loggers> + <AsyncLogger name="bench" level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </AsyncLogger> + <Root level="info" includeLocation="false"> + <AppenderRef ref="File"/> + </Root> + </Loggers> + <Properties> + <Property name="log4j2.asyncLoggerRingBufferSize">4096</Property> + </Properties> +</Configuration> diff --git a/src/main/resources/log4j2-asyncapp-10k.xml b/src/main/resources/log4j2-asyncapp-10k.xml new file mode 100644 index 0000000..40db21e --- /dev/null +++ b/src/main/resources/log4j2-asyncapp-10k.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="true"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + <Async name="Async" bufferSize="10240"> + <AppenderRef ref="File"/> + </Async> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/log4j2-asyncapp-1k.xml b/src/main/resources/log4j2-asyncapp-1k.xml new file mode 100644 index 0000000..ad43e23 --- /dev/null +++ b/src/main/resources/log4j2-asyncapp-1k.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="true"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + <Async name="Async" bufferSize="1024"> + <AppenderRef ref="File"/> + </Async> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/log4j2-asyncapp-1m.xml b/src/main/resources/log4j2-asyncapp-1m.xml new file mode 100644 index 0000000..7b5e1bb --- /dev/null +++ b/src/main/resources/log4j2-asyncapp-1m.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="true"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + <Async name="Async" bufferSize="1048576"> + <AppenderRef ref="File"/> + </Async> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/log4j2-asyncapp-4k.xml b/src/main/resources/log4j2-asyncapp-4k.xml new file mode 100644 index 0000000..af4a2f2 --- /dev/null +++ b/src/main/resources/log4j2-asyncapp-4k.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="true"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + <Async name="Async" bufferSize="4096"> + <AppenderRef ref="File"/> + </Async> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="Async"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/log4j2-sync-buffered.xml b/src/main/resources/log4j2-sync-buffered.xml new file mode 100644 index 0000000..ed143ab --- /dev/null +++ b/src/main/resources/log4j2-sync-buffered.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="false" bufferSize="8192"> + <PatternLayout pattern="[SYNC-BUF] %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="File"/> + </Root> + </Loggers> +</Configuration> diff --git a/src/main/resources/log4j2-sync-immediate.xml b/src/main/resources/log4j2-sync-immediate.xml new file mode 100644 index 0000000..25d5303 --- /dev/null +++ b/src/main/resources/log4j2-sync-immediate.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration status="WARN"> + <Appenders> + <File name="File" fileName="target/bench.log" immediateFlush="true"> + <PatternLayout pattern="[SYNC-IMM] %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> + </File> + </Appenders> + <Loggers> + <Root level="info"> + <AppenderRef ref="File"/> + </Root> + </Loggers> +</Configuration> |
