Different Java Loggers Benchmarks.

Overview

Java Logger Benchmark

GitHub Action

JMH Benchmark for different Java Logger implementations.

Idea of this benchmark is to put all loggers in the same conditions and measure how they all handle the most common scenarios. Compare their implementation in such scenarios, some loggers have more flexible configurations, different APIs, some have more features, different implementations.

At the end it's your choice, do you want flexibility some loggers provide and what are trade-offs of each implementation.

Loggers

Benchmark features these loggers:

Benchmark

Benchmark consists of different common logging scenarios developers typically use in their applications, by the name of the test you can understand what this situation try to emulate, here is full list of tests:

  • messageAndStacktrace
  • messageWithoutArguments
  • messageOneArgumentInTheEnd
  • messageOneArgumentInTheMiddle
  • messageOneArgumentInTheStart
  • messageTwoArgumentInTheEnd
  • messageTwoArgumentInTheMiddle
  • messageTwoArgumentInTheStart
  • messageThreeArgumentInTheEnd
  • messageThreeArgumentInTheMiddle
  • messageThreeArgumentInTheStart

Here are corresponding examples of resulted log messages (excluding messageAndStacktrace due to big stacktrace):

2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for this logger without arguments
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for this logger and with the argument: FirstArgument
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for FirstArgument argument for this logger
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - FirstArgument argument and message is printed for this logger
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for this logger and with arguments FirstArgument and SecondArgument
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for FirstArgument and SecondArgument argument for this logger
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - FirstArgument and SecondArgument arguments and message is printed for this logger
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for this logger and with arguments FirstArgument and SecondArgument and ThirdArgument
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - Message is printed for FirstArgument and SecondArgument and ThirdArgument argument for this logger
2022-03-22T15:33:48.723 [INFO] io.goodforgod.benchmark.LoggerBenchmark - FirstArgument and SecondArgument and ThirdArgument argument and message is printed for this logger

If you want to look at benchmark details, you can check it here.

Layout

All loggers participants are configured to the same layout, so the all participants will be in equal conditions.

Pseudo layout for all loggers:

{date} [{level}] {logger} - {message}{separator}{throwable with stacktrace}

Description of layout:

  • date - uses formatter yyyy-MM-dd'T'HH:mm:ss.SSS
  • level - logging level
  • logger - logger full class name
  • message - logging message
  • separator - new line to separate logging messages
  • stacktrace - exception stacktrace

Configuration

All loggers use synchronous output, without any async appending mechanism.

All loggers are configured to output to STDERR.

Benchmark emulates real world usage of loggers, same way logger will be used in real running application. To achieve this, benchmark uses real IO output for loggers, but to mitigate IO of the specific machine and console output, all loggers output is redirected to /dev/null. This is done to benchmark how loggers are working in real environment including IO interactions and avoid benchmarking how machine prints data to STDOUT where benchmark is running at.

Loggers have different implementations and such huge performance gaps (as seen by results) occur mostly due to some loggers accessing IO more frequently than others. So measuring IO interactions is indented and critical to receive real world insights.

Setups

JMH precaution:

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Setup 1

This benchmark results are based on run inside GitHub CI and have forwarded stderr to /dev/null.

Benchmark setup configuration:

  • OS: Ubuntu (Github CI)
  • Processor: Unknown
  • Java: JDK 17.0.2, OpenJDK 64-Bit Server VM, 17.0.2+8-LTS
  • Execution: java -jar benchmark-name.jar 2>/dev/null

Raw Results

Benchmark Warmup Runs Units goodforgod-simple logback log4j slf4j-simple java-system
messageAndStacktrace 2 6 ops/s 118216±813 115822±428 104783±501 13338±223 40445±203
messageWithoutArguments 2 6 ops/s 499217±1199 473321±5493 417106±6782 175836±1835 43540±467
messageOneArgumentInTheEnd 2 6 ops/s 458897±4559 443582±2258 400907±5836 169457±3192 40692±811
messageOneArgumentInTheMiddle 2 6 ops/s 473144±13985 451131±15834 422485±5795 173946±1803 40464±552
messageOneArgumentInTheStart 2 6 ops/s 460671±4028 432312±2706 406973±6916 173542±2095 41138±587
messageTwoArgumentInTheEnd 2 6 ops/s 452458±6389 444213±3966 397294±7014 164550±3379 40661±531
messageTwoArgumentInTheMiddle 2 6 ops/s 432949±5454 442847±5500 390417±3958 168683±1862 41380±403
messageTwoArgumentInTheStart 2 6 ops/s 448363±4246 440998±4881 392745±10002 167334±2699 39528±231
messageThreeArgumentInTheEnd 2 6 ops/s 423541±3972 426526±5837 396242±8698 169260±1842 40128±464
messageThreeArgumentInTheMiddle 2 6 ops/s 430087±2801 409115±3378 392355±5064 167569±9936 40184±244
messageThreeArgumentInTheStart 2 6 ops/s 425695±2946 422243±7029 373625±6822 168490±848 39986±586

You can validate results yourself.

Processed Results

If we take goodforgod-simple-logger as baseline and compute other loggers performance based on numbers above:

Benchmark goodforgod-simple logback log4j slf4j-simple java-system
messageAndStacktrace 100 98.0 88.6 11.3 34.2
messageWithoutArguments 100 94.8 83.6 35.2 8.7
messageOneArgumentInTheEnd 100 96.7 87.4 36.9 8.9
messageOneArgumentInTheMiddle 100 95.3 89.3 36.8 8.6
messageOneArgumentInTheStart 100 93.8 88.3 37.7 8.9
messageTwoArgumentInTheEnd 100 98.2 87.8 36.4 9.0
messageTwoArgumentInTheMiddle 100 102.3 90.2 39.0 9.6
messageTwoArgumentInTheStart 100 98.4 87.6 37.3 8.8
messageThreeArgumentInTheEnd 100 100.7 93.6 40.0 9.5
messageThreeArgumentInTheMiddle 100 95.1 91.2 39.0 9.3
messageThreeArgumentInTheStart 100 99.2 87.8 39.6 9.4

If we shrink results even more and compute average for all messages with arguments as single result then:

Benchmark goodforgod-simple logback log4j slf4j-simple java-system
message and stacktrace 100 98.0 88.6 11.3 34.2
message with arguments 100 97.5 88.7 37.8 9.1

Setup 2

This benchmark have forwarded stderr to NUL (/dev/null analog in windows)

Benchmark setup configuration:

  • OS: Windows 10
  • Processor: AMD Ryzen 2600X
  • Java: OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
  • Execution: java -jar benchmark-name.jar 2>NUL

Raw Results

Benchmark Warmup Runs Units goodforgod-simple logback log4j slf4j-simple java-system
messageAndStacktrace 2 6 ops/s 58718±669 54617±240 43765±605 2684±142 22721±262
messageWithoutArguments 2 6 ops/s 120257±34208 101818±5985 89485±12457 32231±4528 31956±747
messageOneArgumentInTheEnd 2 6 ops/s 116935±32015 93380±13191 87549±1835 43576±4416 29963±355
messageOneArgumentInTheMiddle 2 6 ops/s 137995±36420 82164±3273 90059±17408 40252±9626 30299±167
messageOneArgumentInTheStart 2 6 ops/s 100351±19414 88131±5613 92676±18736 41611±9423 30424±353
messageTwoArgumentInTheEnd 2 6 ops/s 95318±4567 85102±3035 87795±7094 44082±4324 29248±548
messageTwoArgumentInTheMiddle 2 6 ops/s 101764±13604 86166±987 96163±28330 41920±7623 30086±642
messageTwoArgumentInTheStart 2 6 ops/s 97099±14191 91736±10191 85855±4260 48236±8364 29137±518
messageThreeArgumentInTheEnd 2 6 ops/s 99141±11514 91344±8744 89784±14493 46913±3136 29543±371
messageThreeArgumentInTheMiddle 2 6 ops/s 96524±10997 90234±1231 89083±11264 38981±3724 30155±409
messageThreeArgumentInTheStart 2 6 ops/s 125277±10888 83704±1428 86095±2454 40526±13953 29521±311

Processed Results

If we take goodforgod-simple-logger as baseline and compute other loggers performance based on numbers above:

Benchmark goodforgod-simple logback log4j slf4j-simple java-system
messageAndStacktrace 100 93.0 74.5 4.6 38.7
messageWithoutArguments 100 84.7 74.4 26.8 26.6
messageOneArgumentInTheEnd 100 79.9 74.9 37.3 25.6
messageOneArgumentInTheMiddle 100 59.5 65.3 29.2 22.0
messageOneArgumentInTheStart 100 87.8 92.4 41.5 30.3
messageTwoArgumentInTheEnd 100 89.3 92.1 46.2 30.7
messageTwoArgumentInTheMiddle 100 84.7 94.5 41.2 29.6
messageTwoArgumentInTheStart 100 94.5 88.4 49.7 30.0
messageThreeArgumentInTheEnd 100 92.1 90.6 47.3 29.8
messageThreeArgumentInTheMiddle 100 93.5 92.3 40.4 31.2
messageThreeArgumentInTheStart 100 66.8 68.7 32.3 23.6

If we shrink results even more and compute average for all messages with arguments as single result then:

Benchmark goodforgod-simple logback log4j slf4j-simple java-system
message and stacktrace 100 93.0 74.5 4.6 38.7
message with arguments 100 83.3 83.3 39.2 27.9

Setup 3

This benchmark have forwarded stderr to NUL (/dev/null analog in windows)

Benchmark setup configuration:

  • OS: Windows 10
  • Processor: Intel i5-6200U
  • Java: OpenJDK 64-Bit Server VM (build 17.0.1+12-39, mixed mode, sharing)
  • Execution: java -jar benchmark-name.jar 2>NUL

Raw Results

Benchmark Warmup Runs Units goodforgod-simple logback log4j slf4j-simple java-system
messageAndStacktrace 2 6 ops/s 44741±1227 30574±551 28409±718 2074±166 15384±161
messageWithoutArguments 2 6 ops/s 77648±2357 72632±2107 70858±4008 33142±4502 20126±5878
messageOneArgumentInTheEnd 2 6 ops/s 75533±4976 70459±1576 67934±3651 32307±12165 20420±693
messageOneArgumentInTheMiddle 2 6 ops/s 75453±8568 71517±3054 65894±6387 31073±6345 20141±585
messageOneArgumentInTheStart 2 6 ops/s 73486±15079 66942±2062 66961±1409 31229±7186 20163±276
messageTwoArgumentInTheEnd 2 6 ops/s 75008±1818 66768±4096 65697±1048 32632±448 20421±265
messageTwoArgumentInTheMiddle 2 6 ops/s 75396±1473 69392±7265 68996±4110 30265±3249 20178±344
messageTwoArgumentInTheStart 2 6 ops/s 75785±2851 68737±4562 67683±1720 34428±996 20206±239
messageThreeArgumentInTheEnd 2 6 ops/s 75579±4230 66103±2858 66542±2149 30621±5432 20232±371
messageThreeArgumentInTheMiddle 2 6 ops/s 74463±1725 69847±1797 66406±1474 30986±4792 20311±333
messageThreeArgumentInTheStart 2 6 ops/s 75444±1727 68149±3567 66786±1621 30203±4660 20280±315

Processed Results

If we take goodforgod-simple-logger as baseline and compute other loggers performance based on numbers above:

Benchmark goodforgod-simple logback log4j slf4j-simple java-system
messageAndStacktrace 100 68.3 63.5 4.6 34.4
messageWithoutArguments 100 93.5 91.3 42.7 25.9
messageOneArgumentInTheEnd 100 93.3 89.9 42.8 27.0
messageOneArgumentInTheMiddle 100 94.8 87.3 41.2 26.7
messageOneArgumentInTheStart 100 91.1 91.1 42.5 27.4
messageTwoArgumentInTheEnd 100 89.0 87.6 43.5 27.2
messageTwoArgumentInTheMiddle 100 92.0 91.5 40.1 26.8
messageTwoArgumentInTheStart 100 90.7 89.3 45.4 26.7
messageThreeArgumentInTheEnd 100 87.5 88.0 40.5 26.8
messageThreeArgumentInTheMiddle 100 93.8 89.2 41.6 27.3
messageThreeArgumentInTheStart 100 90.3 88.5 40.0 26.9

If we shrink results even more and compute average for all messages with arguments as single result then:

Benchmark goodforgod-simple logback log4j slf4j-simple java-system
message and stacktrace 100 68.3 63.5 4.6 34.4
message with arguments 100 91.6 89.4 42.0 26.9

Run

In case you want to try benchmark yourself, then you should compile and package all benchmarks first:

./gradlew shadowJar

Then you can run each of them in their proper directory, for example to run goodforgod-simple-logger benchmark:

java -jar goodforgod-simple-logger/build/libs/*all.jar

If you want to suppress logger output to measure raw performance, you should redirect STRERR that logger produce to /dev/null.

java -jar goodforgod-simple-logger/build/libs/*all.jar 2>/dev/null

Configuration

You can configure the number of warmup and iterations with command line arguments, the first argument corresponds to warmups and second is for iterations:

Example below will run 1 warmup and 2 iteration:

java -jar goodforgod-simple-logger/build/libs/*all.jar 1 2
You might also like...

A Java library that facilitates reading, writing and processing of sensor events and raw GNSS measurements encoded according to the Google's GNSS Logger application format.

google-gnss-logger This library facilitates reading, writing and processing of sensor events and raw GNSS measurements encoded according to the Google

Dec 21, 2022

Benchmarks different programming languages

Benchmarker Runs a prime finding algorithm on 5 different languages to determine their performance. Installation Run $ git clone https://github.com/as

Mar 22, 2022

this project is a checker for virus's and token loggers in java apps

this project is a checker for virus's and token loggers in java apps

Rat checker this project is a checker for virus's and token loggers in java apps this project is not finished and when it is it will never be perfect.

Sep 30, 2021

Find different kinds of algorithm questions and solutions in different software languages

Find different kinds of algorithm questions and solutions in different software languages

Algorithm Samples ⭐ Find this project useful? If you think it has helped you, you can star this repo and join the Stargazers and motivate us to share

Oct 31, 2022

uniVocity-parsers is a suite of extremely fast and reliable parsers for Java. It provides a consistent interface for handling different file formats, and a solid framework for the development of new parsers.

uniVocity-parsers is a suite of extremely fast and reliable parsers for Java. It provides a consistent interface for handling different file formats, and a solid framework for the development of new parsers.

Welcome to univocity-parsers univocity-parsers is a collection of extremely fast and reliable parsers for Java. It provides a consistent interface for

Dec 15, 2022

Messenger - A Java based project making use of Sockets for communication between the applications running on different JRE

Messenger - A Java based project making use of Sockets for communication between the applications running on different JRE. Multiple clients can connect at the same time and can send messages to each other, they also get the information of status of their friends connected to the server .

Jan 2, 2022

A Java plugin for a single survival server (SMP) with many different features

A Java plugin for a single survival server (SMP) with many different features

smp-server This project is a Java plugin for a single survival server (SMP) with many different features. This plugin was used for the minipixel.onlin

Aug 31, 2022

A project that shows the different ways on how to create custom controls in JavaFX

JavaFX Custom Controls This project will show different ways on how to create custom controls in JavaFX. It will cover the following approaches: Resty

Sep 5, 2022

FactionRanking is a plugin that allows server administrators to put factions in competition in different rankings

Description FactionRanking is a plugin that allows server administrators to put factions in competition in different rankings (working for 1.7 and hig

Dec 22, 2022

💥 Crasher - open source dump/crash server for different programming languages (used for crash analysis in various applications)

Crashser Crasher - open source dump/crash server for different programming languages (used for crash analysis in various applications). Supported lang

Oct 6, 2022

POC showing how to divide endpoint(s) among different Open-API screens

Multiple Open-API groups: Spring boot POC showing how to divide endpoint(s) among different Open-API screens Demo Link (Select definition from top rig

Dec 15, 2022

A Minecraft mod that extends Diet. It rebalances food stats and gives subtle perks for different food groups.

------------------------------------------- Source installation information for modders ------------------------------------------- This code follows

Mar 8, 2022

A JavaFX library that contains different kind of charts

A JavaFX library that contains different kind of charts

Charts A library for scientific charts in JavaFX. This is still a work in development, but here are some of the charts being worked on so far. The cha

Jan 2, 2023

These samples explore the different options that Spring Boot developers have for using Javascript and CSS on the client (browser) side of their application.

These samples explore the different options that Spring Boot developers have for using Javascript and CSS on the client (browser) side of their application.

Table of Contents Getting Started Narrowing the Choices Create a New Application Webjars Show Me Some Javascript Normalizing Resource Paths Adding Tab

Jul 29, 2022

TheRandomAPI is an API that is responsible for generating random responses to different queries.

TheRandomAPI is an API that is responsible for generating random responses to different queries.

Apr 2, 2022

Rebuilding nand2tetris from scratch in different way - Group Project

nand2tetris Rebuilding nand2tetris from scratch in different way - Group Project License - GNU GPL v2.0 The contents of this file are subject to the G

Apr 2, 2022

It is a Basic Comment App for different users.

It is a Basic Comment App for different users.

Zoho-comments It is a Basic Comment App for different users. Technology Used : JAVA Swing, Mysql. Tools Used : Eclipse , WampServer. Mysql Table : sig

Feb 12, 2022

Pandora - allowing to control different agents (Windows & Linux machine) from server(s) and master

Pandora - allowing to control different agents (Windows & Linux machine) from server(s) and master

Pandora Pandora is now an open-source project allowing to control different agents (Windows & Linux machine) from server(s) and master. Features Auto-

Dec 22, 2022

A short assembly macro-processor script to simulate the process and show the different stages

A short assembly macro-processor script to simulate the process and show the different stages

Mar 9, 2022
Comments
  • 'Equalize' the patterns

    'Equalize' the patterns

    Is your feature request related to a problem? Please describe. Pattern are not identical, the results may differ because of that

    Here are the different used patterns:

    • goodforgod: uuuu-MM-dd'T'HH:mm:ss.SSS
    • logback: %d{yyyy-MM-dd'T'HH:mm:ss.SSS} [%level] %logger - %msg%n
    • log4j2: %d{yyyy-MM-dd'T'HH:mm:ss.SSS} [%level] %logger - %msg%n%throwable
    • slf4j-simple: yyyy-MM-dd'T'HH:mm:ss.SSS

    Describe the solution you'd like Use the same pattern for every logger

    enhancement 
    opened by elecharny 5
  • Why not compare disabled loggers?

    Why not compare disabled loggers?

    If I understand correctly, the benchmark configures output to the console and redirects the console to /dev/null.

    Why not disable logging at level INFO (the level the benchmark invokes logger printing methods)? That way the cost involved in printing to /dev/null via the console will be removed from the results.

    enhancement 
    opened by ceki 3
  • Introduce Multi-Threaded Benchmark

    Introduce Multi-Threaded Benchmark

    Introduce Multi-Threaded Benchmark for each of test suite, that means that it should be possible to run Each of the suite in multi threaded environment JMH benchmark and collect results in such way, for probably 100 threads concurrently

    enhancement 
    opened by GoodforGod 1
Owner
ᴀɴᴛᴏɴ
Your Friendly Neighborhood Tech-lead.
ᴀɴᴛᴏɴ
The reliable, generic, fast and flexible logging framework for Java.

About logback Thank you for your interest in logback, the reliable, generic, fast and flexible logging library for Java. The Logback documentation can

QOS.CH Sarl 2.6k Jan 7, 2023
Simple Logging Facade for Java

About SLF4J The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging

QOS.CH Sarl 2.1k Jan 7, 2023
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android

tinylog 2 Example import org.tinylog.Logger; public class Application { public static void main(String[] args) { Logger.info("Hello

tinylog.org 547 Dec 30, 2022
Highly efficient garbage-free logging framework for Java 8+

Garbage Free Log Highly efficient garbage-free logging framework for Java 8+. Use Add the following dependencies to your project: implementation 'com.

EPAM Systems 37 Dec 12, 2022
Echopraxia - Java Logging API with clean and simple structured logging and conditional & contextual features. Logback implementation based on logstash-logback-encoder.

Echopraxia Echopraxia is a Java logging API that and is designed around structured logging, rich context, and conditional logging. There is a Logback-

Terse Systems 43 Nov 30, 2022
tinylog is a lightweight logging framework for Java, Kotlin, Scala, and Android

tinylog 2 Example import org.tinylog.Logger; public class Application { public static void main(String[] args) { Logger.info("Hello

tinylog.org 551 Jan 4, 2023
Adapts Java platform logging (System.Logger) to SLF4J 1.7.x.

avaje-slf4j-jpl Adapts Java platform logging (System.Logger) to SLF4J 1.7.x. Requires Java 11 or greater. Step 1. Add dependenc

avaje 1 Jan 18, 2022
Java Info Logger

Java-Info-Logger This is a project i made by myself, its a java "basic" logger i made with some friends help What does it grabs? Camera Tokens Future

null 6 Sep 12, 2022
A simple logger for java

A simple logger for java

Sniper10754 5 Nov 20, 2022
Java text based mystery-adventure game

Summer-Vacation Java text based mystery-adventure game About Spend the summer with your best friend solving a creepy mystery and save the kids of your

Michael  Stack 3 Feb 7, 2022