31
31
import java .util .Optional ;
32
32
import java .util .Set ;
33
33
import java .util .TreeSet ;
34
+ import java .util .regex .Matcher ;
35
+ import java .util .stream .Collectors ;
34
36
import javax .management .Attribute ;
35
37
import javax .management .AttributeList ;
36
38
import javax .management .JMException ;
@@ -58,6 +60,7 @@ public interface MBeanReceiver {
58
60
void recordBean (
59
61
String domain ,
60
62
LinkedHashMap <String , String > beanProperties ,
63
+ Map <String , String > attributesAsLabelsWithValues ,
61
64
LinkedList <String > attrKeys ,
62
65
String attrName ,
63
66
String attrType ,
@@ -71,6 +74,7 @@ void recordBean(
71
74
private final String password ;
72
75
private final boolean ssl ;
73
76
private final List <ObjectName > includeObjectNames , excludeObjectNames ;
77
+ private final List <JmxCollector .Rule > rules ;
74
78
private final ObjectNameAttributeFilter objectNameAttributeFilter ;
75
79
private final JmxMBeanPropertyCache jmxMBeanPropertyCache ;
76
80
@@ -82,6 +86,7 @@ public JmxScraper(
82
86
List <ObjectName > includeObjectNames ,
83
87
List <ObjectName > excludeObjectNames ,
84
88
ObjectNameAttributeFilter objectNameAttributeFilter ,
89
+ List <JmxCollector .Rule > rules ,
85
90
MBeanReceiver receiver ,
86
91
JmxMBeanPropertyCache jmxMBeanPropertyCache ) {
87
92
this .jmxUrl = jmxUrl ;
@@ -91,6 +96,7 @@ public JmxScraper(
91
96
this .ssl = ssl ;
92
97
this .includeObjectNames = includeObjectNames ;
93
98
this .excludeObjectNames = excludeObjectNames ;
99
+ this .rules = rules ;
94
100
this .objectNameAttributeFilter = objectNameAttributeFilter ;
95
101
this .jmxMBeanPropertyCache = jmxMBeanPropertyCache ;
96
102
}
@@ -217,6 +223,7 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mBeanName) {
217
223
218
224
final String mBeanNameString = mBeanName .toString ();
219
225
final String mBeanDomain = mBeanName .getDomain ();
226
+ Map <String , Object > attributeMap = attributes .asList ().stream ().collect (Collectors .toMap (Attribute ::getName , Attribute ::getValue ));
220
227
221
228
for (Object object : attributes ) {
222
229
// The contents of an AttributeList should all be Attribute instances, but we'll verify
@@ -237,13 +244,16 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mBeanName) {
237
244
continue ;
238
245
}
239
246
247
+ Map <String , String > attributesAsLabelsWithValues = getAttributesAsLabelsWithValues (mBeanName , attribute , attributeMap );
248
+
240
249
MBeanAttributeInfo mBeanAttributeInfo =
241
250
name2MBeanAttributeInfo .get (attribute .getName ());
242
251
LOGGER .log (FINE , "%s_%s process" , mBeanName , mBeanAttributeInfo .getName ());
243
252
processBeanValue (
244
253
mBeanName ,
245
254
mBeanDomain ,
246
255
jmxMBeanPropertyCache .getKeyPropertyList (mBeanName ),
256
+ attributesAsLabelsWithValues ,
247
257
new LinkedList <>(),
248
258
mBeanAttributeInfo .getName (),
249
259
mBeanAttributeInfo .getType (),
@@ -264,6 +274,45 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mBeanName) {
264
274
}
265
275
}
266
276
277
+ private Map <String , String > getAttributesAsLabelsWithValues (ObjectName mBeanName , Attribute attribute , Map <String , Object > attributeMap ) {
278
+ JmxCollector .Rule matchedRule = null ;
279
+ for (JmxCollector .Rule rule : rules ) {
280
+ if (rule .pattern != null ) {
281
+ Object matchBeanValue = rule .cache ? "<cache>" : attribute .getValue ();
282
+ List <String > attrKeys = new LinkedList <>();
283
+ if (attribute .getValue () instanceof TabularData || attribute .getValue () instanceof CompositeData ) {
284
+ attrKeys .add (attribute .getName ());
285
+ }
286
+ String beanName = mBeanName .getDomain ()
287
+ + angleBrackets (jmxMBeanPropertyCache .getKeyPropertyList (mBeanName ).toString ())
288
+ + angleBrackets (attrKeys .toString ());
289
+ String matchName = beanName + attribute .getName () + ": " + matchBeanValue ;
290
+ Matcher matcher = rule .pattern .matcher (matchName );
291
+ if (matcher .matches () && rule .attributesAsLabels != null ) {
292
+ matchedRule = rule ;
293
+ }
294
+ } else if (rule .name == null ) {
295
+ matchedRule = rule ;
296
+ }
297
+ }
298
+ Map <String , String > attributesAsLabelsWithValues = new HashMap <>();
299
+ if (matchedRule != null ) {
300
+ for (String attributeAsLabel : matchedRule .attributesAsLabels ) {
301
+ Object attrValue = attributeMap .get (attributeAsLabel );
302
+ if (attrValue != null ) {
303
+ attributesAsLabelsWithValues .put (
304
+ attributeAsLabel ,
305
+ attrValue .toString ());
306
+ }
307
+ }
308
+ }
309
+ return attributesAsLabelsWithValues ;
310
+ }
311
+
312
+ private String angleBrackets (String s ) {
313
+ return "<" + s .substring (1 , s .length () - 1 ) + ">" ;
314
+ }
315
+
267
316
private void processAttributesOneByOne (
268
317
MBeanServerConnection beanConn ,
269
318
ObjectName mbeanName ,
@@ -282,6 +331,7 @@ private void processAttributesOneByOne(
282
331
mbeanName ,
283
332
mbeanName .getDomain (),
284
333
jmxMBeanPropertyCache .getKeyPropertyList (mbeanName ),
334
+ new HashMap <>(),
285
335
new LinkedList <>(),
286
336
attr .getName (),
287
337
attr .getType (),
@@ -299,6 +349,7 @@ private void processBeanValue(
299
349
ObjectName objectName ,
300
350
String domain ,
301
351
LinkedHashMap <String , String > beanProperties ,
352
+ Map <String , String > attributesAsLabelsWithValues ,
302
353
LinkedList <String > attrKeys ,
303
354
String attrName ,
304
355
String attrType ,
@@ -316,7 +367,7 @@ private void processBeanValue(
316
367
}
317
368
LOGGER .log (FINE , "%s%s%s scrape: %s" , domain , beanProperties , attrName , value );
318
369
this .receiver .recordBean (
319
- domain , beanProperties , attrKeys , attrName , attrType , attrDescription , value );
370
+ domain , beanProperties , attributesAsLabelsWithValues , attrKeys , attrName , attrType , attrDescription , value );
320
371
} else if (value instanceof CompositeData ) {
321
372
LOGGER .log (FINE , "%s%s%s scrape: compositedata" , domain , beanProperties , attrName );
322
373
CompositeData composite = (CompositeData ) value ;
@@ -330,6 +381,7 @@ private void processBeanValue(
330
381
objectName ,
331
382
domain ,
332
383
beanProperties ,
384
+ attributesAsLabelsWithValues ,
333
385
attrKeys ,
334
386
key ,
335
387
typ ,
@@ -396,6 +448,7 @@ private void processBeanValue(
396
448
objectName ,
397
449
domain ,
398
450
l2s ,
451
+ attributesAsLabelsWithValues ,
399
452
attrNames ,
400
453
name ,
401
454
typ ,
@@ -416,6 +469,7 @@ private void processBeanValue(
416
469
objectName ,
417
470
domain ,
418
471
beanProperties ,
472
+ attributesAsLabelsWithValues ,
419
473
attrKeys ,
420
474
attrName ,
421
475
attrType ,
@@ -428,6 +482,7 @@ private void processBeanValue(
428
482
objectName ,
429
483
domain ,
430
484
beanProperties ,
485
+ attributesAsLabelsWithValues ,
431
486
attrKeys ,
432
487
attrName ,
433
488
attrType ,
@@ -443,6 +498,7 @@ private static class StdoutWriter implements MBeanReceiver {
443
498
public void recordBean (
444
499
String domain ,
445
500
LinkedHashMap <String , String > beanProperties ,
501
+ Map <String , String > attributesAsLabelsWithValues ,
446
502
LinkedList <String > attrKeys ,
447
503
String attrName ,
448
504
String attrType ,
@@ -467,6 +523,7 @@ public static void main(String[] args) throws Exception {
467
523
objectNames ,
468
524
new LinkedList <>(),
469
525
objectNameAttributeFilter ,
526
+ new LinkedList <>(),
470
527
new StdoutWriter (),
471
528
new JmxMBeanPropertyCache ())
472
529
.doScrape ();
@@ -479,6 +536,7 @@ public static void main(String[] args) throws Exception {
479
536
objectNames ,
480
537
new LinkedList <>(),
481
538
objectNameAttributeFilter ,
539
+ new LinkedList <>(),
482
540
new StdoutWriter (),
483
541
new JmxMBeanPropertyCache ())
484
542
.doScrape ();
@@ -491,6 +549,7 @@ public static void main(String[] args) throws Exception {
491
549
objectNames ,
492
550
new LinkedList <>(),
493
551
objectNameAttributeFilter ,
552
+ new LinkedList <>(),
494
553
new StdoutWriter (),
495
554
new JmxMBeanPropertyCache ())
496
555
.doScrape ();
0 commit comments