GaleniumLoggingUtil.java
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2019 wcm.io
* %%
* 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.
* #L%
*/
package io.wcm.qa.glnm.logging.util;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import io.qameta.allure.Allure;
import io.qameta.allure.model.Status;
import io.wcm.qa.glnm.configuration.GaleniumConfiguration;
import io.wcm.qa.glnm.logging.logback.MarkedLogger;
/**
* Utility methods and constants around logging.
*
* @since 4.0.0
*/
public final class GaleniumLoggingUtil {
/**
* For special ERROR log status.
* @deprecated Use Allure compatible markers or use SLF4J log level {@link ch.qos.logback.core.status.Status#ERROR}.
*/
@Deprecated
public static final Marker MARKER_ERROR = getMarker("ERROR");
/**
* For all special ExtentReports events.
* @deprecated Use Allure compatible markers.
*/
@Deprecated
public static final Marker MARKER_EXTENT_REPORT = MarkerFactory.getMarker("EXTENT_REPORT");
/** For special FAIL log status. */
public static final Marker MARKER_FAIL = getMarker(Status.FAILED);
/**
* For special FATAL log status.
* @deprecated Use Allure compatible markers or use SLF4J log levels.
*/
@Deprecated
public static final Marker MARKER_FATAL = getMarker("FATAL");
/**
* For special INFO log status.
* @deprecated Use Allure compatible markers or use SLF4J log level {@link ch.qos.logback.core.status.Status#INFO}.
*/
@Deprecated
public static final Marker MARKER_INFO = getMarker("INFO");
/** For special PASS log status. */
public static final Marker MARKER_PASS = getMarker(Status.PASSED);
/** For special SKIP log status. */
public static final Marker MARKER_SKIP = getMarker(Status.SKIPPED);
/**
* For special WARN log status.
* @deprecated Use Allure compatible markers or use SLF4J log level {@link ch.qos.logback.core.status.Status#WARN}.
*/
@Deprecated
public static final Marker MARKER_WARN = getMarker("WARN");
private static final String MDC_PARAM_GLNM_TESTNAME = "glnm.testname";
private static final File TEST_LOG_ROOT = new File(GaleniumConfiguration.getTestLogDirectory());
private static final IOFileFilter TRUE_FILE_FILTER = FileFilterUtils.trueFileFilter();
private static final Logger LOG = LoggerFactory.getLogger(GaleniumLoggingUtil.class);
private GaleniumLoggingUtil() {
// do not instantiate
}
/**
* Gets a logger which marks every entry with the passed {@link org.slf4j.Marker}.
*
* @param marker to use with this logger
* @param logger to wrap in marked logger
* @return a {@link io.wcm.qa.glnm.logging.logback.MarkedLogger} using the marker
* @since 5.0.0
*/
public static Logger getMarkedLogger(Marker marker, Logger logger) {
return new MarkedLogger(logger, marker);
}
/**
* Gets a logger which marks every entry with a {@link org.slf4j.Marker} using the passed string.
*
* @param marker to use with this logger
* @param logger to wrap in marked logger
* @return a {@link io.wcm.qa.glnm.logging.logback.MarkedLogger} using the marker
* @since 5.0.0
*/
public static Logger getMarkedLogger(String marker, Logger logger) {
return getMarkedLogger(getMarker(marker), logger);
}
/**
* <p>getMarker.</p>
*
* @param name marker name
* @return marker for use with marked logger
* @since 5.0.0
*/
public static Marker getMarker(String name) {
Marker marker = MarkerFactory.getMarker(name);
return marker;
}
/**
* Initializes logging per test.
*
* @since 5.0.0
*/
public static void startTestLogging() {
String currentTestCaseId = Allure.getLifecycle().getCurrentTestCase().orElse("NO_TEST_ID");
if (LOG.isInfoEnabled()) {
LOG.info("Starting test specific logging for: " + currentTestCaseId);
}
MDC.put(MDC_PARAM_GLNM_TESTNAME, currentTestCaseId);
}
/**
* Stops test specific logging.
*
* @since 5.0.0
*/
public static void stopTestLogging() {
String testIdOfFinishedTest = MDC.get(MDC_PARAM_GLNM_TESTNAME);
if (LOG.isInfoEnabled()) {
LOG.info("Stopping test specific logging for: " + testIdOfFinishedTest);
}
addLogsToAllure(testIdOfFinishedTest);
MDC.remove(MDC_PARAM_GLNM_TESTNAME);
}
private static void addLogsToAllure(String testIdOfFinishedTest) {
if (StringUtils.isNotBlank(testIdOfFinishedTest)) {
Collection<File> logFiles = getLogFiles(testIdOfFinishedTest);
for (File logFile : logFiles) {
if (LOG.isTraceEnabled()) {
LOG.trace("Attaching " + logFile + " to Allure report.");
}
Allure.addAttachment(logFile.getName(), asString(logFile));
}
}
}
private static String asString(File logFile) {
String logFileContentAsString;
try {
logFileContentAsString = FileUtils.readFileToString(logFile, StandardCharsets.UTF_8);
}
catch (IOException ex) {
if (LOG.isInfoEnabled()) {
LOG.info("could not read log file.", ex);
}
logFileContentAsString = "Could not read log file: '" + logFile.getPath() + "' (" + ex.getMessage() + ")";
}
return logFileContentAsString;
}
private static Collection<File> getLogFiles(String testIdOfFinishedTest) {
// starting with test ID and ending in 'log'
IOFileFilter logFileFilter = FileFilterUtils.and(
FileFilterUtils.prefixFileFilter(testIdOfFinishedTest),
FileFilterUtils.suffixFileFilter("log"));
Collection<File> logFiles = FileUtils.listFiles(TEST_LOG_ROOT, logFileFilter, TRUE_FILE_FILTER);
if (LOG.isDebugEnabled()) {
LOG.debug("Found " + logFiles.size() + " log files for test id: '" + testIdOfFinishedTest + "'");
}
return logFiles;
}
private static Marker getMarker(Status logStatus) {
return getMarker(logStatus.name());
}
}