Spring Boot - How to check specific application URLs for status 200
Asked Answered
W

1

6

I have several applications monitored under Spring Boot Admin. Spring Boot Admin is great at telling me if an application is up or down and other various metrics.

I would also like to know that certain URLs exposed by these applications are returning an HTTP status of 200. Specifically, I would like to send a GET request to these URLs once a day. If it receives a non 200 status from any of these, it sends an email stating which URLs are reporting non 200.

Is something that Spring Boot Admin is able to do? I know about custom HealthIndicators but not sure if it can be scheduled or if it's appropriate for this.

Just wanted to see if there is something Spring Boot Admin offers to support doing this before I build my own app to make the GET calls and send the email.

Update

The URLs are exposed as Eureka services and I'm calling services from other services via Spring Cloud OpenFeign.

Update 2

I went ahead and built my own custom application to handle this. Details follow but still interested if Spring offers something out-of-the-box to do this.

application.yml

app:
  serviceUrls: 
    - "http://car-service/cars?category=sedan"
    - "http://truck-service/trucks"
cron: "0 0 10 * * *"

Urls are read into:

@Component
@ConfigurationProperties(prefix = "app")
@Getter
@Setter
public class ServiceUrls {
    private String[] serviceUrls;
}

Via cron, scheduled to run once a day:

@Component
@RequiredArgsConstructor
@Slf4j
public class ServiceCheckRunner {
    
    private final ServiceHealth serviceHealth;
    
    @Scheduled(cron = "${cron}")
    public void runCheck() {
        serviceHealth.check();
    }
}

This is the code that checks whether URLs return no errors:

@Service
@RequiredArgsConstructor
@Slf4j
public class ServiceHealth {

    private final ServiceUrls serviceUrls;
    private final RestTemplate rest;
    
    public void check() {

        List<String> failedServiceUrls = new ArrayList<>();
        for (String serviceUrl : serviceUrls.getServiceUrls()) {
            try {

                ResponseEntity<String> response = rest.getForEntity(serviceUrl, String.class);
                
                if (!response.getStatusCode().is2xxSuccessful()) {
                    failedServiceUrls.add(serviceUrl);
                }

            } catch (Exception e){
                failedServiceUrls.add(serviceUrl);
            }
            
        }

        // code to send an email with failedServiceUrls.
    }   
}
Works answered 19/3, 2021 at 16:11 Comment(7)
you can register HealthIndicators for each of the downstream API and call /health endpoint which will return the status of each of the API in JSON format. would this solve your use-case?Ruffina
@Ruffina Thanks for your suggestion. What are your thoughts on what would be calling the /health endpoint for each app? Spring Boot Admin?Works
you can refer to https://mcmap.net/q/380119/-how-to-add-a-custom-health-check-in-spring-boot-health/2987755, baeldung.com/spring-boot-health-indicators, once you register health endpoint for all downstream API, then your applications /health endpoint is tied with rest of all the health checks.Ruffina
Why don't you integrate downstream service(s) health in the service health check?Unison
I could implement HealthIndicators. What would call those /health endpoints? Spring Boot Admin? If I'm building my app that calls those /health endpoints, then it doesn't seem any better than just building the custom app and calling URLs as I already have noted in the OP.Works
"What are your thoughts on what would be calling the /health endpoint for each app?" - the underlying infrastructure. I know Azure allows to create a status check for a list of endpoints (expected status code, content etc). I'm sure other cloud providers have similar options.Burglar
Your solution seems good... whats' the problem with it? isn't it giving you the failed urls?Tank
B
0

You can use Spring Boot Admin in order to send email notifications whenever a registered client changes his status from UP to OFFLINE or otherwise.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>2.4.0</version>
</dependency>

application.properties

spring.mail.host=smtp.example.com
spring.mail.username=smtp_user
spring.mail.password=smtp_password
[email protected]

But, if you really need to check client status once per day, you need to implement a custom solution.

Bitternut answered 29/3, 2021 at 21:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.