-
Notifications
You must be signed in to change notification settings - Fork 44
/
RollbarAssistant.cs
187 lines (172 loc) · 8.27 KB
/
RollbarAssistant.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
namespace Rollbar
{
using Rollbar.Common;
using System;
using System.Collections.Generic;
/// <summary>
/// This is a utility class assisting in collecting extra information for logging.
/// </summary>
public static class RollbarAssistant
{
/// <summary>
/// Captures the state (all the data fields' values of the provided instance).
///
/// It captures all the static and instance data fields (public and non-public)
/// including the inherited ones (if there is any).
/// </summary>
/// <param name="instance">The instance.</param>
/// <returns>
/// either the provided instance or a new instance of a state capture bag that is a dictionary of data field name/value pairs representing
/// the captured state of the supplied instance object or null whenever the state capture is not applicable
/// (for example, when instance argument happened to be uninitialized)
/// </returns>
public static IDictionary<string, object?>? CaptureState(
object instance
)
{
return CaptureState(instance, null, null);
}
/// <summary>
/// Captures the state (all the data fields' values of the provided instance).
///
/// It captures all the static and instance data fields (public and non-public)
/// including the inherited ones (if there is any).
/// </summary>
/// <param name="instance">The instance.</param>
/// <param name="stateCapture">a instance of a state capture bag.</param>
/// <returns>
/// either the provided instance or a new instance of a state capture bag that is a dictionary of data field name/value pairs representing
/// the captured state of the supplied instance object or null whenever the state capture is not applicable
/// (for example, when instance argument happened to be uninitialized)
/// </returns>
public static IDictionary<string, object?>? CaptureState(
object instance,
IDictionary<string, object?>? stateCapture
)
{
return CaptureState(instance, null, stateCapture);
}
/// <summary>
/// Captures the state (all the data fields' values of the provided instance).
///
/// It captures all the static and instance data fields (public and non-public)
/// including the inherited ones (if there is any).
/// </summary>
/// <param name="instance">The instance.</param>
/// <param name="instanceName">Name of the instance.</param>
/// <returns>
/// either the provided instance or a new instance of a state capture bag that is a dictionary of data field name/value pairs representing
/// the captured state of the supplied instance object or null whenever the state capture is not applicable
/// (for example, when instance argument happened to be uninitialized)
/// </returns>
public static IDictionary<string, object?>? CaptureState(
object instance,
string instanceName
)
{
return CaptureState(instance, instanceName, null);
}
/// <summary>
/// Captures the state (all the data fields' values of the provided instance).
///
/// It captures all the static and instance data fields (public and non-public)
/// including the inherited ones (if there is any).
/// </summary>
/// <param name="instance">The instance.</param>
/// <param name="instanceName">Name of the instance.</param>
/// <param name="stateCapture">a instance of a state capture bag.</param>
/// <returns>
/// either the provided instance or a new instance of a state capture bag that is a dictionary of data field name/value pairs representing
/// the captured state of the supplied instance object or null whenever the state capture is not applicable
/// (for example, when instance argument happened to be uninitialized)
/// </returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "S1168:Empty arrays and collections should be returned instead of null", Justification = "In support of Nothing-at-All paradigm.")]
public static IDictionary<string, object?>? CaptureState(
object instance,
string? instanceName,
IDictionary<string, object?>? stateCapture
)
{
if (instance == null)
{
return null;
}
Type instanceType = instance.GetType();
if (instanceType == null)
{
return null;
}
if (instanceType.IsInterface || instanceType.IsEnum)
{
return null;
}
if (instanceType == typeof(Type) && instanceType.IsAbstract && instanceType.IsSealed)
{
return RollbarAssistant.CaptureState((Type)instance);
}
string dataMemberNamePrefix = $"{instanceName ?? string.Empty}[{instanceType.FullName}].";
var memberInfos = ReflectionUtility.GetAllDataFields(instanceType);
if (stateCapture == null)
{
stateCapture = new Dictionary<string, object?>(memberInfos.Length);
}
foreach (var memberInfo in memberInfos)
{
object? value = memberInfo.GetValue(instance);
if (value != null && value.GetType().IsEnum)
{
value = value.ToString();
}
stateCapture[dataMemberNamePrefix + memberInfo.Name] = value;
}
return stateCapture;
}
/// <summary>
/// Captures the state of a static type (all the data fields' values of the provided static type).
/// </summary>
/// <param name="staticType">Type of a static class.</param>
/// <returns>
/// either the provided instance or a new instance of a state capture bag that is a dictionary of data field name/value pairs representing
/// the captured state of the supplied static type or null whenever the state capture is not applicable
/// (for example, when static type argument happened to represent an Enum or an interface).
/// </returns>
public static IDictionary<string, object?>? CaptureState(
Type staticType
)
{
return CaptureState(staticType, null);
}
/// <summary>
/// Captures the state of a static type (all the data fields' values of the provided static type).
/// </summary>
/// <param name="staticType">Type of a static class.</param>
/// <param name="stateCapture">a instance of a state capture bag.</param>
/// <returns>
/// either the provided instance or a new instance of a state capture bag that is a dictionary of data field name/value pairs representing
/// the captured state of the supplied static type or null whenever the state capture is not applicable
/// (for example, when static type argument happened to represent an Enum or an interface).
/// </returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "S1168:Empty arrays and collections should be returned instead of null", Justification = "In support of Nothing-at-All paradigm.")]
public static IDictionary<string, object?>? CaptureState(
Type staticType,
IDictionary<string, object?>? stateCapture
)
{
if (staticType.IsInterface || staticType.IsEnum)
{
return null;
}
string dataMemberNamePrefix = $"[{staticType.FullName}].";
var memberInfos = ReflectionUtility.GetAllDataFields(staticType);
if (stateCapture == null)
{
stateCapture = new Dictionary<string, object?>(memberInfos.Length);
}
foreach (var memberInfo in memberInfos)
{
stateCapture[dataMemberNamePrefix + memberInfo.Name] = memberInfo.GetValue(null);
}
return stateCapture;
}
}
}