tinylog 2.2 released

October 26, 2020

After an half year of development, the second feature update for tinylog 2 is here! Since no bugs were reported for the first release candidate within a month, it can be released unchanged as the final version 2.2.0. All new features and changes can be found in the news post of the release candidate.

Leave a comment

First Release Candidate of tinylog 2.2 is out

September 11, 2020

After five month of development, more than 110 commits, and many pull requests from the community, I’m proud to announce the first release candidate of tinylog 2.2 with many new features and improvements.

Since Java 6 has been outdated for some time, Java 6 is no longer officially supported by tinylog 2.2. However, the bytecode target is still Java 6 for Android support (API level 1 or higher).

All new features and improvements are ready for use. Further release candidates will only contain bug fixes. As usual, the first release candidate, for which no bugs are reported, will be released unchanged as the final version 2.2.0.


Already since version 2.0, all tinylog JARs are modules, which can be used by the Java Platform Module System that was introduced with Java 9. However, tinylog 2.2 uses now real “” files instead of the automatic module feature. This has the advantage that the tinylog JARs are now also jlink compatible and can be used in custom Java runtime images.


The tinylog configuration becomes frozen as soon as the first log entry is issued. In previous versions, tinylog silently ignored all future configuration changes. Now, tinylog provides the getter Configuration.isFrozen() to check whether the configuration is already frozen, and throws an UnsupportedOperationException when trying to change a frozen configuration.

By default, tinylog outputs log entries via all logging providers, which are available in the classpath. Besides the logging provider tinylog from tinylog’s native logging back-end tinylog-impl.jar, there are also logging providers for using the logging backends of web and application servers. These are jul from tinylog-jul.jar for java.util.logging based servers and jboss from tinylog-jboss.jar for JBoss Logging based servers. With tinylog 2.2, it is finally possible to configure multiple active logging providers in the configuration file. Until now, only one logging provider could be activated via configuration files.

tinylog.provider = tinylog, jboss

Already since tinylog 2.0, it is possible to tag log entries and to bind a tag to a writer. Now, even several tags can be bound to the same writer. If tags are bound to a writer, only log entries with the configured tags are output via this writer.

writer     = console

Format Pattern

With version 2.2, tinylog introduces two new placeholders for formatting log entries: {uptime} and {level-code}. The placeholder {uptime} outputs the uptime of the application when a log entry was issued. The application’s uptime is the current time minus the time when the application was started.

writer        = console
writer.format = {uptime: HH:mm} - {message}
00:01 - Hello World!
24:33 - Goodbye!

The other new placeholder {level-code} outputs the severity level of a log entry as integer. The range starts with “1” for errors and ends with “5” for trace log entries.

writer        = console
writer.format = {level-code} - {message}
3 - Hello World!
1 - Oops, something went wrong!

Rolling File Writer

Now, the rolling file writer can create a link to the latest log file and update this link on each rollover. This makes it easier to handle multiple log files, since only the path of the link needs to be remembered or to be configured for monitoring tools. The link can be configured via the new property writer.latest. This feature is only available on standard Java, but not on Android.

writer        = rolling file
writer.latest = latest.log
writer.file   = myapp_{count}.log

Another new feature for the rolling file writer is GZIP compression of backup log files. GZIP compression can be enabled by setting writer.convert = gzip. If activated, tinylog will compress a log file when closing it on shutdown or starting another one due to a policy. The current log file is always kept uncompressed.

writer         = rolling file
writer.file    = myapp_{count}.log
writer.convert = gzip

It is also possible to implement custom converters for additional compression algorithms or any other type of encoding like encryption.

Bug Fixes

In previous versions of tinylog, file based writers created an empty log file when the severity level was set to off. Now, no log files will be created anymore, if the global severity level or the severity level of the writer is set to off.

In tinylog, custom writer implementations have to declare which fields of log entries must be set. However, if a custom writer lied about these fields and tried to use a token for a log entry field, it hasn’t declared as required, a NullPointerException was thrown in some cases. Now, tinylog can handle such cases.


Special thanks to Git5000, sezinkarli, and pabl0rg for their great pull requests! Without them, such a big release wouldn’t have been possible.

Pull requests are welcome! In the tinylog project on GitHub, all approved but not yet assigned issues are tagged as “help wanted”. Easy to fix and beginner friendly issues have additionally a “good first issue” tag. Also, your own ideas for tinylog are always welcome!

Leave a comment

tinylog 2.1.2 released

May 6, 2020

With version 2.1.2, tinylog can now easily be used in Eclipse plug-ins and RCP applications. All tinylog artifacts were already before valid OSGi bundles. However, the API bundle was not able to find the implantation of the logging provider at runtime due to classloader issues.

Now, tinylog-impl, tinylog-jboss, and tinylog-jul are declared as fragments for tinylog-api. This also has the advantage that OSGi bundles and Eclipse plug-ins using tinylog as logging framework do not need to declare or depend on a concrete logging backend implementation. Thus, tinylog automatically use the logging backend implementation available at runtime.

There is now an official P2 repository for tinylog: This repository can be used as software site in a target platform. A minimal example project for using tinylog in a Eclipse plug-in and feature is available on GitHub:

Leave a comment

tinylog 2.1.1 released

March 24, 2020

With tinylog 2.0.1, the first preparations began to support tinylog as logging framework in GraalVM native images. Thanks to shoneslab’s tests and reported issues, tinylog finally fully supports logging in GraalVM native images. A working example project can be found on GitHub.

Leave a comment

tinylog 2.1 released

March 10, 2020

After an half year of development, the first feature update for tinylog 2 is here! Since no bugs were reported for the third release candidate within three weeks, it can be released unchanged as the final version 2.1.0. All new features and changes can be found in the news posts of the previous three release candidates

Leave a comment

Third Release Candidate of tinylog 2.1 is out

February 18, 2020

The previous release candidate was compiled with the class file version 53.0 instead of 50.0. Therefore, the second release candidate could only run on Java 9 and later. However, the third release candidate is again compiled with the class file version 50.0 and also runs on Java 6-8. Thanks to MairwunNx for reporting this issue.

Leave a comment

Second Release Candidate of tinylog 2.1 is out

February 17, 2020

In previous versions, tinylog replaced not only plain “{}” placeholders, but also curly brackets with any text between, when using third-party logging API. This caused incompatibilities with SLF4J, for example. Now, tinylog replaces only placeholders that are explicitly supported by the used third-party logging API.

In the new release candidate, it is possible to escape curly brackets or entire phrases by using single quotes, when issuing log entries with arguments via tinylog’s logging API."Curly brackets as placeholder {} or escaped '{}'", value);

However, this feature has to be explicitly enabled in the configuration file for compatibility reasons.

escaping.enabled = true # default: false

Additionally, there is a class loader fix. If tinylog is initialized in a thread without a context class loader, tinylog can use the class loader from configuration class to avoid a NullPointerException. This fallback mechanism fixes an issue that was initially reported when using the Poynt SDK with tinylog.

Leave a comment

First Release Candidate of tinylog 2.1 is out

January 12, 2020

The first release candidate of tinylog 2.1 brings several improvements and new features for configuring tinylog, using tinylog with Scala, and outputting exceptions. All new improvements and features are ready to use. Further release candidates will only contain bug fixes. The first release candidate, for which no bugs are reported, will be released unchanged as the final version 2.1.0.

In the new version, it is possible to define default values for environment variables and system properties in configuration files for tinylog. These default values will be used if an environment variable and system property is not set to ensure that tinylog will work as expected nevertheless. Many thanks to simonsilvalauinger for the idea and implementation!

Already since the first version, tinylog loads the configuration from the properties file automatically. With the new version, tinylog supports also as configuration for tests and as configuration for development. This makes it easier to use different configurations for different environments. Details can be found in the configuration documentation.

The artifact of tinylog’s Scala API contains the Scala version now. This makes it easier to use and find the artifact. The new artifact name is org.tinylog:tinylog-api-scala_2.12:2.1.0-RC1.

The biggest new feature are throwable filters for filtering and transforming exceptions to get a clearer and more readable output. For example, it is possible to remove internal and generated stack trace elements from the stack trace or to unpack a RuntimeException to output only the exception that caused it. There are four configurable throwable filters, which can be adapted to meet individual requirements.

Leave a comment

tinylog 2.0.1 released

December 1, 2019

tinylog 2.0.1 includes a workaround for ProGuard to avoid incorrect removal of tinylog classes. Thus, tinylog can be used again without the rule “-dontshrink” with ProGuard. The required ProGuard rules for tinylog are documented on the configuration page. Many thanks to grill2010 for reporting this issue and great support with developing a workaround.

Additionally, all tinylog services (logging providers, writers, and policies) have default constructors now. This solves an issue with generating native images via GraalVM. Many thanks to MarkusKramer for reporting this problem. However, there still seem to be a few problems on GraalVM side to make native images really work.

Leave a comment

tinylog 2.0 released

August 21, 2019

After three years of development, this is it. tinylog 2.0 is here! Since no bugs were found for the second release candidate within one month, it can be released unchanged as the final version 2.0.0.

Leave a comment

Second Release Candidate of tinylog 2.0 is out

July 16, 2019

All JARs of tinylog are valid modules now. Thus, tinylog can be used easily in modular Java applications that are using the Java Platform Module System. For consistency, tinylog uses the new module names also as bundle names for OSGi.

Maven Artifact New Module/Bundle Name
tinylog-api org.tinylog.api
tinylog-api-kotlin org.tinylog.api.kotlin
tinylog-api-scala org.tinylog.api.scala
jcl-tinylog org.tinylog.api.jcl
log4j1.2-api org.tinylog.api.log4j12
jul-tinylog org.tinylog.api.jul
jboss-tinylog org.tinylog.api.jboss
slf4j-tinylog org.tinylog.api.slf4j
tinylog1.3-api org.tinylog.api.tinylog13
tinylog-impl org.tinylog.impl
tinylog-jul org.tinylog.adapter.jul
tinylog-jboss org.tinylog.adapter.jboss

Furthermore, the placeholder {timestamp} no longer inserts an SQL timestamp but a numeric UNIX timestamp in database tables. The placeholder {date} can be used for SQL timestamps.

Leave a comment

First Release Candidate of tinylog 2.0 is out

July 7, 2019

With the release of tinylog 2.0.0-RC1, tinylog 2 is feature complete. From now on, there will only be bug fixes. The first release candidate, for which no bugs are reported, will be released unchanged as the final version 2.0.0.

With the new version, tinylog brings support for the logging back-ends of all common web and application servers. The new artifact tinylog-jul can output log entries on Tomcat, Glassfish, and all other servers that use java.util.logging (JUL) as logging back-end. The second new artifact tinylog-jboss can output log entries on Wildfly, JBoss EAP, and all other servers that use JBoss Logging as logging back-end.

Both new artifacts can be used instead of tinylog-impl. It is also possible to use these server adapters together with tinylog-impl concurrently, if log entries should be output by tinylog as well as by the logging back-end of a server.

There is a new placeholder {timestamp} for outputting the UNIX timestamp of log entries. By default, the timestamp will be output in seconds. However, this placeholder is configurable and {timestamp: milliseconds} will output the timestamp in milliseconds. The new placeholder has been developed by ryanthon (thank you very much for the pull request!) and can be used like all other placeholders in a format pattern.

Leave a comment

Minor Update for SLF4J API

May 19, 2019

tinylog 2.0.0-M4.3 fixes a NullPointerException when passing null as marker via the SLF4J API. Thanks to Sander for reporting this issue.

Leave a comment

New Update for Fourth Milestone

April 1, 2019

tinylog 2.0.0-M4.2 renames the property tag of the logcat writer into tagname to avoid conflicts between tinylog tags and logcat tags. Thanks to mailz for identifying the collision of both types of tags.

Leave a comment

Minor Update for Fourth Milestone

March 24, 2019

It is no longer necessary to import org.tinylog.Supplier when using tinylog’s Scala logging API.

Leave a comment

Fourth Milestone of tinylog 2.0 is out

March 23, 2019

tinylog 2.0.0-M4 brings dedicated logging APIs for Scala and Kotlin. If you use one of both languages, you can add the matching artifact to your project and use the new logger object. This avoids unnecessary casts, which was required in Scala and Kotlin using the ‘normal’ logger class, and brings native support for lambdas and higher-ordered functions. Lazy interpolation of strings with embedded variables is quite easy now.

Lazy message passed as lambda in Kotlin: { "Hello $name!" }

Lazy message in Scala thanks to the use of macros:"Hello $name!")

Until now, it was impossible to use pipes in format patterns. The reason is that the pipe is reserved as separator between placeholders and style options. Thus, tinylog 2.0.0-M4 introduces {pipe} as placeholder for pipes.

For example:

writer        = console
writer.format = {level|min-size=5} {pipe} {thread|min-size=8} {pipe} {message}

Possible output:

DEBUG | main     | Hello World!
INFO  | thread-1 | Goodbye

The new milestone of tinylog 2 contains also several bugfixes. Now it is possible to use tinylog 2 in a Java Web Start application. In the previous milestones, tinylog 2 used a wrong class loader for loading services. Under some rare conditions, the rolling file writer could found files as log files that doesn’t match the defined log file pattern. This is fixed in the new milestone. Also, nested format patterns with style options do work again. Many thanks to gabrielnasser, adolgiy, and scott-rc for reporting the issues and supporting the analyses.

Leave a comment

Third Milestone of tinylog 2.0 is out

February 18, 2019

With the third milestone, tinylog 2.0 provides support for the logging APIs of Apache Commons Logging (JCL), Apache Log4j 1.2 and JBoss Logging 3. Already since the previous milestone, JUL, SLF4J and tinylog 1.3 are supported. Thus, all planned third-party logging APIs are implemented now.

For Apache Commons Logging (JCL) and JBoss Logging 3, tinylog provides bindings. This means that the original JARs of both framework can be used together with tinylog by just adding tinylog’s binding for these both frameworks.

Since Apache Log4j 1.2 does not support bindings, tinylog offers a replacement for the legacy Log4j-JAR. This means that the legacy Log4j-JAR has to be removed from the classpath, when using tinylog’s log4j1.2-api.

Furthermore the fix of tinylog 1.3.6 for ConcurrentModificationExceptions that can occur, if system properties change while loading the configuration, has been merged to tinylog 2.

Leave a comment

Update for Second Milestone

December 10, 2018

The version 2.0.0-M2.1 contains two fixes for the second milestone. tinylog can correctly parse parameters for multiple policies for rolling file writer now (see issue 84). In addition, animal sniffer annotations are not a required Maven dependency anymore.

Leave a comment

Second Milestone of tinylog 2.0 is out

November 24, 2018

In the second milestone, tinylog 2 supports the logging API of tinylog 1.3 and first third-party logging APIs. This includes a binding for SLF4J and a bridge for java.util.logging aka JUL. The support for all these logging APIs is provided by separate artifacts and can be integrated as needed.

tinylog’s binding for SLF4J is compatible with the versions 1.6 and 1.7, and has to be in the classpath together with slf4j-api. All log entries will be forwarded from org.slf4j.Logger to tinylog, and processed by the tinylog implementation like other log entries. Markers are mapped to tinylog’s tags. MDC and tinylog’s thread context share their data.

The bridge for forwarding log entries from java.util.logging.Logger to tinylog has to be activated explicitly. JUL doesn’t provide any API to do this automatically. tinylog’s bridge for JUL can be activated by calling org.tinylog.jul.JulTinylogBridge.activate() at the startup of your application, before issuing any log entries via java.util.logging.Logger.

To simplify the migration from tinylog 1.3 to tinylog 2, there is a reimplementation of the legacy logging API of tinylog. Thereby, applications can use both versions of tinylog’s logging API and all log entries will be handled by tinylog 2. This means that only one configuration is necessary.

Leave a comment

First Milestone of tinylog 2.0 is out

November 7, 2018

Today, after two years of development, it is time to release the first milestone of tinylog 2.0. All planned features are already implemented for tinylog itself. Third party logging APIs and implementations for web and application servers are scheduled for the coming milestones. Version 2.0 is a complete redevelopment with a modern architecture. API and implementation are now divided into two different JARs. tinylog will remain a lightweight and easy-to-use logging framework. tinylog will remain a lightweight and easy-to-use logging framework, with rarely used features replaced by new features requested by the community.

Tags for Log Entries

One of the most requested features was the support of tagged log entries. Tags can be output as part of the log entry, or used to output log entries via different writers. An instance of a tagged logger can be fetched from the static logger class. Depending on how often a tag is used, it is recommended to keep the tagged logger as a (member) variable, or to use the inline variant.

TaggedLogger logger = Logger.tag("SYSTEM"); // Get an instance of the tagged logger
logger.debug("Hello World!");
logger.error("An urgent problem occured");
Logger.tag("SYSTEM").info("Hello World!"); // Fluent API inline use

Tags are configured as self-explanatory via the property “tag”. As in the previous version, tinylog 2 can be configured via However, the prefix “tinylog.” is omitted to shorten the number of keystrokes in the new version.

writer        = console
writer.tag    = SYSTEM
writer.format = {date} - {tag} - {message}

File Writer Improvements

By default, tinylog use the default charset of the current operating system for writing log entries to files. In tinylog 2, the charset is configurable, and every charset supported by the current JVM can be used.

writer         = file
writer.file    = test.txt
writer.charset = UTF-8

The rolling file writer is used if a new log file should be started after defined events. For example, when a certain file size is reached or at a fixed time. In tinylog 2, the rolling file writer supports patterns for the file names of log files.

writer          = rolling file
writer.file     = logs/{date:yyyy}/{date:MM}/myapp-{count}.log
writer.policies = daily

Further Minor Changes

The base package name of tinylog has now been shortened from org.pmw.tinylog to just org.tinylog, and the severity level WARNING is just WARN. The new names are easy to remember and save some typing time. To make the API of the logger class clearer, all public methods not related to logging have been removed. Now tinylog 2 is compiled with debug information (as is common nowadays), which simplifies debugging significantly.

The previous version of tinylog could only support system properties and environment variables for resolving file names in the properties file. tinylog 2 supports both in all values, and uses a distinct syntax to distinguish between system properties and environment variables.

writer          = file
writer.file     = ${HOME}/application.log  # Environment variable
writer.format   = #{}: {message}  # System property

Dropped Features

The recommended way to configure tinylog is using properties files. The fluent API for configuration has been dropped, as it was rarely used in real world projects. Configuration can still be set at runtime by using the configuration class. This can be done property based by using the same keys and values as for

For performance reasons, the configuration in tinylog 2 is immutable, as opposed to the previous version of tinylog. As soon as the first logging method is called, the configuration cannot be changed.

Leave a comment