2323import com .signalfx .metrics .errorhandler .OnSendErrorHandler ;
2424import com .signalfx .metrics .flush .AggregateMetricSender ;
2525import com .signalfx .metrics .protobuf .SignalFxProtocolBuffers ;
26- import io .micrometer .core .instrument .*;
26+ import io .micrometer .core .instrument .Clock ;
27+ import io .micrometer .core .instrument .Counter ;
28+ import io .micrometer .core .instrument .DistributionSummary ;
29+ import io .micrometer .core .instrument .FunctionCounter ;
30+ import io .micrometer .core .instrument .FunctionTimer ;
31+ import io .micrometer .core .instrument .Gauge ;
32+ import io .micrometer .core .instrument .LongTaskTimer ;
33+ import io .micrometer .core .instrument .Meter ;
34+ import io .micrometer .core .instrument .Tag ;
35+ import io .micrometer .core .instrument .TimeGauge ;
36+ import io .micrometer .core .instrument .Timer ;
2737import io .micrometer .core .instrument .config .NamingConvention ;
38+ import io .micrometer .core .instrument .distribution .DistributionStatisticConfig ;
39+ import io .micrometer .core .instrument .distribution .HistogramGauges ;
40+ import io .micrometer .core .instrument .distribution .pause .PauseDetector ;
2841import io .micrometer .core .instrument .step .StepMeterRegistry ;
2942import io .micrometer .core .instrument .util .MeterPartition ;
3043import io .micrometer .core .instrument .util .NamedThreadFactory ;
4154import java .util .stream .Stream ;
4255
4356import static com .signalfx .metrics .protobuf .SignalFxProtocolBuffers .MetricType .COUNTER ;
57+ import static com .signalfx .metrics .protobuf .SignalFxProtocolBuffers .MetricType .CUMULATIVE_COUNTER ;
4458import static com .signalfx .metrics .protobuf .SignalFxProtocolBuffers .MetricType .GAUGE ;
4559import static java .util .stream .StreamSupport .stream ;
4660
@@ -59,6 +73,7 @@ public class SignalFxMeterRegistry extends StepMeterRegistry {
5973 private final HttpEventProtobufReceiverFactory eventReceiverFactory ;
6074 private final Set <OnSendErrorHandler > onSendErrorHandlerCollection = Collections .singleton (
6175 metricError -> this .logger .warn ("failed to send metrics: {}" , metricError .getMessage ()));
76+ private final boolean publishCumulativeHistograms ;
6277
6378 public SignalFxMeterRegistry (SignalFxConfig config , Clock clock ) {
6479 this (config , clock , DEFAULT_THREAD_FACTORY );
@@ -71,16 +86,17 @@ public SignalFxMeterRegistry(SignalFxConfig config, Clock clock, ThreadFactory t
7186 URI apiUri = URI .create (config .uri ());
7287 int port = apiUri .getPort ();
7388 if (port == -1 ) {
74- if ("http" .equals (apiUri .getScheme ())) {
89+ if ("http" .equals (apiUri .getScheme ())) {
7590 port = 80 ;
76- } else if ("https" .equals (apiUri .getScheme ())) {
91+ } else if ("https" .equals (apiUri .getScheme ())) {
7792 port = 443 ;
7893 }
7994 }
8095
8196 SignalFxReceiverEndpoint signalFxEndpoint = new SignalFxEndpoint (apiUri .getScheme (), apiUri .getHost (), port );
8297 this .dataPointReceiverFactory = new HttpDataPointProtobufReceiverFactory (signalFxEndpoint );
8398 this .eventReceiverFactory = new HttpEventProtobufReceiverFactory (signalFxEndpoint );
99+ this .publishCumulativeHistograms = config .publishCumulativeHistogram ();
84100
85101 config ().namingConvention (new SignalFxNamingConvention ());
86102
@@ -118,7 +134,27 @@ protected void publish() {
118134 }
119135 }
120136
121- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addMeter (Meter meter ) {
137+ @ Override
138+ protected Timer newTimer (Meter .Id id , DistributionStatisticConfig distributionStatisticConfig , PauseDetector pauseDetector ) {
139+ if (!publishCumulativeHistograms ) {
140+ return super .newTimer (id , distributionStatisticConfig , pauseDetector );
141+ }
142+ Timer timer = new SignalfxTimer (id , clock , distributionStatisticConfig , pauseDetector , getBaseTimeUnit (), config .step ().toMillis ());
143+ HistogramGauges .registerWithCommonFormat (timer , this );
144+ return timer ;
145+ }
146+
147+ @ Override
148+ protected DistributionSummary newDistributionSummary (Meter .Id id , DistributionStatisticConfig distributionStatisticConfig , double scale ) {
149+ if (!publishCumulativeHistograms ) {
150+ return super .newDistributionSummary (id , distributionStatisticConfig , scale );
151+ }
152+ DistributionSummary summary = new SignalfxDistributionSummary (id , clock , distributionStatisticConfig , scale , config .step ().toMillis ());
153+ HistogramGauges .registerWithCommonFormat (summary , this );
154+ return summary ;
155+ }
156+
157+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addMeter (Meter meter ) {
122158 return stream (meter .measure ().spliterator (), false ).flatMap (measurement -> {
123159 String statSuffix = NamingConvention .camelCase .tagKey (measurement .getStatistic ().toString ());
124160 switch (measurement .getStatistic ()) {
@@ -170,23 +206,28 @@ Stream<SignalFxProtocolBuffers.DataPoint.Builder> addLongTaskTimer(LongTaskTimer
170206 );
171207 }
172208
173- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addTimeGauge (TimeGauge timeGauge ) {
209+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addTimeGauge (TimeGauge timeGauge ) {
174210 return Stream .of (addDatapoint (timeGauge , GAUGE , null , timeGauge .value (getBaseTimeUnit ())));
175211 }
176212
177- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addGauge (Gauge gauge ) {
213+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addGauge (Gauge gauge ) {
214+ if (publishCumulativeHistograms
215+ && gauge .getId ().syntheticAssociation () != null
216+ && gauge .getId ().getName ().endsWith (".histogram" )) {
217+ return Stream .of (addDatapoint (gauge , CUMULATIVE_COUNTER , null , gauge .value ()));
218+ }
178219 return Stream .of (addDatapoint (gauge , GAUGE , null , gauge .value ()));
179220 }
180221
181- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addCounter (Counter counter ) {
222+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addCounter (Counter counter ) {
182223 return Stream .of (addDatapoint (counter , COUNTER , null , counter .count ()));
183224 }
184225
185- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addFunctionCounter (FunctionCounter counter ) {
226+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addFunctionCounter (FunctionCounter counter ) {
186227 return Stream .of (addDatapoint (counter , COUNTER , null , counter .count ()));
187228 }
188229
189- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addTimer (Timer timer ) {
230+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addTimer (Timer timer ) {
190231 return Stream .of (
191232 addDatapoint (timer , COUNTER , "count" , timer .count ()),
192233 addDatapoint (timer , COUNTER , "totalTime" , timer .totalTime (getBaseTimeUnit ())),
@@ -195,15 +236,15 @@ private Stream<SignalFxProtocolBuffers.DataPoint.Builder> addTimer(Timer timer)
195236 );
196237 }
197238
198- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addFunctionTimer (FunctionTimer timer ) {
239+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addFunctionTimer (FunctionTimer timer ) {
199240 return Stream .of (
200241 addDatapoint (timer , COUNTER , "count" , timer .count ()),
201242 addDatapoint (timer , COUNTER , "totalTime" , timer .totalTime (getBaseTimeUnit ())),
202243 addDatapoint (timer , GAUGE , "avg" , timer .mean (getBaseTimeUnit ()))
203244 );
204245 }
205246
206- private Stream <SignalFxProtocolBuffers .DataPoint .Builder > addDistributionSummary (DistributionSummary summary ) {
247+ Stream <SignalFxProtocolBuffers .DataPoint .Builder > addDistributionSummary (DistributionSummary summary ) {
207248 return Stream .of (
208249 addDatapoint (summary , COUNTER , "count" , summary .count ()),
209250 addDatapoint (summary , COUNTER , "totalTime" , summary .totalAmount ()),
0 commit comments