SLF4J

SLF4J markers example

In this example, we shall show you how to use Markers with SLF4J.

SLF4J is a simple facade over various logging frameworks. It gives abstraction and therefore makes it easier to change logging implementations later on in a software project. It is a very stable library and is actively used by various open source software like Apache Camel, ActiveMQ, Solr and EhCache etc.

For this example, we will be using logback as logger with SLF4J. Logback was conceived and created as a successor to Log4J. Logback supports markers for the logging calls. These Markers allow association of tags with log statements. These tags enable various appenders to take decision on basis of their presence and absence. For the purposes of this example, we will be associating a ‘confidential’ tag which filter certain log statements on basis of what they are marked with.

For this example we will be using Logback 1.0.1 and SLF4J 1.6.4. The example is compilable on Java 5 and above.

1. Creating Hello World Maven Project

Initially, we will be creating a bare minimum maven project. This will be a command line Hello World application.Later on we will be integrating SLF4J in it.Once you have maven installed and running on your machine, issue following command from command line.

    mvn archetype:generate -DgroupId=com.javacodegeeks -DartifactId=slf4jmarker -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    

Maven will be downloading all dependencies from the default Maven Central repository and creating a bare minimum hello world project for us.

Once the above command have completed, Maven would have generated a really small pom.xml file and src folder for us. There is a single class called ‘App.java’ in the src. If you compile and run application at this point. You will get a command line Hello World message.

2. Integrating SLF4J and Logback

To integrating SLF4J and Logback, we need to make following changes to pom.xml

  • Adding jars file to classpath.

          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.javacodegeeks</groupId>
    	<artifactId>slf4jmarker</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>slf4jmarker</name>
    	<url>http://maven.apache.org</url>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<slf4j.version>1.6.4</slf4j.version>
    		<logback.version>1.0.1</logback.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-api</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-classic</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-core</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    
    	</dependencies>
    </project>
    
                
  • Adding maven exec plugin. This is a helpful plugin for console based applications. Using this plugin we will be invoking our Java application main method from command line. Here are the contents of final pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.javacodegeeks</groupId>
    	<artifactId>slf4jmarker</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>slf4jmarker</name>
    	<url>http://maven.apache.org</url>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<slf4j.version>1.6.4</slf4j.version>
    		<logback.version>1.0.1</logback.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-api</artifactId>
    			<version>${slf4j.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-classic</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    
    		<dependency>
    			<groupId>ch.qos.logback</groupId>
    			<artifactId>logback-core</artifactId>
    			<version>${logback.version}</version>
    		</dependency>
    
    	</dependencies>
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.codehaus.mojo</groupId>
    				<artifactId>exec-maven-plugin</artifactId>
    				<version>1.2.1</version>
    				<executions>
    					<execution>
    						<goals>
    							<goal>java</goal>
    						</goals>
    					</execution>
    				</executions>
    				<configuration>
    					<mainClass>com.javacodegeeks.slf4jmarker.App</mainClass>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>
    
                
  • Creating logback.xml file in resource folder.

    Create a resource folder at /src/main/resources and add following logback.xml file to it.

    <?xml version="1.0" encoding="UTF-8"?>
    
    <configuration>
    
    	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    		<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
    			by default -->
    		<encoder>
    			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
    			</pattern>
    		</encoder>
    	</appender>
    	<root level="DEBUG">
    		<appender-ref ref="STDOUT" />
    	</root>
    </configuration>
                

    We are using ConsoleAppender for this example. So all logging will be directed to console output.Next we are specifying the pattern of logged statements. Just like Log4J, we can use various pattern in the section to format and output log statements.

  • Using SLF4J and in our hello world application.

    We will be using Slf4J for logging to console.

    package com.javacodegeeks.slf4jmarker;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.slf4j.Marker;
    import org.slf4j.MarkerFactory;
    
    /**
     * Hello world!
     *
     */
    public class App
    {
        private static final Logger logger = LoggerFactory.getLogger(App.class);
    
        public static void main( String[] args )
        {
        	String confidentialMarkerText = "CONFIDENTIAL";
           Marker confidentialMarker = MarkerFactory.getMarker(confidentialMarkerText);
           logger.debug("Hello world from slf4j");
           logger.debug("This logger supports confidentail messages....");
           logger.debug(confidentialMarker,"This is a confidential message....");
           logger.debug("Just logged a confidential message");
        }
    }
    
                

    In this step, we are doing debug level logging. In third statement, we are using a marker ‘CONFIDENTIAL’.Therefore third statement will be tagged by logback as CONFIDENTIAL. We will be using this tag in next step to filter out this particular log.

    cd slf4jmarker
    mvn clean install
    mvn exec:java
    
    23:05:47.022 [main] DEBUG javacodegeeks.slf4jmarker.App - Hello world from slf4j
    23:05:47.027 [main] DEBUG javacodegeeks.slf4jmarker.App - This logger supports confidentail messages....
    23:05:47.027 [main] DEBUG javacodegeeks.slf4jmarker.App - This is a confidential message....
    23:05:47.027 [main] DEBUG javacodegeeks.slf4jmarker.App - Just logged a confidential message
    
            
  • Filtering Confidential logs.

    We will be using Logback’s Turbo Filter to filter out tagged messages. Configuring this filter is very simple and can be done via xml file itself.Add TurboFilter tag to logback.xml file created in earlier step. Final file would look like below

            <?xml version="1.0" encoding="UTF-8"?>
    
    <configuration>
    
    	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    		<!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
    			by default -->
    		<encoder>
    			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
    			</pattern>
    		</encoder>
    	</appender>
    
    	<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
    		<Name>CONFIDENTIAL_FILTER</Name>
    		<Marker>CONFIDENTIAL</Marker>
    		<OnMatch>DENY</OnMatch>
    	</turboFilter>
    
    
    	<root level="DEBUG">
    		<appender-ref ref="STDOUT" />
    	</root>
    </configuration>
            

    Building the project

    mvn clean install
    mvn exec:java
    
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building slf4jmarker 0.0.1-SNAPSHOT
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) > validate @ slf4jmarker >
    >>
    [INFO]
    [INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) < validate @ slf4jmarker <
    <<
    [INFO]
    [INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ slf4jmarker ---
    23:20:37.223 [com.javacodegeeks.slf4jmarker.App.main()] DEBUG com.javacodegeeks.
    slf4jmarker.App - Hello world from slf4j
    23:20:37.228 [com.javacodegeeks.slf4jatmarker.App.main()] DEBUG com.javacodegeeks.
    slf4jmarker.App - This logger supports confidentail messages....
    23:20:37.228 [com.javacodegeeks.slf4jmarker.App.main()] DEBUG com.javacodegeeks.
    slf4jmarker.App - Just logged a confidential message
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 0.904 s
    

    As you see, third statement we logged from our code has been filtered out.

5. Download source code

Download
You can download the full source code of this example here: Slf4JMarker Example

Arpit Gautam

Arpit has graduated from Computer Science and Engineering Department from the Institute of Technology and Management Gurgaon. He is working in enterprise product development since a decade and worked on desktop, mobile and server side applications using java. During his studies, he participated in various coding contests and technical paper presentations. He is working as a lead Software Engineer in Workforce Management domain where he is mainly involved with projects based on Java application and C++ system programming. He is curious about writing agile code which can adapt as business changes. He likes to experiment with open source technologies and java tech stack in his spare time.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Pawan
Pawan
3 years ago

Can I use a marker with custom appender? If yes, can you please provide an example.

Thanks a lot!!!!

Back to top button