Merge pull request #27878 from bono007
* pr/27878: Polish "Add startup time metrics" Add startup time metrics Closes gh-27878pull/28064/head
commit
ce95e09308
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2021 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
|
||||||
|
*
|
||||||
|
* https://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 org.springframework.boot.actuate.autoconfigure.metrics.startup;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
|
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||||
|
import org.springframework.boot.actuate.metrics.startup.StartupTimeMetrics;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EnableAutoConfiguration Auto-configuration} for startup time metrics.
|
||||||
|
*
|
||||||
|
* @author Chris Bono
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@AutoConfigureAfter({ MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class })
|
||||||
|
@ConditionalOnClass(MeterRegistry.class)
|
||||||
|
@ConditionalOnBean(MeterRegistry.class)
|
||||||
|
public class StartupTimeMetricsAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public StartupTimeMetrics startupTimeMetrics(MeterRegistry meterRegistry) {
|
||||||
|
return new StartupTimeMetrics(meterRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2021 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
|
||||||
|
*
|
||||||
|
* https://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-configuration for actuator startup time metrics.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.actuate.autoconfigure.metrics.startup;
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2021 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
|
||||||
|
*
|
||||||
|
* https://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 org.springframework.boot.actuate.autoconfigure.metrics.startup;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.TimeGauge;
|
||||||
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
|
||||||
|
import org.springframework.boot.actuate.metrics.startup.StartupTimeMetrics;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link StartupTimeMetricsAutoConfiguration}.
|
||||||
|
*
|
||||||
|
* @author Chris Bono
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
class StartupTimeMetricsAutoConfigurationTests {
|
||||||
|
|
||||||
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple())
|
||||||
|
.withConfiguration(AutoConfigurations.of(StartupTimeMetricsAutoConfiguration.class));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void startupTimeMetricsAreRecorded() {
|
||||||
|
this.contextRunner.run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(StartupTimeMetrics.class);
|
||||||
|
SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class);
|
||||||
|
context.publishEvent(new ApplicationStartedEvent(new SpringApplication(), null,
|
||||||
|
context.getSourceApplicationContext(), Duration.ofMillis(1500)));
|
||||||
|
TimeGauge startedTimeGage = registry.find("application.started.time").timeGauge();
|
||||||
|
assertThat(startedTimeGage).isNotNull();
|
||||||
|
assertThat(startedTimeGage.value(TimeUnit.MILLISECONDS)).isEqualTo(1500L);
|
||||||
|
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), null,
|
||||||
|
context.getSourceApplicationContext(), Duration.ofMillis(2000)));
|
||||||
|
TimeGauge readyTimeGage = registry.find("application.ready.time").timeGauge();
|
||||||
|
assertThat(readyTimeGage).isNotNull();
|
||||||
|
assertThat(readyTimeGage.value(TimeUnit.MILLISECONDS)).isEqualTo(2000L);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void startupTimeMetricsCanBeDisabled() {
|
||||||
|
this.contextRunner.withPropertyValues("management.metrics.enable.application.started.time:false",
|
||||||
|
"management.metrics.enable.application.ready.time:false").run((context) -> {
|
||||||
|
context.publishEvent(new ApplicationStartedEvent(new SpringApplication(), null,
|
||||||
|
context.getSourceApplicationContext(), Duration.ofMillis(2500)));
|
||||||
|
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), null,
|
||||||
|
context.getSourceApplicationContext(), Duration.ofMillis(3000)));
|
||||||
|
SimpleMeterRegistry registry = context.getBean(SimpleMeterRegistry.class);
|
||||||
|
assertThat(registry.find("application.started.time").timeGauge()).isNull();
|
||||||
|
assertThat(registry.find("application.ready.time").timeGauge()).isNull();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void customStartupTimeMetricsAreRespected() {
|
||||||
|
this.contextRunner
|
||||||
|
.withBean("customStartupTimeMetrics", StartupTimeMetrics.class, () -> mock(StartupTimeMetrics.class))
|
||||||
|
.run((context) -> assertThat(context).hasSingleBean(StartupTimeMetrics.class)
|
||||||
|
.hasBean("customStartupTimeMetrics"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2021 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
|
||||||
|
*
|
||||||
|
* https://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 org.springframework.boot.actuate.metrics.startup;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
|
import io.micrometer.core.instrument.Tag;
|
||||||
|
import io.micrometer.core.instrument.Tags;
|
||||||
|
import io.micrometer.core.instrument.TimeGauge;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.context.event.SmartApplicationListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds application startup metrics in response to {@link ApplicationStartedEvent} and
|
||||||
|
* {@link ApplicationReadyEvent}.
|
||||||
|
*
|
||||||
|
* @author Chris Bono
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
public class StartupTimeMetrics implements SmartApplicationListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default name to use for the application started time metric.
|
||||||
|
*/
|
||||||
|
public static final String APPLICATION_STARTED_TIME_METRIC_NAME = "application.started.time";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default name to use for the application ready time metric.
|
||||||
|
*/
|
||||||
|
public static final String APPLICATION_READY_TIME_METRIC_NAME = "application.ready.time";
|
||||||
|
|
||||||
|
private final MeterRegistry meterRegistry;
|
||||||
|
|
||||||
|
private final String applicationStartedTimeMetricName;
|
||||||
|
|
||||||
|
private final String applicationReadyTimeMetricName;
|
||||||
|
|
||||||
|
private final Iterable<Tag> tags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance using default metric names.
|
||||||
|
* @param meterRegistry the registry to use
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance using the specified options.
|
||||||
|
* @param meterRegistry the registry to use
|
||||||
|
* @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) {
|
||||||
|
this.meterRegistry = meterRegistry;
|
||||||
|
this.tags = (tags != null) ? tags : Collections.emptyList();
|
||||||
|
this.applicationStartedTimeMetricName = applicationStartedTimeMetricName;
|
||||||
|
this.applicationReadyTimeMetricName = applicationReadyTimeMetricName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||||
|
return ApplicationStartedEvent.class.isAssignableFrom(eventType)
|
||||||
|
|| ApplicationReadyEvent.class.isAssignableFrom(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationEvent event) {
|
||||||
|
if (event instanceof ApplicationStartedEvent) {
|
||||||
|
onApplicationStarted((ApplicationStartedEvent) event);
|
||||||
|
}
|
||||||
|
if (event instanceof ApplicationReadyEvent) {
|
||||||
|
onApplicationReady((ApplicationReadyEvent) event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onApplicationReady(ApplicationReadyEvent event) {
|
||||||
|
if (event.getReadyTime() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
registerGauge(this.applicationReadyTimeMetricName,
|
||||||
|
"Time taken (ms) for the application to be ready to serve requests", event.getReadyTime(),
|
||||||
|
createTagsFrom(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 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2021 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
|
||||||
|
*
|
||||||
|
* https://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actuator support for startup metrics.
|
||||||
|
*/
|
||||||
|
package org.springframework.boot.actuate.metrics.startup;
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2021 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
|
||||||
|
*
|
||||||
|
* https://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 org.springframework.boot.actuate.metrics.startup;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
|
import io.micrometer.core.instrument.Tags;
|
||||||
|
import io.micrometer.core.instrument.TimeGauge;
|
||||||
|
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link StartupTimeMetrics}.
|
||||||
|
*
|
||||||
|
* @author Chris Bono
|
||||||
|
*/
|
||||||
|
class StartupTimeMetricsTests {
|
||||||
|
|
||||||
|
private MeterRegistry registry;
|
||||||
|
|
||||||
|
private StartupTimeMetrics metrics;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
this.registry = new SimpleMeterRegistry();
|
||||||
|
this.metrics = new StartupTimeMetrics(this.registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void metricsRecordedWithoutCustomTags() {
|
||||||
|
this.metrics.onApplicationEvent(applicationStartedEvent(2000L));
|
||||||
|
this.metrics.onApplicationEvent(applicationReadyEvent(2200L));
|
||||||
|
assertMetricExistsWithValue("application.started.time", 2000L);
|
||||||
|
assertMetricExistsWithValue("application.ready.time", 2200L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
assertMetricExistsWithCustomTagsAndValue("m1", tags, 1000L);
|
||||||
|
assertMetricExistsWithCustomTagsAndValue("m2", tags, 1050L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void metricRecordedWithoutMainAppClassTag() {
|
||||||
|
SpringApplication application = mock(SpringApplication.class);
|
||||||
|
this.metrics.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
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)));
|
||||||
|
TimeGauge applicationReadyGague = this.registry.find("ready").timeGauge();
|
||||||
|
assertThat(applicationReadyGague).isNotNull();
|
||||||
|
assertThat(applicationReadyGague.getId().getTags()).containsExactlyElementsOf(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void metricsNotRecordedWhenStartupTimeNotAvailable() {
|
||||||
|
this.metrics.onApplicationEvent(applicationStartedEvent(null));
|
||||||
|
this.metrics.onApplicationEvent(applicationReadyEvent(null));
|
||||||
|
assertThat(this.registry.find("application.started.time").timeGauge()).isNull();
|
||||||
|
assertThat(this.registry.find("application.ready.time").timeGauge()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApplicationStartedEvent applicationStartedEvent(Long startupTimeMs) {
|
||||||
|
SpringApplication application = mock(SpringApplication.class);
|
||||||
|
doReturn(TestMainApplication.class).when(application).getMainApplicationClass();
|
||||||
|
return new ApplicationStartedEvent(application, null, null,
|
||||||
|
(startupTimeMs != null) ? Duration.ofMillis(startupTimeMs) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApplicationReadyEvent applicationReadyEvent(Long startupTimeMs) {
|
||||||
|
SpringApplication application = mock(SpringApplication.class);
|
||||||
|
doReturn(TestMainApplication.class).when(application).getMainApplicationClass();
|
||||||
|
return new ApplicationReadyEvent(application, null, null,
|
||||||
|
(startupTimeMs != null) ? Duration.ofMillis(startupTimeMs) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertMetricExistsWithValue(String metricName, long expectedValueInMillis) {
|
||||||
|
assertMetricExistsWithCustomTagsAndValue(metricName, Tags.empty(), expectedValueInMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertMetricExistsWithCustomTagsAndValue(String metricName, Tags expectedCustomTags,
|
||||||
|
Long expectedValueInMillis) {
|
||||||
|
assertThat(this.registry.find(metricName)
|
||||||
|
.tags(Tags.concat(expectedCustomTags, "main-application-class", TestMainApplication.class.getName()))
|
||||||
|
.timeGauge()).isNotNull().extracting((m) -> m.value(TimeUnit.MILLISECONDS))
|
||||||
|
.isEqualTo(expectedValueInMillis.doubleValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestMainApplication {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue