From f41c63b8bce679313478fd77e394fe23fb6a5fee Mon Sep 17 00:00:00 2001 From: bono007 Date: Sat, 9 Jan 2021 09:58:02 -0600 Subject: [PATCH] Adds GET support for /actuator/startup Fixes gh-24666 --- .../src/docs/asciidoc/endpoints/startup.adoc | 4 +++- .../boot/actuate/startup/StartupEndpoint.java | 8 ++++++++ .../boot/actuate/startup/StartupEndpointTests.java | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/startup.adoc b/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/startup.adoc index 76ac18e2365c..a2d806b9e415 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/startup.adoc +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/docs/asciidoc/endpoints/startup.adoc @@ -16,7 +16,9 @@ The resulting response is similar to the following: include::{snippets}/startup/http-response.adoc[] - +NOTE: The above call resets the application startup steps buffer - subsequent calls to the endpoint will +not include the returned steps. To retrieve a snapshot of the steps recorded so far without removing them +from the startup buffer, make a `GET` request to `/actuator/startup`. [[startup-retrieving-response-structure]] === Response Structure diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java index 145d1d7317f5..9e8c802e401e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java @@ -18,6 +18,7 @@ import org.springframework.boot.SpringBootVersion; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.context.metrics.buffering.StartupTimeline; @@ -28,6 +29,7 @@ * application startup}. * * @author Brian Clozel + * @author Chris Bono * @since 2.4.0 */ @Endpoint(id = "startup") @@ -50,6 +52,12 @@ public StartupResponse startup() { return new StartupResponse(startupTimeline); } + @ReadOperation + public StartupResponse startupSnapshot() { + StartupTimeline startupTimeline = this.applicationStartup.getBufferedTimeline(); + return new StartupResponse(startupTimeline); + } + /** * A description of an application startup, primarily intended for serialization to * JSON. diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java index 5f9dcf6eb3fc..c33ab1e0af52 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java @@ -30,6 +30,7 @@ * Tests for {@link StartupEndpoint}. * * @author Brian Clozel + * @author Chris Bono */ class StartupEndpointTests { @@ -60,6 +61,19 @@ void bufferIsDrained() { }); } + @Test + void bufferIsNotDrained() { + BufferingApplicationStartup applicationStartup = new BufferingApplicationStartup(256); + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withInitializer((context) -> context.setApplicationStartup(applicationStartup)) + .withUserConfiguration(EndpointConfiguration.class); + contextRunner.run((context) -> { + StartupEndpoint.StartupResponse startup = context.getBean(StartupEndpoint.class).startupSnapshot(); + assertThat(startup.getTimeline().getEvents()).isNotEmpty(); + assertThat(applicationStartup.getBufferedTimeline().getEvents()).isNotEmpty(); + }); + } + @Configuration(proxyBeanMethods = false) static class EndpointConfiguration {