-1

I am very new to log4j and have implemented it in my code. I am not able to create separate logs for each test case I run. This is my XML file

 <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
       <Properties>
        <Property name="basePath">./logs</Property>
    </Properties>
 
  <Appenders>
                             
      <RollingFile name="File" fileName="${basePath}/ICETest.log" filePattern="${basePath}/ICETest-%d{yyyy-MM-dd-HH-mm-ss}.log">
       <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      <SizeBasedTriggeringPolicy size="20000" />
          </RollingFile>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="all">
      <AppenderRef ref="File"/>
    </Root>
  </Loggers>
</Configuration>

And this is how I am using it in my class file:

public class MyClass extends base {
    
    private static org.apache.logging.log4j.Logger log =LogManager.getLogger(MyClass.class.getName());

@BeforeTest

    public void initialize() throws IOException

    {

    driver =IntializeDriver();

    LoginPage  l = new LoginPage(driver);
    ArrayList d = RE.getData("initialize_ice");
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    log.info("Chrome launched successfully");
    driver.get((String) d.get(1));

    // driver.get(prop.getProperty("url"));
    log.info("Page Navigated successfully");


    }

@Test
public void MyTest () throws IOException, InterruptedException
        {
        
    try
    {
         LoginPage l = new LoginPage(driver);
         
        //l.getUserName().sendKeys(prop.getProperty("mapcoord"));
         l.getUserName().sendKeys((String) d.get(3));
          Thread.sleep(1000);
        log.info("username entered successfully");
          Thread.sleep(1000);
        //l.Department().sendKeys(prop.getProperty("Dept"));
            l.Department().sendKeys((String) d.get(4));
             Thread.sleep(1000);
            log.info("Department entered successfully");
}
         catch (Exception e) {
             System.out.println("Ice page not logged In");
             }
             
        }



@AfterTest
public void teardown()
    {
        
        driver.close();
    log.info("browser closed successfully");
        
    }


}

and many other class files are there, now it creates a single log file with the name ICETest.log, I want it to create a separate log file for each class as classname.log

What changes are needed here?

Anuj Mittal
  • 73
  • 1
  • 8
  • This is pretty similar to [another question](https://stackoverflow.com/q/51277543/3284624) to which I provided an answer. In [my answer](https://stackoverflow.com/a/51341832/3284624) I used context map lookup but you could probably use the [EventLookup](https://logging.apache.org/log4j/2.x/manual/lookups.html#EventLookup) instead. – D.B. Jul 24 '21 at 07:36

2 Answers2

0

As I stated in my comment your question is very similar to another question to which I provided an answer. My answer to your question is going to be very similar, but using the EventLookup feature of log4j2 instead of the context map lookup.

Here is some sample code to demonstrate how you can generate separate log files based on the logger name (which usually will match the full class name).

First the log4j2.xml configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Routing name="myAppender">
            <Routes pattern="$${event:Logger}">
                <Route>
                    <File
                        fileName="logs/${event:Logger}.log"
                        name="myAppender-${event:Logger}">
                        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
                    </File>
                </Route>
            </Routes>
        </Routing>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="myAppender" />
        </Root>
    </Loggers>
</Configuration>

Next, a class with a main to act as the controller. This class will call the run methods of 2 other classes which represent your test cases.

package pkg;

public class Log4j2DiffFilePerLoggerMain {
    
    public static void main(String[] args){
        TestClass1 test1 = new TestClass1();
        test1.run();
        TestClass2 test2 = new TestClass2();
        test2.run();
    }
}

Now the first "test case" which is just simply a Java class with a single log statement.

package pkg;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class TestClass1 implements Runnable{
    private static final Logger LOG = LogManager.getLogger();
    
    public void run() {
        LOG.info("Test 1 is running");
    }

}

Finally the second test case which is almost an exact copy of the first but with a different log message.

package pkg;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class TestClass2 implements Runnable{
private static final Logger LOG = LogManager.getLogger();
    
    public void run() {
        LOG.info("Test 2 is running");
    }
}

When you execute the above code it will generate 2 log files:

pkg.TestClass1.log
pkg.TestClass2.log

The first log will contain the message from the first test class and the second will contain the message from the second class.

pkg.TestClass1.log    
09:02:48.366 [main] INFO  pkg.TestClass1 - Test 1 is running

pkg.TestClass2.log
09:02:48.390 [main] INFO  pkg.TestClass2 - Test 2 is running
D.B.
  • 4,523
  • 2
  • 19
  • 39
-1

You should remove this segment

  <Appenders>
                         
  <RollingFile name="File" fileName="${basePath}/ICETest.log" filePattern="${basePath}/ICETest-%d{yyyy-MM-dd-HH-mm-ss}.log">
   <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
  <SizeBasedTriggeringPolicy size="20000" />
      </RollingFile>
<Console name="Console" target="SYSTEM_OUT">
  <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>

This will append with existing file