Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions src/main/java/org/phoebus/channelfinder/MetricsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
Expand All @@ -16,6 +17,8 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.Map.Entry;

Expand All @@ -41,6 +44,9 @@ public class MetricsService {
private final TagRepository tagRepository;
private final MeterRegistry meterRegistry;

private Map<MultiValueMap<String, String>, AtomicLong> propertyMetrics;
private Map<String, AtomicLong> tagMetrics;

@Value("${metrics.tags}")
private String[] tags;

Expand Down Expand Up @@ -87,10 +93,14 @@ private void registerGaugeMetrics() {
registerPropertyMetrics();
}


private void registerTagMetrics() {
// Add tags
tagMetrics = Arrays.stream(tags)
.map(t -> Map.entry(t, new AtomicLong(0)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
for (String tag : tags) {
Gauge.builder(CF_TAG_ON_CHANNELS_COUNT, () -> channelRepository.countByTag(tag))
Gauge.builder(CF_TAG_ON_CHANNELS_COUNT, tagMetrics, m -> m.get(tag).doubleValue())
.description("Number of channels with tag")
.tag("tag", tag)
.baseUnit(BASE_UNIT)
Expand Down Expand Up @@ -154,14 +164,39 @@ private List<Tag> metricTagsFromMultiValueMap(MultiValueMap<String, String> mult
}
return metricTags;
}

private void registerPropertyMetrics() {
Map<String, List<String>> properties = parseProperties();

List<MultiValueMap<String, String>> combinations = generateAllMultiValueMaps(properties);
combinations.forEach(map -> Gauge.builder(CF_CHANNEL_COUNT, () -> channelRepository.count(map))

propertyMetrics = combinations.stream()
.map(t -> Map.entry(t, new AtomicLong(0)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
combinations.forEach(map -> Gauge.builder(CF_CHANNEL_COUNT, propertyMetrics, m -> m.get(map).doubleValue())
.description(METRIC_DESCRIPTION_CHANNEL_COUNT)
.tags(metricTagsFromMultiValueMap(map))
.register(meterRegistry)
);
}

private void updateTagMetrics() {
for (Map.Entry<String, AtomicLong> tagMetricEntry : tagMetrics.entrySet()) {
tagMetricEntry.getValue()
.set(channelRepository.countByTag(tagMetricEntry.getKey()));
}
}

private void updatePropertyMetrics() {
for (Map.Entry<MultiValueMap<String, String>, AtomicLong> propertyMetricEntry : propertyMetrics.entrySet()) {
propertyMetricEntry.getValue()
.set(channelRepository.count(propertyMetricEntry.getKey()));
}
}

@Scheduled(fixedRateString = "${metrics.updateInterval}", timeUnit = TimeUnit.SECONDS)
public void updateMetrics() {
updateTagMetrics();
updatePropertyMetrics();
}
}
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,4 @@ aa.auto_pause=
management.endpoints.web.exposure.include=prometheus, metrics, health, info
metrics.tags=
metrics.properties=pvStatus:Active, Inactive
metrics.updateInterval=60
7 changes: 5 additions & 2 deletions src/test/java/org/phoebus/channelfinder/MetricsServiceIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.core.parameters.P;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
Expand All @@ -35,7 +34,8 @@
locations = "classpath:application_test.properties",
properties = {
"metrics.tags=testTag0, testTag1",
"metrics.properties=testProperty0: value0, value1; testProperty1: value0, !*"
"metrics.properties=testProperty0: value0, value1; testProperty1: value0, !*",
"metrics.updateInterval=1"
})
class MetricsServiceIT {

Expand Down Expand Up @@ -142,6 +142,7 @@ void testTagMultiGaugeMetrics() throws Exception {
Channel testChannel1 = new Channel("testChannelTag1", "testOwner", List.of(), List.of(testTags.get(0)));
channelRepository.save(testChannel1);

Thread.sleep(2000); // Update interval is 1 second
getAndExpectTagMetric(testTags.get(0), 2);
getAndExpectTagMetric(testTags.get(1), 1);
getAndExpectMetricParent(MetricsService.CF_TAG_ON_CHANNELS_COUNT, 3);
Expand Down Expand Up @@ -189,6 +190,8 @@ void testPropertyMultiGaugeMetrics() throws Exception {
channelRepository.save(testChannel);
channelRepository.save(testChannel1);

Thread.sleep(2000); // Update interval is 1 second

getAndExpectMetricParent(MetricsService.CF_CHANNEL_COUNT, 2);
getAndExpectPropertyMetric(testChannel.getProperties().get(0), 1);
getAndExpectPropertyMetric(testChannel1.getProperties().get(0), 1);
Expand Down
3 changes: 2 additions & 1 deletion src/test/resources/application_test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ aa.auto_pause=pvStatus,archive
#actuator
management.endpoints.web.exposure.include=prometheus, metrics, health, info
metrics.tags=group4_10
metrics.properties=group4: 10; group5: 10
metrics.properties=group4: 10; group5: 10
metrics.updateInterval=1
Loading