80

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.

2
  • 2
    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. Commented Feb 19, 2014 at 13:30
  • 1
    @ArnaudDenoyelle He builds with <code>slf4j-log4j12-1.6.4.jar</code> which means he is including an implementation. Commented Feb 19, 2014 at 13:31

5 Answers 5

65

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.

enter image description here

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>
Sign up to request clarification or add additional context in comments.

19 Comments

I have log4j on my build path don't I?
@user2763361 Then you should put a log4j configuration file in your classpath and log4j will use it.
What do I need to call this config file for it to find it?
@user2763361 You do not need to explicitly call it. Log4J tries to find it at its initialization. You only have to place the file in the classpath.
Where does the log file get outputted though?
|
46

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");
              }
            }

enter image description here

7 Comments

Do I need to put it in src/main/resources? Because I don't have main as a subfolder to src. So I just put it in src. Then I overwrote your mylogs.log to /home/user/workspace/project/src/mylogs.log, then ran HelloWorld, and it didn't output a log file in the desired location. (No error message just no output)
Yes, if its a maven project you would have folders created automatically /src/main/resources/. Please see the screen shot above.
It's not a Maven project so I only put it in src.
Yes, you would put in /src/ folder.
This is a much cleaner implementation than writing it in XML.
|
4

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).

2 Comments

assuming OP uses log4j
@CeilingGecko See my other comment - he already states that he includes log4j.
1

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 

or this:

-Dlog4j.configurationFile={file_location}\log4j2.xml

Comments

0

Context

Responding to the:

I read the answer to similar questions but nobody actually says how to fix the problem.

part of the question for gradle (instead of Maven).

Instructions

To log towards a file at the root of your project named: my-log-file.log, using:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

...

private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

...

LOGGER.info("This is an info message");
LOGGER.error("This is an error message");

The following 2 steps can be used:

1. Add the dependencies for outputting a log file to build.gradle

In build.gradle add:

dependencies {
    // Allow logging to file.
    implementation 'org.slf4j:slf4j-api:1.7.32'
    implementation 'ch.qos.logback:logback-classic:1.2.6'
}

2. Create the logging output configuration file

Create a file named: logback.xml and store it, as said the above answer, in: src/main/resources (not in src/main/resources/com/<projectname>/). And it should contain:

<configuration>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>my-log-file.log</file> <!-- Specify the file name here -->
        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>

</configuration>

That is it, if you now build and run your java program, you should see a file named: my-log-file.log at the root of your repository/project, with content:

2023-10-28 20:41:55,394 INFO [main] c.d.Main [Main.java:36] - This is an info message
2023-10-28 20:41:55,394 ERROR [main] c.d.Main [Main.java:37] - This is an error message

Assumptions

This question assumes you already have a working org.slf4j.Logger setup that shows logging info in the terminal but does not store it to file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.