I have the followed imports:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
and the following instantiation:
private static Logger logger = LoggerFactory.getLogger(Test.class);
and the following in my Main method:
logger.info("SOME MESSAGE: ");
However, I'm not able to find the output anywhere. All I see is that in my console there is:
21:21:24.235 [main] INFO some_folder.Test - SOME MESSAGE:
How do I locate the log file?
Note that the following are on my build path:
slf4j-api-1.7.5.jar
slf4j-log4j12-1.6.4.jar
I read the answer to similar questions but nobody actually says how to fix the problem.
slf4j is only an API. You should have a concrete implementation (for example log4j). This concrete implementation has a config file which tells you where to store the logs.
When slf4j catches a log messages with a logger, it is given to an appender which decides what to do with the message. By default, the ConsoleAppender displays the message in the console.
The default configuration file is :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- By default => console -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
If you put a configuration file available in the classpath, then your concrete implementation (in your case, log4j) will find and use it. See Log4J documentation.
Example of file appender :
<Appenders>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
...
</Appenders>
Complete example with a file appender :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
As already mentioned its just a facade and it helps to switch between different logger implementation easily. For example if you want to use log4j implementation.
A sample code would looks like below.
If you use maven get the dependencies
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
Have the below in log4j.properties in location src/main/resources/log4j.properties
log4j.rootLogger=DEBUG, STDOUT, file
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=mylogs.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd-MM-yyyy HH:mm:ss} %-5p %c{1}:%L - %m%n
Hello world code below would prints in console and to a log file as per above configuration.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
It does not write to a file by default. You would need to configure something like the RollingFileAppender
and have the root logger write to it (possibly in addition to the default ConsoleAppender
).
The log file is not visible because the slf4j configuration file location needs to passed to the java run command using the following arguments .(e.g.)
-Dlogging.config={file_location}\log4j2.xml
-Dlog4j.configurationFile={file_location}\log4j2.xml