/*
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
}
}