com.artos.framework.infra.OrganisedLog Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of artos Show documentation
Show all versions of artos Show documentation
The Artos "ART OF SYSTEM TESTING" is a framework designed for regression, functional, integration, end to end and/or unit testing.
/*******************************************************************************
* Copyright (C) 2018-2019 Arpit Shah and Artos Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
package com.artos.framework.infra;
import java.io.File;
import java.util.List;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
import com.artos.framework.FWStaticStore;
import com.artos.framework.parser.TestSuite;
/**
* This class is responsible for initialising all log streams which may require
* during test suite execution
*/
class OrganisedLog {
private LoggerContext loggerContext;
private String logBaseDir;
public static String GENERAL_LOGGER_NAME_STX = "General_";
public static String SUMMARY_LOGGER_NAME_STX = "Summary_";
public static String REALTIME_LOGGER_NAME_STX = "RealTime_";
/**
* Constructor responsible for creating log base directory and Log4J
* loggerContext using Framework configuration and TestSuite information
*
* @param logDirPath
* Log base directory absolute or reference path
* @param testCaseFQCN
* Test case fully qualified class name (Example :
* com.test.unit.Abc)
* @param enableLogDecoration
* Enables/disable log decoration (Time-stamp, source package,
* thread number etc..)
* @param enableTextLog
* Enables/disable text log
* @param enableHTMLLog
* Enable/disable HTML log
* @param testSuiteList
* list of testSuite (if any) or pass null
*/
public OrganisedLog(String logDirPath, String testCaseFQCN, boolean enableLogDecoration, boolean enableTextLog, boolean enableHTMLLog,
List testSuiteList) {
// System.setProperty("log4j.configurationFile",
// "./conf/log4j2.properties");
if(null == logDirPath){
logDirPath = FWStaticStore.LOG_BASE_DIR;
}
if (!logDirPath.endsWith("/") && !logDirPath.endsWith("\\")) {
logDirPath = logDirPath + File.separator;
}
setLogBaseDir(logDirPath + testCaseFQCN + File.separator);
setLoggerContext(dynamicallyConfigureLog4J(getLogBaseDir(), testCaseFQCN, enableLogDecoration, enableTextLog, enableHTMLLog, testSuiteList));
}
/**
* Dynamically Generates and applies Log4J configuration XML as per test
* suite requirement
*
* @param baseDir
* Log file root directory
* @param testFQCN
* Log file name
* @param enableLogDecoration
* Enable/disable log decoration (Time-stamp, source package,
* thread number etc..)
* @param enableTextLog
* Enables/disable text log
* @param enableHTMLLog
* Enable/disable HTML log
* @param testSuiteList
* testSuiteLite (if any) or pass null
* @return {@code LoggerContext}
*
* @see LoggerContext
*/
private LoggerContext dynamicallyConfigureLog4J(String baseDir, String testFQCN, boolean enableLogDecoration, boolean enableTextLog,
boolean enableHTMLLog, List testSuiteList) {
int numberOfAppenders = 1;
if (!baseDir.endsWith("/") && !baseDir.endsWith("\\")) {
baseDir = baseDir + File.separator;
}
if (null != testSuiteList && !testSuiteList.isEmpty()) {
numberOfAppenders = testSuiteList.size();
}
ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel(Level.WARN);
builder.setConfigurationName("RollingBuilder");
// Log Layout for general logs
LayoutComponentBuilder logFileLayout = builder.newLayout("PatternLayout");
// Log Layout for real time logs
LayoutComponentBuilder realTimeLogLayout = builder.newLayout("PatternLayout");
// Log Layout for summary file
LayoutComponentBuilder summaryFileLayout = builder.newLayout("PatternLayout");
/*
* @formatter:off
*
* %highlight{} Highlights log levels in different colour
* [%-5level] = Log level upto 5 char max
* [%d{yyyy-MM-dd_HH:mm:ss.SSS}] = Date and time
* [%t] = Thread number
* [%F] = File where logs are coming from
* [%M] = Method which generated log
* [%c{-1}] = ClassName which issued logCommand
* %msg = Actual msg to be logged
* %n = new line
* %throwable = log exception
*
* @formatter:on
*/
{
if (enableLogDecoration) {
logFileLayout.addAttribute("pattern", "[%-5level][%d{yyyy-MM-dd_HH:mm:ss.SSS}][%t][%F][%M][%c{1}] - %msg%n%throwable");
} else {
logFileLayout.addAttribute("pattern", "%msg%n%throwable");
}
realTimeLogLayout.addAttribute("pattern", "[%-5level][%d{yyyy-MM-dd_HH:mm:ss.SSS}][%t] - %msg%n%throwable");
summaryFileLayout.addAttribute("pattern", "%msg%n%throwable");
}
// HTML Log Layout for general logs
LayoutComponentBuilder htmlLogFileLayout = builder.newLayout("HTMLLayout");
htmlLogFileLayout.addAttribute("title", "Test Logs");
// expensive if enabled
htmlLogFileLayout.addAttribute("locationInfo", false);
htmlLogFileLayout.addAttribute("fontSize", "small");
// HTML Log Layout for summary logs
LayoutComponentBuilder htmlSummaryFileLayout = builder.newLayout("HTMLLayout");
htmlSummaryFileLayout.addAttribute("title", "Test Summary");
// expensive if enabled
htmlSummaryFileLayout.addAttribute("locationInfo", false);
htmlLogFileLayout.addAttribute("fontSize", "small");
// HTML Log Layout for realtime logs
LayoutComponentBuilder htmlrealTimeLogLayout = builder.newLayout("HTMLLayout");
htmlrealTimeLogLayout.addAttribute("title", "Test Summary");
// expensive if enabled
htmlrealTimeLogLayout.addAttribute("locationInfo", false);
htmlrealTimeLogLayout.addAttribute("fontSize", "small");
// File size based rollver Trigger Policy
ComponentBuilder> triggeringPolicy = builder.newComponent("Policies");
triggeringPolicy.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "10MB"));
// create a console appender
{
AppenderComponentBuilder appenderBuilder1 = builder.newAppender("console-log", "CONSOLE");
appenderBuilder1.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder1.add(logFileLayout);
builder.add(appenderBuilder1);
}
for (int i = 0; i < numberOfAppenders; i++) {
// retrieve file prefix
String logFilePrefix = (testSuiteList != null ) ? testSuiteList.get(i).getSuiteName() + "_" : "";
String logFileName = testFQCN + "_" + i + "_" + logFilePrefix + System.currentTimeMillis();
// create a rolling file appender for general logs
{
// Text
AppenderComponentBuilder appenderBuilder2 = builder.newAppender("all-log-text" + i, "RollingFile");
appenderBuilder2.addAttribute("fileName", baseDir + logFileName + "-all.log");
appenderBuilder2.addAttribute("filePattern", baseDir + logFileName + "-all-%d{yyyy-MM-dd_HH.mm.ss.SSS}.log");
appenderBuilder2.add(logFileLayout);
appenderBuilder2.addComponent(triggeringPolicy);
if (enableTextLog) {
builder.add(appenderBuilder2);
}
// HTML
AppenderComponentBuilder appenderBuilder3 = builder.newAppender("all-log-html" + i, "RollingFile");
appenderBuilder3.addAttribute("fileName", baseDir + logFileName + "-all.html");
appenderBuilder3.addAttribute("filePattern", baseDir + logFileName + "-all-%d{yyyy-MM-dd_HH.mm.ss.SSS}.html");
appenderBuilder3.add(htmlLogFileLayout);
appenderBuilder3.addComponent(triggeringPolicy);
if (enableHTMLLog) {
builder.add(appenderBuilder3);
}
}
// create a rolling file appender for summary
{
// Text
AppenderComponentBuilder appenderBuilder6 = builder.newAppender("summary-log-text" + i, "RollingFile");
appenderBuilder6.addAttribute("fileName", baseDir + logFileName + "-summary.log");
appenderBuilder6.addAttribute("filePattern", baseDir + logFileName + "-summary-%d{yyyy-MM-dd_HH.mm.ss.SSS}.log");
appenderBuilder6.add(summaryFileLayout);
appenderBuilder6.addComponent(triggeringPolicy);
if (enableTextLog) {
builder.add(appenderBuilder6);
}
// HTML
AppenderComponentBuilder appenderBuilder7 = builder.newAppender("summary-log-html" + i, "RollingFile");
appenderBuilder7.addAttribute("fileName", baseDir + logFileName + "-summary.html");
appenderBuilder7.addAttribute("filePattern", baseDir + logFileName + "-summary-%d{yyyy-MM-dd_HH.mm.ss.SSS}.html");
appenderBuilder7.add(htmlSummaryFileLayout);
appenderBuilder7.addComponent(triggeringPolicy);
if (enableHTMLLog) {
builder.add(appenderBuilder7);
}
}
// create a rolling file appender for real time logs
{
// Text
AppenderComponentBuilder appenderBuilder8 = builder.newAppender("realtime-log-text" + i, "RollingFile");
appenderBuilder8.addAttribute("fileName", baseDir + logFileName + "-realtime.log");
appenderBuilder8.addAttribute("filePattern", baseDir + logFileName + "-realtime-%d{yyyy-MM-dd_HH.mm.ss.SSS}.log");
appenderBuilder8.add(realTimeLogLayout);
appenderBuilder8.addComponent(triggeringPolicy);
if (enableTextLog) {
builder.add(appenderBuilder8);
}
// HTML
AppenderComponentBuilder appenderBuilder9 = builder.newAppender("realtime-log-html" + i, "RollingFile");
appenderBuilder9.addAttribute("fileName", baseDir + logFileName + "-realtime.html");
appenderBuilder9.addAttribute("filePattern", baseDir + logFileName + "-realtime-%d{yyyy-MM-dd_HH.mm.ss.SSS}.html");
appenderBuilder9.add(htmlrealTimeLogLayout);
appenderBuilder9.addComponent(triggeringPolicy);
if (enableHTMLLog) {
builder.add(appenderBuilder9);
}
}
String generalLoggerName = GENERAL_LOGGER_NAME_STX + i;
String summaryLoggerName = SUMMARY_LOGGER_NAME_STX + i;
String realtimeLoggerName = REALTIME_LOGGER_NAME_STX + i;
// create the new logger
Level loglevel = FWStaticStore.frameworkConfig.getLoglevelFromXML();
LoggerComponentBuilder generalLoggerBuilder = builder.newLogger(generalLoggerName, loglevel);
{
generalLoggerBuilder.addAttribute("additivity", false);
AppenderRefComponentBuilder appendRef1 = builder.newAppenderRef("console-log");
appendRef1.addAttribute("level", Level.ALL);
AppenderRefComponentBuilder appendRef2 = builder.newAppenderRef("all-log-text" + i);
appendRef2.addAttribute("level", Level.ALL);
AppenderRefComponentBuilder appendRef3 = builder.newAppenderRef("all-log-html" + i);
appendRef3.addAttribute("level", Level.ALL);
generalLoggerBuilder.add(appendRef1);
if (enableTextLog) {
generalLoggerBuilder.add(appendRef2);
}
if (enableHTMLLog) {
generalLoggerBuilder.add(appendRef3);
}
}
// create new logger for summary
LoggerComponentBuilder summaryLoggerBuilder = builder.newLogger(summaryLoggerName, Level.ALL);
summaryLoggerBuilder.addAttribute("additivity", false);
{
AppenderRefComponentBuilder appendRef11 = builder.newAppenderRef("summary-log-text" + i);
appendRef11.addAttribute("level", Level.ALL);
AppenderRefComponentBuilder appendRef12 = builder.newAppenderRef("summary-log-html" + i);
appendRef12.addAttribute("level", Level.ALL);
if (enableTextLog) {
summaryLoggerBuilder.add(appendRef11);
}
if (enableHTMLLog) {
summaryLoggerBuilder.add(appendRef12);
}
}
// create new logger for real time logs
LoggerComponentBuilder realTimeLoggerBuilder = builder.newLogger(realtimeLoggerName, Level.ALL);
realTimeLoggerBuilder.addAttribute("additivity", false);
{
AppenderRefComponentBuilder appendRef21 = builder.newAppenderRef("realtime-log-text" + i);
appendRef21.addAttribute("level", Level.ALL);
AppenderRefComponentBuilder appendRef22 = builder.newAppenderRef("realtime-log-html" + i);
appendRef22.addAttribute("level", Level.ALL);
if (enableTextLog) {
realTimeLoggerBuilder.add(appendRef21);
}
if (enableHTMLLog) {
realTimeLoggerBuilder.add(appendRef22);
}
}
builder.add(generalLoggerBuilder);
builder.add(summaryLoggerBuilder);
builder.add(realTimeLoggerBuilder);
}
// create root logger
RootLoggerComponentBuilder rootlogggerBuilder = builder.newRootLogger(Level.ALL);
rootlogggerBuilder.addAttribute("additivity", false);
{
AppenderRefComponentBuilder appendRef0 = builder.newAppenderRef("console-log");
rootlogggerBuilder.add(appendRef0);
}
builder.add(rootlogggerBuilder);
// System.out.println(builder.toXmlConfiguration().toString());
LoggerContext loggerContext = Configurator.initialize(builder.build());
// Print logger xml to log file
loggerContext.getLogger(GENERAL_LOGGER_NAME_STX + 0).trace(builder.toXmlConfiguration().toString());
return loggerContext;
}
/** Returns Log Files Base Directory */
public String getLogBaseDir() {
return logBaseDir;
}
/** Sets Log Files Base Directory */
protected void setLogBaseDir(String logBaseDir) {
this.logBaseDir = logBaseDir;
}
public LoggerContext getLoggerContext() {
return loggerContext;
}
protected void setLoggerContext(LoggerContext loggerContext) {
this.loggerContext = loggerContext;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy