Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application status down, when mongo is down with spring boot actuator

I have created sample project for spring boot actuator with database testing. After running the application when I hit the URL

  • When Mongo DB is running
  • URL: http://localhost:8080/health
  • Response : `{"status":"UP","diskSpace":{"status":"UP","total":493767094272,"free":404928278528,"threshold":10485760},"mongo":{"status":"UP","version":"3.0.2"}}

`

  • When Mongo DB is not running
  • URL: http://localhost:8080/health
  • Response:

    {"status":"DOWN","diskSpace":{"status":"UP","total":493767094272,"free":404929720320,"threshold":10485760},"mongo":{"status":"DOWN","error":"org.springframework.dao.DataAccessResourceFailureException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: connect}}]; nested exception is com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: connect}}]"}}

Question: Why application status is "DOWN" when my mongodb is not running. I want my application status "UP" weather mongodb is "DOWN" or "UP".

Below is my Main class for spring boot application.

package com.company.testing;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>SpringBootSample</artifactId>
    <version>0.0.1</version>
    <name>Spring Boot Sample</name>
    <description>Spring Boot Sample for spring boot actuator</description>
    <groupId>com.company.testing</groupId>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>


    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
like image 229
Harshil Avatar asked Jan 23 '17 09:01

Harshil


2 Answers

application.properties

management.health.mongo.enabled=false
endpoints.mongo.enabled=true

MongoDBHealthCheckEndPoint.java

@ConfigurationProperties(prefix = "endpoints.mongo", ignoreUnknownFields =     true)
@Component
public class MongoDBHealthCheckEndPoint extends    AbstractEndpoint<Map<String, String>> 
 {

@Inject
MongoTemplate mongoTemplate;


private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final Map<String, String> UP = new HashMap<String, String>() {{
    put("mongo.status", "UP");
}};

private static final Map<String, String> DOWN = new HashMap<String, String>() {{
    put("mongo.status", "DOWN");
}};


public MongoDBHealthCheckEndPoint() {
    super("mongo", false);
}

public MongoDBHealthCheckEndPoint(Map<String, ? extends Object> mongo) {
    super("mongo", false);
}

public Map<String, String> invoke() {
    try {
        return (new MongoHealthIndicator(mongoTemplate).health().getStatus().equals(Status.UP)) ? UP : DOWN;
    } catch (Exception e) {
        log.error("mongo database is down", e);
        return DOWN;
    }
}
like image 146
shabinjo Avatar answered Sep 28 '22 00:09

shabinjo


Spring Boot Actuator uses HealthIndicatorAutoconfiguration to configure various health related beans. One of the beans is called healthAggregator which uses the implementation or OrderedHealthAggregator. It will use the lowest status of all the health indicators to provide overall application status (that's why you're getting DOWN for overall app.

You can either turn off MongoDb monitoring (management.health.mongo.enabled=false) or write your own implementation of AbstractHealthAggregator that will ignore MongoDb being down for example and provide it in your config:

    @Bean
    public MyHealthAggregator healthAggregator() {
        return new MyHealthAggregator();
    }
like image 20
Strelok Avatar answered Sep 28 '22 01:09

Strelok