5
5
import org .apache .commons .lang .StringUtils ;
6
6
7
7
import java .util .ArrayList ;
8
+ import java .util .Arrays ;
8
9
import java .util .HashMap ;
9
10
import java .util .List ;
10
11
import java .util .Map ;
@@ -21,17 +22,21 @@ public class MetricsPuppetProfiler implements PuppetProfiler {
21
22
private final MetricRegistry registry ;
22
23
private final Set <String > metric_ids ;
23
24
24
- private static final Pattern FUNCTION_PATTERN = Pattern .compile (".*\\ .functions\\ .([\\ w\\ d_]+)$" );
25
- private static final Pattern RESOURCE_PATTERN = Pattern .compile (".*\\ .compiler\\ .evaluate_resource\\ .([\\ w\\ d_]+\\ [([\\ w\\ d_]+::)*[\\ w\\ d_]+\\ ])$" );
26
- private static final Pattern CATALOG_PATTERN = Pattern .compile (".*\\ .compiler\\ .(static_compile_postprocessing|static_compile|compile|find_node)$" );
27
- private static final Pattern INLINING_PATTERN = Pattern .compile (".*\\ .compiler\\ .static_compile_inlining\\ .(.*)$" );
28
- private static final Pattern PUPPETDB_PATTERN = Pattern .compile (".*\\ .puppetdb\\ .(resource\\ .search|facts\\ .encode|command\\ .submit\\ .replace facts|catalog\\ .munge|command\\ .submit\\ .replace catalog|report\\ .convert_to_wire_format_hash|command\\ .submit\\ .store report|query)$" );
29
-
25
+ private final Map <String , Timer > function_timers ;
26
+ private final Map <String , Timer > resource_timers ;
27
+ private final Map <String , Timer > catalog_timers ;
28
+ private final Map <String , Timer > inlining_timers ;
29
+ private final Map <String , Timer > puppetdb_timers ;
30
30
31
31
public MetricsPuppetProfiler (String hostname , MetricRegistry registry ) {
32
32
this .hostname = hostname ;
33
33
this .registry = registry ;
34
34
this .metric_ids = Collections .newSetFromMap (new ConcurrentHashMap <String , Boolean >());
35
+ this .function_timers = new ConcurrentHashMap <String , Timer >();
36
+ this .resource_timers = new ConcurrentHashMap <String , Timer >();
37
+ this .catalog_timers = new ConcurrentHashMap <String , Timer >();
38
+ this .inlining_timers = new ConcurrentHashMap <String , Timer >();
39
+ this .puppetdb_timers = new ConcurrentHashMap <String , Timer >();
35
40
}
36
41
37
42
@ Override
@@ -43,9 +48,12 @@ public Object start(String message, String[] metric_id) {
43
48
public void finish (Object context , String message , String [] metric_id ) {
44
49
if (shouldTime (metric_id )) {
45
50
Long elapsed = System .currentTimeMillis () - (Long )context ;
46
- for (Timer t : getTimers (metric_id )) {
51
+ Map <String , Timer > metricsByID = getOrCreateTimersByIDs (metric_id );
52
+ for (Timer t : metricsByID .values ()) {
47
53
t .update (elapsed , TimeUnit .MILLISECONDS );
48
54
}
55
+
56
+ updateMetricsTrackers (metric_id , metricsByID );
49
57
}
50
58
}
51
59
@@ -54,29 +62,107 @@ public Set<String> getAllMetricIds() {
54
62
}
55
63
56
64
public Map <String , Timer > getFunctionTimers () {
57
- return getTimers ( FUNCTION_PATTERN ) ;
65
+ return this . function_timers ;
58
66
}
59
67
60
68
public Map <String , Timer > getResourceTimers () {
61
- return getTimers ( RESOURCE_PATTERN ) ;
69
+ return this . resource_timers ;
62
70
}
63
71
64
72
public Map <String , Timer > getCatalogTimers () {
65
- return getTimers ( CATALOG_PATTERN ) ;
73
+ return this . catalog_timers ;
66
74
}
67
75
68
76
public Map <String , Timer > getInliningTimers () {
69
- return getTimers ( INLINING_PATTERN ) ;
77
+ return this . inlining_timers ;
70
78
}
71
79
72
80
public Map <String , Timer > getPuppetDBTimers () {
73
- return getTimers ( PUPPETDB_PATTERN ) ;
81
+ return this . puppetdb_timers ;
74
82
}
75
83
76
84
@ Override
77
85
public void shutdown () {
78
86
}
79
87
88
+ private List <String > sliceOfArrayToList (String [] idSegments , int lengthOfID ) {
89
+ // Callers expect a mutable List returned, but Arrays.asList() returns a
90
+ // fix length array, which is why we have to create a List and then add to it.
91
+ List <String > idList = new ArrayList <String >();
92
+ idList .addAll (Arrays .asList (Arrays .copyOf (idSegments , lengthOfID )));
93
+
94
+ return idList ;
95
+ }
96
+
97
+ private String safeGet (String [] collection , int i ) {
98
+ try {
99
+ return collection [i ];
100
+ } catch (IndexOutOfBoundsException _ex ) {
101
+ return "" ;
102
+ }
103
+ }
104
+
105
+ private void updateMetricsTrackers (String [] metricId , Map <String , Timer > metricsByID ) {
106
+ String firstElement = safeGet (metricId , 0 );
107
+ String secondElement = safeGet (metricId , 1 );
108
+
109
+ if ("functions" .equals (firstElement )) {
110
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 2 )));
111
+ this .function_timers .put (secondElement , metric );
112
+
113
+ } else if ("compiler" .equals (firstElement )) {
114
+ String thirdElemet = safeGet (metricId , 2 );
115
+
116
+ if ("evaluate_resource" .equals (secondElement )) {
117
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 3 )));
118
+ this .resource_timers .put (thirdElemet , metric );
119
+
120
+ } else if ("static_compile_inlining" .equals (secondElement )) {
121
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 3 )));
122
+ this .inlining_timers .put (thirdElemet , metric );
123
+
124
+ } else {
125
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 2 )));
126
+ this .catalog_timers .put (secondElement , metric );
127
+ }
128
+
129
+ } else if ("puppetdb" .equals (firstElement )) {
130
+ if ("query" .equals (secondElement )) {
131
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 2 )));
132
+ this .puppetdb_timers .put (secondElement , metric );
133
+
134
+ } else {
135
+ String thirdElemet = safeGet (metricId , 2 );
136
+
137
+ if (
138
+ ("resource" .equals (secondElement ) && "search" .equals (thirdElemet )) ||
139
+ ("payload" .equals (secondElement ) && "format" .equals (thirdElemet )) ||
140
+ // Set.of would be preferrable but 7.x still support Java 8, which does not have Set.of
141
+ ("facts" .equals (secondElement ) && Arrays .asList ("save" , "find" , "search" , "encode" ).contains (thirdElemet )) ||
142
+ ("catalog" .equals (secondElement ) && Arrays .asList ("save" , "munge" ).contains (thirdElemet )) ||
143
+ ("report" .equals (secondElement ) && Arrays .asList ("convert_to_wire_format_hash" , "process" ).contains (thirdElemet ))
144
+ ) {
145
+ String key = String .join ("." , secondElement , thirdElemet );
146
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 3 )));
147
+ this .puppetdb_timers .put (key , metric );
148
+
149
+ } else if ("command" .equals (secondElement ) && "submit" .equals (thirdElemet )) {
150
+ String fourthElement = safeGet (metricId , 3 );
151
+
152
+ if (
153
+ "store report" .equals (fourthElement ) ||
154
+ "replace facts" .equals (fourthElement ) ||
155
+ "replace catalog" .equals (fourthElement )
156
+ ) {
157
+ String key = String .join ("." , secondElement , thirdElemet , fourthElement );
158
+ Timer metric = metricsByID .get (getMetricName (sliceOfArrayToList (metricId , 4 )));
159
+ this .puppetdb_timers .put (key , metric );
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+
80
166
private boolean shouldTime (String [] metric_id ) {
81
167
if (metric_id == null ) {
82
168
return false ;
@@ -90,8 +176,8 @@ private boolean shouldTime(String[] metric_id) {
90
176
return true ;
91
177
}
92
178
93
- private List < Timer > getTimers (String [] metric_id ) {
94
- List < Timer > timers = new ArrayList < Timer >();
179
+ private Map < String , Timer > getOrCreateTimersByIDs (String [] metric_id ) {
180
+ Map < String , Timer > timers = new HashMap < String , Timer >();
95
181
// If this is turns out to be a performance hit, we could cache these in a
96
182
// map or something.
97
183
for (int i = 0 ; i < metric_id .length ; i ++) {
@@ -101,7 +187,7 @@ private List<Timer> getTimers(String[] metric_id) {
101
187
}
102
188
String metric_name = getMetricName (current_id );
103
189
registerMetricName (metric_name );
104
- timers .add ( registry .timer (metric_name ));
190
+ timers .put ( metric_name , registry .timer (metric_name ));
105
191
}
106
192
return timers ;
107
193
}
@@ -114,15 +200,4 @@ private String getMetricName(List<String> metric_id) {
114
200
private void registerMetricName (String metric_name ) {
115
201
this .metric_ids .add (metric_name );
116
202
}
117
-
118
- private Map <String , Timer > getTimers (Pattern pattern ) {
119
- Map <String , Timer > rv = new HashMap <>();
120
- for (String metric_id : this .metric_ids ) {
121
- Matcher matcher = pattern .matcher (metric_id );
122
- if (matcher .matches ()) {
123
- rv .put (matcher .group (1 ), registry .timer (metric_id ));
124
- }
125
- }
126
- return rv ;
127
- }
128
203
}
0 commit comments