Skip to content

Commit 6a82778

Browse files
committed
Fix the property metrics for prometheus
1 parent 40c39f7 commit 6a82778

File tree

4 files changed

+65
-57
lines changed

4 files changed

+65
-57
lines changed

src/main/java/org/phoebus/channelfinder/MetricsService.java

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,92 +11,99 @@
1111
import org.springframework.stereotype.Service;
1212
import org.springframework.util.LinkedMultiValueMap;
1313

14+
import javax.annotation.PostConstruct;
1415
import java.util.ArrayList;
1516
import java.util.Arrays;
17+
import java.util.List;
18+
import java.util.Map;
1619
import java.util.logging.Level;
1720
import java.util.logging.Logger;
21+
import java.util.stream.Collectors;
1822

1923
@Service
2024
@PropertySource(value = "classpath:application.properties")
2125
public class MetricsService {
2226

23-
private static final Logger logger = Logger.getLogger(MetricsService.class.getName());
2427
public static final String CF_TOTAL_CHANNEL_COUNT = "cf.total.channel.count";
2528
public static final String CF_PROPERTY_COUNT = "cf.property.count";
2629
public static final String CF_TAG_COUNT = "cf.tag.count";
2730
public static final String CF_CHANNEL_COUNT = "cf.channel.count";
2831
private static final String METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT = "Count of all ChannelFinder channels";
2932
private static final String METRIC_DESCRIPTION_PROPERTY_COUNT = "Count of all ChannelFinder properties";
3033
private static final String METRIC_DESCRIPTION_TAG_COUNT = "Count of all ChannelFinder tags";
31-
private static final String METRIC_DESCRIPTION_CHANNEL_COUNT =
32-
"Count of channels with specific property with and specific value";
34+
3335
private final ChannelRepository channelRepository;
3436
private final PropertyRepository propertyRepository;
3537
private final TagRepository tagRepository;
3638
private final MeterRegistry meterRegistry;
3739

38-
MultiGauge channelCounts;
39-
4040
@Value("${metrics.tags}")
4141
private String[] tags;
4242

43-
@Value("#{${metrics.properties:{{'pvStatus', 'Active'}, {'pvStatus', 'Inactive'}}}}")
44-
private String[][] properties;
43+
@Value("${metrics.properties}")
44+
private String metricProperties;
45+
46+
Map<String, List<String>> parseProperties() {
47+
if (metricProperties == null || metricProperties.isEmpty()) {
48+
return new LinkedMultiValueMap<>();
49+
}
50+
return Arrays.stream(metricProperties.split(";")).map(s ->
51+
{
52+
String[] split = s.split(":");
53+
String k = split[0].trim();
54+
List<String> v = Arrays.stream(split[1].split(",")).map(String::trim).toList();
55+
return Map.entry(k, v);
56+
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
57+
}
4558

4659
@Autowired
4760
public MetricsService(
48-
final ChannelRepository channelRepository,
49-
final PropertyRepository propertyRepository,
50-
final TagRepository tagRepository,
51-
final MeterRegistry meterRegistry) {
61+
final ChannelRepository channelRepository,
62+
final PropertyRepository propertyRepository,
63+
final TagRepository tagRepository,
64+
final MeterRegistry meterRegistry) {
5265
this.channelRepository = channelRepository;
5366
this.propertyRepository = propertyRepository;
5467
this.tagRepository = tagRepository;
5568
this.meterRegistry = meterRegistry;
56-
registerGaugeMetrics();
5769
}
5870

71+
@PostConstruct
5972
private void registerGaugeMetrics() {
6073
Gauge.builder(CF_TOTAL_CHANNEL_COUNT, () -> channelRepository.count(new LinkedMultiValueMap<>()))
61-
.description(METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT)
62-
.register(meterRegistry);
74+
.description(METRIC_DESCRIPTION_TOTAL_CHANNEL_COUNT)
75+
.register(meterRegistry);
6376
Gauge.builder(CF_PROPERTY_COUNT, propertyRepository::count)
64-
.description(METRIC_DESCRIPTION_PROPERTY_COUNT)
65-
.register(meterRegistry);
77+
.description(METRIC_DESCRIPTION_PROPERTY_COUNT)
78+
.register(meterRegistry);
6679
Gauge.builder(CF_TAG_COUNT, tagRepository::count)
67-
.description(METRIC_DESCRIPTION_TAG_COUNT)
68-
.register(meterRegistry);
69-
channelCounts = MultiGauge.builder(CF_CHANNEL_COUNT)
70-
.description(METRIC_DESCRIPTION_CHANNEL_COUNT)
71-
.baseUnit("channels")
72-
.register(meterRegistry);
80+
.description(METRIC_DESCRIPTION_TAG_COUNT)
81+
.register(meterRegistry);
82+
registerTagMetrics();
83+
registerPropertyMetrics();
7384
}
7485

75-
@Scheduled(fixedRate = 5000)
76-
public void updateMetrics() {
77-
logger.log(
78-
Level.FINER,
79-
() -> "Updating metrics for properties " + Arrays.deepToString(properties) + " and tags " + Arrays.toString(tags));
80-
ArrayList<MultiGauge.Row<?>> rows = new ArrayList<>();
86+
private void registerTagMetrics() {
8187

8288
// Add tags
83-
for (String tag: tags) {
84-
long count = channelRepository.countByTag(tag);
85-
rows.add(MultiGauge.Row.of(Tags.of("tag", tag), count ));
86-
logger.log(
87-
Level.FINER,
88-
() -> "Updating metrics for tag " + tag + " to " + count);
89+
for (String tag : tags) {
90+
Gauge.builder(CF_CHANNEL_COUNT, () -> channelRepository.countByTag(tag))
91+
.description("Number of channels with tag")
92+
.tag("tag", tag)
93+
.baseUnit("channels")
94+
.register(meterRegistry);
8995
}
96+
}
9097

91-
// Add properties
92-
for (String[] propertyValue: properties) {
93-
long count = channelRepository.countByProperty(propertyValue[0], propertyValue[1]);
94-
rows.add(MultiGauge.Row.of(Tags.of(propertyValue[0], propertyValue[1]), count));
95-
logger.log(
96-
Level.FINER,
97-
() -> "Updating metrics for property " + propertyValue[0] + ":" + propertyValue[1] + " to " + count);
98-
}
98+
private void registerPropertyMetrics() {
99+
Map<String, List<String>> properties = parseProperties();
99100

100-
channelCounts.register(rows, true);
101+
properties.forEach((propertyName, propertyValues) -> propertyValues.forEach(propertyValue ->
102+
Gauge.builder(CF_CHANNEL_COUNT + "." + propertyName, () -> channelRepository.countByProperty(propertyName, propertyValue))
103+
.description(String.format("Number of channels with property '%s'", propertyName))
104+
.tag(propertyName, propertyValue)
105+
.baseUnit("channels")
106+
.register(meterRegistry))
107+
);
101108
}
102109
}

src/main/resources/application.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ server.compression.mime-types=application/json,application/xml,text/html,text/xm
2020
server.compression.min-response-size=1024
2121
# Enable HTTP/2 support, if the current environment supports it
2222
server.http2.enabled=true
23-
logging.level.org.springframework.web=INFO
23+
logging.level.org.springframework.web=DEBUG
2424

2525
############## LDAP - External ##############
2626
ldap.enabled = false
@@ -137,4 +137,4 @@ aa.auto_pause=
137137
#actuator
138138
management.endpoints.web.exposure.include=prometheus, metrics, health, info
139139
metrics.tags=
140-
metrics.properties={{'pvStatus', 'Active'}, {'pvStatus', 'Inactive'}}
140+
metrics.properties=pvStatus:Active, Inactive

src/test/java/org/phoebus/channelfinder/MetricsServiceIT.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,23 @@
3636
locations = "classpath:application_test.properties",
3737
properties = {
3838
"metrics.tags=testTag0, testTag1",
39-
"metrics.properties={{'testProperty0', 'testProperty0Value'}, {'testProperty1', 'testProperty1Value'}}"
39+
"metrics.properties=testProperty0: testProperty0Value; testProperty1: testProperty1Value"
4040
})
4141
class MetricsServiceIT {
4242

4343
public static final String METRICS_ENDPOINT = "/actuator/metrics/";
4444
public static final String METRICS_TAG_LABEL = "tag";
45-
public static final String PROPERTY_0_LABEL = "testProperty0:testProperty0Value";
46-
public static final String PROPERTY_1_LABEL = "testProperty1:testProperty1Value";
45+
public static final String METRICS_PROPERTY_NAME = "testProperty";
46+
public static final String PROPERTY_0_LABEL = METRICS_PROPERTY_NAME + "0:testProperty0Value";
47+
public static final String PROPERTY_1_LABEL = METRICS_PROPERTY_NAME + "1:testProperty1Value";
4748
public static final String TAG_0_LABEL = "tag:testTag0";
4849
public static final String TAG_1_LABEL = "tag:testTag1";
4950
private final List<Tag> testTags =
5051
Arrays.asList(new Tag("testTag0", "testTagOwner0"), new Tag("testTag1", "testTagOwner1"));
5152
private final List<Property> testProperties = Arrays.asList(
52-
new Property("testProperty0", "testPropertyOwner0"),
53-
new Property("testProperty1", "testPropertyOwner1"),
54-
new Property("testProperty2", "testPropertyOwner2"));
53+
new Property(METRICS_PROPERTY_NAME + "0", "testPropertyOwner0"),
54+
new Property(METRICS_PROPERTY_NAME + "1", "testPropertyOwner1"),
55+
new Property(METRICS_PROPERTY_NAME + "2", "testPropertyOwner2"));
5556

5657
@Autowired
5758
ChannelRepository channelRepository;
@@ -141,10 +142,10 @@ void testTagMultiGaugeMetrics() throws Exception {
141142

142143
@Test
143144
void testPropertyMultiGaugeMetrics() throws Exception {
144-
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT)
145+
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT + "." + METRICS_PROPERTY_NAME + "0")
145146
.param(METRICS_TAG_LABEL, PROPERTY_0_LABEL))
146147
.andExpect(jsonPath("$.measurements[0].value").value(0));
147-
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT)
148+
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT+ "." + METRICS_PROPERTY_NAME + "1")
148149
.param(METRICS_TAG_LABEL, PROPERTY_1_LABEL))
149150
.andExpect(jsonPath("$.measurements[0].value").value(0));
150151

@@ -156,15 +157,15 @@ void testPropertyMultiGaugeMetrics() throws Exception {
156157
"testOwner",
157158
testProperties.stream()
158159
.map(p -> new Property(p.getName(), p.getOwner(), p.getName() + "Value"))
159-
.collect(Collectors.toList()),
160+
.toList(),
160161
testTags);
161162
channelRepository.save(testChannel);
162163

163164
await().untilAsserted(() -> {
164-
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT)
165+
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT+ "." + METRICS_PROPERTY_NAME + "0")
165166
.param(METRICS_TAG_LABEL, PROPERTY_0_LABEL))
166167
.andExpect(jsonPath("$.measurements[0].value").value(1));
167-
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT)
168+
mockMvc.perform(get(METRICS_ENDPOINT + MetricsService.CF_CHANNEL_COUNT+ "." + METRICS_PROPERTY_NAME + "1")
168169
.param(METRICS_TAG_LABEL, PROPERTY_1_LABEL))
169170
.andExpect(jsonPath("$.measurements[0].value").value(1));
170171
});

src/test/resources/application_test.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,4 @@ aa.auto_pause=pvStatus,archive
107107
#actuator
108108
management.endpoints.web.exposure.include=prometheus, metrics, health, info
109109
metrics.tags=group4_10
110-
metrics.properties={{'group4', '10'}, {'group5', '10'}}
110+
metrics.properties=group4: 10; group5: 10

0 commit comments

Comments
 (0)