We are going to discuss the following topics
- What is Log4j
- History of Log4j
- Features of Log4j
- Components of Log4j
- Installation of Log4j
- Using Log 4j in web app
- Architecture of Log 4j
- Log 4j configuration
- Debug level
- Log 4j Program
- Logging Method
- Logging level of Log4j
- Formatting of Log4j
- Layout of Log4j
- Layout Method
- Logging in Files -Log4j
- Logging in Multiple Files
- Difference between Log4j vs SLF4J
What is Log4J?
Log4j is a fast, flexible, reliable logging framework (API) written in java. Log4j developed in 1996. It is also distributed under the Apache software languages. Log 4J will port to the C, C++, C#, Perl, Python, Ruby, and Eiffel languages. This tool is used for small or large scale Selenium Automation projects.
History of Log4j
- After maven,· Log4j is produced in 1996, working as a tracing API for E.U.SEMPER(Secure Electronic /Marketplace For Europe) Project.
- This package is also distributed under the Apache Software License certified by the open-source initiative.
- After countless enhancements and many incarnations, the initial API has emerged to become log4j, a simplified logging package for Java.
- The Log4j latest version including its full source code, class file, and documentation can be available at http://logging.apache.org/log4j/.
Features of Log4j
- It is used for optimizing the speed
- It is designed to handle the JAVA EXCEPTION
- It is based on a named logger hierarchy tree.
- The log output format can be changed by extending Layout Class
- It is not restricted the predefined set of facilities
- The target of log output, as well as a writing strategy, can be altered by implementing the Appender interface.
- Logging behavior will be set at run-time using a contour(configuration) file.
Components of Log4j
LOG4J has three Principal Components:
- Loggers:– it is responsible for logging information.
- Appenders:- it is used to deliver log events to the destination. It decides what will happen to the log information.
- Layouts:- This layout is responsible for formatting logging information in different styles.

XML Parser: We needed a JAXP compatible parser to use log 4j. We have to sure Xerces.jar installed on your machine.
Installation of Log4j
To download the latest version of log4j on your system, go to the following URL: http://logging.apache.org/log4j/1.2/download.html
Step 1: Download the latest binary release from the Apache Logging Services Sites. If using Maven2 for a project, then simply use and declare its dependency in your Maven2 porn.xml, and Maven will grab the library for you.
Step 2: Unzip the downloaded file in /usr/local/ directory as follows.
1 2 3 4 5 6 7 8 9 10 |
$ gunzip apache-log4j-1.2.15.tar.gz $ tar -xvf apache-log4j-1.2.15.tar apache-log4j-1.2.15/tests/input/ apache-log4j-1.2.15/tests/input/xml/ apache-log4j-1.2.15/tests/src/ apache-log4j-1.2.15/tests/src/java/ apache-log4j-1.2.15/tests/src/java/org/ ....................................... |
While untarring, it would build a directory hierarchy with a name apache-log4j-x.x.x as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
-rw-r--r-- 1 root root 3565 2007-08-25 00:09 BUILD-INFO.txt -rw-r--r-- 1 root root 2607 2007-08-25 00:09 build.properties.sample -rw-r--r-- 1 root root 32619 2007-08-25 00:09 build.xml drwxr-xr-x 14 root root 4096 2010-02-04 14:09 contribs drwxr-xr-x 5 root root 4096 2010-02-04 14:09 examples -rw-r--r-- 1 root root 2752 2007-08-25 00:09 INSTALL -rw-r--r-- 1 root root 4787 2007-08-25 00:09 KEYS -rw-r--r-- 1 root root 11366 2007-08-25 00:09 LICENSE -rw-r--r-- 1 root root 391834 2007-08-25 00:29 log4j-1.2.15.jar -rw-r--r-- 1 root root 160 2007-08-25 00:09 NOTICE -rwxr-xr-x 1 root root 10240 2007-08-25 00:27 NTEventLogAppender.dll -rw-r--r-- 1 root root 17780 2007-08-25 00:09 pom.xml drwxr-xr-x 7 root root 4096 2007-08-25 00:13 site drwxr-xr-x 8 root root 4096 2010-02-04 14:08 src drwxr-xr-x 6 root root 4096 2010-02-04 14:09 tests |
Step 3: This step is optional and depends on what features are going to use from the Log4j framework. If you already have the following packages installed on the machine, it is ok unless you need to install them to use log4j.
- JavaMail API:-This is e-mail based logging feature in log4j that requires the Java Mail API (mail.jar) to be installed on your machine
- JavaBeans Activation Framework: This Java Mail API required JavaBeans Activation Framework (activation.jar) and it should be installed on the computer from http://java.sun.com/products/javabeans/jaf/index.jsp
- Java Message Service: The JMS -compatible features of Log4j will require both JMS & JNDI(java naming and directory interface) needed to be installed in the machine.
To set the Classpath and Path variable correctly. See the below image.
1 2 3 4 5 6 |
$ pwd /usr/local/apache-log4j-1.2.15 $ export CLASSPATH=$CLASSPATH:/usr/local/apache-log4j-1.2.15/log4j-1.2.15.jar $ export PATH=$PATH:/usr/local/apache-log4j-1.2.15/ |
Using Log4j in a web app
The following steps have to follow while using it.
Step 1: Download the latest binary release from the Apache Logging Services Sites. If using Maven2 for a project, then simply use and declare its dependency in your Maven2 porn.xml, and Maven will grab the library for it.
Step 2: Import the jar file into the web project if we are using Maven, then we can skip this step after declaring the dependency. Maven will properly put the jar file in the proper place when we build. We have to import a log4j jar file into the WEB-INF/lib directory so that it will be in the classpath of a web application.
Step 3: Import some existing Log 4j XML Configuration Files
Step 4: Put logging code in classes
Step 5: Run your app to and make sure it works.
Architecture of Log 4j
Log4j is a layered architecture where each layer has a different object to perform different work. This architecture makes design flexible and easy to implement.
Two Types of concerning Objects available with log4j framework
1. Core Object: This is a mandatory object framework. These are required to use the framework.
2. Support Object: These are optional objects of the framework. They always support core objects to perform an additional but important task.
Core Objects
Core object include the following type of object
1. Loggers Object: This is a top-level layer logger that provides the logger object. The Logger object is always responsible for capturing logging information & they are also stored in a namespace hierarchy.
Syntax to get Logger objects:
1 2 3 |
static Logger log =Logger.getLogger(YourClassName.class.getName()). |
2. Layout Object: The layout layer provides objects which are used to format logging information in various styles. It provides support to Appender objects before publishing logging information. Layout objects play an important role in publishing logging information in a way that is a human-readable and reusable facility.
3. Appender Object: The ability to selectively enable or disable registration requests based on your registrar is only part of the image. Log4j allows registration requests to be printed in multiple destinations. In log4j, an exit destination is called Appender.

Support Object
There are some other important objects in the log4j framework that play a vital role in the logging framework. Some are:
1. Level Object: This object defines the granularity and priority of any logging information. There are seven levels of logging defined within the API: OFF, DEBUG, ERROR, INFO, FATAL, and ALL.
2. Filter Object: It is used to analyze logging information and making further decisions to check whether that information should be logging or not. If logging information is passed to a particular Appender object, all the Filter objects compared with that Appender need to approve the logging information before it can be distributed to the attached destination.
3. ObjectRenderer: It is specialized in a string representation of different objects passed to the logging framework. It is also used by layout objects to prepare the final logging information.
4. LogManager: The LogManager will manage the logging framework. It is always responsible for reading the initial configuration parameter from a system-wide configuration file.
Log4J Configuration
Log4j configuration file is a Log4j. Properties which keeps attributes in key-value sets
Properties in the classpath:
- The level of the root logger is described as DEBUG.
- DEBUG attaches the Appender named Y to it.
- Set the Appender named Y to be a valid Appender.
- Set the layout for the Appender Y.
Log4j.Properties Syntax
1 2 3 4 5 6 7 8 9 |
# Define the root logger by Appender Y log4j.rootLogger = DEBUG, # Set the Appender named Y to be a File Appender log4j.Appender.Y=org.apache.log4j.FileAppender # Define the layout for Y Appender log4j.Appender.Y.layout=org.apache.log4j.PatternLayout log4j.Appender.Y.layout.conversionPattern=%m%n |
Debug Level
We have handled Debug by both the Appenders. Some options are:
- Trace
- Debug
- Info
- Warn
- Error
- Fatal
- All
Appenders
Apache log4j renders Appender objects which are essentially responsible for printing logging messages to different destinations such as consoles, files, devices, NT event logs, etc.
Each Appender object has several properties associated with it, and these properties show the behavior of that object.
Layout
We have used a pattern layout with our Appender. Some likely options are:
- HTMLLayout
- PatternLayout
- DateLayout
- SimpleLayout
- XmlLayout
Example of Log4j
The content of Log4j.Properties as follow
1 2 3 4 5 |
# Define the root logger with Appender file log = /usr/home/log4j log4j.rootLogger = DEBUG, FILE |
1 2 3 4 5 |
# Define the file Appender log4j.Appender.FILE=org.apache.log4j.FileAppender log4j.Appender.FILE.File=${log}/log.out |
1 2 3 4 5 |
# Define the layout for file Appender log4j.Appender.FILE.layout=org.apache.log4j.PatternLayout log4j.Appender.FILE.layout.conversionPattern=%m%n |
Using Log4j in Java Program
The following Java class is a very simple example that initializes and then uses the log4j logging library for Java applications.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import org.apache.log4j.Logger; import java.io.*; import java.sql.SQLException; import java.util.*; public class Example{ /* Get class name to be printed on */ static Logger log = Logger.getLogger(Example.class.getName()); public static void main(String args[])throwsIOException,SQLException { log.debug("hello this is debug message it"); log.info(" hello this is info message it "); } } |
Compile and Execute
All the libraries should be available in Log4J.Properties in the path. The steps are given below
- Create Log4j.properties
- Create Example.java, as shown above.
- Compile and execute the Example program.
Output
The output will be shown inside /usr/home/log4j/log.out file
Logging Methods
Logger class gives a variety of methods to manage logging activities. And Logger class does not permit us to instantiate a new Logger situation. Logging Method provides two static methods for obtaining a Logger object.
- public static Logger getRootLogger():
- public static Logger getLogger(String name);
The first two methods always return the application instance’s root logger & it does not have a name.
Any other named Logger object instance is obtained through the second method by passing the name of the logger. The name of the registrar can be any string that can pass, usually a class or package name see the below syntax.:
1 2 3 4 5 |
*/ static Logger log = Logger.getLogger(Example.class.getName()); */ |
Some Logging Method
- public void debug(Object message)
debug: This is used to print the message with Level.DEBUG
- public void error(Object message)
error: this is used to print the message with Level.ERROR
- public void fatal(Object message)
fatal: this is used to print the message with Level.FATAL
- public void info(Object message)
info: it is used to print the message with Level.INFO
- public void warn(Object message)
warn: it is used to print the message with Level.WARN
- public void trace(Object message)
trace: it is used to print the message with Level.TRACE
All the levels are outlined in the org.apache.log4j.Level class and any of the above-mentioned methods can be called as follows −
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
importorg.apache.lo4j.Logger; public class LogClass { private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class); public static void main(String args[]) { log.trace("Trace Message!"); log.debug("Debug Message!"); log.info("Info Message!"); log.warn("Warn Message!"); log.error("Error Message!"); log.fatal("Fatal Message!"); } } |
Logging Levels of Log4j
Logging levels are adopted to describe the entries in your log file. But they categorize in a very particular way, i.e., by need.
- During the search, you can filter Log files
- Amount of information that you log can be maintained
The log4j level configuration in the configuration file organizes the amount and type of information provided in the system and the event logs. Each log message is prefixed with the level of information.
Log levels are an occurrence of the org.apache.log4j.Level class.
The Log4j levels are defined in org.apache.log4j.Level. You can also define your design levels by subclassing the Level class.
Log Level | Description |
ALL | This level is used to turn all the levels logging. It combines the custom logging levels that you have defined. Once this one is configured, and the levels are not viewed at all, then all the Appenders will start streaming the log events in log files. |
DEBUG | It is most useful for debug an application |
INFO | It is used to record a message about routine application operations. In a real-time system, the Administrator views what is happening in the system right now. And it also monitors the problem arising in the system. Logging in Multiple Files |
WARN | Choose potentially harmful situation. |
ERROR | It is used to choose a serious problem that you should investigate immediately, but not in a serious FATAL. And the application meets the unwanted state. Still, the app allows you to continue running the application. For example unexcepted formatted input |
FATAL | The FATAL record level, as ERROR, indicates a problem. But unlike ERROR, it designates a very serious error event. You will not consider their presence much on an average day, but once they appear, it is terrible news, even the application of death. |
OFF | The highest possible rank and It is possible to turn off logging. |
How do Levels Works?
A logging request of level p in a logger with level q is permitted if p >= q. This rule is at the heart of log4j. It implies that levels are dictated. For the standard levels, we have ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF.
The following example shows how we can filter all our DEBUG and INFO messages. This program uses logger method setLevel(Level.X) to set the desired logging level:
This example would print all the notes except Debug and Info:
Note: Here we will filter data using log.setLevel(Level.info);
Example :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import org.apache.log4j.*; public class Example { private static org.apache.log4j.Logger log = Logger.getLogger(Example.class); public static void main(String args[]) { log.setLevel(Level.info); log.trace(" Trace Message!"); log.debug(" Debug Message!"); log.info(" Info Message!"); log.warn(" Warn Message!"); log.error(" Error Message!"); log.fatal(" Fatal Message!"); } } |
Output
While executing this code, the output will be
1 2 3 4 |
Error Message Fatal Message |
Formatting of log4j
Apache log4j supports several design objects, each of which can format the log data according to various designs. We can also create a design object that formats the log data in a specific way of the application.
All design objects are LoggingEvent object of Appender objects. The design objects retrieve the message argument from the LoggingEvent and apply the appropriate ObjectRenderer to obtain the string representation of the message.
The Layout Types
An Abstract class is a top-level class in the hierarchy
org.apache.log4j.Layout. It is also known as a base class for all other Layout classes in the log4j API.
The Layout class is defined as abstract within an application, and we never use this class directly; instead, we work with its sub-classes which are as follows:
- DateLayout
- HTMLLayout
- PatternLayout
- SimpleLayout
- XMLLayout
Layout Method
This class is base or skeleton implementation of all common operations across all other objects and holds two abstract methods.
S.No | Method | Description |
1 | Public abstract Boolean ignoresThrowable() | This method defines whether the registration information handles any java.lang.Throwable object that is passed to it as part of the registration event. If the design objects manage the Throwable object, the design object does not ignore it and returns false.. |
2 | public abstract String format(LoggingEvent event) | Individual design subclasses implement this method for the specific design format. |
Layout class provides detailed implementation for the method given below.
S.No | Methods | Description |
1 | public String getContentType() | This is used by Layout object and return the content type .The base class return plain or text as default content type. |
2 | public String getFooter() | It specifies the footer message of logging information |
3 | public String getHeader() | This method is implemented to specify the header information of the logging message |
Logging in Files -Log4j
We use org.apache.log4j.FileAppender to write information into a file.
File Appender Parameters
It has the following configuration.
Parameters | Description |
ImmediateFlush | The flag value is set to be true, which means the output stream to the file being flushed with each append operation. |
Encoding | It is a platform-specific encoding scheme. We can use any character scheme. |
threshold | The threshold for this Appender. |
Filename | It is name of log file. |
fileAppend | Default value set to be true, which means the logging information is appended to the end of same file |
bufferedIO | This indicator defines whether we need buffer writing enabled. The default value is false. |
bufferSize | It will indicate buffer size , by default it is set to 8kb, if buffered input/output is enable to true. |
Following is a sample configuration file log4j.properties :-
1 2 3 4 |
# Define the root logger with Appender file log4j.rootLogger = DEBUG, FILE |
1 2 3 4 |
# Define the file Appender log4j.Appender.FILE=org.apache.log4j.FileAppender |
1 2 3 4 |
# Set the name of the file log4j.Appender.FILE.File=${log}/log.out |
1 2 3 4 |
# Set the immediate flush to true (default) log4j.Appender.FILE.ImmediateFlush=true |
1 2 3 4 |
# Set the threshold to debug mode log4j.Appender.FILE.Threshold=debug |
1 2 3 4 |
# Set the append to false, overwrite log4j.Appender.FILE.Append=false |
1 2 3 4 5 |
# Define the layout for file Appender log4j.Appender.FILE.layout=org.apache.log4j.PatternLayout log4j.Appender.FILE.layout.conversionPattern=%m%n |
Program Example2.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
importorg.apache.log4j.Logger; importjava.io.*; importjava.sql.SQLException; importjava.util.*; publicclassHtmlLayoutEx{ staticLoggerlog=Logger.getLogger(HtmlLayoutEx.class.getName()); publicstaticvoidmain(Stringargs [])throwsIOException,SQLException{ log.debug("Hellomessage is debug internal"); log.info("Helloinfo message"); } } |
Output
1 2 3 4 |
Hello message is debug internal Hello info message |
If we have an XML File configuration equivalent to the above log4j.properties files, the content is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPElog4j:configurationSYSTEM"log4j.dtd"> <log4j:configuration> <Appendername="FILE"class="org.apache.log4j.FileAppender"> <paramname="file"value="${log}/log.out"/> <paramname="immediateFlush"value="true"/> <paramname="threshold"value="debug"/> <paramname="append"value="false"/> <layoutclass="org.apache.log4j.PatternLayout"> <paramname="conversion"value="%n%m"/> </layout> </Appender> <loggername="log4j.rootLogger"additivity="false"> <Appender-refref="FILE"/> </logger> </log4j:configuration> |
Logging in Multiple Files
To write your log information to files daily, you must use the org.apache.log4j. Daily Rolling File Appender class, which extends the File Appender class and inherits all its properties.
We can also write multiple messages into multiple files for certain reasons, for example, if the file size reached a certain threshold.
We have the following configurable parameters for file Appender.
DatePattern:- This intimates when to rollover the file and the naming pattern to be followed. The rollover is performed at midnight per day by default.
Date Pattern | Description |
‘.’yyyy-MM | It will rollover at end of month and beginning of the month. |
‘.’yyyy-MM-dd | It is default value. It will rollover at midnight. |
‘.’yyyy-MM-dd-a | In this, rollover is performed in midnight and mid day of every day. |
‘.’yyyy-MM-dd-HH | At top of every hour, it will rollover. |
‘.’yyyy-MM-dd-HH-mm | At every minute, rollover is performed. |
‘.’yyyy-ww | First day of every week, rollover is performed. |
Some sample configuration file log4j.properties to generate log files rolling over at a every hour:
1 2 3 4 |
#DefinetherootloggerwithAppenderfile log4j.rootLogger=DEBUG,FILE |
1 2 3 4 |
#DefinethefileAppender log4j.Appender.FILE=org.apache.log4j.DailyRollingFileAppender |
1 2 3 4 |
#Setthenameofthefile log4j.Appender.FILE.File=${log}/log.out |
1 2 3 4 |
# Set the immediate flush to true (default) log4j.Appender.FILE.ImmediateFlush=true |
1 2 3 4 |
# Set the threshold to debug mode log4j.Appender.FILE.Threshold=debug |
1 2 3 4 |
# Set the append-false, should not overwrite log4j.Appender.FILE.Append=true |
1 2 3 4 |
# Set the DatePattern log4j.Appender.FILE.DatePattern='.' yyyy-MM-dd-HH |
1 2 3 4 5 |
# Define the layout for file Appender log4j.Appender.FILE.layout=org.apache.log4j.PatternLayout log4j.Appender.FILE.layout.conversionPattern=%m%n |
Difference between Log4j vs SLF4J.
SLF4J(Simple Logging Façade for java) is an API designed to give generic access to many logging frameworks, log4j being one of them. It is an abstraction layer.
It is not a logging implementation. It means that if we are writing a library and we use SLF4J, we can give that library to someone else to use and they can choose which logging implementation to use with SLF4J, e.g., log4j or the Java logging API. It is used to prevent applications from being dependent on different logging APIs just as they use libraries that are dependent on them. Log4j and SLF4J are not similar.
In the case of Log4j, it is a registration component and performs the indicated registration. Then we can say that SLF4J and Log4J are logically two different things.

Why is SLF4J better than Log4J?
When we are using a logging abstraction, SLF4J, in particular, we can migrate to any logging framework we want at the time of deployment without opting for a single dependency.
Following are the reasons, which are good enough to choose SLF4J over Log4j:
- It is always better to use abstraction.
- SLF4J is an open-source library or internal library that makes it independent of any particular registry implementation.
- SLF4J grants a record based on the placeholder, which develops the readability of the code by removing the isInforEnabled(), is DebugEnabled() checks,
- By using the SLF4J logging method, we defer the cost of building log messages (string) until you need it, which is efficient for both the CPU and memory.
- Since SLF4J uses less number of time chains, it means less work for the garbage collector, which means better performance and performance for your application.
So, essentially, SLF4J does not replace log4j; both work together. It eliminates the dependency of log4j on your application and makes it easier to replace it in the future with the most capable library.
Logging in Database
You should create a table to keep all log information before you start using JDBC-based logging. The SQL statement to create the LOGS table follows.
1 2 3 4 5 6 7 8 9 |
CREATE TABLE LOGS (USER_ID VARCHAR(30) NOT NULL, DATED DATE NOT NULL, LOGGER VARCHAR(50) NOT NULL, LEVEL VARCHAR(10) NOT NULL, MESSAGE VARCHAR(1000) NOT NULL ; ); |
Configuration File
Below is a sample log4j.properties configuration file for JDBCAppender that will be used to log messages to a LOGS table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# Define the root logger with appender file log4j.rootLogger = DEBUG, DB # Define the DB appender log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender # JDBC URL to set log4j.appender.DB.URL=jdbc:mysql://localhost/Database name # Database Driver to set log4j.appender.DB.driver=com.mysql.jdbc.Driver # Database user name and password to be set log4j.appender.DB.user=user_name log4j.appender.DB.password=password # The SQL statement to be executed. log4j.appender.DB.sql=INSERT INTO LOGS VALUES('%x','%d','%C','%p','%m') # Define the layout for file appender log4j.appender.DB.layout=org.apache.log4j.PatternLayout |
We should use the actual DBNAME, user ID and password for MySQL database, where you created the LOGS table. The SQL statement is to execute an INSERT statement with the LOGS table name and the table values to enter.
if we want to have an XML configuration file equivalent to the above log4j.properties file, then the content is below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <appender name="DBase" class="org.apache.log4j.jdbc.JDBCAppender"> <param name="url" value="jdbc:mysql://localhost/DBNAME"/> <param name="driver " value="com.mysql.jdbc.Driver"/> <param name="user" value="user_id"/> <param name="password" value="password"/> <param name="sql" value="INSERT INTO LOGS VALUES('%x','%d','%C','%p','%m')"/> <layout class="org.apache.log4j.PatternLayout"> </layout> </appender> <logger name="log4j.rootLogger" additivity="false"> <level value="DEBUG"/> <appender-ref ref="DB"/> </logger> </log4j:configuration> |
Program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import org.apache.log4j.Logger; import java.io.*; import java.util.*; import java.sql.*; public class Example2{ static Logger log = Logger.getLogger(Example2.class.getName()); public static void main(String[] args)throws IOException,SQLException { log.debug("Debugg"); log.info("Infor"); } } |
Compile and Execute
Here are the steps in which the above mentioned program can be compiled and run. Before compiling and executing, make sure you set PATH and CLASSPATH properly.
Following steps –
- Create log4j.properties as shown above.
- Create Example2.java as shown above and compile it.
- Execute Example2 binary to run the program.
1 2 3 4 5 6 7 8 9 10 |
mysql > select * from LOGS; +---------+------------+--------------+-------+---------+ | USER_ID | DATED | LOGGER | LEVEL | MESSAGE | +---------+------------+--------------+-------+---------+ | | 2019-10-24 | Example2 | DEBUG | Debug | | | 2019-10-24 | Example2 | INFO | Info | +---------+------------+--------------+-------+---------+ 2 rows in set (0.00 sec) |