All Downloads are FREE. Search and download functionalities are using the official Maven repository.

TeamControlium.Utilities.Logger Maven / Gradle / Ivy

Go to download

TeamControlium Utilities provides a set of Test Framework utilities for use within the Team Controlium suite

There is a newer version: 1.2.3
Show newest version
package TeamControlium.Utilities;

import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/// Enables test scripts to log data that assists in debugging of test scripts and/or framework.  Library and
/// helper classes write to the debug log using log levels and to ensure detailed analysis
/// is possible.
/// Debug text redirection is possible if underlying tool supplies its own logging and/or debug output, wired up /// to and is set to false. /// The timestamp, shown on every line of the log output, is reset on the first call to the TeamControlium.Utilities.Logger. /// public final class Logger { private boolean errorWrittenToEventLog; private Date testTimer; // Used to keep track of time since first call to TeamControlium.Utilities.Logger class made. private HashMap testToolStrings; // Used to build string-per-thread as logger Write calls made static private Logger _Logger; private Logger() { errorWrittenToEventLog = false; testToolStrings = new HashMap<>(); _LoggingLevel = LogLevels.TestInformation; // Default logging level ResetTimer(); } /// /// Logging level. Lowest is Error (least amount of log data written - only writes at /// level Error are written to the log). Most data is written to /// the log if level set is FrameworkDebug /// private LogLevels _LoggingLevel; static public LogLevels getLoggingLevel() { if (_Logger==null) { _Logger = new Logger(); } return _Logger._LoggingLevel;} static public void setLoggingLevel(LogLevels loggingLevel) { if (_Logger==null) { _Logger = new Logger(); } _Logger._LoggingLevel = loggingLevel;} /// /// Defines where log lines are written to. /// If true (or has not been defined), debug data is written to the Console (stdout) /// If false, debug data logging is written to the delegate (if wired up) /// /// /// The default is for log data to be written to the console /// private boolean _WriteToConsole; static public boolean getWriteToConsole() { if (_Logger==null) { _Logger = new Logger(); } return _Logger._WriteToConsole;} static public void setWriteToConsole(boolean writeToConsole) { if (_Logger==null) { _Logger = new Logger(); } _Logger._WriteToConsole = writeToConsole;} /// /// System delegate to write debug data to if WriteToConsole is false. /// public Consumer _TestToolLog; static public Consumer getTestToolLog() { if (_Logger==null) { _Logger = new Logger(); } return _Logger._TestToolLog;} static public void setTestToolLog(Consumer testToolLog) { if (_Logger==null) { _Logger = new Logger(); } _Logger._TestToolLog = testToolLog;} /// /// Levels of logging - Verbose (Maximum) to Exception (Minimum). If level of text being written to /// logging is equal to, or higher than the current LoggingLevel the text is written.
/// This is used to filter logging so that only entries to log are made if the level of the write is equal /// or greater than the logging level set by LoggingLevel. ///
public enum LogLevels { /// /// Data written to log if LoggingLevel is FrameworkDebug and Write is FrameworkDebug or higher /// FrameworkDebug (0), /// /// Data written to log if LoggingLevel is FrameworkInformation and Write is FrameworkInformation or higher /// FrameworkInformation (1), /// /// Data written to log if LoggingLevel is TestDebug and Write is TestDebug or higher /// TestDebug (2), /// /// Data written to log if LoggingLevel is TestInformation and Write is TestInformation or Error /// TestInformation (3), /// /// Data always written to results /// Error (4); private int numVal; public int getVal() { return this.numVal;} LogLevels(int numVal) { this.numVal = numVal; } public int getNumVal() { return numVal; } }; /// /// Appends text to currently active line and writes line to active log. If new line, text is pre-pended with Line header information /// /// MethodBase of class calling TeamControlium.Utilities.Logger class /// Level of debug text to be written /// Text string to be written /// Text is written if TypeOfWrite is equal to, or higher the current Logging Level private void DoWriteLine(StackTraceElement methodBase, LogLevels TypeOfWrite, String textString) { if (TypeOfWrite.getVal() >= getLoggingLevel().getVal()) { String textToWrite = textString; // // Ensure only one thread can do the actual writing to the log. Prevents line corruption and allows us to direct writes to correct thread // //synchronized (this) { long threadID = Thread.currentThread().getId(); if (testToolStrings.containsKey(threadID)) { try { testToolStrings.put(threadID,testToolStrings.get(threadID).endsWith(" ") ? "" : " " + textToWrite); textToWrite = testToolStrings.get(threadID); } finally { testToolStrings.remove(threadID); } } else { String preAmble = GetPreAmble(methodBase, TypeOfWrite); textToWrite = preAmble + ((textString==null)?"":textString); } try { Consumer d = getTestToolLog(); if (getWriteToConsole() || getTestToolLog() == null) // If we are writing to the console or test tool has not wired up their logger... System.out.println(textToWrite); else _TestToolLog.accept(textToWrite); } catch (Exception ex) { // // Hmmm, dunno how yet.. // // String details; // if (!errorWrittenToEventLog) // { // using (EventLog appLog = new EventLog("Application")) // { // if (WriteToConsole) // { // details = "console (STDOUT)"; // } // else // { // details = string.Format("delegate provide by tool{0}.", (TestToolLog == null) ? // " (Is null! - Has not been implemented!)" : // ""); // } // appLog.Source = "Application"; // appLog.WriteEntry(string.Format("AppServiceInterfaceMock - TeamControlium.Utilities.Logger error writing to {0}.\r\n\r\n" + // "Attempt to write line;\r\n" + // "{1}\r\n\r\n" + // "No further log writes to event log will happen in this session", details, textToWrite, ex), EventLogEntryType.Warning, 12791, 1); // } // errorWrittenToEventLog = true; // } } } } } /// /// Appends text to currently active line. If the start of line, text is pre-pended with Line header information /// /// Text is written if TypeOfWrite is equal to, or higher the current Logging Level private void DoWrite(StackTraceElement methodBase, LogLevels TypeOfWrite, String textString) { // Only do write if level of this write is equal to or greater than the current logging level if (TypeOfWrite.getVal() >= getLoggingLevel().getVal()) { // Ensure thread safety by locking code around the write synchronized(this) { // // Get the id of the current thread and append text to end of the dictionary item for that // thread (create new item if doesnt already exist). If this is // first time this thread is doing a write, prepend the PreAmble text first. // long threadID = Thread.currentThread().getId(); if (testToolStrings.containsKey(threadID)) testToolStrings.put(threadID,GetPreAmble(methodBase, TypeOfWrite)); testToolStrings.put(threadID,testToolStrings.get(threadID).endsWith(" ") ? "" : " " + textString); } } } /// /// Gets class-type and Method name of passed MethodBase class. /// private String CallingMethodDetails(StackTraceElement methodBase) { String methodName=""; String typeName=""; if (methodBase != null) { methodName = methodBase.getMethodName(); if (methodName==null) methodName = ""; typeName = methodBase.getClassName(); if (typeName==null) typeName = ""; } return String.format("%s.%s", typeName, methodName); } /// /// Constructs and returns a log-file pre-amble. Preamble is {Log Type} {Time} [Calling Type.Method]: /// private String GetPreAmble(StackTraceElement methodBase, LogLevels TypeOfWrite) { SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SS"); String time = String.format("[%s}][%s]", timeFormat.format(Calendar.getInstance().getTime()), elapsedTime()); int totalTimeLength = time.length() + (8 - TypeOfWrite.getNumVal()); String preAmble = String.format("%s %s [%s]: ", TypeOfWrite.toString(), time, CallingMethodDetails(methodBase)); return preAmble; } private boolean FileExists(String fullPathAndFilename) { File f = new File(fullPathAndFilename); return (f.exists() && !f.isDirectory()); } public String elapsedTime() { long diffInMilliSeconds = Calendar.getInstance().getTime().getTime() - testTimer.getTime(); List units = Arrays.asList(TimeUnit.HOURS,TimeUnit.MINUTES,TimeUnit.SECONDS,TimeUnit.MILLISECONDS); //new Arrays.asList()//Arrays.asList(TimeUnit.HOURS,TimeUnit.MINUTES); // Collections.reverse(units); String result =""; long milliSecondsRest = diffInMilliSeconds; for (TimeUnit unit : units) { long diff = unit.convert(milliSecondsRest,TimeUnit.MILLISECONDS); milliSecondsRest = milliSecondsRest - unit.toMillis(diff); switch (unit) { case HOURS: result += String.format("%02d:",diff); break; case MINUTES: result += String.format("%02d:",diff); break; case SECONDS: result += String.format("%02d:",diff); break; case MILLISECONDS: result += String.format("%03d",diff); break; } } return result; } /// /// Resets the logger elapsed timer to zero /// public void ResetTimer() { testTimer = Calendar.getInstance().getTime(); } /// /// Writes details of a caught exception to the active debug log at level Error /// /// /// If current error logging level is FrameworkDebug the full /// exception is written, including stacktrace etc.
/// With any other Log Level only the exception message is written. If an exception is thrown during write, TeamControlium.Utilities.Logger /// attempts to write the error details if able. ///
static public void LogException(Exception ex) { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); StackTraceElement caller = stackTraceElements[2]; if (_Logger==null) { _Logger = new Logger(); } if (_Logger.getLoggingLevel() == LogLevels.FrameworkDebug) { _Logger.DoWriteLine(caller,LogLevels.Error,String.format("Exception thrown: %s",ex.toString())); } else { _Logger.DoWriteLine(caller, LogLevels.Error, String.format("Exception thrown: %s", ex.getMessage())); } } /// /// Writes details of a caught exception to the active debug log at levelError /// /// /// If current error logging level is FrameworkDebug the full /// exception is written, including stacktrace etc.
/// With any other Log Level only the exception message is writteIf an exception is thrown during write, TeamControlium.Utilities.Logger /// attempts to write the error details if able. ///
static public void LogException(Exception ex, String text, Object... args) { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); StackTraceElement caller = stackTraceElements[2]; if (_Logger==null) { _Logger = new Logger(); } _Logger.DoWrite(caller, LogLevels.Error, String.format(text, args)); if (_Logger.getLoggingLevel() == LogLevels.FrameworkDebug) { _Logger.DoWriteLine(caller, LogLevels.Error, String.format("Exception thrown: %s", ex.toString())); } else { _Logger.DoWriteLine(caller, LogLevels.Error, String.format("Exception thrown: %s", ex.getMessage())); } } /// /// Writes a line of data to the active debug log with no line termination /// static public void Write(LogLevels logLevel, String textString, Object... args) { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); StackTraceElement caller = stackTraceElements[2]; if (_Logger==null) { _Logger = new Logger(); } _Logger.DoWrite(caller, logLevel, String.format(textString, args)); } /// /// Writes a line of data to the active debug log. /// Data can be formatted in the standard string.format syntax. If an exception is thrown during write, TeamControlium.Utilities.Logger /// attempts to write the error deatils if able. /// static public void WriteLine(LogLevels logLevel, String textString, Object... args) { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); StackTraceElement caller = stackTraceElements[2]; if (_Logger==null) { _Logger = new Logger(); } _Logger.DoWriteLine(caller, logLevel, String.format(textString, args)); } /// /// Writes given Text to a text file, optionally auto versioning (adding (n) to filename) OR /// overwriting. /// /// /// No exception is raised if there is any problem, but details of error is written to TeamControlium.Utilities.Logger log /// static public void WriteTextToFile(String Filename, boolean AutoVersion, String Text) { if (_Logger==null) { _Logger = new Logger(); } try { String FilenameToUse = Filename; if (AutoVersion) { int count = 1; String fileNameOnly = FilenameUtils.removeExtension(Filename); String extension = FilenameUtils.getExtension(Filename); String path = Paths.get(Filename).getParent().toString(); FilenameToUse = Filename; while (_Logger.FileExists(FilenameToUse)) { String tempFileName = String.format("%s(%d)", fileNameOnly, count++); File preAmble = new File(path); File combined = new File(preAmble,tempFileName + extension); FilenameToUse = combined.getPath(); } } List lines = Arrays.asList(Text.split("\\r?\\n")); Path file = Paths.get(FilenameToUse); Files.write(file,lines, Charset.forName("UTF-8")); } catch (Exception ex) { LogException(ex, String.format("Cannot write data to file [%s] (AutoVersion=[%s])",(Filename==null)? "Null Filename!":Filename, (AutoVersion) ? "Yes" : "No")); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy