Easiest SLF4J Tutorial for Beginners
What is SLF4J
SLF4J stands for Simple Logging Facade for Java.
To log is to record then later display an output /information of an activity or event of a running program.
A facade is the front side of anything, usually a building or anything with a front and back side.
But in programming, to Facade is used to mean bringing to the front the logs of the running programming.
Java is an Object oriented programming language. Its syntax is usually a bit similar but not fully to that of C programming language.
What actually is SLF4J?
SLF4J is a tool(software jar) that provides abstraction for all other java logging libraries/frameworks.
It is therefore not a logging library by itself, but contains the jars of the included logging libraries.
Consider SLF4J as a big Jar that contains and packages smaller or other logging library jars.
It therefore works as the calling point when you want to use the functionalities of the specific logging jars.
It basically tries to achieve simplicity and easy migration at runtime e.g if we choose a different logger library and reduce tight coupling on a single logging library.
So what logger libraries does it have?
It will have java logger libraries such as Log4j, Logback, JUL (java.util.logging) just to mention a few.
Why choose SLF4J?
- One can migrate to the desired logging framework at the time of deployment.
- SL4J provides bindings to all popular logging frameworks such as log4j, JUL, Simple logging and, NOP and hence more flexibity if need to switch to any.
- offers support for parameterized logging messages irrespective of the binding you use.
- SLF4J decouples the application and logging framework used and hence reduces over dependency on a single specific logging library thus no need to worry about the logger library being used for an application.
- Provides a migrator tool if you were using a specific logger framework.
Introduction to how logging frameworks work
A logging framework usually has three main elements:
- Logger — captures messages and metadata for events being tracked.
- Formatter — Takes care of formatting messages recorded by the logger.
- Handler /Appender — sends/disseminates the message by printing it out, storing it in a database or even sending it via email or any other configured channel.
Messages in any Logger framework are logged based on their severity.
Actual Logging
To log anything you need to have a logger object that has a severity level set in it.
Severity Levels
The following severity commonly exist in logger libraries:
- Fatal — Used if an issue can terminate program execution.
- Error — used in case of runtime errors.
- Warning — used just to warn on issues you may opt to take care of.
- Info — Information about events of a program in runtime.
- Debug — information usually about how the program is executing line by line(flow).
- Trace — More detailed information about program execution/flow.
Creating a logger interface Object
Logger logger = LoggerFactory.getLogger("SampleLogger");
Example logging out an info message
logger.info("Hi This is my first SLF4J program");
Example full program using a logger
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JExample {
public static void main(String[] args) {
//Creating the Logger object
Logger logger = LoggerFactory.getLogger("SampleLogger");
//Logging the information
logger.info("Hi This is my first SLF4J program");
}
}
Parameterized logging
Parameterized logging allows us to pass place holders/ parameters then pass the values later while still on the same logger object(i.e on the same statement). E.g.
Integer age=27;
Logger.info("At the age of {} ramu got his first job", age);
From the above code, the curly braces stands in place of the age variable(place holders) which is passed later after the comma.
The full single parameter logging example code is as below
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(PlaceHolders.class);
Integer age = 23;
//Logging the information
logger.info("At the age of {} ramu got his first job", age);
}
}
Output of the above code is as folllows:
Dec 10, 2018 3:25:45 PM PlaceHolders main
INFO: At the age of 23 Ramu got his first job
This is one of the great powers of SLF4J.
Note: We can also pass multiple parameters to our logger object as follows. we separate the place holders with commas or put them in between other text and do the same for variables.
Its important to note values of the place holders are inserted in the order they appear in the curly brackets.
Example of multiple parameter logging
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
Integer oldWeight;
Integer newWeight;
Scanner sc = new Scanner(System.in);
System.out.println("Enter old weight:");
oldWeight = sc.nextInt();
System.out.println("Enter new weight:");
newWeight = sc.nextInt();
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("Old weight is {}. new weight is {}.", oldWeight, newWeight);
//Logging the information
logger.info("After the program weight reduced is: "+(oldWeight-newWeight));
}
}
The output of the above code will be as follows
Enter old weight:
85
Enter new weight:
74
Dec 10, 2018 4:12:31 PM PlaceHolders main
INFO: Old weight is 85. new weight is 74.
Dec 10, 2018 4:12:31 PM PlaceHolders main
INFO: After the program weight reduced is: 11
Logger example with three parameters
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlaceHolders {
public static void main(String[] args) {
Integer age = 24;
String designation = "Software Engineer";
String company = "Google";
//Creating the Logger object
Logger logger = LoggerFactory.getLogger(Sample.class);
//Logging the information
logger.info("At the age of {} ramu got his first job as a {} at {}", age, designation, company);
}
}
The output is:
Dec 10, 2018 4:23:52 PM PlaceHolders main
INFO: At the age of 24 ramu got his first job as a Software Engineer at Google
More on SLF4J — TO DO
Feel free to do more research on SLF4J Migrator and profiler. I will however touch briefly on components of SLF4J below.
What is profiling in coding?
This is the analysis of code performance usually mostly in regard to the time it takes to execute or space used when it runs.
SLF4J jar also has APIs for profiling functionalities.
SLF4J provides a class named Profiler in the org.slf4j.profiler package for profiling purpose.
Profiling Using the Profiler class
The profiler has stopwatches and child stopwatches that we are able to start and stop using the built in methods provided by the profiler class.
Steps of Doing profiling with the profiler class
Step 1 — Instantiate the profiler class
Example
//Creating a profiler
Profiler profiler = new Profiler("Sample");
Step 2 — Start a child stopwatch
Example
//Starting a child stopwatch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
Step 3: Can Start another child stopwatch(optional)
Example
//Starting another child stopwatch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
Step 4: Stop the watches
example
// Stopping the current child stopwatch and the global stopwatch.
TimeInstrument tm = profiler.stop();
Step 5: Print the contents of the time instrument.
example
//printing the contents of the time instrument
tm.print();
Full code using profiler
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;
public class ProfilerExample {
public void demoMethod1(){
double sum = 0;
for(int i=0; i< 1000; i++){
sum = sum+(Math.pow(i, 2));
}
System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
}
public void demoMethod2(){
int sum = 0;
for(int i=0; i< 10000; i++){
sum = sum+i;
}
System.out.println("Sum of the numbers from 1 to 10000: "+sum);
}
public static void main(String[] args) {
ProfilerExample obj = new ProfilerExample();
//Creating a profiler
Profiler profiler = new Profiler("Sample");
//Starting a child stop watch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
//Starting another child stop watch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
//Stopping the current child watch and the global watch.
TimeInstrument tm = profiler.stop();
//printing the contents of the time instrument
tm.print();
}
}
The output is
Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000
+ Profiler [BASIC]
|-- elapsed time [Task 1] 2291.827 microseconds.
|-- elapsed time [Task 2] 225.802 microseconds.
|-- Total [BASIC] 3221.598 microseconds.
Real example using profiler
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;
import org.slf4j.profiler.TimeInstrument;
public class ProfilerExample_logger {
public void demoMethod1(){
double sum = 0;
for(int i=0; i< 1000; i++){
sum = sum+(Math.pow(i, 2));
}
System.out.println("Sum of squares of the numbers from 1 to 10000: "+sum);
}
public void demoMethod2(){
int sum = 0;
for(int i=0; i< 10000; i++){
sum = sum+i;
}
System.out.println("Sum of the numbers from 1 to 10000: "+sum);
}
public static void main(String[] args) {
ProfilerExample_logger obj = new ProfilerExample_logger();
//Creating a logger
Logger logger = LoggerFactory.getLogger(ProfilerExample_logger.class);
//Creating a profiler
Profiler profiler = new Profiler("Sample");
//Adding logger to the profiler
profiler.setLogger(logger);
//Starting a child stop watch and stopping the previous one.
profiler.start("Task 1");
obj.demoMethod1();
//Starting another child stop watch and stopping the previous one.
profiler.start("Task 2");
obj.demoMethod2();
//Stopping the current child watch and the global watch.
TimeInstrument tm = profiler.stop();
//Logging the contents of the time instrument
tm.log();
}
}
The output is
Sum of squares of the numbers from 1 to 10000: 3.328335E8
Sum of the numbers from 1 to 10000: 49995000
closing remarks
I hope the article helped. Thank you for reading. See you next time.