About Mayank Gupta

Senior JEE developer with experience in large scale IT projects, especially in the telecommunications and financial services sectors. Mayank has been designing and building J2EE applications since 2007. Fascinated by all forms of software development; keen to explore upcoming areas of technology like AI, machine learning, blockchain development and AR. Lover of gadgets, apps, technology and gaming.

Slf4j Format String Example

In this example, we are going to see how String log messages can be constructed in SLF4J with parameter substitution.

1. Introduction

SLF4J is a facade or an abstraction layer over various logging frameworks. Also known as Simple logging Facade for Java is not actually a logging implementation, instead, it’s an abstraction layer. It allows you to use any logging library with it.

Now if you would ask why SLF4J, when we already have so many logging frameworks. The answer is, you can write your piece of pluggable code using SLF4J for logging without worrying about the underlying implementation. Now whatever the application which will use your pluggable piece, can use the logging implementation of it’s own choice.

While constructing logging messages, programmers often need to provide some piece of information to be able to trace the cause of the problem as well as to know general flow of information in erroneous as well as normal cases. SLF4J provides an easy way to construct these messages; in this example we will see how.

2. Technologies Used

For this example, we use the following tools on a Windows 10 platform:

Eclipse IDE

Apache Maven

JDK 1.8

Slf4j 1.7.25

Log4J 1.2.17

3. SLF4J Format String Example

3.1 Create a Maven Project

We will create a bare minimum Maven project. Once you have the Maven installed and running on your machine, issue the following command from the command line.

3.4 Test Class

We are going to use SLF4J’s style of parameter substitution for log messages formatting. Though these logging calls look simple but behind the scenes it uses org.slf4j.helpers.MessageFormatter to format messages.

Slf4jSusbstitutionExample.java

package com.javacodegeeks.slf4.formatting;
import java.lang.invoke.MethodHandles;
import java.text.MessageFormat;
import java.util.Calendar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Substituting Parameters!
*
*/
public class Slf4jSusbstitutionExample
{
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static void main( String[] args )
{
String user = "john";
String application = "gateway";
// Crafting a message without substitution.
// Not a good idea as the String concatenation and evaluation will happen irrespective of whether
// logging level is permissible or not to be logged.
LOGGER.info("Bad experience for user " + user + " at time " + Calendar.getInstance().getTime());
// Substitution with one formatting anchor and one argument
LOGGER.info("Bad experience for user {}", user);
// If you happen to forget to provide a substituting object
LOGGER.info("Bad experience for user {}");
// Substitution with two formatting anchors and two arguments
LOGGER.info("Bad experience for user {} at time {}", user, Calendar.getInstance().getTime());
// Substitution with three formatting anchors and three arguments
LOGGER.info("Bad experience for user {} at time {} while accessing {}", user, Calendar.getInstance().getTime(), application);
// Escaping formatting anchor
LOGGER.info("ERROR CODE \\{}; Bad experience for user {} at time {}", user, Calendar.getInstance().getTime());
// Formatting anchor with data inside; no problem
LOGGER.info("ERROR CODE {22}; Bad experience for user {} at time {}", user, Calendar.getInstance().getTime());
// Crafting a message with Java's own MessageFormatter.
// Not a good idea as per SLF4J's documentation.
// 1. SLF4J's implementation is 10 times faster than that of MessageFormat.
// 2. Moreover to make sure that the evaluation happens only if that particular logging
// level is allowed, you need to do a check.
if(LOGGER.isInfoEnabled()) {
String message = MessageFormat.format("Bad experience for user {0} at time {1} while accessing {2}", user, Calendar.getInstance().getTime(), application);
LOGGER.info(message);
}
}
}

As per SLF4J’s documentation of org.slf4j.helpers.MessageFormatter, following points are worth noting:

Formats messages according to very simple substitution rules. Substitutions can be made 1, 2 or more arguments.

The {} pair is called the formatting anchor. It serves to designate the location where arguments need to be substituted within the message pattern.

If for whatever reason you need to place the string “{}” in the message without its formatting anchor meaning, then you need to escape the ‘{‘ character with ‘\’, that is the backslash character. Only the ‘{‘ character should be escaped. There is no need to escape the ‘}’ character.

The formatting conventions are different than those of MessageFormat which ships with the Java platform. This is justified by the fact that SLF4J’s implementation is 10 times faster than that of MessageFormat. This local performance difference is both measurable and significant in the larger context of the complete logging processing chain.

4. Summary

SLF4J’s substitution parameters while constructing log messages is suggested over String concatenation for the following two reasons:

No explicit check needed for log level

Performance improvement – If the log message is not supposed to be logged then the message will not simply be constructed.

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Receive Java & Developer job alerts in your Area

Leave this field empty if you're human:

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.