001package io.prometheus.metrics.instrumentation.dropwizard; 002 003import com.codahale.metrics.Counter; 004import com.codahale.metrics.Gauge; 005import com.codahale.metrics.Histogram; 006import com.codahale.metrics.Meter; 007import com.codahale.metrics.Metric; 008import com.codahale.metrics.MetricFilter; 009import com.codahale.metrics.MetricRegistry; 010import com.codahale.metrics.Snapshot; 011import com.codahale.metrics.Timer; 012import io.prometheus.metrics.annotations.StableApi; 013import io.prometheus.metrics.instrumentation.dropwizard5.InvalidMetricHandler; 014import io.prometheus.metrics.instrumentation.dropwizard5.internal.AbstractDropwizardExports; 015import io.prometheus.metrics.instrumentation.dropwizard5.labels.CustomLabelMapper; 016import io.prometheus.metrics.model.registry.PrometheusRegistry; 017import io.prometheus.metrics.model.snapshots.MetricSnapshots; 018import javax.annotation.Nullable; 019 020/** 021 * Collect Dropwizard 4.x metrics from a MetricRegistry. 022 * 023 * <p>This is a thin wrapper around {@link AbstractDropwizardExports} that handles the Dropwizard 024 * 4.x specific API where metric names are Strings. 025 */ 026@StableApi 027public class DropwizardExports 028 extends AbstractDropwizardExports< 029 MetricRegistry, 030 MetricFilter, 031 Counter, 032 Gauge<?>, 033 Histogram, 034 Timer, 035 Meter, 036 Metric, 037 Snapshot> { 038 039 /** 040 * Creates a new DropwizardExports and {@link MetricFilter#ALL}. 041 * 042 * @param registry a metric registry to export in prometheus. 043 */ 044 public DropwizardExports(MetricRegistry registry) { 045 this(registry, MetricFilter.ALL, null, InvalidMetricHandler.ALWAYS_THROW); 046 } 047 048 /** 049 * Creates a new DropwizardExports with a custom {@link MetricFilter}. 050 * 051 * @param registry a metric registry to export in prometheus. 052 * @param metricFilter a custom metric filter. 053 */ 054 public DropwizardExports(MetricRegistry registry, MetricFilter metricFilter) { 055 this(registry, metricFilter, null, InvalidMetricHandler.ALWAYS_THROW); 056 } 057 058 /** 059 * @param registry a metric registry to export in prometheus. 060 * @param metricFilter a custom metric filter. 061 * @param labelMapper a labelMapper to use to map labels. 062 */ 063 public DropwizardExports( 064 MetricRegistry registry, MetricFilter metricFilter, @Nullable CustomLabelMapper labelMapper) { 065 this(registry, metricFilter, labelMapper, InvalidMetricHandler.ALWAYS_THROW); 066 } 067 068 /** 069 * @param registry a metric registry to export in prometheus. 070 * @param metricFilter a custom metric filter. 071 * @param labelMapper a labelMapper to use to map labels. 072 * @param invalidMetricHandler handler for invalid metrics. 073 */ 074 private DropwizardExports( 075 MetricRegistry registry, 076 MetricFilter metricFilter, 077 @Nullable CustomLabelMapper labelMapper, 078 InvalidMetricHandler invalidMetricHandler) { 079 super(registry, metricFilter, labelMapper, invalidMetricHandler); 080 } 081 082 @Override 083 protected MetricSnapshots collectMetricSnapshots() { 084 MetricSnapshots.Builder metricSnapshots = MetricSnapshots.builder(); 085 // For Dropwizard 4.x, map keys are Strings, so we just use identity function 086 collectMetricKind( 087 metricSnapshots, registry.getGauges(metricFilter), this::fromGauge, key -> key); 088 collectMetricKind( 089 metricSnapshots, registry.getCounters(metricFilter), this::fromCounter, key -> key); 090 collectMetricKind( 091 metricSnapshots, registry.getHistograms(metricFilter), this::fromHistogram, key -> key); 092 collectMetricKind( 093 metricSnapshots, registry.getTimers(metricFilter), this::fromTimer, key -> key); 094 collectMetricKind( 095 metricSnapshots, registry.getMeters(metricFilter), this::fromMeter, key -> key); 096 return metricSnapshots.build(); 097 } 098 099 @Override 100 protected long getCounterCount(Counter counter) { 101 return counter.getCount(); 102 } 103 104 @Override 105 protected Object getGaugeValue(Gauge<?> gauge) { 106 return gauge.getValue(); 107 } 108 109 @Override 110 protected Snapshot getHistogramSnapshot(Histogram histogram) { 111 return histogram.getSnapshot(); 112 } 113 114 @Override 115 protected long getHistogramCount(Histogram histogram) { 116 return histogram.getCount(); 117 } 118 119 @Override 120 protected Snapshot getTimerSnapshot(Timer timer) { 121 return timer.getSnapshot(); 122 } 123 124 @Override 125 protected long getTimerCount(Timer timer) { 126 return timer.getCount(); 127 } 128 129 @Override 130 protected long getMeterCount(Meter meter) { 131 return meter.getCount(); 132 } 133 134 @Override 135 protected double getMedian(Snapshot snapshot) { 136 return snapshot.getMedian(); 137 } 138 139 @Override 140 protected double get75thPercentile(Snapshot snapshot) { 141 return snapshot.get75thPercentile(); 142 } 143 144 @Override 145 protected double get95thPercentile(Snapshot snapshot) { 146 return snapshot.get95thPercentile(); 147 } 148 149 @Override 150 protected double get98thPercentile(Snapshot snapshot) { 151 return snapshot.get98thPercentile(); 152 } 153 154 @Override 155 protected double get99thPercentile(Snapshot snapshot) { 156 return snapshot.get99thPercentile(); 157 } 158 159 @Override 160 protected double get999thPercentile(Snapshot snapshot) { 161 return snapshot.get999thPercentile(); 162 } 163 164 public static Builder builder() { 165 return new Builder(); 166 } 167 168 // Builder class for DropwizardExports 169 public static class Builder { 170 @Nullable private MetricRegistry registry; 171 private MetricFilter metricFilter; 172 @Nullable private CustomLabelMapper labelMapper; 173 private InvalidMetricHandler invalidMetricHandler; 174 175 private Builder() { 176 this.metricFilter = MetricFilter.ALL; 177 this.invalidMetricHandler = InvalidMetricHandler.ALWAYS_THROW; 178 } 179 180 public Builder dropwizardRegistry(MetricRegistry registry) { 181 this.registry = registry; 182 return this; 183 } 184 185 public Builder metricFilter(MetricFilter metricFilter) { 186 this.metricFilter = metricFilter; 187 return this; 188 } 189 190 public Builder customLabelMapper(CustomLabelMapper labelMapper) { 191 this.labelMapper = labelMapper; 192 return this; 193 } 194 195 public Builder invalidMetricHandler(InvalidMetricHandler invalidMetricHandler) { 196 this.invalidMetricHandler = invalidMetricHandler; 197 return this; 198 } 199 200 DropwizardExports build() { 201 if (registry == null) { 202 throw new IllegalArgumentException("MetricRegistry must be set"); 203 } 204 return new DropwizardExports(registry, metricFilter, labelMapper, invalidMetricHandler); 205 } 206 207 public void register() { 208 register(PrometheusRegistry.defaultRegistry); 209 } 210 211 public void register(PrometheusRegistry registry) { 212 DropwizardExports dropwizardExports = build(); 213 registry.register(dropwizardExports); 214 } 215 } 216}