Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Spring Boot Actuator without a Spring Boot Application [duplicate]

Spring Boot's Actuator library with production information endpoints is really useful for any server application. But the problem is I could not find a way to integrate into a traditional Spring Application (which is not a Spring BOOT application).

There must be some way to use the endpoints of actuator but I could not wire them up.

I have a JavaConfig class like below

@Configuration
@ComponentScan(basePackages = { "com.company.helper", "org.springframework.boot" })
@EnableWebMvc
@Import({ DbConfig.class })

public class AppConfig extends WebMvcConfigurerAdapter {

}

But this configuration throws an error during deployment.

Can this wiring be done without the Spring Boot application?

like image 570
LostMohican Avatar asked Nov 13 '14 16:11

LostMohican


People also ask

Can we use actuator without spring boot?

First let's clarify that you cannot use Spring Boot Actuator without using Spring Boot. I was wrong about not being able to it without Spring Boot. See @stefaan-neyts answer for an example of how to do it.

Is spring boot actuator enabled by default?

In order to access the actuator endpoints using HTTP, we need to both enable and expose them. By default, all endpoints but /shutdown are enabled.

How do you use a spring boot actuator?

To enable Spring Boot actuator endpoints to your Spring Boot application, we need to add the Spring Boot Starter actuator dependency in our build configuration file. Maven users can add the below dependency in your pom. xml file. Gradle users can add the below dependency in your build.

Can we use spring boot for non Spring application?

The application can also be called as Spring Boot Standalone application. To develop a non web application, your Application needs to implement CommandLineRunner interface along with its run method. This run method acts like a main of your application.


3 Answers

I have added information on how to add spring boot actuator in a non boot application in this blog post

http://givenwhenthen.blogspot.com/2015/09/adding-spring-boot-actuator-to-non.html

In the application's build.gradle, I added the following dependency

compile('org.springframework.boot:spring-boot-actuator:1.2.5.RELEASE'){
    exclude group: 'org.springframework.boot', module:'spring-boot-starter-logging'}

In the application's Spring Config class, I added the following things:

 import org.springframework.beans.factory.annotation.Autowired;  
 import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;  
 import org.springframework.boot.actuate.endpoint.BeansEndpoint;  
 import org.springframework.boot.actuate.endpoint.HealthEndpoint;  
 import org.springframework.boot.actuate.endpoint.InfoEndpoint;  
 import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;  
 import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;  
 import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;  
 import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint;  
 import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;  

 @Configuration  
 @Import(EndpointAutoConfiguration.class)  
 public class MyAppSpringConfig {  

   @Bean  
   @Autowired  
   //Define the HandlerMapping similar to RequestHandlerMapping to expose the endpoint  
   public EndpointHandlerMapping endpointHandlerMapping(  
     Collection<? extends MvcEndpoint> endpoints  
   ){  
     return new EndpointHandlerMapping(endpoints);  
   }  

   @Bean  
   @Autowired  
   //define the HealthPoint endpoint  
   public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate){  
     return new HealthMvcEndpoint(delegate, false);  
   }  

   @Bean  
   @Autowired  
   //define the Info endpoint  
   public EndpointMvcAdapter infoMvcEndPoint(InfoEndpoint delegate){  
      return new EndpointMvcAdapter(delegate);  
   }  

   @Bean  
   @Autowired  
   //define the beans endpoint  
   public EndpointMvcAdapter beansEndPoint(BeansEndpoint delegate){  
     return new EndpointMvcAdapter(delegate);  
   }  

   @Bean  
   @Autowired  
   //define the mappings endpoint  
   public EndpointMvcAdapter requestMappingEndPoint(  
     RequestMappingEndpoint delegate  
   ){  
     return new EndpointMvcAdapter(delegate);  
  }  
}  

If you want to get rid of one additional dependency then please refer to the blogpost.

UPDATE

Also you need to make sure you have a bean defined for RequestMappingHandlerAdapter, if you do not have it the ServletDispatcher will not be able to fetch the adapter for the handler of your HealthMvcEndpoint.

if you dont have it just add it to your bean configuration file

xml configurations:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonConverter"/>
            </list>
        </property>
    </bean>

    <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes" value="application/json" />
        <property name="prettyPrint" value="true" />
    </bean>
like image 78
Prateek Negi Avatar answered Oct 05 '22 16:10

Prateek Negi


The project I'm working on uses Spring, but neither Spring-boot nor Spring-MVC. The following solution may not be as automagic as the actuator with boot, but it exposes the endpoints in a pretty succinct way.

Basically, all actuator endpoints are just beans, so you can create a new component and autowire in the endpoints however you see fit.

The only additional dependencies in my pom are spring-boot-actuator and spring-webmvc:

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator</artifactId>
        <version>1.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId> 
        <version>4.1.4.RELEASE</version>
    </dependency>

Then all you need to do is create a single component class (maybe register it if you need to). Make sure to annotate with @EnableAutoConfiguration:

@Component
@EnableAutoConfiguration
@Path("/actuator/")
public class ActuatorResource {

private ObjectMapper mapper = new ObjectMapper();


@Autowired 
private DumpEndpoint dumpEndpoint;

@GET
@Produces("application/json")
@Path("/dump")
@Transactional(readOnly = true)
public String getDump() throws JsonProcessingException { 
    return mapper.writeValueAsString(dumpEndpoint.invoke());
}

@Autowired
private EnvironmentEndpoint envEndpoint;

@GET
@Produces("application/json")
@Path("/environment")
@Transactional(readOnly = true)
public String getEnvironment() throws JsonProcessingException {
    return mapper.writeValueAsString(envEndpoint.invoke());
}

}
like image 26
dneronique Avatar answered Oct 05 '22 16:10

dneronique


In our project we used a little hack, that worked for us. To enable actuator we used dependencies from spring-boot in POM.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator</artifactId>
        <version>1.2.3.RELEASE</version>
        <type>jar</type>
    </dependency>
     <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.2.Final</version>
    </dependency>

and just used additional config class as follows:

@EnableConfigurationProperties
@Configuration
@EnableAutoConfiguration
@Import(EndpointAutoConfiguration.class)
public class SpringBootActuatorConfig {

}
like image 35
RadekSohlich Avatar answered Oct 05 '22 17:10

RadekSohlich