5050 * Publishes meters in OTLP (OpenTelemetry Protocol) format.
5151 * HTTP with Protobuf encoding is the only option currently supported.
5252 *
53+ * @author Tommy Ludwig
5354 * @since 1.9.0
5455 */
5556public class OtlpMeterRegistry extends PushMeterRegistry {
@@ -219,14 +220,36 @@ Metric writeHistogramSupport(HistogramSupport histogramSupport) {
219220 Metric .Builder metricBuilder = getMetricBuilder (histogramSupport .getId ());
220221 boolean isTimeBased = histogramSupport instanceof Timer || histogramSupport instanceof LongTaskTimer ;
221222 HistogramSnapshot histogramSnapshot = histogramSupport .takeSnapshot ();
223+
224+ Iterable <? extends KeyValue > tags = getTagsForId (histogramSupport .getId ());
225+ long startTimeNanos = ((StartTimeAwareMeter ) histogramSupport ).getStartTimeNanos ();
222226 long wallTimeNanos = TimeUnit .MILLISECONDS .toNanos (this .clock .wallTime ());
227+ double total = isTimeBased ? histogramSnapshot .total (getBaseTimeUnit ()) : histogramSnapshot .total ();
228+ long count = histogramSnapshot .count ();
229+
230+ // if percentiles configured, use summary
231+ if (histogramSnapshot .percentileValues ().length != 0 ) {
232+ SummaryDataPoint .Builder summaryData = SummaryDataPoint .newBuilder ()
233+ .addAllAttributes (tags )
234+ .setStartTimeUnixNano (startTimeNanos )
235+ .setTimeUnixNano (wallTimeNanos )
236+ .setSum (total )
237+ .setCount (count );
238+ for (ValueAtPercentile percentile : histogramSnapshot .percentileValues ()) {
239+ summaryData .addQuantileValues (SummaryDataPoint .ValueAtQuantile .newBuilder ()
240+ .setQuantile (percentile .percentile ())
241+ .setValue (TimeUtils .convert (percentile .value (), TimeUnit .NANOSECONDS , getBaseTimeUnit ())));
242+ }
243+ metricBuilder .setSummary (Summary .newBuilder ().addDataPoints (summaryData ));
244+ return metricBuilder .build ();
245+ }
223246
224247 HistogramDataPoint .Builder histogramDataPoint = HistogramDataPoint .newBuilder ()
225- .addAllAttributes (getTagsForId ( histogramSupport . getId ()) )
226- .setStartTimeUnixNano ((( StartTimeAwareMeter ) histogramSupport ). getStartTimeNanos () )
248+ .addAllAttributes (tags )
249+ .setStartTimeUnixNano (startTimeNanos )
227250 .setTimeUnixNano (wallTimeNanos )
228- .setSum (isTimeBased ? histogramSnapshot . total ( getBaseTimeUnit ()) : histogramSnapshot . total () )
229- .setCount (histogramSnapshot . count () );
251+ .setSum (total )
252+ .setCount (count );
230253
231254 // if histogram enabled, add histogram buckets
232255 if (histogramSnapshot .histogramCounts ().length != 0 ) {
@@ -240,22 +263,6 @@ Metric writeHistogramSupport(HistogramSupport histogramSupport) {
240263 return metricBuilder .build ();
241264 }
242265
243- // if percentiles configured, use summary
244- if (histogramSnapshot .percentileValues ().length != 0 ) {
245- SummaryDataPoint .Builder summaryData = SummaryDataPoint .newBuilder ()
246- .addAllAttributes (getTagsForId (histogramSupport .getId ()))
247- .setTimeUnixNano (wallTimeNanos )
248- .setSum (isTimeBased ? histogramSnapshot .total (getBaseTimeUnit ()) : histogramSnapshot .total ())
249- .setCount (histogramSnapshot .count ());
250- for (ValueAtPercentile percentile : histogramSnapshot .percentileValues ()) {
251- summaryData .addQuantileValues (SummaryDataPoint .ValueAtQuantile .newBuilder ()
252- .setQuantile (percentile .percentile ())
253- .setValue (TimeUtils .convert (percentile .value (), TimeUnit .NANOSECONDS , getBaseTimeUnit ())));
254- }
255- metricBuilder .setSummary (Summary .newBuilder ().addDataPoints (summaryData ));
256- return metricBuilder .build ();
257- }
258-
259266 return metricBuilder .setHistogram (Histogram .newBuilder ()
260267 .setAggregationTemporality (AggregationTemporality .AGGREGATION_TEMPORALITY_CUMULATIVE )
261268 .addDataPoints (histogramDataPoint )).build ();
@@ -288,22 +295,23 @@ private Metric.Builder getMetricBuilder(Meter.Id id) {
288295
289296 private Iterable <? extends KeyValue > getTagsForId (Meter .Id id ) {
290297 return id .getTags ().stream ()
291- .map (tag -> KeyValue .newBuilder ()
292- .setKey (tag .getKey ())
293- .setValue (AnyValue .newBuilder ().setStringValue (tag .getValue ()).build ())
294- .build ())
298+ .map (tag -> createKeyValue (tag .getKey (), tag .getValue ()))
295299 .collect (Collectors .toList ());
296300 }
297301
302+ private KeyValue createKeyValue (String key , String value ) {
303+ return KeyValue .newBuilder ().setKey (key ).setValue (AnyValue .newBuilder ().setStringValue (value )).build ();
304+ }
305+
298306 private Iterable <KeyValue > getResourceAttributes () {
299307 List <KeyValue > attributes = new ArrayList <>();
300308 // TODO How to expose configuration of the service.name
301- attributes .add (KeyValue . newBuilder (). setKey ( "service.name" ). setValue ( AnyValue . newBuilder (). setStringValue ( "unknown_service" )). build ( ));
302- attributes .add (KeyValue . newBuilder (). setKey ( "telemetry.sdk.name" ). setValue ( AnyValue . newBuilder (). setStringValue ( "io.micrometer" )). build ( ));
303- attributes .add (KeyValue . newBuilder (). setKey ( "telemetry.sdk.language" ). setValue ( AnyValue . newBuilder (). setStringValue ( "java" )). build ( ));
309+ attributes .add (createKeyValue ( "service.name" , "unknown_service" ));
310+ attributes .add (createKeyValue ( "telemetry.sdk.name" , "io.micrometer" ));
311+ attributes .add (createKeyValue ( "telemetry.sdk.language" , "java" ));
304312 String micrometerCoreVersion = MeterRegistry .class .getPackage ().getImplementationVersion ();
305313 if (micrometerCoreVersion != null ) {
306- attributes .add (KeyValue . newBuilder (). setKey ( "telemetry.sdk.version" ). setValue ( AnyValue . newBuilder (). setStringValue ( MeterRegistry . class . getPackage (). getImplementationVersion ())). build ( ));
314+ attributes .add (createKeyValue ( "telemetry.sdk.version" , micrometerCoreVersion ));
307315 }
308316 return attributes ;
309317 }
0 commit comments