3131import java .util .Optional ;
3232import java .util .Set ;
3333import java .util .TreeSet ;
34+ import java .util .Collections ;
35+ import java .util .stream .Collectors ;
3436import javax .management .Attribute ;
3537import javax .management .AttributeList ;
3638import javax .management .JMException ;
@@ -72,6 +74,7 @@ public interface MBeanReceiver {
7274 void recordBean (
7375 String domain ,
7476 LinkedHashMap <String , String > beanProperties ,
77+ Map <String , String > attributesAsLabelsWithValues ,
7578 LinkedList <String > attrKeys ,
7679 String attrName ,
7780 String attrType ,
@@ -85,6 +88,7 @@ void recordBean(
8588 private final String password ;
8689 private final boolean ssl ;
8790 private final List <ObjectName > includeObjectNames , excludeObjectNames ;
91+ private final List <JmxCollector .MetricCustomizer > metricCustomizers ;
8892 private final ObjectNameAttributeFilter objectNameAttributeFilter ;
8993 private final JmxMBeanPropertyCache jmxMBeanPropertyCache ;
9094
@@ -109,6 +113,7 @@ public JmxScraper(
109113 List <ObjectName > includeObjectNames ,
110114 List <ObjectName > excludeObjectNames ,
111115 ObjectNameAttributeFilter objectNameAttributeFilter ,
116+ List <JmxCollector .MetricCustomizer > metricCustomizers ,
112117 MBeanReceiver receiver ,
113118 JmxMBeanPropertyCache jmxMBeanPropertyCache ) {
114119 this .jmxUrl = jmxUrl ;
@@ -118,6 +123,7 @@ public JmxScraper(
118123 this .ssl = ssl ;
119124 this .includeObjectNames = includeObjectNames ;
120125 this .excludeObjectNames = excludeObjectNames ;
126+ this .metricCustomizers = metricCustomizers ;
121127 this .objectNameAttributeFilter = objectNameAttributeFilter ;
122128 this .jmxMBeanPropertyCache = jmxMBeanPropertyCache ;
123129 }
@@ -253,6 +259,12 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mBeanName) {
253259
254260 final String mBeanNameString = mBeanName .toString ();
255261 final String mBeanDomain = mBeanName .getDomain ();
262+ JmxCollector .MetricCustomizer metricCustomizer = getMetricCustomizer (mBeanName );
263+ Map <String , String > attributesAsLabelsWithValues = Collections .emptyMap ();
264+ if (metricCustomizer != null ) {
265+ attributesAsLabelsWithValues =
266+ getAttributesAsLabelsWithValues (metricCustomizer , attributes );
267+ }
256268
257269 for (Object object : attributes ) {
258270 // The contents of an AttributeList should all be Attribute instances, but we'll verify
@@ -280,6 +292,7 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mBeanName) {
280292 mBeanName ,
281293 mBeanDomain ,
282294 jmxMBeanPropertyCache .getKeyPropertyList (mBeanName ),
295+ attributesAsLabelsWithValues ,
283296 new LinkedList <>(),
284297 mBeanAttributeInfo .getName (),
285298 mBeanAttributeInfo .getType (),
@@ -300,6 +313,35 @@ private void scrapeBean(MBeanServerConnection beanConn, ObjectName mBeanName) {
300313 }
301314 }
302315
316+ private Map <String , String > getAttributesAsLabelsWithValues (JmxCollector .MetricCustomizer metricCustomizer , AttributeList attributes ) {
317+ Map <String , Object > attributeMap = attributes .asList ().stream ()
318+ .collect (Collectors .toMap (Attribute ::getName , Attribute ::getValue ));
319+ Map <String , String > attributesAsLabelsWithValues = new HashMap <>();
320+ for (String attributeAsLabel : metricCustomizer .attributesAsLabels ) {
321+ Object attrValue = attributeMap .get (attributeAsLabel );
322+ if (attrValue != null ) {
323+ attributesAsLabelsWithValues .put (attributeAsLabel , attrValue .toString ());
324+ }
325+ }
326+ return attributesAsLabelsWithValues ;
327+ }
328+
329+ private JmxCollector .MetricCustomizer getMetricCustomizer (ObjectName mBeanName ) {
330+ if (!metricCustomizers .isEmpty ()) {
331+ for (JmxCollector .MetricCustomizer metricCustomizer : metricCustomizers ) {
332+ if (filterMbeanByDomainAndProperties (mBeanName , metricCustomizer )) {
333+ return metricCustomizer ;
334+ }
335+ }
336+ }
337+ return null ;
338+ }
339+
340+ private boolean filterMbeanByDomainAndProperties (ObjectName mBeanName , JmxCollector .MetricCustomizer metricCustomizer ) {
341+ return metricCustomizer .mbeanFilter .domain .equals (mBeanName .getDomain ()) &&
342+ mBeanName .getKeyPropertyList ().entrySet ().containsAll (metricCustomizer .mbeanFilter .properties .entrySet ());
343+ }
344+
303345 private void processAttributesOneByOne (
304346 MBeanServerConnection beanConn ,
305347 ObjectName mbeanName ,
@@ -318,6 +360,7 @@ private void processAttributesOneByOne(
318360 mbeanName ,
319361 mbeanName .getDomain (),
320362 jmxMBeanPropertyCache .getKeyPropertyList (mbeanName ),
363+ new HashMap <>(),
321364 new LinkedList <>(),
322365 attr .getName (),
323366 attr .getType (),
@@ -335,6 +378,7 @@ private void processBeanValue(
335378 ObjectName objectName ,
336379 String domain ,
337380 LinkedHashMap <String , String > beanProperties ,
381+ Map <String , String > attributesAsLabelsWithValues ,
338382 LinkedList <String > attrKeys ,
339383 String attrName ,
340384 String attrType ,
@@ -352,7 +396,7 @@ private void processBeanValue(
352396 }
353397 LOGGER .log (FINE , "%s%s%s scrape: %s" , domain , beanProperties , attrName , value );
354398 this .receiver .recordBean (
355- domain , beanProperties , attrKeys , attrName , attrType , attrDescription , value );
399+ domain , beanProperties , attributesAsLabelsWithValues , attrKeys , attrName , attrType , attrDescription , value );
356400 } else if (value instanceof CompositeData ) {
357401 LOGGER .log (FINE , "%s%s%s scrape: compositedata" , domain , beanProperties , attrName );
358402 CompositeData composite = (CompositeData ) value ;
@@ -366,6 +410,7 @@ private void processBeanValue(
366410 objectName ,
367411 domain ,
368412 beanProperties ,
413+ attributesAsLabelsWithValues ,
369414 attrKeys ,
370415 key ,
371416 typ ,
@@ -432,6 +477,7 @@ private void processBeanValue(
432477 objectName ,
433478 domain ,
434479 l2s ,
480+ attributesAsLabelsWithValues ,
435481 attrNames ,
436482 name ,
437483 typ ,
@@ -452,6 +498,7 @@ private void processBeanValue(
452498 objectName ,
453499 domain ,
454500 beanProperties ,
501+ attributesAsLabelsWithValues ,
455502 attrKeys ,
456503 attrName ,
457504 attrType ,
@@ -464,6 +511,7 @@ private void processBeanValue(
464511 objectName ,
465512 domain ,
466513 beanProperties ,
514+ attributesAsLabelsWithValues ,
467515 attrKeys ,
468516 attrName ,
469517 attrType ,
@@ -479,6 +527,7 @@ private static class StdoutWriter implements MBeanReceiver {
479527 public void recordBean (
480528 String domain ,
481529 LinkedHashMap <String , String > beanProperties ,
530+ Map <String , String > attributesAsLabelsWithValues ,
482531 LinkedList <String > attrKeys ,
483532 String attrName ,
484533 String attrType ,
@@ -503,6 +552,7 @@ public static void main(String[] args) throws Exception {
503552 objectNames ,
504553 new LinkedList <>(),
505554 objectNameAttributeFilter ,
555+ new LinkedList <>(),
506556 new StdoutWriter (),
507557 new JmxMBeanPropertyCache ())
508558 .doScrape ();
@@ -515,6 +565,7 @@ public static void main(String[] args) throws Exception {
515565 objectNames ,
516566 new LinkedList <>(),
517567 objectNameAttributeFilter ,
568+ new LinkedList <>(),
518569 new StdoutWriter (),
519570 new JmxMBeanPropertyCache ())
520571 .doScrape ();
@@ -527,6 +578,7 @@ public static void main(String[] args) throws Exception {
527578 objectNames ,
528579 new LinkedList <>(),
529580 objectNameAttributeFilter ,
581+ new LinkedList <>(),
530582 new StdoutWriter (),
531583 new JmxMBeanPropertyCache ())
532584 .doScrape ();
0 commit comments