Skip to content

Commit 990e921

Browse files
authored
Refactor: Split up MetricsReporter into MetricsClient (#11)
1 parent 1dd0379 commit 990e921

File tree

18 files changed

+141
-105
lines changed

18 files changed

+141
-105
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ openapi.validation.excluded-headers[0]=User-Agent: .*(bingbot|googlebot).*
9797
openapi.validation.validation-report-throttle-wait-seconds=10
9898

9999
# Throttle the validation reporting (logs & metrics) to a maximum of 1 log/metric per 10 seconds.
100-
# Default is "openapi.validation.error".
101-
openapi.validation.validation-report-metric-name=openapi.violation
100+
# Default is "openapi.validation".
101+
openapi.validation.validation-report-metric-name=validation.openapi
102102

103103
# Add additional tags to be logged with metrics. They should be in the format {KEY}={VALUE},{KEY}={VALUE}
104104
# Default is no additional tags.
@@ -199,7 +199,7 @@ result in a violation error with log level `warn`.
199199

200200
```java
201201
@Configuration
202-
public class ValidatorConfiguration {
202+
public class OpenApiValidatorConfiguration {
203203
@Bean
204204
public ValidatorConfiguration buildValidatorConfiguration() {
205205
return new ValidatorConfigurationBuilder()

examples/example-spring-boot-starter-web-spring2.7/src/main/java/com/getyourguide/openapi/validation/example/configuration/ExampleConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package com.getyourguide.openapi.validation.example.configuration;
22

33
import com.getyourguide.openapi.validation.api.log.LoggerExtension;
4-
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
4+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
55
import com.getyourguide.openapi.validation.example.logging.ExampleLoggerExtension;
6-
import com.getyourguide.openapi.validation.metrics.LoggingMetricsReporter;
6+
import com.getyourguide.openapi.validation.metrics.client.LoggingMetricsClient;
77
import org.springframework.context.annotation.Bean;
88
import org.springframework.context.annotation.Configuration;
99

1010
@Configuration
1111
public class ExampleConfiguration {
1212
@Bean
13-
public MetricsReporter metricsReporter() {
14-
return new LoggingMetricsReporter();
13+
public MetricsClient metricsClient() {
14+
return new LoggingMetricsClient();
1515
}
1616

1717
@Bean

examples/example-spring-boot-starter-web/src/main/java/com/getyourguide/openapi/validation/example/configuration/ExampleConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package com.getyourguide.openapi.validation.example.configuration;
22

33
import com.getyourguide.openapi.validation.api.log.LoggerExtension;
4-
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
4+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
55
import com.getyourguide.openapi.validation.example.logging.ExampleLoggerExtension;
6-
import com.getyourguide.openapi.validation.metrics.LoggingMetricsReporter;
6+
import com.getyourguide.openapi.validation.metrics.client.LoggingMetricsClient;
77
import org.springframework.context.annotation.Bean;
88
import org.springframework.context.annotation.Configuration;
99

1010
@Configuration
1111
public class ExampleConfiguration {
1212
@Bean
13-
public MetricsReporter metricsReporter() {
14-
return new LoggingMetricsReporter();
13+
public MetricsClient metricsClient() {
14+
return new LoggingMetricsClient();
1515
}
1616

1717
@Bean

metrics-reporter/metrics-reporter-datadog-spring-boot/src/main/java/com/getyourguide/openapi/validation/metrics/datadog/autoconfigure/FallbackLibraryAutoConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.getyourguide.openapi.validation.metrics.datadog.autoconfigure;
22

3-
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
4-
import com.getyourguide.openapi.validation.metrics.datadog.StatsDClientMetricsReporter;
3+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
4+
import com.getyourguide.openapi.validation.metrics.datadog.client.StatsDClientMetricsClient;
55
import com.timgroup.statsd.StatsDClient;
66
import lombok.AllArgsConstructor;
77
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -18,8 +18,8 @@ public class FallbackLibraryAutoConfiguration {
1818
@Bean
1919
@ConditionalOnBean(StatsDClient.class)
2020
@ConditionalOnMissingBean
21-
public MetricsReporter metricsReporterStatsDClient(StatsDClient statsDClient) {
22-
return new StatsDClientMetricsReporter(statsDClient);
21+
public MetricsClient metricsClientStatsDClient(StatsDClient statsDClient) {
22+
return new StatsDClientMetricsClient(statsDClient);
2323
}
2424

2525
}

metrics-reporter/metrics-reporter-datadog-spring-boot/src/main/java/com/getyourguide/openapi/validation/metrics/datadog/autoconfigure/LibraryAutoConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
import static com.getyourguide.openapi.validation.metrics.datadog.OpenApiValidationDataDogMetricsApplicationProperties.PROPERTY_STATSD_SERVICE_HOST;
44
import static com.getyourguide.openapi.validation.metrics.datadog.OpenApiValidationDataDogMetricsApplicationProperties.PROPERTY_STATSD_SERVICE_PORT;
55

6-
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
6+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
77
import com.getyourguide.openapi.validation.metrics.datadog.OpenApiValidationDataDogMetricsApplicationProperties;
8-
import com.getyourguide.openapi.validation.metrics.datadog.StatsDClientMetricsReporter;
8+
import com.getyourguide.openapi.validation.metrics.datadog.client.StatsDClientMetricsClient;
99
import com.timgroup.statsd.NonBlockingStatsDClientBuilder;
1010
import lombok.AllArgsConstructor;
1111
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -23,12 +23,12 @@ public class LibraryAutoConfiguration {
2323
@Bean
2424
@ConditionalOnClass(name = "com.timgroup.statsd.StatsDClient")
2525
@ConditionalOnProperty({PROPERTY_STATSD_SERVICE_HOST, PROPERTY_STATSD_SERVICE_PORT})
26-
public MetricsReporter metricsReporterCustomStatsDClient() {
26+
public MetricsClient metricsClientCustomStatsDClient() {
2727
var statsDClient = new NonBlockingStatsDClientBuilder()
2828
.prefix(properties.getMetricPrefix())
2929
.hostname(properties.getStatsd().getService().getHost())
3030
.port(properties.getStatsd().getService().getPort())
3131
.build();
32-
return new StatsDClientMetricsReporter(statsDClient);
32+
return new StatsDClientMetricsClient(statsDClient);
3333
}
3434
}

metrics-reporter/metrics-reporter-datadog-spring-boot/src/test/java/com/getyourguide/openapi/validation/metrics/datadog/autoconfigure/LibraryAutoConfigurationMetricsLoggerTest.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import static org.assertj.core.api.Assertions.assertThat;
44
import static org.mockito.Mockito.mock;
55

6-
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
7-
import com.getyourguide.openapi.validation.metrics.datadog.StatsDClientMetricsReporter;
6+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
7+
import com.getyourguide.openapi.validation.metrics.datadog.client.StatsDClientMetricsClient;
88
import com.timgroup.statsd.StatsDClient;
99
import org.junit.jupiter.api.BeforeEach;
1010
import org.junit.jupiter.api.Test;
@@ -24,23 +24,23 @@ void setUp() {
2424
}
2525

2626
@Test
27-
void withDataDogPropertiesShouldCreateStatsDClientMetricsReporter() {
27+
void withDataDogPropertiesShouldCreateStatsDClientMetricsClient() {
2828
contextRunner
2929
.withPropertyValues(
3030
"openapi.validation.datadog.statsd.service.host=localhost",
3131
"openapi.validation.datadog.statsd.service.port=8125"
3232
)
3333
.run(context -> {
3434
assertThat(context)
35-
.hasSingleBean(MetricsReporter.class);
36-
assertThat(context.getBeansOfType(MetricsReporter.class))
37-
.extractingByKey("metricsReporterCustomStatsDClient")
38-
.isInstanceOf(StatsDClientMetricsReporter.class);
35+
.hasSingleBean(MetricsClient.class);
36+
assertThat(context.getBeansOfType(MetricsClient.class))
37+
.extractingByKey("metricsClientCustomStatsDClient")
38+
.isInstanceOf(StatsDClientMetricsClient.class);
3939
});
4040
}
4141

4242
@Test
43-
void withStatsDClientPropertiesAndExistingStatsDClientShouldCreateNewStatsDClientAndCreateStatsDClientMetricsReporter() {
43+
void withStatsDClientPropertiesAndExistingStatsDClientShouldCreateNewStatsDClientAndCreateStatsDClientMetricsClient() {
4444
contextRunner
4545
.withPropertyValues(
4646
"openapi.validation.datadog.statsd.service.host=localhost",
@@ -49,10 +49,10 @@ void withStatsDClientPropertiesAndExistingStatsDClientShouldCreateNewStatsDClien
4949
.withBean(StatsDClient.class, () -> mock(StatsDClient.class))
5050
.run(context -> {
5151
assertThat(context)
52-
.hasSingleBean(MetricsReporter.class);
53-
assertThat(context.getBeansOfType(MetricsReporter.class))
54-
.extractingByKey("metricsReporterCustomStatsDClient")
55-
.isInstanceOf(StatsDClientMetricsReporter.class);
52+
.hasSingleBean(MetricsClient.class);
53+
assertThat(context.getBeansOfType(MetricsClient.class))
54+
.extractingByKey("metricsClientCustomStatsDClient")
55+
.isInstanceOf(StatsDClientMetricsClient.class);
5656
});
5757
}
5858

@@ -63,10 +63,10 @@ void noPropertiesWithExistingStatsDClientBean() {
6363
.withBean(StatsDClient.class, () -> mock(StatsDClient.class))
6464
.run(context -> {
6565
assertThat(context)
66-
.hasSingleBean(MetricsReporter.class);
67-
assertThat(context.getBeansOfType(MetricsReporter.class))
68-
.extractingByKey("metricsReporterStatsDClient")
69-
.isInstanceOf(StatsDClientMetricsReporter.class);
66+
.hasSingleBean(MetricsClient.class);
67+
assertThat(context.getBeansOfType(MetricsClient.class))
68+
.extractingByKey("metricsClientStatsDClient")
69+
.isInstanceOf(StatsDClientMetricsClient.class);
7070
});
7171
}
7272

@@ -75,7 +75,7 @@ void noPropertiesWithoutExistingStatsDClientBean() {
7575
contextRunner
7676
.run(context -> {
7777
assertThat(context)
78-
.doesNotHaveBean(MetricsReporter.class);
78+
.doesNotHaveBean(MetricsClient.class);
7979
});
8080
}
8181
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
package com.getyourguide.openapi.validation.metrics.datadog;
1+
package com.getyourguide.openapi.validation.metrics.datadog.client;
22

33
import com.getyourguide.openapi.validation.api.metrics.MetricTag;
4-
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
4+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
55
import com.timgroup.statsd.StatsDClient;
66
import java.util.Arrays;
77
import java.util.Optional;
8+
import lombok.AllArgsConstructor;
89

9-
public class StatsDClientMetricsReporter implements MetricsReporter {
10+
@AllArgsConstructor
11+
public class StatsDClientMetricsClient implements MetricsClient {
1012
private final StatsDClient statsDClient;
1113

12-
public StatsDClientMetricsReporter(StatsDClient statsDClient) {
13-
this.statsDClient = statsDClient;
14-
}
15-
1614
@Override
1715
public void increment(String aspect, MetricTag... tags) {
1816
statsDClient.increment(aspect, mapTags(tags));
1917
}
2018

2119
private static String[] mapTags(MetricTag[] tags) {
2220
return Optional.of(tags)
23-
.map(nonNullTags -> Arrays.stream(nonNullTags).map(tag -> tag.getKey() + ":" + tag.getValue()).toArray(String[]::new))
21+
.map(nonNullTags ->
22+
Arrays.stream(nonNullTags).map(tag -> tag.getKey() + ":" + tag.getValue()).toArray(String[]::new)
23+
)
2424
.orElse(new String[0]);
2525
}
2626
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.getyourguide.openapi.validation.api.metrics;
2+
3+
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
4+
import com.getyourguide.openapi.validation.api.model.OpenApiViolation;
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import lombok.AllArgsConstructor;
8+
import lombok.Builder;
9+
import lombok.Getter;
10+
11+
@AllArgsConstructor
12+
public class DefaultMetricsReporter implements MetricsReporter {
13+
14+
private final MetricsClient metricsClient;
15+
private final Configuration configuration;
16+
17+
@Override
18+
public void reportViolation(OpenApiViolation violation) {
19+
var violationMetricName = configuration.getMetricName() + ".error";
20+
metricsClient.increment(violationMetricName, createTagsForViolation(violation));
21+
}
22+
23+
private MetricTag[] createTagsForViolation(OpenApiViolation violation) {
24+
var tags = new ArrayList<MetricTag>();
25+
26+
tags.add(new MetricTag("type", violation.getDirection().toString().toLowerCase()));
27+
tags.add(new MetricTag("method", violation.getRequestMetaData().getMethod().toLowerCase()));
28+
violation.getNormalizedPath().ifPresent(path -> tags.add(new MetricTag("path", path)));
29+
violation.getResponseStatus()
30+
.ifPresent(responseStatus -> tags.add(new MetricTag("status", responseStatus.toString())));
31+
32+
if (configuration.getMetricAdditionalTags() != null) {
33+
tags.addAll(configuration.getMetricAdditionalTags());
34+
}
35+
36+
return tags.toArray(MetricTag[]::new);
37+
}
38+
39+
@Builder
40+
@Getter
41+
public static class Configuration {
42+
private final String metricName;
43+
private final List<MetricTag> metricAdditionalTags;
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.getyourguide.openapi.validation.api.metrics;
22

3+
import com.getyourguide.openapi.validation.api.model.OpenApiViolation;
4+
35
public interface MetricsReporter {
4-
void increment(String aspect, MetricTag... tags);
6+
void reportViolation(OpenApiViolation violation);
57
}

openapi-validation-api/src/main/java/com/getyourguide/openapi/validation/api/metrics/NoOpMetricsReporter.java

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)