/
LoggedMethodAttribute.cs
239 lines (210 loc) · 6.56 KB
/
LoggedMethodAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
using PostSharp.Aspects;
using ResultWrappers;
using System;
using System.Reflection;
using System.Text;
using System.Web.Script.Serialization;
namespace LoggingService
{
/// <summary>
/// LoggedMethodAttribute class
/// </summary>
[Serializable]
public sealed class LoggedMethodAttribute : OnMethodBoundaryAspect
{
#region Variables
/* START Added for PS 3.0 */
// This field is initialized and serialized at build time, then deserialized at runtime.
private readonly string category;
// These fields are initialized at runtime. They do not need to be serialized.
[NonSerialized]
private string enteringMessage;
[NonSerialized]
private string exitingMessage;
/* END Added for PS 3.0 */
private string methodName;
private ParameterInfo[] parameters;
private DateTime startTime;
#endregion
/* START Added for PS 3.0 */
public LoggedMethodAttribute()
{
}
// Constructor specifying the tracing category, invoked at build time.
public LoggedMethodAttribute(string category)
{
this.category = category;
}
// Invoked only once at runtime from the static constructor of type declaring the target method.
public override void RuntimeInitialize(MethodBase method)
{
string methodName = method.DeclaringType.FullName + method.Name;
this.enteringMessage = "Entering " + methodName;
this.exitingMessage = "Exiting " + methodName;
}
// Invoked at runtime before that target method is invoked.
public override void OnEntry(MethodExecutionArgs args)
{
startTime = DateTime.UtcNow;
//Trace.WriteLine(this.enteringMessage, this.category);
}
// Invoked at runtime after the target method is invoked (in a finally block).
public override void OnExit(MethodExecutionArgs args)
{
//Trace.WriteLine(this.exitingMessage, this.category);
}
/* END Added for PS 3.0 */
/// <summary>
/// Method invoked at build time to initialize the instance fields of the current aspect. This method is invoked before any other build-time method.
/// </summary>
/// <param name="method">Method to which the current aspect is applied</param>
/// <param name="aspectInfo">Reserved for future usage.</param>
public override void CompileTimeInitialize(System.Reflection.MethodBase method, AspectInfo aspectInfo)
{
this.methodName = method.Name;
this.parameters = method.GetParameters();
}
/// <summary>
/// Method executed after the body of methods to which this aspect is applied, but only when the method successfully returns (i.updateEmail. when no exception flies out the method.).
/// </summary>
/// <param name="args">Event arguments specifying which method is being executed and which are its arguments.</param>
public override void OnSuccess(MethodExecutionArgs args)
{
LogMethod(args, true);
}
/// <summary>
/// Method executed after the body of methods to which this aspect is applied, in case that the method resulted with an exception (i.updateEmail., in a catch block).
/// </summary>
/// <param name="args">Advice arguments.</param>
public override void OnException(MethodExecutionArgs args)
{
LogMethod(args, false);
}
/// <summary>
/// Log the Methods execution results details.
/// </summary>
/// <param name="args">Advice arguments.</param>
/// <param name="success">Result of the method operation.</param>
private void LogMethod(MethodExecutionArgs args, bool success)
{
var endTime = DateTime.UtcNow;
Guid errorGuid = Guid.Empty;
Guid exceptionGuid = Guid.Empty;
string sessionId = null;
ServiceError error = null;
string returnValues;
extractReturnValue(args, out returnValues);
// Save the MB error if returning one to the caller
Object returnValue = args.ReturnValue;
if (returnValue is IServiceResult)
{
error = ((IServiceResult)returnValue).error;
if (error.hadException)
{
var m = new BL.MethodLogException(error.exception, DateTime.UtcNow);
exceptionGuid = m.guid;
m.save();
}
if (!error.success)
{
var mle = new BL.MethodErrorMessage(Guid.NewGuid(), "2",
error.friendlyErrorMsg, error.developerErrorMsg, DateTime.UtcNow);
errorGuid = mle.guid;
mle.save();
}
}
StringBuilder stringBuilder = new StringBuilder();
var jsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
int i;
// Get the list of all arguments.
for (i = 0; i < args.Arguments.Count; i++)
{
if (parameters[i].Name.Equals("sessionid", StringComparison.InvariantCultureIgnoreCase))
{
object sessionValue = args.Arguments.GetArgument(i);
if (sessionValue != null)
{
sessionId = sessionValue.ToString();
}
}
else
{
if (i > 0)
stringBuilder.Append(", ");
stringBuilder.Append(parameters[i].Name).Append("=");
if (parameters[i].Name.ToLower().Contains("password"))
{
stringBuilder.Append("[redacted]");
}
else
{
object arg = args.Arguments.GetArgument(i);
stringBuilder.Append(arg ?? "null");
if (arg != null)
{
Type argType = args.Arguments.GetArgument(i).GetType();
if (!argType.IsPrimitive && !argType.Equals(typeof(string)) && argType.IsSerializable)
{
stringBuilder.Append(":").Append(jsonSerializer.Serialize(args.Arguments.GetArgument(i)));
}
}
}
}
}
var ml = new BL.MethodLog(this.methodName, stringBuilder.ToString(), startTime,
errorGuid.Equals(Guid.Empty), Guid.Empty, exceptionGuid, errorGuid,
(endTime - startTime).TotalMilliseconds, false, "LogServ", returnValues);
ml.save();
}
private static void LogException(Exception ex, DateTime callDate)
{
var mle = new BL.MethodLogException(ex, callDate);
mle.save();
}
private void extractReturnValue(MethodExecutionArgs args, out string returnVal)
{
returnVal = "";
var rv = args.ReturnValue;
var jss = new JavaScriptSerializer();
string jrv = "";
string jmbr = "";
try
{
jrv = jss.Serialize(args.ReturnValue);
}
catch (Exception e)
{
var x = 0;
}
if (!(rv is IServiceResult))
{
returnVal = rv.ToString();
return;
}
var mbResult = ((IServiceResult)rv).error;
if (rv is BasicServiceResult)
{
returnVal = "Success: " + mbResult.success.ToString();
return;
}
try
{
jmbr = jss.Serialize(mbResult);
jmbr = "\"MBResult\":" + jmbr;
var contains = jrv.Contains(jmbr);
if(contains)
jrv = jrv.Replace(jmbr, "");
}
catch (Exception e)
{
var x = 0;
}
if (jrv.Length > 1000)
{
returnVal = jrv.Substring(0, 1000);
}
else
returnVal = jrv;
}
}
}