Polish "Add startup time metrics"

See gh-27878
This commit is contained in:
Phillip Webb
2021-09-21 13:38:46 -07:00
parent c9dc40a465
commit 98a0e07dd5
15 changed files with 148 additions and 152 deletions

View File

@@ -36,9 +36,10 @@ import org.springframework.context.event.SmartApplicationListener;
* {@link ApplicationReadyEvent}.
*
* @author Chris Bono
* @author Phillip Webb
* @since 2.6.0
*/
public class StartupTimeMetrics implements SmartApplicationListener {
public class StartupTimeMetricsListener implements SmartApplicationListener {
/**
* The default name to use for the application started time metric.
@@ -52,11 +53,11 @@ public class StartupTimeMetrics implements SmartApplicationListener {
private final MeterRegistry meterRegistry;
private final String applicationStartedTimeMetricName;
private final String startedTimeMetricName;
private final String applicationReadyTimeMetricName;
private final String readyTimeMetricName;
private final Iterable<Tag> tags;
private final Tags tags;
/**
* Create a new instance using default metric names.
@@ -64,26 +65,25 @@ public class StartupTimeMetrics implements SmartApplicationListener {
* @see #APPLICATION_STARTED_TIME_METRIC_NAME
* @see #APPLICATION_READY_TIME_METRIC_NAME
*/
public StartupTimeMetrics(MeterRegistry meterRegistry) {
this(meterRegistry, Collections.emptyList(), APPLICATION_STARTED_TIME_METRIC_NAME,
APPLICATION_READY_TIME_METRIC_NAME);
public StartupTimeMetricsListener(MeterRegistry meterRegistry) {
this(meterRegistry, APPLICATION_STARTED_TIME_METRIC_NAME, APPLICATION_READY_TIME_METRIC_NAME,
Collections.emptyList());
}
/**
* Create a new instance using the specified options.
* @param meterRegistry the registry to use
* @param startedTimeMetricName the name to use for the application started time
* metric
* @param readyTimeMetricName the name to use for the application ready time metric
* @param tags the tags to associate to application startup metrics
* @param applicationStartedTimeMetricName the name to use for the application started
* time metric
* @param applicationReadyTimeMetricName the name to use for the application ready
* time metric
*/
public StartupTimeMetrics(MeterRegistry meterRegistry, Iterable<Tag> tags, String applicationStartedTimeMetricName,
String applicationReadyTimeMetricName) {
public StartupTimeMetricsListener(MeterRegistry meterRegistry, String startedTimeMetricName,
String readyTimeMetricName, Iterable<Tag> tags) {
this.meterRegistry = meterRegistry;
this.tags = (tags != null) ? tags : Collections.emptyList();
this.applicationStartedTimeMetricName = applicationStartedTimeMetricName;
this.applicationReadyTimeMetricName = applicationReadyTimeMetricName;
this.startedTimeMetricName = startedTimeMetricName;
this.readyTimeMetricName = readyTimeMetricName;
this.tags = Tags.of(tags);
}
@Override
@@ -103,33 +103,27 @@ public class StartupTimeMetrics implements SmartApplicationListener {
}
private void onApplicationStarted(ApplicationStartedEvent event) {
if (event.getStartedTime() == null) {
return;
}
registerGauge(this.applicationStartedTimeMetricName, "Time taken (ms) to start the application",
event.getStartedTime(), createTagsFrom(event.getSpringApplication()));
registerGauge(this.startedTimeMetricName, "Time taken (ms) to start the application", event.getTimeTaken(),
event.getSpringApplication());
}
private void onApplicationReady(ApplicationReadyEvent event) {
if (event.getReadyTime() == null) {
return;
}
registerGauge(this.applicationReadyTimeMetricName,
"Time taken (ms) for the application to be ready to service requests", event.getReadyTime(),
createTagsFrom(event.getSpringApplication()));
registerGauge(this.readyTimeMetricName, "Time taken (ms) for the application to be ready to service requests",
event.getTimeTaken(), event.getSpringApplication());
}
private void registerGauge(String metricName, String description, Duration time, Iterable<Tag> tags) {
TimeGauge.builder(metricName, time::toMillis, TimeUnit.MILLISECONDS).tags(tags).description(description)
.register(this.meterRegistry);
private void registerGauge(String name, String description, Duration timeTaken,
SpringApplication springApplication) {
if (timeTaken != null) {
Iterable<Tag> tags = createTagsFrom(springApplication);
TimeGauge.builder(name, timeTaken::toMillis, TimeUnit.MILLISECONDS).tags(tags).description(description)
.register(this.meterRegistry);
}
}
private Iterable<Tag> createTagsFrom(SpringApplication springApplication) {
Class<?> mainClass = springApplication.getMainApplicationClass();
if (mainClass == null) {
return this.tags;
}
return Tags.concat(this.tags, "main-application-class", mainClass.getName());
return (mainClass != null) ? this.tags.and("main-application-class", mainClass.getName()) : this.tags;
}
}

View File

@@ -35,26 +35,26 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link StartupTimeMetrics}.
* Tests for {@link StartupTimeMetricsListener}.
*
* @author Chris Bono
*/
class StartupTimeMetricsTests {
class StartupTimeMetricsListenerTests {
private MeterRegistry registry;
private StartupTimeMetrics metrics;
private StartupTimeMetricsListener listener;
@BeforeEach
void setup() {
this.registry = new SimpleMeterRegistry();
this.metrics = new StartupTimeMetrics(this.registry);
this.listener = new StartupTimeMetricsListener(this.registry);
}
@Test
void metricsRecordedWithoutCustomTags() {
this.metrics.onApplicationEvent(applicationStartedEvent(2000L));
this.metrics.onApplicationEvent(applicationReadyEvent(2200L));
this.listener.onApplicationEvent(applicationStartedEvent(2000L));
this.listener.onApplicationEvent(applicationReadyEvent(2200L));
assertMetricExistsWithValue("application.started.time", 2000L);
assertMetricExistsWithValue("application.ready.time", 2200L);
}
@@ -62,9 +62,9 @@ class StartupTimeMetricsTests {
@Test
void metricsRecordedWithCustomTagsAndMetricNames() {
Tags tags = Tags.of("foo", "bar");
this.metrics = new StartupTimeMetrics(this.registry, tags, "m1", "m2");
this.metrics.onApplicationEvent(applicationStartedEvent(1000L));
this.metrics.onApplicationEvent(applicationReadyEvent(1050L));
this.listener = new StartupTimeMetricsListener(this.registry, "m1", "m2", tags);
this.listener.onApplicationEvent(applicationStartedEvent(1000L));
this.listener.onApplicationEvent(applicationReadyEvent(1050L));
assertMetricExistsWithCustomTagsAndValue("m1", tags, 1000L);
assertMetricExistsWithCustomTagsAndValue("m2", tags, 1050L);
}
@@ -72,7 +72,7 @@ class StartupTimeMetricsTests {
@Test
void metricRecordedWithoutMainAppClassTag() {
SpringApplication application = mock(SpringApplication.class);
this.metrics.onApplicationEvent(new ApplicationStartedEvent(application, null, null, Duration.ofSeconds(2)));
this.listener.onApplicationEvent(new ApplicationStartedEvent(application, null, null, Duration.ofSeconds(2)));
TimeGauge applicationStartedGague = this.registry.find("application.started.time").timeGauge();
assertThat(applicationStartedGague).isNotNull();
assertThat(applicationStartedGague.getId().getTags()).isEmpty();
@@ -82,8 +82,8 @@ class StartupTimeMetricsTests {
void metricRecordedWithoutMainAppClassTagAndAdditionalTags() {
SpringApplication application = mock(SpringApplication.class);
Tags tags = Tags.of("foo", "bar");
this.metrics = new StartupTimeMetrics(this.registry, tags, "started", "ready");
this.metrics.onApplicationEvent(new ApplicationReadyEvent(application, null, null, Duration.ofSeconds(2)));
this.listener = new StartupTimeMetricsListener(this.registry, "started", "ready", tags);
this.listener.onApplicationEvent(new ApplicationReadyEvent(application, null, null, Duration.ofSeconds(2)));
TimeGauge applicationReadyGague = this.registry.find("ready").timeGauge();
assertThat(applicationReadyGague).isNotNull();
assertThat(applicationReadyGague.getId().getTags()).containsExactlyElementsOf(tags);
@@ -91,8 +91,8 @@ class StartupTimeMetricsTests {
@Test
void metricsNotRecordedWhenStartupTimeNotAvailable() {
this.metrics.onApplicationEvent(applicationStartedEvent(null));
this.metrics.onApplicationEvent(applicationReadyEvent(null));
this.listener.onApplicationEvent(applicationStartedEvent(null));
this.listener.onApplicationEvent(applicationReadyEvent(null));
assertThat(this.registry.find("application.started.time").timeGauge()).isNull();
assertThat(this.registry.find("application.ready.time").timeGauge()).isNull();
}