/* Developer: Tyler Allen Date Created: 08/24/2016 --------------------------------------------------- */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using CPE.App.NotifyConsole.Models.Enums; using log4net; namespace CPE.App.NotifyConsole.Extensions { public static class LoggingExtensions { private static readonly ILog _logging = LogManager.GetLogger(new StackTrace().GetFrame(2) .GetMethod() .DeclaringType); #region private helper methods // ReSharper disable once RedundantAssignment private static void ignoreException(Exception exception) { Console.WriteLine(exception); } private static string getMethodText(MethodBase methodBase = null) { if(methodBase == null) { methodBase = getMethodBase(); } if(methodBase != null) { var declaringType = methodBase.DeclaringType; var methodName = $"{declaringType}.{methodBase.Name}"; return methodName; } return null; } private static MethodBase getMethodBase() { var methodBase = getStackFrame() .GetMethod(); return methodBase; } private static StackFrame getStackFrame() { var stackTrace = new StackTrace(true); StackFrame stackFrame = null; var frames = stackTrace.GetFrames(); var logFound = false; foreach (var frame in frames) { var methodName = frame.GetMethod() .Name; if(methodName.ToLower() == "log") { logFound = true; } else if((methodName.ToLower() != "log") && logFound) { try { stackFrame = frame; break; } catch (Exception exception) { ignoreException(exception); } } } return stackFrame; } private static ParameterInfo[] getParameters(MethodBase methodBase = null) { if(methodBase == null) { methodBase = getMethodBase(); } var parameters = methodBase?.GetParameters(); return parameters; } private static string getParameterText(MethodBase methodBase = null) { var parameters = getParameters(methodBase); if(parameters != null) { var parameterText = new StringBuilder(); foreach (var parameter in parameters) { try { var parameterType = parameter.ParameterType; var parameterTypeSplit = parameterType.ToString() .Split(Convert.ToChar(".")); var parameterTypeString = parameterTypeSplit.Last(); parameterText.AppendFormat("{0} {1}", parameterTypeString, parameter.Name); if(parameter.HasDefaultValue) { string defaultValue = null; if(parameter.DefaultValue == null) { defaultValue = "null"; } else { defaultValue = parameter.DefaultValue.ToString(); } parameterText.AppendFormat(" = {0}", defaultValue); } parameterText.Append(", "); } catch (Exception exception) { ignoreException(exception); } } if(parameterText.ToString() .EndsWith(", ")) { parameterText = parameterText.Remove(parameterText.Length - 2, 2); } return parameterText.ToString(); } return null; } #endregion #region public logging methods /// /// Universal extension for logging within the application. /// /// This is the value of the object that will be logged /// Optional log4net level with Debug /// Optional message that will be appended to log /// Optional key parameter for easy searching of log /// public static T Log(this T value, LoggingLevels loggingLevel = LoggingLevels.Debug, string message = null, long? key = null) { // Values for identifying class and method information var logText = new StringBuilder(); try { var method = getMethodBase(); var methodText = getMethodText(method); var parameterText = getParameterText(method); var stackFrame = getStackFrame(); var stackFrameLineNumber = stackFrame.GetFileLineNumber(); string methodName = $"{methodText}({parameterText})[Line: {stackFrameLineNumber}]"; var keyValue = ""; if(key.HasValue) { keyValue = $"[key:{key}]"; } // Generate text for method information logText.AppendFormat("[{0}]{1} {2}", methodName, keyValue, value); } catch (Exception exception) { // There was an error getting method information logText.Append("[Undefined]"); ignoreException(exception); } if(message != null) { logText.AppendFormat(" : {0}", message); } // Call log4net methods to log the message against the appenders switch (loggingLevel) { case LoggingLevels.Info: _logging.Info(logText); break; case LoggingLevels.Debug: _logging.Debug(logText); break; case LoggingLevels.Warn: _logging.Warn(logText); break; case LoggingLevels.Error: _logging.Error(logText); break; case LoggingLevels.Fatal: _logging.Fatal(logText); break; } return value; } public static List Log(this List values, LoggingLevels loggingLevel = LoggingLevels.Debug, string message = null) { foreach (var value in values) { value.ToString() .Log(loggingLevel, message); } return values; } #endregion } }