30

For some reason my Eclipse console no longer displays Log4j INFO and DEBUG statements when I run JUnit tests. In terms of code there hasn't been any change, so it must something to do with the Eclipse configuration.

All I do in my Unit test is the following and for some reason ONLY the ERROR statement is displayed in the Eclipse console. Why? Where shall I look for clues?

public class SampleTest
{
   private static final Logger LOGGER = Logger.getLogger(SampleTest.class);

   @Before
   public void init() throws Exception
   {
       // Log4J junit configuration.
       BasicConfigurator.configure();

       LOGGER.info("INFO TEST");
       LOGGER.debug("DEBUG TEST");
       LOGGER.error("ERROR TEST");
   }
}

Details:

  • log4j-1.2.6.jar
  • junit-4.6.jar Eclipse
  • IDE for Java Developers, Version: Helios Release, Build id: 20100617-1415
leppie
  • 115,091
  • 17
  • 196
  • 297
javaExpert
  • 599
  • 2
  • 9
  • 12
  • 3
    Did you already got the answer? Their is nearly every possible solution explained, so it would be interesting, whether one helped. – user357206 Sep 02 '10 at 07:52

18 Answers18

25

Go to Run configurations in your eclipse then -VM arguments add this: -Dlog4j.configuration=log4j-config_folder/log4j.xml

replace log4j-config_folder with your folder structure where you have your log4j.xml file

Huzi--- Javiator
  • 3,631
  • 1
  • 17
  • 5
  • Thanks for the suggestion. This way it worked! Although I'm still a bit annoyed for two reasons: 1) I thought if I used the BasicConfigurator.configure() I didn't have to bother having the log4j.properties 2) When I run a simple JUnit test I just want to right clik and "run", not having to define a configuration I've tried again my original test, but adding the following line to see if it was using some variable defined somewhere in Eclipse: System.out.println(System.getProperty("log4j.configuration")); But it prints out "null" – javaExpert Aug 17 '10 at 13:50
  • hmmm.. interesting.. k ll get back to yu – Huzi--- Javiator Aug 18 '10 at 08:59
  • 4
    Add `-Dlog4j.debug` to the JVM arguments for this Eclipse launch configuration. – AbuNassar Jul 30 '16 at 17:02
12

Look in the log4j.properties or log4j.xml file for the log level. It's probably set to ERROR instead of DEBUG

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 1
    Thanks for the reply Aaron. I have checked the log4.properties and it was set on INFO. I have now changed it to DEBUG, but it doesn't make any difference. Any other idea? log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%t:%d{ddMMMyy HH:mm:ss.SSS} %-5p (%F:%L) %m%n – javaExpert Aug 17 '10 at 10:23
  • 12
    add `-Dlog4j.debug` to your VM environment startup properties to have log4j print out it's debugging info - perhaps a different log4j configuration file is being picked up on the classpath (such as one bundled inside a JAR) than the one you intend – matt b Aug 17 '10 at 11:35
  • @javaExpert: In that case, it find a different log4j.properties somewhere on the classpath. Look into your JARs, too! – Aaron Digulla Aug 17 '10 at 12:23
9

Configuring with BasicConfigurator.configure(); sets up a basic console appender set at debug. A project with the setup above and no other code (except for a test) should produce three lines of logging in the console. I cannot say anything else than "it works for me".

Have you tried creating an empty project with just log4j and junit, with only the code above and ran it?

Also, in order to get the @Beforemethod running:

@Test
public void testname() throws Exception {
    assertTrue(true);
}

EDIT:

If you run more than one test at one time, each of them will call init before running.

In this case, if you had two tests, the first would have one logger and the second test would call init again, making it log twice (try it) - you should get 9 lines of logging in console with two tests.

You might want to use a static init method annotated with @BeforeClass to avoid this. Though this also happens across files, you might want to have a look at documentation on TestSuites in JUnit 4. And/or call BasicConfigurator.resetConfiguration(); in an @AfterClass annotated class, to remove all loggers after each test class / test suite.

Also, the root logger is reused, so that if you set the root logger's level in a test method that runs early, it will keep this setting for all other tests that are run later, even if they are in different files. (will not happen when resetting configuration).

Testcase - this will cause 9 lines of logging:

import static org.junit.Assert.assertTrue;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;

public class SampleTest
{
   private static final Logger LOGGER = Logger.getLogger(SampleTest.class);

   @Before
   public void init() throws Exception
   {
       // Log4J junit configuration.
       BasicConfigurator.configure();
   }

   @Test
    public void testOne() throws Exception {
       LOGGER.info("INFO TEST");
       LOGGER.debug("DEBUG TEST");
       LOGGER.error("ERROR TEST");

       assertTrue(true);
    }

   @Test
   public void testTwo() throws Exception {
       LOGGER.info("INFO TEST");
       LOGGER.debug("DEBUG TEST");
       LOGGER.error("ERROR TEST");

       assertTrue(true);
   }
}

Changing the init method reduces to the excepted six lines:

@BeforeClass
public static void init() throws Exception
{
    // Log4J junit configuration.
    BasicConfigurator.configure();
}

Your problem is probably caused in some other test class or test suite where the logging level of the root logger is set to ERROR, and not reset.

You could also test this out by resetting in the @BeforeClass method, before setting logging up.

Be advised that these changes might break expected logging for other test cases until it is fixed at all places. I suggest trying out how this works in a separate workspace/project to get a feel for how it works.

Tormod
  • 454
  • 3
  • 7
  • I've tried to create an empty project with only log4j, junit and the code above and it works perfectly i.e. prints all 3 statements. Is there some Eclipse project level setting that overrides the BasicConfigurator? – javaExpert Aug 17 '10 at 11:52
  • No, I'm pretty sure Eclipse does it's best not to affect the project directly in any way; suggested source of problem in edited answer. It is normal to keep a different `log4j.properties` file for tests in the test source folder, in order to let the classes under test log differently than the application. – Tormod Aug 17 '10 at 12:43
7

One thing to note, if you have a log4j.properties file on your classpath you do not need to call BasicConfigurator. A description of how to configure the properties file is here.

You could pinpoint whether your IDE is causing the issue by trying to run this class from the command line with log4j.jar and log4j.properties on your classpath.

Jon Freedman
  • 9,469
  • 4
  • 39
  • 58
4

Check your log4j.properties file

Check easy example here at here.

Maulzey
  • 4,100
  • 5
  • 22
  • 30
3

Makes sure when running junit test cases, you have the log4j.properties or log4j.xml file in your test/resources folder.

Venkat
  • 1,229
  • 1
  • 15
  • 23
  • The problem with me is log4j.xml is loaded by code from src/resources not from test/resources. I don't know what exactly is wrong in my code. – Abhishek Dec 30 '19 at 05:13
2

Thought this was a genuine defect but it turns out that my console size was limited, and caused the old content past 80000 characters to be cut off.

Right click on the console for the preferences and increase the console size limit.

Kiren
  • 21
  • 1
1

Add a test dependency to your pom to slf4j.

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j.version}</version>
            <scope>test</scope>
        </dependency>
cajunesque
  • 21
  • 4
1

Sounds like log4j picks up another configuration file than the one you think it does.

Put a breakpoint in log4j where the file is opened and have a look at the files getAbsolutePath().

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
1

Check for log4j configuration files in your output (i.e. bin or target/classes) directory or within generated project artifacts (.jar/.war/.ear). If this is on your classpath it gets picked up by log4j.

Adriaan Koster
  • 15,870
  • 5
  • 45
  • 60
0

I once had an issue like this, when i downloadad a lib from Amazon (for Amazon webservices) and that jar file contained a log4j.properties and somehow that was used instead of my good old, self configed log4j. Worth a check.

Zsolt János
  • 491
  • 8
  • 18
0

There is a case I make: exception happen in somewhere, but I catched the exception without print anything, thus the code didn't even reach the log4j code, so no output.

Eric
  • 22,183
  • 20
  • 145
  • 196
0

I had the same error.

I am using Jboss 7.1 AS. In the configuration file - standalone.xml edit the following tag. (stop your server and edit)

     <root-logger>
            <level name="ALL"/>
            <handlers>
                <handler name="CONSOLE"/>
                <handler name="FILE"/>
            </handlers>
    </root-logger>

The ALL has the lowest possible rank and is intended to turn on all logging.

GGN
  • 85
  • 11
0

The Eclipse Console Window has a Filter Property (in some cases only system.err is active).

Rigt click into Eclipse console window -> Preferences -> Console and ensure that checkbox

Show when Program writes to standard out

is active.

Alternatively you can configure log4j to write alway to System.err like this:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="AppConsole" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.err" />
        <param name="Encoding" value="ISO-8859-15" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="%d{dd.MM.yyyy HH:mm:ss} %5p kontext.%c{1}:%L - %m%n" />
        </layout>
    </appender>
    <root>
        <level value="debug" />
        <appender-ref ref="AppConsole" />
    </root>
</log4j:configuration> 
Nic W
  • 1
0

if the log4j.xml file is not in the project,and you are using tomcat, try going to tomcat instance and search for log4j. Try changing the consoleAppender level to debug and redeploy the application in tomcat. That might help.

Rajan
  • 1,501
  • 4
  • 21
  • 37
0

Check that your log4j.properties or log4j.xml are copied to your IDE classpath and loads when calling BasicConfigurator.configure()

Bivas
  • 1,484
  • 1
  • 11
  • 17
0

My situation was solved by specifing the VM argument to the JAVA program being debugged, I assume you can also set this in `eclipse.ini file aswell:

enable-debug-level-in-eclipse

Daniel Sokolowski
  • 11,982
  • 4
  • 69
  • 55
0

A simple log4j.properties file can look like this:

log4j.rootCategory=debug,console

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.immediateFlush=true
log4j.appender.console.encoding=UTF-8
log4j.appender.console.threshold=info

log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=%d [%t] %-5p %c - %m%n

Place it in your class path (target/classes folder). Or you if you have a Maven project, place it under your src/main/resources and Eclipse will copy it to your class path.

Without a configuration file, you should see an Eclipse warning in the console like this:

log4j:WARN No appenders could be found for logger.
log4j:WARN Please initialize the log4j system properly.
ezzadeen
  • 1,033
  • 10
  • 9