tinylog 2.7.0 released

You can edit this post on GitHub

After three milestones, finally the final version of tinylog 2.7.0 is there! Since no bugs were reported for the third milestone, it can be released unchanged as the final version 2.7.0. All new features and improvements can be found in the news posts of the first, second, and third milestone.

Third milestone of tinylog 2.7 is out

You can edit this post on GitHub

With the third milestone of tinylog 2.7, the ability to continue existing log files has been improved. Now, the rolling file writer is able to find the correct log file to continue, even if there are newer files in the same directory that are not related to tinylog. In addition, the rolling file writer can now continue log files if the placeholder {dynamic} is used and refers to an already existing log file at startup.

Second milestone of tinylog 2.7 is out

You can edit this post on GitHub

Until now, tinylog’s writing thread woke up every few milliseconds, even if there were no log entries to output. With this second milestone of tinylog 2.7.0, the writing thread will only wake up if there are log entries to output. This prevents the processor from waking up unnecessarily during idle phases, which improves the battery life of mobile devices including Android smartphones. Special thanks to manisiu, who not only found the problem but also fixed it straight away.

First milestone of tinylog 2.7 is out

You can edit this post on GitHub

The first milestone of tinylog 2.7 introduces a new writer for syslog servers. Now, tinylog can send log entries to syslog compatible servers out of the box!

Example syslog server configuration:

writer          = syslog
writer.level    = debug
writer.format   = {class}: {message}
writer.protocol = UDP
writer.host     = 192.168.0.1
writer.port     = 514

Detailed information and all configuration parameters for the new syslog writer can be found on the configuration page. Many thanks to Piotr Karlowicz, who developed the new writer.

tinylog 2.6.2 released

You can edit this post on GitHub

The second update for tinylog 2.6 fixes an issue that prevented the output of log entries with using custom severity levels in conjunction with the new fluent logging API of SLF4J 2.0.

tinylog 2.6.1 released

You can edit this post on GitHub

The first update for tinylog 2.6 fixes a NoClassDefFoundError for org.slf4j.spi.LoggingEventAware with SLF4J 1.7 and earlier.

tinylog 2.6.0 released

You can edit this post on GitHub

The final version 2.6.0 of tinylog there! Since no bugs were reported for the second milestone, it can be released unchanged as the final version 2.6.0. All bugfixes and new features can be found in the news posts of the first and second milestone.

Second milestone of tinylog 2.6 is out

You can edit this post on GitHub

In previous versions, the artifact tinylog-impl had an unwanted dependency on animal-sniffer-annotations. Actually, these annotations are only required at compile time to ensure backward compatibility for Java 6 and 7. Now, animal-sniffer-annotations is correctly declared as a compile-time only dependency.

All manifests of all tinylog artifacts now contain specification and implementation details. This makes it possible, for example, to resolve the tinylog version at runtime.

New website

You can edit this post on GitHub

The new website of tinylog is online! Before, the website was based on WordPress. Now, the website is based on Hugo. The static site generator generates the tinylog website from the new GitHub repository tinylog-org/website. There, all content exists as Markdown and is generated into static HTML pages. This has the advantage that everyone can edit all content directly on GitHub. Also, the web pages are delivered faster now, because there is no PHP or other code to run on the server side.

As part of the changeover, I also revised the layout and start page. However, the overall content and structure of the website has remained the same. If you notice any issues, please feel free to file an issue or pull request on tinylog-org/website.

First milestone of tinylog 2.6 is out

You can edit this post on GitHub

tinylog 2.6 is mainly a maintenance release. All Maven plug-ins and libraries have been updated to the latest version, with only a few handpicked exceptions to ensure we don’t have to drop support for Java 6. For very old legacy versions of Android, Java 6 is still important. The two most important enhancements are improved support for SLF4J 2 and improved compatibility with Scala 2.12.17 and 2.13.9.

With the first milestone of the version 2.6, the SLF4J binding for tinylog supports location aware logging for the new fluent logging API of SLF4J 2.0.0. Thereby, tinylog ensures that the correct location information such as class name, method name and line number is output. Furthermore, tinylog now implements all new MDC methods so that no compilation errors can occur when using the new deque methods of SLF4J 2.

For improving the compatibility with Scala 2.12.17 and 2.13.9, all Scala macros (more than 2,000 lines!) of the logging API for Scala have been rewritten from scratch. The logging API for Scala 2.12 and 2.13 are two different artifacts. When using OSGi bundles, both artifacts now have different bundle names: org.tinylog.api.scala_2.12 and org.tinylog.api.scala_2.13. This change is necessary to be able to deliver both bundles via the same P2 repository for Eclipse. Unfortunately, the rewritten logging API for Scala now requires at least Java 8. However, the logging APIs for Java and Kotlin are still compatible with Java 6 and 7.

tinylog 2.5.0 released

You can edit this post on GitHub

I’m proud to announce the release of tinylog 2.5.0! As usual, the final release includes the same set of features as the first and second milestone. All new features and bug fixes are described in detail in the linked news posts of both milestones.

Special thanks to f4lco for his generous donation to tinylog!

Contributions and donations for tinylog can be made via github.com/tinylog-org/tinylog

Update for second milestone

You can edit this post on GitHub

tinylog 2.5.0-M2.1 fixes a java.lang.VerifyError while loading the configuration on legacy Android versions. This issue was discovered on Android 4.4 and occurred only on very old and unsupported Android versions. Additionally, tinylog’s Kotlin API is now compiled with Kotlin 1.4.21 due to CVE-2020-29582. Nevertheless, Kotlin 1.3 - 1.7 are still supported.

Second milestone of tinylog 2.5 is out

You can edit this post on GitHub

The focus of the second milestone of tinylog 2.5 was the support of line-delimited JSON and the buffering of log entries in case of temporary loss of database connections.

Already with version 2.4 a JSON writer was integrated into tinylog. This JSON writer stores all log entries in a JSON array by default to comply with the JSON standard. However, most professional JSON consumers, including ElasticSearch, accept line-delimited JSON. Here, every log entry is a JSON object in a separate line without any JSON array brackets around it. This simplifies parsing of JSON log files, reduces resource consumption (memory and CPU usage), and even allows streaming of log entries. Line-delimited JSON can be enabled via the configuration by the property writer.format = LDJSON.

Example JSON writer configuration:

writer               = json
writer.format        = LDJSON
writer.file          = log.json
writer.field.level   = level
writer.field.message = message

Example JSON output:

{"level": "INFO", "message": "Hello World"}
{"level": "INFO", "message": "Good Bye"}

The JDBC writer can insert log entries into SQL databases. Of course, this requires a working connection to the database. However, tinylog now keeps log entries buffered in case of temporary losses of the database connection. tinylog buffers now up to 100 log entries and inserts them into the database as soon as the connection can be reestablished. This prevents log entries from being lost in case of short temporary database downtimes without consuming much memory.

There is a small change in the DynamicPolicy. Now, existing log files are automatically continued. Furthermore, there is a bugfix for using the new JndiValueResolver in Java modules projects. The org.tinylog.api module now correctly defines java.naming as an optional dependency.

First milestone of tinylog 2.5 is out

You can edit this post on GitHub

tinylog 2.5 has a new binding for System.Logger. Java introduced System.Logger as a generic logging API with version 9. The optional binding can be found on the download page and outputs all log entries that are issued via System.Logger via the logging back-end of tinylog. Special thanks to Trig, who has developed the new binding.

For the rolling file writer, there is a new dynamic placeholder and a new dynamic policy. The dynamic placeholder can be used for setting and changing a part of the path to the log file dynamically in Java by calling the static method DynamicSegment.setText(). The initial text can be set as {dynamic: initial text}. Setting a new text triggers a rollover event for the dynamic policy. Additionally, a rollover event can be triggered directly by calling the static method DynamicPolicy.setReset().

Example rolling file writer configuration:

writer          = rolling file
writer.file     = logs/{dynamic: foo}/log_{count}.txt
writer.policies = startup, dynamic

Many thanks to Simon Legner, who has developed the placeholder and policy.

Already with tinylog 2.4, a JSON writer was introduced for outputting log entries as JSON. With tinylog 2.5, the writer sets correct array brackets after each flush and not only when closing the JSON log file. This improvement makes it easier to parse the JSON log file while tinylog is still writing log entries into it.

By default, tinylog’s JDBC writer inserts log entries into the configured table in the database’s default schema. Thanks to Sollder1, it is now possible to configure a specific schema:

writer        = jdbc
writer.url    = jdbc:mysql://localhost:3306/example
writer.schema = public
writer.table  = LOG_TABLE

With the new tinylog version, it is also possible to define and resolve JNDI values in configuration files. The format for JNDI value placeholders is @{value}, which resolves the JNDI value from java:comp/env/value.

Example for resolving the path from java:comp/env/log/path:

writer      = file
writer.file = @{log/path}/log.txt

Furthermore, tinylog 2.5 brings many bug fixes and new minor features such as support for Scala 2.13 and the ability to extend the TinylogLoggingProvider for using another ContextProvider.

10 years tinylog

You can edit this post on GitHub

Exactly ten years ago, on January 23, 2012, the first commit of tinylog was pushed. A lot has happened since then. In the same year, on August 9, 2012, the first public beta of tinylog was released. Three years later, on August 1, 2015, tinylog 1.0 was ready and four years later, tinylog 2.0 was already released.

At the beginning of tinylog, I was the only developer. Since then, a great community has emerged. People have started to write articles about tinylog, and more and more pull requests are created. By now, more new features are developed by the community than by myself. Thank you very much to everyone who has helped to make tinylog to the logging framework it is today!

Currently, tinylog 2.5 and 3.0 are being developed in parallel. tinylog 2.5 will be an iterative feature update for tinylog 2, whereas tinylog 3.0 is a complete rewrite of the logging framework with a more flexible and extensible core. Nonetheless, the logging API will be source-compatible with tinylog 2. tinylog 3.0 can be expected sometime next year. Stay tuned!

Log4j vulnerability doesn’t affect tinylog

You can edit this post on GitHub

Due to the critical vulnerability CVE-2021-44228 in Log4j 2.14.1 and prior, I receive questions about the relevance to tinylog. The good news is that tinylog 1 and 2 are not affected. tinylog does not depend on Log4j 2. Both projects do not share any source code. tinylog is an independent logging framework and does not use JNDI.

tinylog 2.4.0 released

You can edit this post on GitHub

I’m happy to announce the second big release of tinylog for 2021: The final version 2.4.0 of tinylog there! As usual, the final release includes the same set of features as the first and second milestone. All new features and bug fixes are described in detail in the linked news posts of both milestones.

Additionally, tinylog 2.4.0 supports the latest alpha 5 of SLF4J 2.0 now. Previous alpha versions of SLF4J 2.0 may be incompatible.

Second milestone of tinylog 2.4 is out

You can edit this post on GitHub

tinylog now supports multiple tags for log entries. Besides Logger.tag("foo"), there is now an additional method Logger.tags("foo", "bar", "baz") for getting a tagged logger with multiple tags. Each issued log entry will be output with each assigned tag.

Already since the first version of tinylog 2, it is possible to define a minimum size for format pattern placeholders. With the new milestone, it is also possible to define a fixed or maximum size. tinylog will add spaces at the end of a placeholder value, if the value is too short. However, if a placeholder value is too large, the characters at the beginning of the value are truncated. For example, the class name com.foo.MyClass would be formatted as .foo.MyClass in the example below.

{level|min-size=7} - {thread|size=6} - {class|max-size=12} - {message}

To avoid invisible configuration errors, tinylog now automatically trims white space at the end of configuration values. For example, writer.charset = UTF-8·· (two spaces at the end) has caused an invalid charset error in previous tinylog versions. Now, tinylog trims such trailing white space and can correctly parse the configuration value in this example as “UTF-8”. By the way, leading white space in front of configuration values has never been a problem, because Java already trims such white space automatically in properties files.

In Android apps with shared user IDs, tinylog 2.3 and earlier versions could not find and load their service files. This was due to an issue with the class loader and is fixed in the current milestone. In addition, all bug fixes from tinylog 2.3.1 and 2.3.2 are now also part of tinylog 2.4.

Special thanks to kropp and kahgoh for their pull requests that made this big release possible.

tinylog 2.3.2 released

You can edit this post on GitHub

The latest update 2.3.2 fixes using GZIP compression in a Java Platform Module System project and using a user defined configuration loader instead of tinylog’s default properties file loader.

tinylog 2.3.1 released

You can edit this post on GitHub

The first update of tinylog 2.3 fixes a problem with BOMs for UTF-16 and UTF-32. In previous versions, tinylog added a BOM for each log entry in a log file when UTF-16 or UTF-32 was used as charset encoding. Now, tinylog 2.3.1 inserts correctly a BOM for both charsets only at the beginning of a log file.

First milestone of tinylog 2.4 is out

You can edit this post on GitHub

The SLF4J binding of tinylog supports SLF4J 2.0 now. This means that apart from SLF4J 1.6 and 1.7, the latest alpha version of SLF4J 2.0 can be used with tinylog as logging implementation. Special thanks to f4lco, who made the necessary modifications to the SLF4J binding.

For the first time since the release of tinylog 2.0, there is a new writer. The new JSON writer can write log entries in the JSON format to log files.

[
   {
      "level" : "INFO" ,
      "source" : "Application.main()" ,
      "message" : "Hello World!" 
   }
]

Detailed information and all configuration parameters for the new JSON writer can be found on the configuration page. Many thanks to Direnc Timur, who developed the new writer.

tinylog 2.3.0 released

You can edit this post on GitHub

I’m happy to announce the release of the next feature update of tinylog 2 within the usual half-yearly rhythm! The final release version 2.3.0 includes the same set of features as the second milestone. All new features are described in detail in the news posts of the first milestone and second milestone.

Additionally, the new release version includes a few performance optimizations. The updated benchmark compares the performance of tinylog 2.3.0 with all relevant Java logging benchmarks. Now, there are even three different benchmarks for different log format patterns with distinct caller information.

Second milestone of tinylog 2.3 is out

You can edit this post on GitHub

The monthly policy for the rolling file writer is back! With this policy, it is possible to start a new log file on the first day of each month. As for the daily policy, the rollover time can be configured and is midnight by default. The monthly policy was part of tinylog 1, but was never migrated to tinylog 2 until now.

If a count placeholder is used after a date or PID placeholder in log file names, the count is never restarted during runtime rollovers in previous tinylog versions. Now, tinylog restarts the count correctly, if the file path in front of the count placeholder is changed. For example, let’s assume that {date: yyyy}_{count}.log has been set as the file name. Before tinylog 2.3, the log files “2020_0.log” and “2020_1.log” were followed by the log file “2021_2.log” at the turn of the year. In the new version, the log file “2021_0.log” would follow instead.

During the development of tinylog 2.3, the benchmarks were rewritten to test the performance of outputting log entries with different location information:

  1. Class name with method name

  2. Class name (tinylog 1 and 2) or category (all other logging frameworks) only

  3. No location information at all

The results of the benchmarks will be published on the tinylog website together with the release of tinylog 2.3. However, I can already reveal that tinylog 2.3 will be twice as fast as tinylog 2.2, if no location information is to be output.

Furthermore, the second milestone of tinylog 2.3 contains two bug fixes. tinylog now issues an error log entry, if the file writer cannot create a compressed log file due to missing write permissions. The second bug fix is related to tinylog’s SLF4J adapter. Before version 2.3, tinylog throws an exception, if a LocationAwareLogger for SLF4J contains an invalid logger class name that does not exist in the stack trace. Now, tinylog only issues an error log entry instead of throwing an exception.

First milestone of tinylog 2.3 is out

You can edit this post on GitHub

Already since version 2.2, multiple tags can be bound to a single writer. With the first milestone of tinylog 2.3, it is even possible to define a different severity level for each tag. For example: writer.tag=BACKEND@warn,FRONTEND@debug. Details about the usage can be found in the configuration documentation.

The console writer can write log entries to the standard error stream and the standard output stream. By default, tinylog writes log entries with the severity levels INFO, WARN, and ERROR to the standard error stream and all log entries with the severity levels TRACE and DEBUG to the standard output stream. Now, it is possible to configure the severity level threshold for using the standard error stream. For example. the configuration property writer.stream=err@INFO would also write log entries with the severity level INFO to the standard error stream instead to the standard output stream. As always, further detail can be found in the configuration documentation.

Typically, tinylog is configured via properties files. However, the configuration loader is extendable now, which allows implementing custom configuration loaders for other file formats. Great examples for JSON and YAML can be found on github.com/Git5000/tinylog_extra_stuff.

tinylog supports choice format patterns for formatting log messages. With the first milestone of tinylog 2.3, it is possible to use multiple placeholders in a single choice format pattern. tinylog 2.2 and earlier support only a single placeholder.

Special thanks to Git5000, who is the main committer of most of the new features in this milestone!

tinylog 2.2.1 released

You can edit this post on GitHub

The new version 2.2.1 of tinylog fixes a bug that prevented the output of tagged log entries on Kotlin, if the visible severity level was higher than trace. Many thanks to psimicek for reporting and fixing this bug!

tinylog 2.2 released

You can edit this post on GitHub

After a 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.

First release candidate of tinylog 2.2 is out

You can edit this post on GitHub

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.

Modules

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 “module-info.java” 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.

Configuration

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
writer.tag = SYSTEM, BACKEND, FRONTEND

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.

Committers

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!

tinylog 2.1.2 released

You can edit this post on GitHub

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: http://tinylog.org/p2-repository/2.1.2/. This repository can be used as software site in a target platform. A minimal example project for using tinylog in an Eclipse plug-in and feature is available on GitHub: https://github.com/tinylog-org/tinylog-eclipse-plugin-example.

tinylog 2.1 released

You can edit this post on GitHub

After a 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

Third release candidate of tinylog 2.1 is out

You can edit this post on GitHub

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.

Second release candidate of tinylog 2.1 is out

You can edit this post on GitHub

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.

Logger.info("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.

First release candidate of tinylog 2.1 is out

You can edit this post on GitHub

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 tinylog.properties automatically. With the new version, tinylog supports also tinylog-test.properties as configuration for tests and tinylog-dev.properties 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.

tinylog 2.0.1 released

You can edit this post on GitHub

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.

tinylog 2.0 released

You can edit this post on GitHub

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.

Second release candidate of tinylog 2.0 is out

You can edit this post on GitHub

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 ArtifactNew Module/Bundle Name
tinylog-api-kotlinorg.tinylog.api.kotlin
tinylog-api-scalaorg.tinylog.api.scala
jcl-tinylogorg.tinylog.api.jcl
log4j1.2-apiorg.tinylog.api.log4j12
jul-tinylogorg.tinylog.api.jul
jboss-tinylogorg.tinylog.api.jboss
slf4j-tinylogorg.tinylog.api.slf4j
tinylog1.3-apiorg.tinylog.api.tinylog13
tinylog-implorg.tinylog.impl
tinylog-julorg.tinylog.adapter.jul
tinylog-jbossorg.tinylog.adapter.jboss
tinylog-apiorg.tinylog.api

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.

First release candidate of tinylog 2.0 is out

You can edit this post on GitHub

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.

Minor update for SLF4J API

You can edit this post on GitHub

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.

Fourth milestone of tinylog 2.0 is out

You can edit this post on GitHub

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:

Logger.info { "Hello $name!" }

Lazy message in Scala thanks to the use of macros:

Logger.info(s"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 find 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.

Third milestone of tinylog 2.0 is out

You can edit this post on GitHub

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.

Update for second milestone

You can edit this post on GitHub

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.

Second milestone of tinylog 2.0 is out

You can edit this post on GitHub

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 re-implementation 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.

First milestone of tinylog 2.0 is out

You can edit this post on GitHub

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 occurred");
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 tinylog.properties. 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   = #{user.name}: {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 tinylog.properties.

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.