Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Provide custom MetricTags during runtime #111

Merged
merged 2 commits into from
May 31, 2024
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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,20 @@ public class ViolationExclusionsExample implements ViolationExclusions {
}
```

### Provide metric tags at runtime
Sometimes you want to generate your own metric tags based on the violation.
This can be achieved as demonstrated in the following snippet.

```java
@Component
public class MetricTagProviderExample implements MetricTagProvider {
@Override
public List<MetricTag> getTagsForViolation(OpenApiViolation violation) {
return List.of(new MetricTag("rule", violation.getRule()));
}
}
```

## Examples
Run examples with `./gradlew :examples:example-spring-boot-starter-web:bootRun` or `./gradlew :examples:example-spring-boot-starter-webflux:bootRun`.

Expand Down
9 changes: 8 additions & 1 deletion examples/example-spring-boot-starter-web/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ plugins {
dependencies {
implementation project(':examples:examples-common')
implementation project(':spring-boot-starter:spring-boot-starter-web')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
exclude group: 'io.undertow', module: 'undertow-websockets-jsr'
}

implementation 'org.springframework.boot:spring-boot-starter-undertow'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.hibernate.validator:hibernate-validator'

implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation(libs.openapi.tools.jacksonDatabindNullable)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.getyourguide.openapi.validation.api.metrics;

import com.getyourguide.openapi.validation.api.model.OpenApiViolation;
import java.util.List;

public interface MetricTagProvider {
List<MetricTag> getTagsForViolation(OpenApiViolation violation);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.getyourguide.openapi.validation.api.metrics;

import com.getyourguide.openapi.validation.api.model.OpenApiViolation;
import java.util.List;

public class NullMetricTagProvider implements MetricTagProvider {
@Override
public List<MetricTag> getTagsForViolation(OpenApiViolation violation) {
return List.of();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.getyourguide.openapi.validation.api.metrics;
package com.getyourguide.openapi.validation.core.metrics;

import com.getyourguide.openapi.validation.api.log.LogLevel;
import com.getyourguide.openapi.validation.api.metrics.MetricTag;
import com.getyourguide.openapi.validation.api.metrics.MetricTagProvider;
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
import com.getyourguide.openapi.validation.api.model.OpenApiViolation;
import java.util.ArrayList;
Expand All @@ -13,6 +16,7 @@
public class DefaultMetricsReporter implements MetricsReporter {

private final MetricsClient metricsClient;
private final MetricTagProvider metricTagProvider;
private final Configuration configuration;

@Override
Expand Down Expand Up @@ -49,7 +53,8 @@ private MetricTag[] createTagsForViolation(OpenApiViolation violation) {
violation.getResponseStatus()
.ifPresent(responseStatus -> tags.add(new MetricTag("status", responseStatus.toString())));

addAdditionalTags(tags);
tags.addAll(getMetricTagsFromConfiguration());
tags.addAll(metricTagProvider.getTagsForViolation(violation));

return tags.toArray(MetricTag[]::new);
}
Expand All @@ -64,15 +69,16 @@ private MetricTag[] createTagsForStartup(
tags.add(new MetricTag("validation_enabled", String.valueOf(isValidationEnabled)));
tags.add(new MetricTag("sample_rate", String.valueOf(sampleRate)));
tags.add(new MetricTag("throttling", String.valueOf(validationReportThrottleWaitSeconds)));
addAdditionalTags(tags);
tags.addAll(getMetricTagsFromConfiguration());

return tags.toArray(MetricTag[]::new);
}

private void addAdditionalTags(ArrayList<MetricTag> tags) {
private List<MetricTag> getMetricTagsFromConfiguration() {
if (configuration.getMetricAdditionalTags() != null) {
tags.addAll(configuration.getMetricAdditionalTags());
return configuration.getMetricAdditionalTags();
}
return List.of();
}

@Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
import com.getyourguide.openapi.validation.api.log.NoOpLoggerExtension;
import com.getyourguide.openapi.validation.api.log.OpenApiViolationHandler;
import com.getyourguide.openapi.validation.api.log.ViolationLogger;
import com.getyourguide.openapi.validation.api.metrics.DefaultMetricsReporter;
import com.getyourguide.openapi.validation.api.metrics.MetricTagProvider;
import com.getyourguide.openapi.validation.api.metrics.MetricsReporter;
import com.getyourguide.openapi.validation.api.metrics.NullMetricTagProvider;
import com.getyourguide.openapi.validation.api.metrics.client.MetricsClient;
import com.getyourguide.openapi.validation.api.metrics.client.NoOpMetricsClient;
import com.getyourguide.openapi.validation.api.model.ValidatorConfiguration;
Expand All @@ -22,6 +23,7 @@
import com.getyourguide.openapi.validation.core.log.ExclusionsOpenApiViolationHandler;
import com.getyourguide.openapi.validation.core.log.ThrottlingOpenApiViolationHandler;
import com.getyourguide.openapi.validation.core.mapper.ValidationReportToOpenApiViolationsMapper;
import com.getyourguide.openapi.validation.core.metrics.DefaultMetricsReporter;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
Expand Down Expand Up @@ -49,12 +51,16 @@ public ViolationLogger violationLogger(Optional<LoggerExtension> loggerExtension

@Bean
@ConditionalOnMissingBean
public MetricsReporter metricsReporter(Optional<MetricsClient> metricsClient) {
public MetricsReporter metricsReporter(
Optional<MetricsClient> metricsClient,
Optional<MetricTagProvider> metricTagProvider
) {
var metricName = properties.getValidationReportMetricName() != null
? properties.getValidationReportMetricName()
: DEFAULT_METRIC_NAME;
return new DefaultMetricsReporter(
metricsClient.orElseGet(NoOpMetricsClient::new),
metricTagProvider.orElseGet(NullMetricTagProvider::new),
DefaultMetricsReporter.Configuration.builder()
.metricName(metricName)
.metricAdditionalTags(properties.getValidationReportMetricAdditionalTags())
Expand Down
Loading