/*
 * 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 org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;
import org.openjdk.jmh.annotations.GenerateMicroBenchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.logic.BlackHole;

@State(Scope.Thread)
public class Log4jLogEventBenchmark {
    private static Message MESSAGE;
    private static Throwable ERROR;

    @Setup
    public void setup() {
        MESSAGE = new SimpleMessage("Test message");
        ERROR = new Exception("test");
    }

    @GenerateMicroBenchmark
    public void testBaseline(final BlackHole bh) {
    }

    @GenerateMicroBenchmark
    public void testNoException(final BlackHole bh) {
        final Throwable t = null;
        final Log4jLogEvent event = new Log4jLogEvent("a.b.c", null, "a.b.c", Level.INFO, MESSAGE, t);
        bh.consume(event);
    }

    @GenerateMicroBenchmark
    public void testException(final BlackHole bh) {
        final Throwable t = ERROR;
        final Log4jLogEvent event = new Log4jLogEvent("a.b.c", null, "a.b.c", Level.INFO, MESSAGE, t);
        bh.consume(event);
    }

    // ============================== HOW TO RUN THIS TEST: ====================================
    //
    // In sampling mode (latency test):
    // java -jar log4j-perf/target/microbenchmarks.jar ".*Log4jLogEventBenchmark.*" -i 5 -f 1 -wi 5 -bm sample -tu ns
    //
    // Throughput test:
    // java -jar microbenchmarks.jar ".*Log4jLogEventBenchmark.*" -i 5 -f 1 -wi 5 -bm Throughput -tu ms
    //
    // Usage help:
    // java -jar log4j-perf/target/microbenchmarks.jar -help
    //
}

@@ -877,16 +877,63 @@
 .Level;%0A
+import org.apache.logging.log4j.core.LogEvent;%0A
 import o
@@ -1311,16 +1311,46 @@
 kHole;%0A%0A
+import java.io.Serializable;%0A%0A
 @State(S
@@ -1996,16 +1996,18 @@
 oid test
+No
 Exceptio
@@ -1999,32 +1999,44 @@
  testNoException
+UsingBuilder
 (final BlackHole
@@ -2060,156 +2060,1729 @@
 nal 
-Throwable t = ERROR;%0A        final Log4jLogEvent event = new Log4jLogEvent(%22a.b.c%22, null, %22a.b.c%22, Level.INFO, MESSAGE, t);%0A        bh.consume(event
+LogEvent event = Log4jLogEvent.newBuilder()%0A            .setLoggerName(%22a.b.c%22)%0A            .setLoggerFqcn(%22a.b.c%22)%0A            .setLevel(Level.INFO)%0A            .setMessage(MESSAGE)%0A            .build();%0A        bh.consume(event);%0A    %7D%0A%0A    @GenerateMicroBenchmark%0A    public void testException(final BlackHole bh) %7B%0A        final LogEvent event = Log4jLogEvent.newBuilder()%0A            .setLoggerName(%22a.b.c%22)%0A            .setLoggerFqcn(%22a.b.c%22)%0A            .setLevel(Level.INFO)%0A            .setMessage(MESSAGE)%0A            .setThrown(ERROR)%0A            .build();%0A        bh.consume(event);%0A    %7D%0A%0A    @GenerateMicroBenchmark%0A    public void testSourceLocation(final BlackHole bh) %7B%0A        final LogEvent event = Log4jLogEvent.newBuilder()%0A            .setLoggerName(this.getClass().getName())%0A            .setLoggerFqcn(this.getClass().getName())%0A            .setLevel(Level.INFO)%0A            .setMessage(MESSAGE)%0A            .build();%0A        event.setIncludeLocation(true);%0A        final StackTraceElement source = event.getSource();%0A        bh.consume(source);%0A    %7D%0A%0A    @GenerateMicroBenchmark%0A    public void testSerializationWithoutException(final BlackHole bh) %7B%0A        final Log4jLogEvent event = new Log4jLogEvent(%22a.b.c%22, null, %22a.b.c%22, Level.INFO, MESSAGE, null);%0A        final Serializable serializable = Log4jLogEvent.serialize(event, false);%0A        bh.consume(serializable);%0A    %7D%0A%0A    @GenerateMicroBenchmark%0A    public void testSerializationWithException(final BlackHole bh) %7B%0A        final Log4jLogEvent event = new Log4jLogEvent(%22a.b.c%22, null, %22a.b.c%22, Level.INFO, MESSAGE, ERROR);%0A        final Serializable serializable = Log4jLogEvent.serialize(event, false);%0A        bh.consume(serializable
 );%0A 

Add more Log4jLogEvent benchmarks.