@@ -82,6 +82,10 @@ public class OtlpMeterRegistry extends PushMeterRegistry {
82
82
83
83
private final OtlpMetricsSender metricsSender ;
84
84
85
+ private final HistogramFlavorPerMeterLookup histogramFlavorPerMeterLookup ;
86
+
87
+ private final MaxBucketsPerMeterLookup maxBucketsPerMeterLookup ;
88
+
85
89
private final Resource resource ;
86
90
87
91
private final AggregationTemporality aggregationTemporality ;
@@ -111,15 +115,19 @@ public OtlpMeterRegistry(OtlpConfig config, Clock clock) {
111
115
* @since 1.14.0
112
116
*/
113
117
public OtlpMeterRegistry (OtlpConfig config , Clock clock , ThreadFactory threadFactory ) {
114
- this (config , clock , threadFactory , new OtlpHttpMetricsSender (new HttpUrlConnectionSender ()));
118
+ this (config , clock , threadFactory , new OtlpHttpMetricsSender (new HttpUrlConnectionSender ()),
119
+ OtlpMeterRegistry ::histogramFlavorPerMeter , OtlpMeterRegistry ::maxBucketsPerMeter );
115
120
}
116
121
117
122
private OtlpMeterRegistry (OtlpConfig config , Clock clock , ThreadFactory threadFactory ,
118
- OtlpMetricsSender metricsSender ) {
123
+ OtlpMetricsSender metricsSender , HistogramFlavorPerMeterLookup histogramFlavorPerMeterLookup ,
124
+ MaxBucketsPerMeterLookup maxBucketsPerMeterLookup ) {
119
125
super (config , clock );
120
126
this .config = config ;
121
127
this .baseTimeUnit = config .baseTimeUnit ();
122
128
this .metricsSender = metricsSender ;
129
+ this .histogramFlavorPerMeterLookup = histogramFlavorPerMeterLookup ;
130
+ this .maxBucketsPerMeterLookup = maxBucketsPerMeterLookup ;
123
131
this .resource = Resource .newBuilder ().addAllAttributes (getResourceAttributes ()).build ();
124
132
this .aggregationTemporality = config .aggregationTemporality ();
125
133
config ().namingConvention (NamingConvention .dot );
@@ -430,16 +438,12 @@ private Histogram getHistogram(Meter.Id id, DistributionStatisticConfig distribu
430
438
}
431
439
432
440
private int getMaxBuckets (Meter .Id id ) {
433
- Integer perMeterMaxBuckets = config .maxBucketsPerMeter (id );
434
- return perMeterMaxBuckets == null ? config .maxBucketCount () : perMeterMaxBuckets ;
441
+ return maxBucketsPerMeterLookup .getMaxBuckets (config , id );
435
442
}
436
443
437
444
private HistogramFlavor histogramFlavor (Meter .Id id , OtlpConfig otlpConfig ,
438
445
DistributionStatisticConfig distributionStatisticConfig ) {
439
- HistogramFlavor preferredHistogramFlavor = otlpConfig .histogramFlavorPerMeter (id );
440
- preferredHistogramFlavor = preferredHistogramFlavor == null ? otlpConfig .histogramFlavor ()
441
- : preferredHistogramFlavor ;
442
-
446
+ HistogramFlavor preferredHistogramFlavor = histogramFlavorPerMeterLookup .getHistogramFlavor (otlpConfig , id );
443
447
final double [] serviceLevelObjectiveBoundaries = distributionStatisticConfig
444
448
.getServiceLevelObjectiveBoundaries ();
445
449
if (distributionStatisticConfig .isPublishingHistogram ()
@@ -499,6 +503,76 @@ static double[] getSloWithPositiveInf(DistributionStatisticConfig distributionSt
499
503
return sloWithPositiveInf ;
500
504
}
501
505
506
+ private static HistogramFlavor histogramFlavorPerMeter (OtlpConfig config , Meter .Id id ) {
507
+ for (Map .Entry <String , HistogramFlavor > entry : config .histogramFlavorPerMeter ().entrySet ()) {
508
+ if (id .getName ().startsWith (entry .getKey ())) {
509
+ return entry .getValue ();
510
+ }
511
+ }
512
+ return config .histogramFlavor ();
513
+ }
514
+
515
+ private static Integer maxBucketsPerMeter (OtlpConfig config , Meter .Id id ) {
516
+ for (Map .Entry <String , Integer > entry : config .maxBucketsPerMeter ().entrySet ()) {
517
+ if (id .getName ().startsWith (entry .getKey ())) {
518
+ return entry .getValue ();
519
+ }
520
+ }
521
+ return config .maxBucketCount ();
522
+ }
523
+
524
+ /**
525
+ * Overridable lookup mechanism for {@link HistogramFlavor}.
526
+ *
527
+ * @since 1.15.0
528
+ */
529
+ @ FunctionalInterface
530
+ public interface HistogramFlavorPerMeterLookup {
531
+
532
+ /**
533
+ * Looks up the histogram flavor to use on a per-meter level. This will override
534
+ * the {@link OtlpConfig#histogramFlavor()} for matching Meters. The default
535
+ * implementation in {@link OtlpMeterRegistry} does a prefix match on the Meter's
536
+ * name in the map that {@link OtlpConfig#histogramFlavorPerMeter()} returns. This
537
+ * means that {@link OtlpConfig#histogramFlavorPerMeter()} provides the data while
538
+ * this method provides the logic for the lookup, and you can override them
539
+ * independently.
540
+ * @param id the {@link Meter.Id} the {@link HistogramFlavor} is configured for
541
+ * @return the histogram flavor mapped to the {@link Meter.Id}
542
+ * @see OtlpConfig#histogramFlavorPerMeter()
543
+ * @see OtlpConfig#histogramFlavor()
544
+ */
545
+ HistogramFlavor getHistogramFlavor (OtlpConfig config , Meter .Id id );
546
+
547
+ }
548
+
549
+ /**
550
+ * Overridable lookup mechanism for max bucket count. This has no effect on a meter if
551
+ * it does not have an exponential bucket histogram configured.
552
+ *
553
+ * @since 1.15.0
554
+ */
555
+ @ FunctionalInterface
556
+ public interface MaxBucketsPerMeterLookup {
557
+
558
+ /**
559
+ * Looks up the max bucket count to use on a per-meter level. This will override
560
+ * the {@link OtlpConfig#maxBucketCount()} for matching Meters. The default
561
+ * implementation in {@link OtlpMeterRegistry} does a prefix match on the Meter's
562
+ * name in the map that {@link OtlpConfig#maxBucketsPerMeter()} returns. This
563
+ * means that {@link OtlpConfig#maxBucketsPerMeter()} provides the data while this
564
+ * method provides the logic for the lookup, and you can override them
565
+ * independently. This has no effect on a meter if it does not have an exponential
566
+ * bucket histogram configured.
567
+ * @param id the {@link Meter.Id} the max bucket count is configured for
568
+ * @return the max bucket count mapped to the {@link Meter.Id}
569
+ * @see OtlpConfig#maxBucketsPerMeter()
570
+ * @see OtlpConfig#maxBucketCount()
571
+ */
572
+ Integer getMaxBuckets (OtlpConfig config , Meter .Id id );
573
+
574
+ }
575
+
502
576
/**
503
577
* Builder for {@link OtlpMeterRegistry}.
504
578
*
@@ -514,9 +588,15 @@ public static class Builder {
514
588
515
589
private OtlpMetricsSender metricsSender ;
516
590
591
+ private HistogramFlavorPerMeterLookup histogramFlavorPerMeterLookup ;
592
+
593
+ private MaxBucketsPerMeterLookup maxBucketsPerMeterLookup ;
594
+
517
595
private Builder (OtlpConfig otlpConfig ) {
518
596
this .otlpConfig = otlpConfig ;
519
597
this .metricsSender = new OtlpHttpMetricsSender (new HttpUrlConnectionSender ());
598
+ this .histogramFlavorPerMeterLookup = OtlpMeterRegistry ::histogramFlavorPerMeter ;
599
+ this .maxBucketsPerMeterLookup = OtlpMeterRegistry ::maxBucketsPerMeter ;
520
600
}
521
601
522
602
/** Override the default clock. */
@@ -542,8 +622,19 @@ public Builder metricsSender(OtlpMetricsSender metricsSender) {
542
622
return this ;
543
623
}
544
624
625
+ public Builder histogramFlavorPerMeterLookup (HistogramFlavorPerMeterLookup histogramFlavorPerMeterLookup ) {
626
+ this .histogramFlavorPerMeterLookup = histogramFlavorPerMeterLookup ;
627
+ return this ;
628
+ }
629
+
630
+ public Builder maxBucketsPerMeterLookup (MaxBucketsPerMeterLookup maxBucketsPerMeterLookup ) {
631
+ this .maxBucketsPerMeterLookup = maxBucketsPerMeterLookup ;
632
+ return this ;
633
+ }
634
+
545
635
public OtlpMeterRegistry build () {
546
- return new OtlpMeterRegistry (otlpConfig , clock , threadFactory , metricsSender );
636
+ return new OtlpMeterRegistry (otlpConfig , clock , threadFactory , metricsSender , histogramFlavorPerMeterLookup ,
637
+ maxBucketsPerMeterLookup );
547
638
}
548
639
549
640
}
0 commit comments