25
25
import java .util .concurrent .ConcurrentHashMap ;
26
26
import java .util .function .Supplier ;
27
27
28
-
29
- import com .fasterxml . jackson . annotation . JsonProperty ;
28
+ import com . fasterxml . jackson . annotation . JsonValue ;
29
+ import com .google . common . base . Strings ;
30
30
import com .google .common .base .Suppliers ;
31
31
import com .google .common .base .Throwables ;
32
- import com .google .common .collect .HashMultimap ;
33
32
import com .google .common .collect .ImmutableMap ;
34
- import com .google .common .collect .Multimap ;
35
- import com .google .common .collect .Multimaps ;
36
33
import com .google .common .util .concurrent .AtomicLongMap ;
37
34
import com .google .errorprone .DescriptionListener ;
38
35
import com .google .errorprone .ErrorProneTimings ;
39
36
import com .google .errorprone .matchers .Suppressible ;
40
37
import com .sun .tools .javac .util .Context ;
41
38
42
39
public class HubSpotMetrics {
40
+
41
+ enum ErrorType {
42
+ EXCEPTIONS ("errorProneExceptions" ),
43
+ MISSING ("errorProneMissingChecks" ),
44
+ INIT_ERRORS ("errorProneInitErrors" ),
45
+ LISTENER_INIT_ERRORS ("errorProneListenerInitErrors" ),
46
+ LISTENER_ON_DESCRIBE_ERROR ("errorProneListenerDescribeErrors" ),
47
+ UNHANDLED_ERRORS ("errorProneUnhandledErrors" );
48
+
49
+ final String value ;
50
+
51
+ ErrorType (String value ) {
52
+ this .value = value ;
53
+ }
54
+
55
+ @ JsonValue
56
+ public String getValue () {
57
+ return value ;
58
+ }
59
+ }
60
+
43
61
public static synchronized HubSpotMetrics instance (Context context ) {
44
62
HubSpotMetrics metrics = context .get (HubSpotMetrics .class );
45
63
@@ -59,23 +77,26 @@ private static HubSpotMetrics create(Context context) {
59
77
return metrics ;
60
78
}
61
79
62
- private final ErrorState errors ;
80
+ private final ConcurrentHashMap < ErrorType , Set < String >> errors ;
63
81
private final AtomicLongMap <String > timings ;
82
+
64
83
private final Supplier <FileManager > fileManagerSupplier ;
65
84
66
85
67
86
HubSpotMetrics (Supplier <FileManager > fileManagerSupplier ) {
68
- this .errors = new ErrorState ();
87
+ this .errors = new ConcurrentHashMap <> ();
69
88
this .timings = AtomicLongMap .create ();
70
89
this .fileManagerSupplier = fileManagerSupplier ;
71
90
}
72
91
73
- public void recordError (Suppressible s , Throwable t ) {
74
- errors .exceptions .put (s .canonicalName (), t );
92
+ public void recordError (Suppressible s ) {
93
+ errors .computeIfAbsent (ErrorType .EXCEPTIONS , ignored -> ConcurrentHashMap .newKeySet ())
94
+ .add (s .canonicalName ());
75
95
}
76
96
77
97
public void recordMissingCheck (String checkName ) {
78
- errors .missing .add (checkName );
98
+ errors .computeIfAbsent (ErrorType .MISSING , ignored -> ConcurrentHashMap .newKeySet ())
99
+ .add (checkName );
79
100
}
80
101
81
102
public void recordTimings (Context context ) {
@@ -85,11 +106,13 @@ public void recordTimings(Context context) {
85
106
}
86
107
87
108
public void recordListenerDescribeError (DescriptionListener listener , Throwable t ) {
88
- errors .listenerOnDescribeErrors .put (listener .getClass ().getCanonicalName (), t );
109
+ errors .computeIfAbsent (ErrorType .LISTENER_ON_DESCRIBE_ERROR , ignored -> ConcurrentHashMap .newKeySet ())
110
+ .add (toErrorMessage (t ));
89
111
}
90
112
91
113
public void recordUncaughtException (Throwable throwable ) {
92
- errors .unhandledErrors .add (throwable );
114
+ errors .computeIfAbsent (ErrorType .UNHANDLED_ERRORS , ignored -> ConcurrentHashMap .newKeySet ())
115
+ .add (toErrorMessage (throwable ));
93
116
94
117
fileManagerSupplier .get ().getUncaughtExceptionPath ().ifPresent (p -> {
95
118
// this should only ever be called once so overwriting is fine
@@ -103,12 +126,22 @@ public void recordUncaughtException(Throwable throwable) {
103
126
});
104
127
}
105
128
106
- public void recordCheckLoadError (String name , Throwable t ) {
107
- errors .initErrors .put (name , t );
129
+ public void recordCheckLoadError (Throwable t ) {
130
+ errors .computeIfAbsent (ErrorType .INIT_ERRORS , ignored -> ConcurrentHashMap .newKeySet ())
131
+ .add (toErrorMessage (t ));
108
132
}
109
133
110
- public void recordListenerInitError (String name , Throwable t ) {
111
- errors .listenerInitErrors .put (name , t );
134
+ public void recordListenerInitError (Throwable t ) {
135
+ errors .computeIfAbsent (ErrorType .LISTENER_INIT_ERRORS , ignored -> ConcurrentHashMap .newKeySet ())
136
+ .add (toErrorMessage (t ));
137
+ }
138
+
139
+ private static String toErrorMessage (Throwable e ) {
140
+ if (Strings .isNullOrEmpty (e .getMessage ())) {
141
+ return "Unknown error" ;
142
+ } else {
143
+ return e .getMessage ();
144
+ }
112
145
}
113
146
114
147
private void write () {
@@ -126,23 +159,4 @@ private Map<String, Long> computeFinalTimings() {
126
159
.collect (ImmutableMap .toImmutableMap (Entry ::getKey , Entry ::getValue ));
127
160
}
128
161
129
- private static class ErrorState {
130
- @ JsonProperty ("errorProneExceptions" )
131
- public final Multimap <String , Throwable > exceptions = Multimaps .synchronizedMultimap (HashMultimap .create ());
132
-
133
- @ JsonProperty ("errorProneMissingChecks" )
134
- public final Set <String > missing = ConcurrentHashMap .newKeySet ();
135
-
136
- @ JsonProperty ("errorProneInitErrors" )
137
- public final Multimap <String , Throwable > initErrors = Multimaps .synchronizedMultimap (HashMultimap .create ());
138
-
139
- @ JsonProperty ("errorProneListenerInitErrors" )
140
- public final Multimap <String , Throwable > listenerInitErrors = Multimaps .synchronizedMultimap (HashMultimap .create ());
141
-
142
- @ JsonProperty ("errorProneListenerDescribeErrors" )
143
- public final Multimap <String , Throwable > listenerOnDescribeErrors = Multimaps .synchronizedMultimap (HashMultimap .create ());
144
-
145
- @ JsonProperty ("errorProneUnhandledErrors" )
146
- public final Set <Throwable > unhandledErrors = ConcurrentHashMap .newKeySet ();
147
- }
148
162
}
0 commit comments