linked metrics-endpoint (#132)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #132 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
parent
7212c92fe2
commit
6464d6f1ec
@ -0,0 +1,44 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||||
|
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Endpoint(id="metric-links")
|
||||||
|
// BLOG: implement a custom Spring Actuator endpoint to view _clickable_ Spring Actuator (Micrometer) Metrics endpoints
|
||||||
|
// HOWTO: implement a custom Spring Actuator endpoint
|
||||||
|
public class CustomActuatorEndpoint {
|
||||||
|
|
||||||
|
private final RestTemplate restTemplate = new RestTemplate();
|
||||||
|
|
||||||
|
@ReadOperation
|
||||||
|
public String getMetricsLinks() {
|
||||||
|
final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();
|
||||||
|
final var metricsEndpoint = baseUrl + "/actuator/metrics";
|
||||||
|
|
||||||
|
final var response = restTemplate.getForObject(metricsEndpoint, ActuatorMetricsEndpointResource.class);
|
||||||
|
|
||||||
|
if (response == null || response.getNames() == null) {
|
||||||
|
throw new IllegalStateException("no metrics available");
|
||||||
|
}
|
||||||
|
return generateJsonLinksToMetricEndpoints(response, metricsEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateJsonLinksToMetricEndpoints(final ActuatorMetricsEndpointResource response, final String metricsEndpoint) {
|
||||||
|
final var links = response.getNames().stream()
|
||||||
|
.map(name -> "\"" + name + "\": \"" + metricsEndpoint + "/" + name + "\"")
|
||||||
|
.toList();
|
||||||
|
return "{\n" + String.join(",\n", links) + "\n}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static class ActuatorMetricsEndpointResource {
|
||||||
|
private List<String> names;
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,8 @@ management:
|
|||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: info, health, metrics
|
# HOWTO: view _clickable_ Spring Actuator (Micrometer) Metrics endpoints: http://localhost:8081/actuator/metric-links
|
||||||
|
include: info, health, metrics, metric-links
|
||||||
observations:
|
observations:
|
||||||
annotations:
|
annotations:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
@ -16,6 +16,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService;
|
import net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -120,6 +121,7 @@ public class ArchitectureTest {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static final ArchRule configPackageRule = classes()
|
public static final ArchRule configPackageRule = classes()
|
||||||
.that().resideInAPackage("..config..")
|
.that().resideInAPackage("..config..")
|
||||||
|
.and().areNotAnnotatedWith(SpringBootTest.class)
|
||||||
.should().onlyDependOnClassesThat()
|
.should().onlyDependOnClassesThat()
|
||||||
.resideOutsideOfPackage(NET_HOSTSHARING_HSADMINNG);
|
.resideOutsideOfPackage(NET_HOSTSHARING_HSADMINNG);
|
||||||
|
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import io.restassured.RestAssured;
|
||||||
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
|
import net.hostsharing.hsadminng.test.DisableSecurityConfig;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.server.LocalManagementPort;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = { HsadminNgApplication.class, DisableSecurityConfig.class }
|
||||||
|
)
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
class CustomActuatorEndpointAcceptanceTest {
|
||||||
|
|
||||||
|
@LocalManagementPort
|
||||||
|
private Integer managementPort;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldListMetricLinks() {
|
||||||
|
RestAssured // @formatter:off
|
||||||
|
.given()
|
||||||
|
.port(managementPort)
|
||||||
|
.when()
|
||||||
|
.get("http://localhost/actuator/metric-links")
|
||||||
|
.then().log().all().assertThat()
|
||||||
|
.statusCode(200)
|
||||||
|
.contentType("application/vnd.spring-boot.actuator.v3+json")
|
||||||
|
.body("", lenientlyEquals("""
|
||||||
|
{
|
||||||
|
"application.ready.time": "http://localhost:%{managementPort}/actuator/metrics/application.ready.time",
|
||||||
|
"application.started.time": "http://localhost:%{managementPort}/actuator/metrics/application.started.time"
|
||||||
|
}
|
||||||
|
""".replace("%{managementPort}", managementPort.toString())));
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,7 +6,7 @@ management:
|
|||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: info, health, metrics
|
include: info, health, metrics, metric-links
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
sql:
|
sql:
|
||||||
|
Loading…
Reference in New Issue
Block a user