77import org .springframework .beans .factory .annotation .Autowired ;
88import org .springframework .beans .factory .annotation .Value ;
99import org .springframework .context .annotation .PropertySource ;
10+ import org .springframework .scheduling .annotation .Scheduled ;
1011import org .springframework .stereotype .Service ;
1112import org .springframework .util .LinkedMultiValueMap ;
1213import org .springframework .util .MultiValueMap ;
1617import java .util .Arrays ;
1718import java .util .List ;
1819import java .util .Map ;
20+ import java .util .concurrent .TimeUnit ;
21+ import java .util .concurrent .atomic .AtomicLong ;
1922import java .util .stream .Collectors ;
2023import java .util .Map .Entry ;
2124
@@ -41,6 +44,9 @@ public class MetricsService {
4144 private final TagRepository tagRepository ;
4245 private final MeterRegistry meterRegistry ;
4346
47+ private Map <MultiValueMap <String , String >, AtomicLong > propertyMetrics ;
48+ private Map <String , AtomicLong > tagMetrics ;
49+
4450 @ Value ("${metrics.tags}" )
4551 private String [] tags ;
4652
@@ -87,10 +93,14 @@ private void registerGaugeMetrics() {
8793 registerPropertyMetrics ();
8894 }
8995
96+
9097 private void registerTagMetrics () {
9198 // Add tags
99+ tagMetrics = Arrays .stream (tags )
100+ .map (t -> Map .entry (t , new AtomicLong (0 )))
101+ .collect (Collectors .toMap (Entry ::getKey , Entry ::getValue ));
92102 for (String tag : tags ) {
93- Gauge .builder (CF_TAG_ON_CHANNELS_COUNT , () -> channelRepository . countByTag (tag ))
103+ Gauge .builder (CF_TAG_ON_CHANNELS_COUNT , tagMetrics , m -> m . get (tag ). doubleValue ( ))
94104 .description ("Number of channels with tag" )
95105 .tag ("tag" , tag )
96106 .baseUnit (BASE_UNIT )
@@ -154,14 +164,39 @@ private List<Tag> metricTagsFromMultiValueMap(MultiValueMap<String, String> mult
154164 }
155165 return metricTags ;
156166 }
167+
157168 private void registerPropertyMetrics () {
158169 Map <String , List <String >> properties = parseProperties ();
159170
160171 List <MultiValueMap <String , String >> combinations = generateAllMultiValueMaps (properties );
161- combinations .forEach (map -> Gauge .builder (CF_CHANNEL_COUNT , () -> channelRepository .count (map ))
172+
173+ propertyMetrics = combinations .stream ()
174+ .map (t -> Map .entry (t , new AtomicLong (0 )))
175+ .collect (Collectors .toMap (Entry ::getKey , Entry ::getValue ));
176+ combinations .forEach (map -> Gauge .builder (CF_CHANNEL_COUNT , propertyMetrics , m -> m .get (map ).doubleValue ())
162177 .description (METRIC_DESCRIPTION_CHANNEL_COUNT )
163178 .tags (metricTagsFromMultiValueMap (map ))
164179 .register (meterRegistry )
165180 );
166181 }
182+
183+ private void updateTagMetrics () {
184+ for (Map .Entry <String , AtomicLong > tagMetricEntry : tagMetrics .entrySet ()) {
185+ tagMetricEntry .getValue ()
186+ .set (channelRepository .countByTag (tagMetricEntry .getKey ()));
187+ }
188+ }
189+
190+ private void updatePropertyMetrics () {
191+ for (Map .Entry <MultiValueMap <String , String >, AtomicLong > propertyMetricEntry : propertyMetrics .entrySet ()) {
192+ propertyMetricEntry .getValue ()
193+ .set (channelRepository .count (propertyMetricEntry .getKey ()));
194+ }
195+ }
196+
197+ @ Scheduled (fixedRateString = "${metrics.updateInterval}" , timeUnit = TimeUnit .SECONDS )
198+ public void updateMetrics () {
199+ updateTagMetrics ();
200+ updatePropertyMetrics ();
201+ }
167202}
0 commit comments