blob: 417930e38d40f1062756edc079bf31ee98dd4326 [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.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext.ContextStack;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.layout.PatternLayout;
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.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
/**
* Compares Log4j2 with Logback PatternLayout performance.
*/
// ============================== HOW TO RUN THIS TEST: ====================================
//
// single thread:
// java -jar log4j-perf/target/benchmarks.jar ".*PatternLayoutComparison.*" -f 1 -wi 10 -i 10 -tu ns -bm sample
//
// Usage help:
// java -jar log4j-perf/target/benchmarks.jar -help
//
@State(Scope.Thread)
public class PatternLayoutComparisonBenchmark {
final static String STR = "AB!(%087936DZYXQWEIOP$#^~-=/><nb"; // length=32
final static LogEvent LOG4J2EVENT = createLog4j2Event();
private static final Charset CHARSET_DEFAULT = Charset.defaultCharset();
private static final String LOG4JPATTERN = "%d %5p [%t] %c{1} %X{transactionId} - %m%n";
private final PatternLayout LOG4J2_PATTERN_LAYOUT = PatternLayout.newBuilder()
.setPattern((String) LOG4JPATTERN)
.setPatternSelector(null)
.setConfiguration(null)
.setRegexReplacement(null)
.setCharset((Charset) CHARSET_DEFAULT)
.setAlwaysWriteExceptions(false)
.setNoConsoleNoAnsi(true)
.setHeader(null)
.setFooter(null)
.build();
private static LogEvent createLog4j2Event() {
final Marker marker = null;
final String fqcn = "com.mycom.myproject.mypackage.MyClass";
final Level level = Level.DEBUG;
final Message message = new SimpleMessage(STR);
final Throwable t = null;
final StringMap mdc = null;
final ContextStack ndc = null;
final String threadName = null;
final StackTraceElement location = null;
final long timestamp = 12345678;
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();
}
// Logback
private static final String LOGBACKPATTERN = "%d %5p [%t] %c{0} %X{transactionId} - %m%n";
private final PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder();
private final LoggerContext context = new LoggerContext();
private final Logger logger = context.getLogger(PatternLayoutComparisonBenchmark.class);
private final ILoggingEvent LOGBACKEVENT = makeLoggingEvent(STR);
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
@Setup
public void setUp() throws IOException {
patternLayoutEncoder.setPattern(LOGBACKPATTERN);
patternLayoutEncoder.setContext(context);
patternLayoutEncoder.start();
((ch.qos.logback.classic.PatternLayout) patternLayoutEncoder.getLayout()).setOutputPatternAsHeader(false);
}
ILoggingEvent makeLoggingEvent(final String message) {
return new LoggingEvent(PatternLayoutComparisonBenchmark.class.getName(), logger,
ch.qos.logback.classic.Level.DEBUG, message, null, null);
}
@Benchmark
public byte[] logback() throws IOException {
baos.reset();
return patternLayoutEncoder.encode(LOGBACKEVENT);
}
@Benchmark
public byte[] log4j2() {
return LOG4J2_PATTERN_LAYOUT.toByteArray(LOG4J2EVENT);
}
}