92

Looking at the last JUnit test case I wrote, I called log4j's BasicConfigurator.configure() method inside the class constructor. That worked fine for running just that single class from Eclipse's "run as JUnit test case" command. But I realize it's incorrect: I'm pretty sure our main test suite runs all of these classes from one process, and therefore log4j configuration should be happening higher up somewhere.

But I still need to run a test case by itself some times, in which case I want log4j configured. Where should I put the configuration call so that it gets run when the test case runs standalone, but not when the test case is run as part of a larger suite?

James McMahon
  • 48,506
  • 64
  • 207
  • 283
skiphoppy
  • 97,646
  • 72
  • 174
  • 218

4 Answers4

64

I generally just put a log4j.xml file into src/test/resources and let log4j find it by itself: no code required, the default log4j initialisation will pick it up. (I typically want to set my own loggers to 'DEBUG' anyway)

araqnid
  • 127,052
  • 24
  • 157
  • 134
  • 6
    For standard building testing I would set Log4j to warning or even error. If the tests succeeds(also negative tests) there should be no logging, which gets the users attention. – keiki Nov 21 '12 at 13:15
  • 3
    Yep that's right for log4j 1.x . For log4j2 apparently you can use more "exotic" files like log4j2-test.properties file...https://logging.apache.org/log4j/2.x/manual/configuration.html :) – rogerdpack May 16 '18 at 15:14
  • Are you sure about log4j-test.properties? Documentation about the hierarchy of places that the configuration will look for is not very clear about it – Sreeram Boyapati Feb 05 '21 at 02:44
53

The LogManager class determines which log4j config to use in a static block which runs when the class is loaded. There are three options intended for end-users:

  1. If you specify log4j.defaultInitOverride to false, it will not configure log4j at all.
  2. Specify the path to the configuration file manually yourself and override the classpath search. You can specify the location of the configuration file directly by using the following argument to java:

    -Dlog4j.configuration=<path to properties file>

    in your test runner configuration.

  3. Allow log4j to scan the classpath for a log4j config file during your test. (the default)

See also the online documentation.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Paul Morie
  • 15,528
  • 9
  • 52
  • 57
  • How will it know it's a "log4j configuration file?" What is the filename? (log4j.xml?) – Chad Aug 24 '13 at 02:37
  • 1
    @Chad: I've edited my answer to address your question. Please see the link to the static block to see exactly how this is implemented. – Paul Morie Aug 29 '13 at 04:15
  • I'm using log4j2 and I had to use the following setting to indicate a file: `-Dlog4j.configurationFile=log4j2.xml`. Also, if you are trying to debug loading/startup, this setting can be useful: `-Dlog4j2.debug=true`. – Kent Nov 02 '17 at 00:40
6

You may want to look into to Simple Logging Facade for Java (SLF4J). It is a facade that wraps around Log4j that doesn't require an initial setup call like Log4j. It is also fairly easy to switch out Log4j for Slf4j as the API differences are minimal.

James McMahon
  • 48,506
  • 64
  • 207
  • 283
5

I use system properties in log4j.xml:

...
<param name="File" value="${catalina.home}/logs/root.log"/>
...

and start tests with:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <systemProperties>
            <property>
                <name>catalina.home</name>
                <value>${project.build.directory}</value>
            </property>
        </systemProperties>
    </configuration>
</plugin>
calvinf
  • 3,754
  • 3
  • 28
  • 41
gavenkoa
  • 45,285
  • 19
  • 251
  • 303