blob: a6c60ec1d2a975bf02239883eac47d5692db939e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.logging.log4j.perf.jmh;
import java.io.File;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.util.StringMap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
/**
* Benchmarks Log4j 2's Console, File, RandomAccessFile, MemoryMappedFile and Rewrite appender.
*/
// HOW TO RUN THIS TEST
// java -jar log4j-perf/target/benchmarks.jar ".*Log4j2AppenderComparisonBenchmark.*" -f 1 -wi 10 -i 20
//
// RUNNING THIS TEST WITH 4 THREADS:
// java -jar log4j-perf/target/benchmarks.jar ".*Log4j2AppenderComparisonBenchmark.*" -f 1 -wi 10 -i 20 -t 4
@State(Scope.Benchmark)
public class Log4j2AppenderComparisonBenchmark {
public static final String MESSAGE = "Short message";
private final LogEvent EVENT = createLogEvent();
private Logger fileLogger;
private Logger rafLogger;
private Logger mmapLogger;
private Logger consoleLogger;
private Logger directConsoleLogger;
private Logger noopLogger;
private Logger rewriteLogger;
private Appender fileAppender;
private Appender rafAppender;
private Appender mmapAppender;
private Appender consoleAppender;
private Appender directConsoleAppender;
private Appender noopAppender;
private Appender rewriteAppender;
private static LogEvent createLogEvent() {
final Marker marker = null;
final String fqcn = "com.mycom.myproject.mypackage.MyClass";
final Level level = Level.DEBUG;
final Message message = new SimpleMessage(MESSAGE);
final Throwable t = null;
final StringMap mdc = null;
final ThreadContext.ContextStack ndc = null;
final String threadName = "THREAD";
final StackTraceElement location = null;
final long timestamp = System.currentTimeMillis();
return Log4jLogEvent.newBuilder() //
.setLoggerName("name(ignored)") //
.setMarker(marker) //
.setLoggerFqcn(fqcn) //
.setLevel(level) //
.setMessage(message) //
.setThrown(t) //
.setContextData(mdc) //
.setContextStack(ndc) //
.setThreadName(threadName) //
.setSource(location) //
.setTimeMillis(timestamp) //
.build();
}
@Setup
public void setUp() throws Exception {
System.setProperty("log4j.configurationFile", "log4j2-appenderComparison.xml");
deleteLogFiles();
fileLogger = LogManager.getLogger("FileLogger");
rafLogger = LogManager.getLogger("RAFLogger");
mmapLogger = LogManager.getLogger("MMapLogger");
consoleLogger = LogManager.getLogger("ConsoleLogger");
directConsoleLogger = LogManager.getLogger("DirectConsoleLogger");
noopLogger = LogManager.getLogger("NoopLogger");
rewriteLogger = LogManager.getLogger("RewriteLogger");
fileAppender = ((org.apache.logging.log4j.core.Logger) fileLogger).getAppenders().get("File");
rafAppender = ((org.apache.logging.log4j.core.Logger) rafLogger).getAppenders().get("RandomAccessFile");
mmapAppender = ((org.apache.logging.log4j.core.Logger) mmapLogger).getAppenders().get("MemoryMappedFile");
consoleAppender = ((org.apache.logging.log4j.core.Logger) consoleLogger).getAppenders().get("Console");
directConsoleAppender = ((org.apache.logging.log4j.core.Logger) directConsoleLogger).getAppenders().get("DirectConsole");
noopAppender = ((org.apache.logging.log4j.core.Logger) noopLogger).getAppenders().get("NoOp");
rewriteAppender = ((org.apache.logging.log4j.core.Logger) rewriteLogger).getAppenders().get("Rewrite");
}
@TearDown
public void tearDown() {
System.clearProperty("log4j.configurationFile");
deleteLogFiles();
}
private void deleteLogFiles() {
final File log4j2File = new File ("target/testlog4j2.log");
log4j2File.delete();
final File log4jRandomFile = new File ("target/testRandomlog4j2.log");
log4jRandomFile.delete();
final File mmapFile = new File ("target/MemoryMappedFileAppenderTest.log");
mmapFile.delete();
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void baseline() {
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endRAF() {
rafLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderRAF() {
rafAppender.append(EVENT);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endFile() {
fileLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderFile() {
fileAppender.append(EVENT);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endMMap() {
mmapLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderMMap() {
mmapAppender.append(EVENT);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endNoop() {
noopLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderNoop() {
noopAppender.append(EVENT);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endRewrite() {
rewriteLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderRewrite() {
rewriteAppender.append(EVENT);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endConsole() {
consoleLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderConsole() {
consoleAppender.append(EVENT);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void end2endDirectConsole() {
directConsoleLogger.debug(MESSAGE);
}
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@Benchmark
public void appenderDirectConsole() {
directConsoleAppender.append(EVENT);
}
}