Remove ProjectGenerationMetricsListener

Fixes gh-809
This commit is contained in:
Madhura Bhave 2019-02-05 13:17:22 -08:00
parent 8a0d413a06
commit 857923b549
6 changed files with 2 additions and 567 deletions

View File

@ -1,46 +0,0 @@
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.initializr.actuate.autoconfigure;
import io.micrometer.core.instrument.MeterRegistry;
import io.spring.initializr.actuate.metric.ProjectGenerationMetricsListener;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} to handle the metrics of an initializr instance.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass(MeterRegistry.class)
@AutoConfigureAfter(CompositeMeterRegistryAutoConfiguration.class)
public class InitializrMetricsAutoConfiguration {
@Bean
@ConditionalOnSingleCandidate(MeterRegistry.class)
public ProjectGenerationMetricsListener metricsListener(MeterRegistry meterRegistry) {
return new ProjectGenerationMetricsListener(meterRegistry);
}
}

View File

@ -1,136 +0,0 @@
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.initializr.actuate.metric;
import java.util.List;
import io.micrometer.core.instrument.MeterRegistry;
import io.spring.initializr.generator.ProjectFailedEvent;
import io.spring.initializr.generator.ProjectGeneratedEvent;
import io.spring.initializr.generator.ProjectRequest;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.util.Agent;
import org.springframework.context.event.EventListener;
import org.springframework.util.StringUtils;
/**
* A {@link ProjectGeneratedEvent} listener that uses a {@link MeterRegistry} to update
* various project related metrics.
*
* @author Stephane Nicoll
*/
public class ProjectGenerationMetricsListener {
private final MeterRegistry meterRegistry;
public ProjectGenerationMetricsListener(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@EventListener
public void onGeneratedProject(ProjectGeneratedEvent event) {
handleProjectRequest(event.getProjectRequest());
}
@EventListener
public void onFailedProject(ProjectFailedEvent event) {
handleProjectRequest(event.getProjectRequest());
increment(key("failures"));
}
protected void handleProjectRequest(ProjectRequest request) {
increment(key("requests")); // Total number of requests
handleDependencies(request);
handleType(request);
handleJavaVersion(request);
handlePackaging(request);
handleLanguage(request);
handleBootVersion(request);
handleUserAgent(request);
}
protected void handleDependencies(ProjectRequest request) {
List<Dependency> dependencies = request.getResolvedDependencies();
if (dependencies != null) {
dependencies.forEach((it) -> {
if (!ProjectRequest.DEFAULT_STARTER.equals(it.getId())) {
String id = sanitize(it.getId());
increment(key("dependency." + id));
}
});
}
}
protected void handleType(ProjectRequest request) {
if (StringUtils.hasText(request.getType())) {
String type = sanitize(request.getType());
increment(key("type." + type));
}
}
protected void handleJavaVersion(ProjectRequest request) {
if (StringUtils.hasText(request.getJavaVersion())) {
String javaVersion = sanitize(request.getJavaVersion());
increment(key("java_version." + javaVersion));
}
}
protected void handlePackaging(ProjectRequest request) {
if (StringUtils.hasText(request.getPackaging())) {
String packaging = sanitize(request.getPackaging());
increment(key("packaging." + packaging));
}
}
protected void handleLanguage(ProjectRequest request) {
if (StringUtils.hasText(request.getLanguage())) {
String language = sanitize(request.getLanguage());
increment(key("language." + language));
}
}
protected void handleBootVersion(ProjectRequest request) {
if (StringUtils.hasText(request.getBootVersion())) {
String bootVersion = sanitize(request.getBootVersion());
increment(key("boot_version." + bootVersion));
}
}
protected void handleUserAgent(ProjectRequest request) {
String userAgent = (String) request.getParameters().get("user-agent");
if (userAgent != null) {
Agent agent = Agent.fromUserAgent(userAgent);
if (agent != null) {
increment(key("client_id." + agent.getId().getId()));
}
}
}
protected void increment(String key) {
this.meterRegistry.counter(key).increment();
}
protected String key(String part) {
return "initializr." + part;
}
protected String sanitize(String s) {
return s.replace(".", "_");
}
}

View File

@ -1,4 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.spring.initializr.actuate.autoconfigure.InitializrActuatorEndpointsAutoConfiguration,\
io.spring.initializr.actuate.autoconfigure.InitializrStatsAutoConfiguration,\
io.spring.initializr.actuate.autoconfigure.InitializrMetricsAutoConfiguration
io.spring.initializr.actuate.autoconfigure.InitializrStatsAutoConfiguration

View File

@ -16,10 +16,6 @@
package io.spring.initializr.actuate;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import io.spring.initializr.web.AbstractInitializrIntegrationTests.Config;
import org.junit.jupiter.api.Test;
@ -36,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Stephane Nicoll
*/
@ActiveProfiles("test-default")
@SpringBootTest(classes = Config.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = "management.endpoints.web.exposure.include=info,metrics")
@SpringBootTest(classes = Config.class, webEnvironment = WebEnvironment.RANDOM_PORT, properties = "management.endpoints.web.exposure.include=info")
class ActuatorIntegrationTests extends AbstractFullStackInitializrIntegrationTests {
@Test
@ -47,57 +43,4 @@ class ActuatorIntegrationTests extends AbstractFullStackInitializrIntegrationTes
assertThat(body).contains("\"version\":\"2.1.4.RELEASE\"");
}
@Test
void metricsAreRegistered() {
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa");
JsonNode result = metricsEndpoint();
JsonNode names = result.get("names");
List<String> metrics = new ArrayList<>();
for (JsonNode name : names) {
metrics.add(name.textValue());
}
assertThat(metrics).contains("initializr.requests", "initializr.packaging.jar",
"initializr.java_version.1_8", "initializr.dependency.web",
"initializr.dependency.data-jpa");
int requests = metricValue("initializr.requests");
int packaging = metricValue("initializr.packaging.jar");
int javaVersion = metricValue("initializr.java_version.1_8");
int webDependency = metricValue("initializr.dependency.web");
int jpaDependency = metricValue("initializr.dependency.data-jpa");
// No jpa dep this time
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web");
assertThat(metricValue("initializr.requests"))
.as("Number of request should have increased").isEqualTo(requests + 1);
assertThat(metricValue("initializr.packaging.jar"))
.as("jar packaging metric should have increased")
.isEqualTo(packaging + 1);
assertThat(metricValue("initializr.java_version.1_8"))
.as("java version metric should have increased")
.isEqualTo(javaVersion + 1);
assertThat(metricValue("initializr.dependency.web"))
.as("web dependency metric should have increased")
.isEqualTo(webDependency + 1);
assertThat(metricValue("initializr.dependency.data-jpa"))
.as("jpa dependency metric should not have increased")
.isEqualTo(jpaDependency);
}
private JsonNode metricsEndpoint() {
return parseJson(getRestTemplate().getForObject(createUrl("/actuator/metrics"),
String.class));
}
private int metricValue(String metric) {
JsonNode root = parseJson(getRestTemplate()
.getForObject(createUrl("/actuator/metrics/" + metric), String.class));
JsonNode measurements = root.get("measurements");
assertThat(measurements.isArray());
assertThat(measurements.size()).isEqualTo(1);
JsonNode measurement = measurements.get(0);
return measurement.get("value").intValue();
}
}

View File

@ -1,56 +0,0 @@
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.initializr.actuate.autoconfigure;
import io.micrometer.core.instrument.MeterRegistry;
import io.spring.initializr.actuate.metric.ProjectGenerationMetricsListener;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link InitializrMetricsAutoConfiguration}.
*
* @author Madhura Bhave
*/
class InitializrMetricsAutoConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class,
CompositeMeterRegistryAutoConfiguration.class,
InitializrMetricsAutoConfiguration.class));
@Test
void autoConfigRegistersProjectGenerationMetricsListenerBean() {
this.contextRunner.run((context) -> assertThat(context)
.hasSingleBean(ProjectGenerationMetricsListener.class));
}
@Test
void autoConfigConditionalOnMeterRegistryClass() {
this.contextRunner.withClassLoader(new FilteredClassLoader(MeterRegistry.class))
.run((context) -> assertThat(context)
.doesNotHaveBean(ProjectGenerationMetricsListener.class));
}
}

View File

@ -1,269 +0,0 @@
/*
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.initializr.actuate.metric;
import java.util.Arrays;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.spring.initializr.actuate.test.MetricsAssert;
import io.spring.initializr.generator.ProjectFailedEvent;
import io.spring.initializr.generator.ProjectGeneratedEvent;
import io.spring.initializr.generator.ProjectRequest;
import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* @author Stephane Nicoll
*/
class ProjectGenerationMetricsListenerTests {
private InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
.addDependencyGroup("core", "web", "security", "spring-data").build();
private ProjectGenerationMetricsListener listener;
private MetricsAssert metricsAssert;
@BeforeEach
public void setup() {
SimpleMeterRegistry meterRegistry = new SimpleMeterRegistry();
this.listener = new ProjectGenerationMetricsListener(meterRegistry);
this.metricsAssert = new MetricsAssert(meterRegistry);
}
@Test
void projectGenerationCount() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.requests");
}
@Test
void projectGenerationCountWithFailure() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectFailedEvent(request);
this.metricsAssert.hasValue(1, "initializr.requests");
this.metricsAssert.hasValue(1, "initializr.failures");
}
@Test
void dependencies() {
ProjectRequest request = initialize();
request.getStyle().addAll(Arrays.asList("security", "spring-data"));
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.dependency.security",
"initializr.dependency.spring-data");
}
@Test
void noDependencies() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasNoValue("initializr.dependency.");
}
@Test
void resolvedWebDependency() {
ProjectRequest request = initialize();
request.getStyle().add("spring-data");
request.setPackaging("war");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.dependency.web",
"initializr.dependency.spring-data");
}
@Test
void aliasedDependencyUseStandardId() {
Dependency dependency = new Dependency();
dependency.setId("foo");
dependency.getAliases().add("foo-old");
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
.addDependencyGroup("core", dependency).build();
ProjectRequest request = new ProjectRequest();
request.initialize(metadata);
request.getStyle().add("foo-old");
request.resolve(metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.dependency.foo"); // standard id is
// used
}
@Test
void defaultType() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.type.maven-project");
}
@Test
void explicitType() {
ProjectRequest request = initialize();
request.setType("gradle-build");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.type.gradle-build");
}
@Test
void defaultPackaging() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.packaging.jar");
}
@Test
void explicitPackaging() {
ProjectRequest request = initialize();
request.setPackaging("war");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.packaging.war");
}
@Test
void defaultJavaVersion() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.java_version.1_8");
}
@Test
void explicitJavaVersion() {
ProjectRequest request = initialize();
request.setJavaVersion("1.7");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.java_version.1_7");
}
@Test
void defaultLanguage() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.language.java");
}
@Test
void explicitGroovyLanguage() {
ProjectRequest request = initialize();
request.setLanguage("groovy");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.language.groovy");
}
@Test
void explicitKotlinLanguage() {
ProjectRequest request = initialize();
request.setLanguage("kotlin");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.language.kotlin");
}
@Test
void defaultBootVersion() {
ProjectRequest request = initialize();
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.boot_version.2_1_1_RELEASE");
}
@Test
void explicitBootVersion() {
ProjectRequest request = initialize();
request.setBootVersion("1.5.17.RELEASE");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.boot_version.1_5_17_RELEASE");
}
@Test
void userAgentAvailable() {
ProjectRequest request = initialize();
request.getParameters().put("user-agent", "HTTPie/0.9.2");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.client_id.httpie");
}
@Test
void collectAllMetrics() {
ProjectRequest request = initialize();
request.getStyle().addAll(Arrays.asList("web", "security"));
request.setType("gradle-project");
request.setPackaging("jar");
request.setJavaVersion("1.6");
request.setLanguage("groovy");
request.setBootVersion("1.5.17.RELEASE");
request.getParameters().put("user-agent", "SpringBootCli/1.3.0.RELEASE");
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.requests", "initializr.dependency.web",
"initializr.dependency.security", "initializr.type.gradle-project",
"initializr.packaging.jar", "initializr.java_version.1_6",
"initializr.language.groovy", "initializr.boot_version.1_5_17_RELEASE",
"initializr.client_id.spring").metricsCount(9);
}
@Test
void incrementMetrics() {
ProjectRequest request = initialize();
request.getStyle().addAll(Arrays.asList("security", "spring-data"));
request.resolve(this.metadata);
fireProjectGeneratedEvent(request);
this.metricsAssert.hasValue(1, "initializr.requests",
"initializr.dependency.security", "initializr.dependency.spring-data");
ProjectRequest anotherRequest = initialize();
anotherRequest.getStyle().addAll(Arrays.asList("web", "spring-data"));
anotherRequest.resolve(this.metadata);
fireProjectGeneratedEvent(anotherRequest);
this.metricsAssert.hasValue(2, "initializr.dependency.spring-data",
"initializr.dependency.spring-data");
this.metricsAssert.hasValue(1, "initializr.dependency.web",
"initializr.dependency.security");
}
private void fireProjectGeneratedEvent(ProjectRequest projectRequest) {
this.listener.onGeneratedProject(new ProjectGeneratedEvent(projectRequest));
}
private void fireProjectFailedEvent(ProjectRequest projectRequest) {
this.listener.onFailedProject(new ProjectFailedEvent(projectRequest, null));
}
private ProjectRequest initialize() {
ProjectRequest request = new ProjectRequest();
request.initialize(this.metadata);
return request;
}
}