'log4j2 logs are not getting logged in auto generated log file under logs folder

Here i am trying to save my logs generated during execution in logs file i have used lo4j2.properties with Testng listener to save my logs , my log4j2.properties is as below

log4j2.properties

name=PropertiesConfig
property.filename = logs
appenders = console, file

appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n

appender.file.type = File
appender.file.name = LOGFILE
appender.file.fileName=${filename}/automationLogs.log
appender.file.layout.type=PatternLayout
appender.file.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
appender.file.append=true

loggers=file
logger.file.name=Demo
logger.file.level = debug
logger.file.appenderRefs = file
logger.file.appenderRef.file.ref = LOGFILE

rootLogger.level = debug
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT

TestListeners.java file file has following code

TestListeners.java

package Listners;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

import RecallAgreementPojo.RecallAgreementPayload;
import io.restassured.response.Response;
import utils.ConvertJSON;


public class TestListeners implements ITestListener{

    private static Logger logger = LogManager.getLogger(TestListeners.class);
    Response  response = null;  
    public void onTestStart(ITestResult result) {

        logger.info("********* Test started **********" + result.getName());

    }

    public void onTestSuccess(ITestResult result) {
        logger.info("********* Test Success **********");
    }

    public void onTestFailure(ITestResult result) {
        ITestContext context = result.getTestContext();
        response = (Response) context.getAttribute("Response");
        if(response != null)
            logger.error("********* Test Failed **********" + response.prettyPrint());

    }

    public void onTestSkipped(ITestResult result) {

        logger.warn("********* Test Skipped **********" + result.getName());

    }

    public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
//      logger.warn("********* Test passed partially with  **********" + result.SUCCESS_PERCENTAGE_FAILURE);

    }

    public void onStart(ITestContext context) {
        logger.info("=========== onStart :-" + context.getName() + "===============");
    }

    public void onFinish(ITestContext context) {
        logger.info("********* Test Completed **********" + context.getName());
        Map<String,List> newAgreementDetails =  (Map<String, List>) context.getAttribute("AgreementDetails");
        Map<String,RecallAgreementPayload> newAgreementsMap = (Map<String, RecallAgreementPayload>) context.getAttribute("AgreementRequests");
        for(Entry<String, List> entry : newAgreementDetails.entrySet()) {
            logger.info(entry.getKey() + " : " +  entry.getValue());
        }

        for(Entry<String, RecallAgreementPayload> entry : newAgreementsMap.entrySet()) {
            logger.info(entry.getKey() + " : " );
            ConvertJSON.JSONConverter(entry.getValue());
        }
    }

}

However i am getting empty file as automationLogs.log



Solution 1:[1]

The logger in log4j2.properties is named Demo.

logger.file.name=Demo              <<-- logger name
logger.file.appenderRef.file.ref = LOGFILE    <<-- reference to the appender that will write to file

In order to write to the file, you will need to provide LogManager the logger's name (Demo) for the LogManager to use it. LogManager.getLogger("<logger name>").

The appender LOGFILE, that logger Demo is referencing, will then write the logs to the file automationLogs.log.

In other words, change this:

private static Logger logger = LogManager.getLogger(TestListeners.class);

to this:

private static Logger logger = LogManager.getLogger("Demo");

If this is not the behavior you are expecting, and are really more interested in passing the TestListeners.class to the LogManager, then perhaps using a RollingFile will be better suited for your needs.

Though I have not tested the below on your configs, this would be the idea:

appender.rolling.type = RollingFile
appender.rolling.name = fileLogger
appender.rolling.fileName= ${filename}/automationLogs.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern =[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
appender.rolling.policies.type = Policies

and use the root logger to reference it:

rootLogger.appenderRef.rolling.ref = fileLogger

hope this helped :)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1