com.teradata.logging.TestFrameworkLoggingAppender Maven / Gradle / Ivy
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.teradata.logging;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalNotification;
import com.google.inject.ConfigurationException;
import com.teradata.tempto.context.TestContext;
import com.teradata.tempto.internal.listeners.TestMetadata;
import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.io.Files.createParentDirs;
import static com.teradata.tempto.context.ThreadLocalTestContextHolder.testContextIfSet;
import static org.apache.commons.io.FileUtils.getTempDirectoryPath;
/**
* This class is a custom log appender that is responsible for two things:
*
* - Writing out messages to the console when they meet the minimum level
* - Writing out messages to a per-test file when they meet the minimum level
*
* For now, the console and file levels are defined statically, as well as the output patterns.
*/
public class TestFrameworkLoggingAppender
extends AppenderSkeleton
{
private static final PatternLayout DEFAULT_FILE_OUTPUT_FORMAT = new PatternLayout("[%d{yyyy-MM-dd HH:mm:ss}] [%p] %c{10}: %m%n");
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'_'HH-mm-ss");
private final LoadingCache printWriterCache = buildPrintWriterCache();
private final String logsDirectory = selectLogsDirectory();
public TestFrameworkLoggingAppender()
{
setLayout(DEFAULT_FILE_OUTPUT_FORMAT);
}
private LoadingCache buildPrintWriterCache()
{
return CacheBuilder.newBuilder()
.maximumSize(20)
.removalListener((RemovalNotification rn) -> rn.getValue().close())
.build(new CacheLoader()
{
@Override
public PrintWriter load(String fileName)
throws Exception
{
File file = new File(fileName);
createParentDirs(file);
return new PrintWriter(new FileOutputStream(file, true));
}
});
}
private String getRootLogsDirectory()
{
String userLogsDir = System.getProperty("com.teradata.tempto.root.logs.dir");
if (userLogsDir != null) {
return userLogsDir;
}
else {
return getTempDirectoryPath() + "/tempto_logs";
}
}
private String selectLogsDirectory()
{
return getRootLogsDirectory() + "/" + DATE_FORMAT.format(new Date());
}
@Override
protected void append(LoggingEvent event)
{
checkState(!closed, "Cannot append to a closed TestFrameworkLoggingAppender");
writeToFile(getLayout().format(event));
String[] throwableStack = event.getThrowableStrRep();
if (throwableStack != null) {
for (String throwableElement : throwableStack) {
if (getLayout().ignoresThrowable()) {
writeToFile(formatThrowableElement(throwableElement));
}
}
}
}
private String formatThrowableElement(String throwableElement) {return " " + throwableElement + "\n";}
private void writeToFile(String message)
{
Optional printWriter = getFilePrintWriterForCurrentTest();
if (printWriter.isPresent()) {
printWriter.get().print(message);
printWriter.get().flush();
}
}
private Optional getFilePrintWriterForCurrentTest()
{
Optional currentTestLogFileName = getCurrentTestLogFileName();
if (currentTestLogFileName.isPresent()) {
return Optional.of(getFilePrintWriter(currentTestLogFileName.get()));
}
else {
return Optional.empty();
}
}
private PrintWriter getFilePrintWriter(String fileName)
{
return printWriterCache.getUnchecked(fileName);
}
private Optional getCurrentTestLogFileName()
{
Optional testContext = testContextIfSet();
try {
String testName = "SUITE";
if (testContext.isPresent()) {
Optional testMetadata = testContext.get().getOptionalDependency(TestMetadata.class);
if (testMetadata.isPresent()) {
testName = testMetadata.get().testName;
}
}
return Optional.of(logsDirectory + "/" + testName);
}
catch (ConfigurationException e) {
System.err.append("Could not load TestMetadata from guice context");
return Optional.empty();
}
}
@Override
public void close()
{
closed = true;
printWriterCache.invalidateAll();
printWriterCache.cleanUp();
}
@Override
public boolean requiresLayout()
{
return true;
}
/**
* @return logs directory for configured TestFrameworkLoggingAppender
*/
public static Optional getSelectedLogsDirectory()
{
Enumeration allAppenders = Logger.getRootLogger().getAllAppenders();
while (allAppenders.hasMoreElements()) {
Appender appender = (Appender) allAppenders.nextElement();
if (appender instanceof TestFrameworkLoggingAppender) {
return Optional.of(((TestFrameworkLoggingAppender) appender).logsDirectory);
}
}
return Optional.empty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy