1414import java .io .StringWriter ;
1515import java .util .ArrayList ;
1616import java .util .HashMap ;
17+ import java .util .HashSet ;
1718import java .util .Iterator ;
1819import java .util .LinkedHashMap ;
1920import java .util .LinkedList ;
2021import java .util .List ;
2122import java .util .Map ;
2223import java .util .Set ;
2324import java .util .TreeMap ;
25+ import java .util .logging .Level ;
2426import java .util .logging .Logger ;
2527import java .util .regex .Matcher ;
2628import java .util .regex .Pattern ;
@@ -335,9 +337,50 @@ private static boolean isLegalCharacter(char input) {
335337 (input >= '0' && input <= '9' ));
336338 }
337339
338- class Receiver implements JmxScraper .MBeanReceiver {
340+ /**
341+ * A sample is uniquely identified by its name, labelNames and labelValues
342+ */
343+ static class SampleKey {
344+ String name ;
345+ List <String > labelNames ;
346+ List <String > labelValues ;
347+
348+ SampleKey (String name , List <String > labelNames , List <String > labelValues ) {
349+ this .name = name ;
350+ this .labelNames = labelNames ;
351+ this .labelValues = labelValues ;
352+ }
353+
354+ static SampleKey of (MetricFamilySamples .Sample sample ) {
355+ return new SampleKey (sample .name , sample .labelNames , sample .labelValues );
356+ }
357+
358+ @ Override
359+ public boolean equals (Object o ) {
360+ if (this == o ) return true ;
361+ if (o == null || getClass () != o .getClass ()) return false ;
362+
363+ SampleKey sampleKey = (SampleKey ) o ;
364+
365+ if (name != null ? !name .equals (sampleKey .name ) : sampleKey .name != null ) return false ;
366+ if (labelNames != null ? !labelNames .equals (sampleKey .labelNames ) : sampleKey .labelNames != null ) return false ;
367+ return labelValues != null ? labelValues .equals (sampleKey .labelValues ) : sampleKey .labelValues == null ;
368+ }
369+
370+ @ Override
371+ public int hashCode () {
372+ int result = name != null ? name .hashCode () : 0 ;
373+ result = 31 * result + (labelNames != null ? labelNames .hashCode () : 0 );
374+ result = 31 * result + (labelValues != null ? labelValues .hashCode () : 0 );
375+ return result ;
376+ }
377+
378+ }
379+
380+ static class Receiver implements JmxScraper .MBeanReceiver {
339381 Map <String , MetricFamilySamples > metricFamilySamplesMap =
340382 new HashMap <String , MetricFamilySamples >();
383+ Set <SampleKey > uniqueSampleKeys = new HashSet <SampleKey >();
341384
342385 Config config ;
343386 MatchedRulesCache .StalenessTracker stalenessTracker ;
@@ -362,16 +405,20 @@ void addSample(MetricFamilySamples.Sample sample, Type type, String help) {
362405 mfs = new MetricFamilySamples (sample .name , type , help , new ArrayList <MetricFamilySamples .Sample >());
363406 metricFamilySamplesMap .put (sample .name , mfs );
364407 }
365- MetricFamilySamples .Sample existing = findExisting (sample , mfs );
366- if (existing != null ) {
408+ SampleKey sampleKey = SampleKey .of (sample );
409+ boolean exists = uniqueSampleKeys .contains (sampleKey );
410+ if (exists ) {
411+ if (LOGGER .isLoggable (Level .FINE )) {
367412 String labels = "{" ;
368- for (int i = 0 ; i < existing .labelNames .size (); i ++) {
369- labels += existing .labelNames .get (i ) + "=" + existing .labelValues .get (i ) + "," ;
413+ for (int i = 0 ; i < sample .labelNames .size (); i ++) {
414+ labels += sample .labelNames .get (i ) + "=" + sample .labelValues .get (i ) + "," ;
370415 }
371416 labels += "}" ;
372- LOGGER .fine ("Metric " + existing .name + labels + " was created multiple times. Keeping the first occurrence. Dropping the others." );
417+ LOGGER .fine ("Metric " + sample .name + labels + " was created multiple times. Keeping the first occurrence. Dropping the others." );
418+ }
373419 } else {
374420 mfs .samples .add (sample );
421+ uniqueSampleKeys .add (sampleKey );
375422 }
376423 }
377424
0 commit comments