-
Notifications
You must be signed in to change notification settings - Fork 296
Expand file tree
/
Copy pathUtil.cs
More file actions
352 lines (312 loc) · 13 KB
/
Util.cs
File metadata and controls
352 lines (312 loc) · 13 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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
namespace Microsoft.ApplicationInsights.Metrics
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Metrics.Extensibility;
internal static class Util
{
public const string NullString = "null";
private const double MicroOne = 0.000001;
private const string FallbackParameterName = "specified parameter";
#if NETSTANDARD1_3 || NETSTANDARD2_0
private static string sdkVersionMoniker = SdkVersionUtils.GetSdkVersion("m-agg2c:");
#else
private static string sdkVersionMoniker = SdkVersionUtils.GetSdkVersion("m-agg2:");
#endif
/// <summary>
/// Parameter check for Null.
/// </summary>
/// <param name="value">Value to be checked.</param>
/// <param name="name">Name of the parameter being checked.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateNotNull(object value, string name)
{
if (value == null)
{
throw new ArgumentNullException(name ?? Util.FallbackParameterName);
}
}
/// <summary>
/// String parameter check with a more informative exception that specifies whether
/// the problem was that the string was null or empty.
/// </summary>
/// <param name="value">Value to be checked.</param>
/// <param name="name">Name of the parameter being checked.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateNotNullOrEmpty(string value, string name)
{
if (value == null)
{
throw new ArgumentNullException(name ?? Util.FallbackParameterName);
}
if (value.Length == 0)
{
throw new ArgumentException((name ?? Util.FallbackParameterName) + " may not be empty.");
}
}
/// <summary>
/// String parameter check with a more informative exception that specifies whether
/// the problem was that the string was null, empty or whitespace only.
/// </summary>
/// <param name="value">Value to be checked.</param>
/// <param name="name">Name of the parameter being checked.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateNotNullOrWhitespace(string value, string name)
{
ValidateNotNullOrEmpty(value, name);
if (String.IsNullOrWhiteSpace(value))
{
throw new ArgumentException((name ?? Util.FallbackParameterName) + " may not be whitespace only.");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double EnsureConcreteValue(double x)
{
return (x < -Double.MaxValue)
? -Double.MaxValue
: (x > Double.MaxValue)
? Double.MaxValue
: Double.IsNaN(x)
? 0.0
: x;
}
public static double RoundAndValidateValue(double value)
{
if (double.IsNaN(value))
{
throw new ArgumentException("Cannot process the specified value."
+ " A non-negative whole number was expected, but the specified value is Double.NaN."
+ " Have you specified the correct metric configuration?");
}
if (value < -MicroOne)
{
throw new ArgumentException("Cannot process the specified value."
+ " A non-negative whole number was expected, but the specified value is"
+ " a negative double value (" + value + ")."
+ " Have you specified the correct metric configuration?");
}
double wholeValue = Math.Round(value);
if (wholeValue > uint.MaxValue)
{
throw new ArgumentException("Cannot process the specified value."
+ " A non-negative whole number was expected, but the specified value is"
+ " larger than the maximum accepted value (" + value + ")."
+ " Have you specified the correct metric configuration?");
}
double delta = Math.Abs(value - wholeValue);
if (delta > MicroOne)
{
throw new ArgumentException("Cannot process the specified value."
+ " A non-negative whole number was expected, but the specified value is"
+ " a double value that does not equal to a whole number (" + value + ")."
+ " Have you specified the correct metric configuration?");
}
return wholeValue;
}
public static double ConvertToDoubleValue(object metricValue)
{
if (metricValue == null)
{
return Double.NaN;
}
if (metricValue is SByte)
{
return (double)(SByte)metricValue;
}
else if (metricValue is Byte)
{
return (double)(Byte)metricValue;
}
else if (metricValue is Int16)
{
return (double)(Int16)metricValue;
}
else if (metricValue is UInt16)
{
return (double)(UInt16)metricValue;
}
else if (metricValue is Int32)
{
return (double)(Int32)metricValue;
}
else if (metricValue is UInt32)
{
return (double)(UInt32)metricValue;
}
else if (metricValue is Int64)
{
return (double)(Int64)metricValue;
}
else if (metricValue is UInt64)
{
return (double)(UInt64)metricValue;
}
else if (metricValue is Single)
{
return (double)(Single)metricValue;
}
else if (metricValue is Double)
{
return (double)(Double)metricValue;
}
else
{
string stringValue = metricValue as string;
if (stringValue != null)
{
double doubleValue;
if (Double.TryParse(stringValue, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleValue))
{
return doubleValue;
}
else
{
throw new ArgumentException("Cannot process the specified value."
+ " A numeric value was expected, but the specified " + nameof(metricValue) + " is"
+ " a String that cannot be parsed into a number (\"" + metricValue + "\")."
+ " Have you specified the correct metric configuration?");
}
}
else
{
throw new ArgumentException("Cannot process the specified value."
+ " A numeric value was expected, but the specified " + nameof(metricValue) + " is"
+ " of type " + metricValue.GetType().FullName + "."
+ " Have you specified the correct metric configuration?");
}
}
}
public static DateTimeOffset RoundDownToMinute(DateTimeOffset dto)
{
return new DateTimeOffset(dto.Year, dto.Month, dto.Day, dto.Hour, dto.Minute, 0, 0, dto.Offset);
}
public static DateTimeOffset RoundDownToSecond(DateTimeOffset dto)
{
return new DateTimeOffset(dto.Year, dto.Month, dto.Day, dto.Hour, dto.Minute, dto.Second, 0, dto.Offset);
}
public static bool FilterWillConsume(IMetricSeriesFilter seriesFilter, MetricSeries series, out IMetricValueFilter valueFilter)
{
valueFilter = null;
try
{
return (seriesFilter == null) || seriesFilter.WillConsume(series, out valueFilter);
}
catch
{
// Protect against errors in user's implementation of IMetricSeriesFilter.WillConsume(..).
// If it throws, assume that the filter is not functional and accept all values.
return true;
}
}
public static bool FilterWillConsume(IMetricValueFilter valueFilter, MetricSeries series, double metricValue)
{
try
{
return (valueFilter == null) || valueFilter.WillConsume(series, metricValue);
}
catch
{
// If user code in IMetricValueFilter.WillConsume(..) throws, assume that the filter is not functional and accept all values.
return true;
}
}
public static bool FilterWillConsume(IMetricValueFilter valueFilter, MetricSeries series, object metricValue)
{
try
{
return (valueFilter == null) || valueFilter.WillConsume(series, metricValue);
}
catch
{
// If user code in IMetricValueFilter.WillConsume(..) throws, assume that the filter is not functional and accept all values.
return true;
}
}
public static int CombineHashCodes(int hash1)
{
int hash = 17;
unchecked
{
hash = (hash * 23) + hash1;
}
return hash;
}
public static int CombineHashCodes(int hash1, int hash2)
{
int hash = 17;
unchecked
{
hash = (hash * 23) + hash1;
hash = (hash * 23) + hash2;
}
return hash;
}
public static int CombineHashCodes(int hash1, int hash2, int hash3, int hash4)
{
int hash = 17;
unchecked
{
hash = (hash * 23) + hash1;
hash = (hash * 23) + hash2;
hash = (hash * 23) + hash3;
hash = (hash * 23) + hash4;
}
return hash;
}
public static int CombineHashCodes(int[] arr)
{
if (arr == null)
{
return 0;
}
int hash = 17;
unchecked
{
for (int i = 0; i < arr.Length; i++)
{
hash = (hash * 23) + arr[i];
}
}
return hash;
}
/// <summary>@ToDo: Complete documentation before stable release. {659}</summary>
/// <param name="source">@ToDo: Complete documentation before stable release. {688}</param>
/// <param name="target">@ToDo: Complete documentation before stable release. {859}</param>
public static void CopyTelemetryContext(TelemetryContext source, TelemetryContext target)
{
Util.ValidateNotNull(source, nameof(source));
Util.ValidateNotNull(target, nameof(target));
// Copy internal tags:
target.Initialize(source, instrumentationKey: null);
// Copy public properties:
#pragma warning disable CS0618 // Type or member is obsolete
Utils.CopyDictionary(source.Properties, target.Properties);
#pragma warning restore CS0618 // Type or member is obsolete
// This check avoids accessing the public accessor GlobalProperties
// unless needed, to avoid the penalty of ConcurrentDictionary instantiation.
if (source.GlobalPropertiesValue != null)
{
Utils.CopyDictionary(source.GlobalProperties, target.GlobalProperties);
}
// Copy iKey:
if (source.InstrumentationKey != null)
{
target.InstrumentationKey = source.InstrumentationKey;
}
}
public static void StampSdkVersionToContext(ITelemetry aggregate)
{
InternalContext context = aggregate?.Context?.GetInternalContext();
if (context == null)
{
return;
}
context.SdkVersion = sdkVersionMoniker;
}
}
}