forked from stackify/stackify-api-dotnet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLogger.cs
More file actions
323 lines (270 loc) · 10.3 KB
/
Copy pathLogger.cs
File metadata and controls
323 lines (270 loc) · 10.3 KB
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using StackifyLib.Internal.Logs;
using StackifyLib.Internal.Metrics;
using StackifyLib.Models;
using StackifyLib.Utils;
namespace StackifyLib
{
public class Logger
{
public static int _MaxLogBufferSize = 10000;
private static LogClient _LogClient = null;
static Logger()
{
_LogClient = new LogClient("StackifyLib.net");
}
/// <summary>
/// Used to override the appname being used by any and all logging appenders. Be it this Logger class, log4net, NLog, etc
/// </summary>
[Obsolete("Use StackifyLib.Config instead", true)]
public static string GlobalAppName = null;
/// <summary>
/// Used to override the environment being used by any and all logging appenders. Be it this Logger class, log4net, NLog, etc
/// </summary>
[Obsolete("Use StackifyLib.Config instead", true)]
public static string GlobalEnvironment = null;
/// <summary>
/// Used to override the api key being used by any and all logging appenders. Be it this Logger class, log4net, NLog, etc
/// </summary>
[Obsolete("Use StackifyLib.Config instead", true)]
public static string GlobalApiKey = null;
/// <summary>
/// Used to get/set the api key used by this logger class, not appenders like log4net, NLog, etc. Set GlobalApiKey to change it for those
/// </summary>
[Obsolete("Use StackifyLib.Config instead", true)]
public static string ApiKey
{
get
{
return _LogClient.APIKey;
}
set
{
//close the log client and create a new one with the new key
//people shouldn't really be changing this around so not worried about it being crazily set
if (_LogClient.APIKey != value)
{
_LogClient.Close();
_LogClient = new LogClient("StackifyLib.net", value);
}
}
}
/// <summary>
/// Global setting for any log appenders for how big the log queue size can be in memory before messages are lost if there are problems uploading or we can't upload fast enough
/// </summary>
public static int MaxLogBufferSize
{
get { return _MaxLogBufferSize; }
set { _MaxLogBufferSize = value; }
}
/// <summary>
/// Flushes any items in the queue when shutting down an app
/// </summary>
public static void Shutdown()
{
//flush logs queue
_LogClient.Close();
//flush any remaining metrics as well
MetricClient.StopMetricsQueue("Logger Shutdown called");
}
/// <summary>
/// Gets info about the app
/// </summary>
/// <returns></returns>
public static AppIdentityInfo Identity()
{
return _LogClient.GetIdentity();
}
/// <summary>
/// Used to check if there have been recent failures or if the queue is backed up and if logs can be sent or not
/// </summary>
/// <returns></returns>
public static bool CanSend()
{
if (_LogClient == null)
return false;
return _LogClient.CanQueue();
}
public static void Queue(string level, string message, object debugData = null)
{
var msg = new LogMsg()
{
Level = level,
Msg = message
};
if (debugData != null)
{
//set json data to pass through as debugging data
msg.data = StackifyLib.Utils.HelperFunctions.SerializeDebugData(debugData, true);
}
QueueLogObject(msg, null);
}
public static void QueueException(Exception exceptionObject,
object debugData = null)
{
QueueException("ERROR", exceptionObject.Message, exceptionObject, debugData);
}
public static void QueueException(string message, Exception exceptionObject,
object debugData = null)
{
QueueException("ERROR", message, exceptionObject, debugData);
}
public static void QueueException(string level, string message, Exception exceptionObject, object debugData = null)
{
var msg = new LogMsg()
{
Level = level,
Msg = message
};
if (debugData != null)
{
//set json data to pass through as debugging data
msg.data = StackifyLib.Utils.HelperFunctions.SerializeDebugData(debugData, true);
}
QueueLogObject(msg, exceptionObject);
}
internal static bool ErrorShouldBeSent(StackifyError error)
{
return _LogClient.ErrorShouldBeSent(error);
}
public static void PauseUpload(bool isPaused)
{
_LogClient.PauseUpload(isPaused);
}
public static void QueueException(StackifyError error)
{
var msg = new LogMsg()
{
Level = "ERROR",
Msg = error.Message,
Ex = error
};
QueueLogObject(msg);
}
public static void QueueLogObject(StackifyLib.Models.LogMsg msg)
{
try
{
if (PrefixEnabled() || _LogClient.CanQueue())
{
if (msg.Ex != null)
{
if (string.IsNullOrEmpty(msg.Level))
{
msg.Level = "ERROR";
}
string origMsg = msg.Msg;
if (msg.Msg != null && msg.Ex != null)
{
msg.Msg += "\r\n" + msg.Ex.ToString();
}
else if (msg.Msg == null && msg.Ex != null)
{
msg.Msg = msg.Ex.ToString();
}
bool ignore = StackifyError.IgnoreError(msg.Ex);
bool shouldSend = _LogClient.ErrorShouldBeSent(msg.Ex);
if (!ignore)
{
if (!string.IsNullOrEmpty(origMsg))
{
msg.Ex.SetAdditionalMessage(origMsg);
}
if (!shouldSend)
{
msg.Ex = null;
msg.Msg += " #errorgoverned";
}
}
else
{
msg.Ex = null;
}
}
_LogClient.QueueMessage(msg);
}
else
{
StackifyAPILogger.Log("Unable to send log because the queue is full");
}
}
catch (Exception ex)
{
StackifyAPILogger.Log(ex.ToString());
}
}
public static void QueueLogObject(StackifyLib.Models.LogMsg msg, Exception exceptionObject)
{
if (exceptionObject != null)
{
msg.Ex = StackifyError.New(exceptionObject);
}
QueueLogObject(msg);
}
/// <summary>
/// Helper method for getting the current stack trace
/// </summary>
/// <param name="declaringClassName"></param>
/// <param name="maxFrames"></param>
/// <param name="simpleMethodNames"></param>
/// <returns></returns>
public static List<TraceFrame> GetCurrentStackTrace(string declaringClassName, int maxFrames = 99, bool simpleMethodNames = false)
{
var frames = new List<TraceFrame>();
#if NETFULL
try
{
//moves to the part of the trace where the declaring method starts then the other loop gets all the frames. This is to remove frames that happen within the logging library itself.
var stackTrace = new StackTrace(true);
var stackTraceFrames = stackTrace.GetFrames();
if (stackTraceFrames != null)
{
int index1;
for (index1 = 0; index1 < stackTraceFrames.Length; ++index1)
{
var frame = stackTraceFrames[index1];
if (frame != null)
{
var method = frame.GetMethod();
if (method != null && method.DeclaringType != null &&
method.DeclaringType.FullName == declaringClassName)
{
break;
}
}
}
if (index1 < stackTraceFrames.Length)
{
for (int index2 = index1; index2 < stackTraceFrames.Length; ++index2)
{
var frame2 = stackTraceFrames[index2];
var f2 = new TraceFrame();
f2.CodeFileName = frame2.GetFileName();
f2.LineNum = frame2.GetFileLineNumber();
f2.Method = ErrorItem.GetMethodFullName(frame2.GetMethod(), simpleMethodNames);
frames.Add(f2);
if (frames.Count > maxFrames)
{
return frames;
}
}
}
}
}
catch
{
// ignored
}
#endif
return frames;
}
public static bool PrefixEnabled()
{
return PrefixOrAPM.GetProfilerType() == PrefixOrAPM.ProfilerType.Prefix;
}
}
}