4

I am trying to set up Spring Actuator with existing Gradle Spring MVC project. I am not able to use @EnableAutoConfiguration. Unfortunately, I am not able to reach actuator endpoints, I think I am missing something.

The Spring dependencies in the project are:

// springVersion = 5.1.+
implementation(
            "org.springframework:spring-beans:$springVersion",
            "org.springframework:spring-webmvc:$springVersion",
            "org.springframework:spring-jdbc:$springVersion")

implementation 'org.springframework.boot:spring-boot-starter-actuator'

I am trying to configure project with following:

@Configuration
@Import({EndpointAutoConfiguration.class,
        MetricsEndpointAutoConfiguration.class,
        HealthEndpointAutoConfiguration.class,
        MappingsEndpointAutoConfiguration.class,
        InfoEndpointAutoConfiguration.class})
@EnableWebMvc
public class DI_App {

}

In properties file, I added:

management.endpoints.web.exposure.include=*

Non of actuator endpoints is enabled, I am getting 404 when trying to access them. I went through many related questions, but non of the solutions worked for me.

I might need to define custom EndpointHandlerMapping but not sure how to do this, it seems unavailable. (Ref: https://stackoverflow.com/a/53010693)


EDIT:
Currently, my app config looks like this:
@Configuration
@EnableWebMvc
@ComponentScan("com.test.springtest")
@Import({
        ConfigurationPropertiesReportEndpointAutoConfiguration.class,
        EndpointAutoConfiguration.class,
        WebEndpointAutoConfiguration.class,
        HealthEndpointAutoConfiguration.class,
        HealthIndicatorAutoConfiguration.class,
        InfoEndpointAutoConfiguration.class,
        InfoContributorAutoConfiguration.class,
        LogFileWebEndpointAutoConfiguration.class,
        LoggersEndpointAutoConfiguration.class,
        WebMvcMetricsAutoConfiguration.class,
        ManagementWebSecurityAutoConfiguration.class,
        ManagementContextAutoConfiguration.class,
        ServletManagementContextAutoConfiguration.class
})
public class DI_App {
    private final ApplicationContext _applicationContext;

    DI_App(ApplicationContext applicationContext) {
        _applicationContext = applicationContext;
        System.setProperty("management.endpoints.web.exposure.include", "*");
        System.setProperty("management.endpoints.jmx.exposure.exclude", "*");
        System.setProperty("management.endpoints.web.base-path", "/manage");
        System.setProperty("management.server.port", "10100");
    }

    @Bean
    public WebMvcEndpointHandlerMapping endpointHandlerMapping(Collection<ExposableWebEndpoint> endpoints) {
        List<String> mediaTypes = List.of(MediaType.APPLICATION_JSON_VALUE, ActuatorMediaType.V2_JSON);
        EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes, mediaTypes);
        WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(_applicationContext,
                new ConversionServiceParameterValueMapper(),
                endpointMediaTypes,
                List.of(EndpointId::toString),
                emptyList(),
                emptyList());

        return new WebMvcEndpointHandlerMapping(new EndpointMapping("/manage"),
                endpoints,
                endpointMediaTypes,
                new CorsConfiguration(),
                new EndpointLinksResolver(discoverer.getEndpoints()));
    }
}

I had to add dispatcherServlet bean, in order to be able to add ManagementContextAutoConfiguration.class to Imports:

@Component
public class AppDispatcherServlet implements DispatcherServletPath {
    @Override
    public String getPath() {
        return "/";
    }
}

Current state is that when going to /manage endpoint I get this:

{"_links":{"self":{"href":"http://localhost:10100/dev/manage","templated":false},"info":{"href":"http://localhost:10100/dev/manage/info","templated":false}}}

But http://localhost:10100/dev/manage/info returns 404 and no other endpoints are available.

Kamila
  • 371
  • 5
  • 13
  • 1
    You can check which configurations does the autoconfiguration process by checking the spring.factories file (https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories). I haven't checked which ones are missing, but `org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration` is one that exposes the web endpoint, so you will certainly need to import that. – helospark May 28 '19 at 10:44
  • Have you tried to add the artifact `spring-boot-actuator-autoconfigure` ? – mrkernelpanic May 28 '19 at 11:40
  • You must have the `compile("org.springframework.boot:spring-boot-starter-actuator")` in your dependecies. – Meziane May 28 '19 at 13:35
  • Did you checked this question? https://stackoverflow.com/questions/29953157/spring-boot-actuator-without-spring-boot – Dmytro Patserkovskyi May 28 '19 at 14:43
  • Adding `spring-boot-actuator-autoconfigure` directly made no difference, I do have `spring-boot-starter-actuator` in my build file. I also checked linked question - it relates to v1.x of Actuator, I need help with version 2 – Kamila May 28 '19 at 16:44
  • @shagrin Add `WebMvcEndpointManagementContextConfiguration.class` to the imports, and it will work. – helospark May 29 '19 at 10:55
  • @helospark I tried that, but then it was complaining about missing dispatcherServlet. Ended up with this: https://stackoverflow.com/questions/56359240/spring-boot-actuator-missing-loggers-and-logfile-endpoints and encountered new problems.. – Kamila May 29 '19 at 11:13
  • @shagrin I'm not sure, where the DispatcherServler is missing (MVC does not have as bean), however, have you tried to register the WebMvcEndpointHandlerMapping manually as `HandlerMapping`? Like the config: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.java The actuator should be working, it is not put behind your Spring MVC URL mappings, that is why you need to register the above HandlerMapping. – helospark May 29 '19 at 20:04
  • I'm getting an error that it can't autowire the `Collection endpoints` because there is more than one bean of Collection type. But I don't find another bean. – JensW Oct 16 '19 at 12:20

1 Answers1

1

I'm using Maven, not Gradle, but was in a similar situation. I had a working spring-boot-actuator 1.4.2.RELEASE Health actuator endpoint with Spring MVC 4.3.21. Upgraded to spring-boot-starter-actuator 2.6.1 and Spring MVC 5.3.13 and the following works for me to reach /myAppContext/health.

The DispatcherServletAutoConfiguration import may be able to replace your explicit DispatcherServlet bean. My case doesn't include the Info actuator endpoint but the key thing for me was the specific Imports below. Order is somewhat important for certain imports, at least in my testing.

I know very little about spring boot so this is the result of enabling auto configuration, pouring through spring boot TRACE log output, and trying lots of different import combinations.

@Configuration
@EnableWebMvc
@Import({
        DispatcherServletAutoConfiguration.class,
        WebMvcAutoConfiguration.class,
        WebEndpointAutoConfiguration.class,
        EndpointAutoConfiguration.class,
        HealthEndpointAutoConfiguration.class,
        WebMvcEndpointManagementContextConfiguration.class
})

@PropertySource("classpath:/health.properties")
public class MyAppActuatorConfig {
    // 1.x version had EndpointHandlerMapping and HealthMvcEndpoint beans here.
    // There may be a more spring-boot-ish way to get this done : )
}

And a minimal health.properties that suited my deployment specifics where security was already in place:

management.endpoints.web.base-path=/

management.endpoint.health.show-details=when-authorized
management.endpoint.health.show-components=when-authorized
jnichols959
  • 402
  • 4
  • 12