| 0 | 1 using System; | 
|  | 2 using System.Diagnostics; | 
|  | 3 using System.Globalization; | 
|  | 4 using System.IO; | 
|  | 5 using System.Collections; | 
|  | 6 using System.Text; | 
|  | 7 | 
|  | 8 namespace BLToolkit.Aspects | 
|  | 9 { | 
|  | 10 	public delegate void LogOperation(InterceptCallInfo interceptCallInfo, LoggingAspect.Parameters parameters); | 
|  | 11 	public delegate void LogOutput   (string logText, string fileName); | 
|  | 12 | 
|  | 13 	/// <summary> | 
|  | 14 	/// http://www.bltoolkit.net/Doc/Aspects/index.htm | 
|  | 15 	/// </summary> | 
|  | 16 	public class LoggingAspect : Interceptor | 
|  | 17 	{ | 
|  | 18 		public class Parameters | 
|  | 19 		{ | 
|  | 20 			public string FileName; | 
|  | 21 			public int    MinCallTime; | 
|  | 22 			public bool   LogExceptions; | 
|  | 23 			public bool   LogParameters; | 
|  | 24 		} | 
|  | 25 | 
|  | 26 		private string              _instanceFileName; | 
|  | 27 		private int?                _instanceMinCallTime; | 
|  | 28 		private bool?               _instanceLogExceptions; | 
|  | 29 		private bool?               _instanceLogParameters; | 
|  | 30 		private readonly Parameters _parameters = new Parameters(); | 
|  | 31 | 
|  | 32 		public override void Init(CallMethodInfo info, string configString) | 
|  | 33 		{ | 
|  | 34 			base.Init(info, configString); | 
|  | 35 | 
|  | 36 			string[] ps = configString.Split(';'); | 
|  | 37 | 
|  | 38 			foreach (string p in ps) | 
|  | 39 			{ | 
|  | 40 				string[] vs = p.Split('='); | 
|  | 41 | 
|  | 42 				if (vs.Length == 2) | 
|  | 43 				{ | 
|  | 44 					switch (vs[0].ToLower().Trim()) | 
|  | 45 					{ | 
|  | 46 						case "filename":      _instanceFileName      =            vs[1].Trim();  break; | 
|  | 47 						case "mincalltime":   _instanceMinCallTime   = int. Parse(vs[1].Trim()); break; | 
|  | 48 						case "logexceptions": _instanceLogExceptions = bool.Parse(vs[1].Trim()); break; | 
|  | 49 						case "logparameters": _instanceLogParameters = bool.Parse(vs[1].Trim()); break; | 
|  | 50 					} | 
|  | 51 				} | 
|  | 52 			} | 
|  | 53 		} | 
|  | 54 | 
|  | 55 		protected override void OnFinally(InterceptCallInfo info) | 
|  | 56 		{ | 
|  | 57 			if (IsEnabled) | 
|  | 58 			{ | 
|  | 59 				_parameters.FileName      = _instanceFileName      ?? FileName; | 
|  | 60 				_parameters.MinCallTime   = _instanceMinCallTime   ?? MinCallTime; | 
|  | 61 				_parameters.LogExceptions = _instanceLogExceptions ?? LogExceptions; | 
|  | 62 				_parameters.LogParameters = _instanceLogParameters ?? LogParameters; | 
|  | 63 | 
|  | 64 				LogOperation(info, _parameters); | 
|  | 65 			} | 
|  | 66 		} | 
|  | 67 | 
|  | 68 		#region Parameters | 
|  | 69 | 
|  | 70 		private static bool _logParameters = true; | 
|  | 71 		public  static bool  LogParameters | 
|  | 72 		{ | 
|  | 73 			get { return _logParameters;  } | 
|  | 74 			set { _logParameters = value; } | 
|  | 75 		} | 
|  | 76 | 
|  | 77 		private static bool _logExceptions = true; | 
|  | 78 		public  static bool  LogExceptions | 
|  | 79 		{ | 
|  | 80 			get { return _logExceptions;  } | 
|  | 81 			set { _logExceptions = value; } | 
|  | 82 		} | 
|  | 83 | 
|  | 84 		private static int _minCallTime; | 
|  | 85 		public  static int  MinCallTime | 
|  | 86 		{ | 
|  | 87 			get { return _minCallTime;  } | 
|  | 88 			set { _minCallTime = value; } | 
|  | 89 		} | 
|  | 90 | 
|  | 91 		private static string _fileName; | 
|  | 92 		public  static string  FileName | 
|  | 93 		{ | 
|  | 94 			get { return _fileName;  } | 
|  | 95 			set { _fileName = value; } | 
|  | 96 		} | 
|  | 97 | 
|  | 98 		private static bool _isEnabled = true; | 
|  | 99 		public  static bool  IsEnabled | 
|  | 100 		{ | 
|  | 101 			get { return _isEnabled;  } | 
|  | 102 			set { _isEnabled = value; } | 
|  | 103 		} | 
|  | 104 | 
|  | 105 		#endregion | 
|  | 106 | 
|  | 107 		#region LogOperation | 
|  | 108 | 
|  | 109 		private static LogOperation _logOperation = LogOperationInternal; | 
|  | 110 		public  static LogOperation  LogOperation | 
|  | 111 		{ | 
|  | 112 			get { return _logOperation; } | 
|  | 113 			set { _logOperation = value ?? LogOperationInternal; } | 
|  | 114 		} | 
|  | 115 | 
|  | 116 		private static void LogOperationInternal(InterceptCallInfo info, Parameters parameters) | 
|  | 117 		{ | 
|  | 118 			DateTime end  = DateTime.Now; | 
|  | 119 			int      time = (int)((end - info.BeginCallTime).TotalMilliseconds); | 
|  | 120 | 
|  | 121 			if (info.Exception != null && parameters.LogExceptions || | 
|  | 122 				info.Exception == null && time >= parameters.MinCallTime) | 
|  | 123 			{ | 
|  | 124 				string callParameters = null; | 
|  | 125 				int    plen           = info.ParameterValues.Length; | 
|  | 126 | 
|  | 127 				if (parameters.LogParameters && plen > 0) | 
|  | 128 				{ | 
|  | 129 					StringBuilder sb = new StringBuilder(); | 
|  | 130 					object[] values = info.ParameterValues; | 
|  | 131 | 
|  | 132 					FormatParameter(values[0], sb); | 
|  | 133 					for (int i = 1; i < plen; i++) | 
|  | 134 					{ | 
|  | 135 						FormatParameter(values[i], sb.Append(", ")); | 
|  | 136 					} | 
|  | 137 | 
|  | 138 					callParameters = sb.ToString(); | 
|  | 139 				} | 
|  | 140 | 
|  | 141 				string exText = null; | 
|  | 142 | 
|  | 143 				if (info.Exception != null) | 
|  | 144 					exText = string.Format( | 
|  | 145 						" with exception '{0}' - \"{1}\"", | 
|  | 146 						info.Exception.GetType().FullName, | 
|  | 147 						info.Exception.Message); | 
|  | 148 | 
|  | 149 				LogOutput( | 
|  | 150 					string.Format("{0}: {1}.{2}({3}) - {4} ms{5}{6}.", | 
|  | 151 						end, | 
|  | 152 						info.CallMethodInfo.MethodInfo.DeclaringType.FullName, | 
|  | 153 						info.CallMethodInfo.MethodInfo.Name, | 
|  | 154 						callParameters, | 
|  | 155 						time, | 
|  | 156 						info.Cached? " from cache": null, | 
|  | 157 						exText), | 
|  | 158 					parameters.FileName); | 
|  | 159 			} | 
|  | 160 		} | 
|  | 161 | 
|  | 162 		private static void FormatParameter(object parameter, StringBuilder sb) | 
|  | 163 		{ | 
|  | 164 			if (parameter == null) | 
|  | 165 				sb.Append("<null>"); | 
|  | 166 			else if (parameter is string) | 
|  | 167 				sb.Append('"').Append((string)parameter).Append('"'); | 
|  | 168 			else if (parameter is char) | 
|  | 169 				sb.Append('\'').Append((char)parameter).Append('\''); | 
|  | 170 			else if (parameter is IEnumerable) | 
|  | 171 			{ | 
|  | 172 				sb.Append('['); | 
|  | 173 				bool first = true; | 
|  | 174 				foreach (object item in (IEnumerable)parameter) | 
|  | 175 				{ | 
|  | 176 					FormatParameter(item, first? sb: sb.Append(',')); | 
|  | 177 					first = false; | 
|  | 178 				} | 
|  | 179 				sb.Append(']'); | 
|  | 180 			} | 
|  | 181 			else if (parameter is IFormattable) | 
|  | 182 			{ | 
|  | 183 				IFormattable formattable = (IFormattable)parameter; | 
|  | 184 				sb.Append(formattable.ToString(null, CultureInfo.InvariantCulture)); | 
|  | 185 			} | 
|  | 186 			else | 
|  | 187 				sb.Append(parameter.ToString()); | 
|  | 188 		} | 
|  | 189 | 
|  | 190 		#endregion | 
|  | 191 | 
|  | 192 		#region LogOuput | 
|  | 193 | 
|  | 194 		private static LogOutput _logOutput = LogOutputInternal; | 
|  | 195 		public  static LogOutput  LogOutput | 
|  | 196 		{ | 
|  | 197 			get { return _logOutput; } | 
|  | 198 			set { _logOutput = value ?? LogOutputInternal; } | 
|  | 199 		} | 
|  | 200 | 
|  | 201 		private static void LogOutputInternal(string logText, string fileName) | 
|  | 202 		{ | 
|  | 203 			if (string.IsNullOrEmpty(fileName)) | 
|  | 204 				Debug.WriteLine(logText); | 
|  | 205 			else | 
|  | 206 				using (StreamWriter sw = new StreamWriter(fileName, true)) | 
|  | 207 					sw.WriteLine(logText); | 
|  | 208 		} | 
|  | 209 | 
|  | 210 		#endregion | 
|  | 211 	} | 
|  | 212 } |