initial commit
[CPE_learningsite] / CPE / CPE.App / CPE.App.NotifyConsole / Extensions / LoggingExtensions.cs
1 /*
2 Developer: Tyler Allen
3 Date Created: 08/24/2016
4 ---------------------------------------------------
5 */
6
7 using System;
8 using System.Collections.Generic;
9 using System.Diagnostics;
10 using System.Linq;
11 using System.Reflection;
12 using System.Text;
13 using CPE.App.NotifyConsole.Models.Enums;
14 using log4net;
15
16 namespace CPE.App.NotifyConsole.Extensions {
17     public static class LoggingExtensions {
18         private static readonly ILog _logging = LogManager.GetLogger(new StackTrace().GetFrame(2)
19                                                                                      .GetMethod()
20                                                                                      .DeclaringType);
21
22         #region private helper methods
23
24         // ReSharper disable once RedundantAssignment
25         private static void ignoreException(Exception exception) {
26             Console.WriteLine(exception);
27         }
28
29         private static string getMethodText(MethodBase methodBase = null) {
30             if(methodBase == null) {
31                 methodBase = getMethodBase();
32             }
33             if(methodBase != null) {
34                 var declaringType = methodBase.DeclaringType;
35                 var methodName = $"{declaringType}.{methodBase.Name}";
36                 return methodName;
37             }
38             return null;
39         }
40
41         private static MethodBase getMethodBase() {
42             var methodBase = getStackFrame()
43                 .GetMethod();
44             return methodBase;
45         }
46
47         private static StackFrame getStackFrame() {
48             var stackTrace = new StackTrace(true);
49             StackFrame stackFrame = null;
50             var frames = stackTrace.GetFrames();
51
52             var logFound = false;
53             foreach (var frame in frames) {
54                 var methodName = frame.GetMethod()
55                                       .Name;
56                 if(methodName.ToLower() == "log") {
57                     logFound = true;
58                 } else if((methodName.ToLower() != "log") && logFound) {
59                     try {
60                         stackFrame = frame;
61                         break;
62                     } catch (Exception exception) {
63                         ignoreException(exception);
64                     }
65                 }
66             }
67
68             return stackFrame;
69         }
70
71         private static ParameterInfo[] getParameters(MethodBase methodBase = null) {
72             if(methodBase == null) {
73                 methodBase = getMethodBase();
74             }
75             var parameters = methodBase?.GetParameters();
76             return parameters;
77         }
78
79         private static string getParameterText(MethodBase methodBase = null) {
80             var parameters = getParameters(methodBase);
81             if(parameters != null) {
82                 var parameterText = new StringBuilder();
83                 foreach (var parameter in parameters) {
84                     try {
85                         var parameterType = parameter.ParameterType;
86                         var parameterTypeSplit = parameterType.ToString()
87                                                               .Split(Convert.ToChar("."));
88                         var parameterTypeString = parameterTypeSplit.Last();
89                         parameterText.AppendFormat("{0} {1}", parameterTypeString, parameter.Name);
90
91                         if(parameter.HasDefaultValue) {
92                             string defaultValue = null;
93                             if(parameter.DefaultValue == null) {
94                                 defaultValue = "null";
95                             } else {
96                                 defaultValue = parameter.DefaultValue.ToString();
97                             }
98
99                             parameterText.AppendFormat(" = {0}", defaultValue);
100                         }
101                         parameterText.Append(", ");
102                     } catch (Exception exception) {
103                         ignoreException(exception);
104                     }
105                 }
106                 if(parameterText.ToString()
107                                 .EndsWith(", ")) {
108                     parameterText = parameterText.Remove(parameterText.Length - 2, 2);
109                 }
110                 return parameterText.ToString();
111             }
112             return null;
113         }
114
115         #endregion
116
117         #region public logging methods
118
119         /// <summary>
120         ///     Universal extension for logging within the application.
121         /// </summary>
122         /// <param name="value">This is the value of the object that will be logged</param>
123         /// <param name="loggingLevel">Optional log4net level with Debug</param>
124         /// <param name="message">Optional message that will be appended to log</param>
125         /// <param name="key">Optional key parameter for easy searching of log</param>
126         /// <returns></returns>
127         public static T Log<T>(this T value, LoggingLevels loggingLevel = LoggingLevels.Debug, string message = null, long? key = null) {
128             // Values for identifying class and method information
129
130             var logText = new StringBuilder();
131
132             try {
133                 var method = getMethodBase();
134                 var methodText = getMethodText(method);
135                 var parameterText = getParameterText(method);
136                 var stackFrame = getStackFrame();
137                 var stackFrameLineNumber = stackFrame.GetFileLineNumber();
138                 string methodName = $"{methodText}({parameterText})[Line: {stackFrameLineNumber}]";
139
140                 var keyValue = "";
141                 if(key.HasValue) {
142                     keyValue = $"[key:{key}]";
143                 }
144
145                 // Generate text for method information
146                 logText.AppendFormat("[{0}]{1} {2}", methodName, keyValue, value);
147             } catch (Exception exception) {
148                 // There was an error getting method information
149                 logText.Append("[Undefined]");
150                 ignoreException(exception);
151             }
152
153             if(message != null) {
154                 logText.AppendFormat(" : {0}", message);
155             }
156
157             // Call log4net methods to log the message against the appenders
158             switch (loggingLevel) {
159                 case LoggingLevels.Info:
160                     _logging.Info(logText);
161                     break;
162                 case LoggingLevels.Debug:
163                     _logging.Debug(logText);
164                     break;
165                 case LoggingLevels.Warn:
166                     _logging.Warn(logText);
167                     break;
168                 case LoggingLevels.Error:
169                     _logging.Error(logText);
170                     break;
171                 case LoggingLevels.Fatal:
172                     _logging.Fatal(logText);
173                     break;
174             }
175             return value;
176         }
177
178         public static List<T> Log<T>(this List<T> values, LoggingLevels loggingLevel = LoggingLevels.Debug, string message = null) {
179             foreach (var value in values) {
180                 value.ToString()
181                      .Log(loggingLevel, message);
182             }
183             return values;
184         }
185
186         #endregion
187     }
188 }