log4j: ОШИБКА Попытка добавить к закрытому приложению с именем при написании приложения автоматически

Я пытаюсь добавить просеивающие приложения для log4j, а затем выполнить тесты JUnit для него. Тест JUnit просто пытается записать некоторый контент в ifx-1.log, ifx-2.log, а также ifx-3.log файлы, а затем сравнить его с уже существующими файлами. Затем он пытается закрыть файл appender перед удалением файла.

У меня есть следующий код;

import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

public class Log4jUtil {

    private static String pattern = "%d{HH:mm:ss.SSS} [%thread] %p %c{2}: %m%n";
    public final static String DESCRIMINATOR_KEY = "logFileName";

    private static final Logger logger = Logger.getRootLogger();

    public static boolean addSiftingAppender(String logFileName) {

        if (logger.getAppender(logFileName) == null) {

            try {

                String logfile = logFileName + ".log";
                FileAppender fileAppender = new FileAppender(
                        new PatternLayout(pattern), logfile, true);
                fileAppender.setName(logFileName);
                fileAppender.addFilter(new RunIdFilter(logFileName));
                fileAppender.setImmediateFlush(true);

                logger.addAppender(fileAppender);

            } catch (Exception e) {
                logger.warn("[ifx] Failed to log to file using log4j logger", e);
                return false;
            }
        }
        return true;

    }

    public static void stopFileAppender(String logFileName) {

        Appender appender = logger.getAppender(logFileName);
        if (appender != null) {
            appender.close();
        }
    }

}

RunIdFilter

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;

public class RunIdFilter extends Filter {

    private final String runId;

    public RunIdFilter(String runId) {
        this.runId = runId;
    }

    @Override
    public int decide(LoggingEvent event) {
        Object mdc = event.getMDC(Log4jUtil.DESCRIMINATOR_KEY);

        if (runId.equals(mdc)) {
            return Filter.ACCEPT;
        }

        return Filter.DENY;
    }
}

JUnit test

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import jdk.nashorn.internal.ir.annotations.Ignore;

import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.MDC;

import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner;
import com.anarsoft.vmlens.concurrent.junit.ThreadCount;

import lombok.extern.slf4j.Slf4j;

@RunWith(ConcurrentTestRunner.class)
@Slf4j
public class Log4jProgrammaticSiftingAppenderTest {

    private final static int THREAD_COUNT = 3;
    private static int count = 0;

    Path resourceDirectory = Paths.get("src", "test", "resources");

    // This function will write to file using log4j logger in a multi-threaded manner
    @Test
    @ThreadCount(THREAD_COUNT)
    @Ignore
    public void writeLogs() {

        Thread.currentThread().setName("ifx-" + ++count);

        Log4jUtil.addSiftingAppender(Thread.currentThread().getName());

        MDC.put("logFileName", Thread.currentThread().getName());

        log.info("Start test");
        log.warn("hello in " + Thread.currentThread().getName());

        // try {
        // Thread.sleep(500);
        // } catch (InterruptedException e) {
        // log.error("Exception occurent in writing log4j ifx logs", e);
        // }

        MDC.remove(Thread.currentThread().getName());

        MDC.put("logFileName", Thread.currentThread().getName());

        log.error("hello2 in " + Thread.currentThread().getName());
        log.info("End test");

        MDC.remove(Thread.currentThread().getName());
        Log4jUtil.stopFileAppender(Thread.currentThread().getName());

    }

    // This function will check if the written log file content is correct
    @After
    public void checkLogFileContent() {

        int numberOfFiles = THREAD_COUNT;
        boolean areEqual = true;

        while (numberOfFiles > 0) {
            try {

                BufferedReader resourceDirectoryLogFileReader = new BufferedReader(
                        new FileReader(resourceDirectory + "\\logs\\ifx-" + numberOfFiles + ".log"));

                BufferedReader logFileReader = new BufferedReader(new FileReader("ifx-" + numberOfFiles + ".log"));

                String resourceDirectoryLogFileLine = resourceDirectoryLogFileReader.readLine();
                String logFileLine = logFileReader.readLine();

                while (resourceDirectoryLogFileLine != null && logFileLine != null)
                {
                    if (!logFileLine.contains(resourceDirectoryLogFileLine))
                    {
                        areEqual = false;
                        log.error(
                                "[ifx] Logs don't contain the desired string. They should contain %s. But they have %s ",
                                resourceDirectoryLogFileLine, logFileLine);
                        fail("[ifx] Log files are not being written correctly for ifx using log4j logger");
                    }
                    resourceDirectoryLogFileLine = resourceDirectoryLogFileReader.readLine();
                    logFileLine = logFileReader.readLine();
                }
                resourceDirectoryLogFileReader.close();
                logFileReader.close();
            } catch (FileNotFoundException filenotFoundException) {
                log.error("", filenotFoundException);
                fail("[ifx] Log files are not being written correctly for ifx using log4j logger");

            } catch (IOException ioException) {
                log.error("", ioException);
                fail("[ifx] Log files are not being written correctly for ifx using log4j logger");
            } finally {
                deleteFile("ifx-" + numberOfFiles + ".log");
            }
            numberOfFiles--;
        }
        assertTrue(areEqual);
    }

    private void deleteFile(String fileName) {

        File file = new File(fileName);
        if (file.exists() && !file.delete()) {
            log.warn("Error occurred while deleting file %s", fileName);
        }

    }
}

Когда я запускаю тест JUnit, он проходит успешно, но я получаю следующую ошибку

log4j:ERROR Attempted to append to closed appender named [ifx-3].
log4j:ERROR Attempted to append to closed appender named [ifx-3].
2018-03-12 16:53:53,243  INFO Log4jProgrammaticSiftingAppenderTest - End test
log4j:ERROR Attempted to append to closed appender named [ifx-3].
2018-03-12 16:53:53,240 ERROR Log4jProgrammaticSiftingAppenderTest - hello2 in ifx-1
log4j:ERROR Attempted to append to closed appender named [ifx-2].
2018-03-12 16:53:54,257  INFO Log4jProgrammaticSiftingAppenderTest - End test
log4j:ERROR Attempted to append to closed appender named [ifx-3].
log4j:ERROR Attempted to append to closed appender named [ifx-2].
log4j:ERROR Attempted to append to closed appender named [ifx-3].

Я закрываю приложение, когда закончу писать и после MDC.remove, Что мне не хватает?

0 ответов

Другие вопросы по тегам