In this tutorial, we will be building a simple front end application with React that we will use to monitor uptime and downtime of a spring boot service. I chose Spring boot because it provides us with HTTP endpoints that we can use for monitoring and managing our Spring Boot application with little effort on our part.
When the web service is not running or goes down for some reason, we want to automatically change the server icon color to red. When the service is up, we will set the server icon to green.
Here is a look at what we will be building:
Ready! Let’s get started…
Part 1: Setup the Spring boot service
Let’s head on over to https://start.spring.io/ where we will bootstrap a spring boot project. Thanks to the folks at Pivotal for providing this handy tool! My setup looks like this:
Don’t forget to add the dependencies or else you will need to add them yourself in the pom.xml. Add the“Spring Boot Actuator” and “Spring Web Starter” dependencies. You need to search for the dependencies and add them. We need these dependencies so we can access Spring Boot’s actuator HTTP endpoints to monitor our service. We also don’t want to go through the hassle of setting up a web server. Luckily, with the Spring Web Starter we get an embedded Tomcat server.
Now you can go ahead and click “Generate the project”. A zip file will be downloaded to your computer containing the project files.
Go ahead and unzip the folder and import the generated maven project in your favorite IDE.
Run the service and you should see the console log below. The tomcat server starts on port 8080 by default.
So, how can we know when our service is up or down?
The Spring boot actuator dependency exposes several endpoints attached to the base path /actuator that we can use to monitor our service. We will be using the /health endpoint that will return a JSON object that simply tells us if our service is up. To confirm that your service is up, go to http://localhost:8080/actuator/health and make sure you see the page below:
Great! Our spring boot service is running and we have a way to monitor it. Now, let’s move on the next section and setup the front end application with React.
Part 2: Creating our React app
Let’s use Facebook’s create-react-app tool to setup our project.
$ create-react-app server-monitor
This may take some time depending on your machine. Once setup is complete, go ahead and start the application with the command:
$ npm start
Go to http://localhost:3000/ to make sure the application is running. If you see a spinning React logo you are good to go!
You will notice in the /src directory there are a number of files generated for us. Let’s remove all those files and create our own structure:
Rather than using the default structure, I like to refactor my react applications to make things more clear.
To style our application a bit and get that cool server icon we saw before, we will be using Semantic UI. Let’s go ahead and include the CSS stylesheet within the <head> tag in public/index.html
<link rel=”stylesheet” href=”https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css"/>
Open up App.css and paste the following code. This is just some additional styling we will add so our app is centered in the browser.
.main {
display: flex;
justify-content: center;
text-align: center;
}.main i {
margin-left: auto;
margin-right: auto;
}
Now, let’s get to coding! Open up the App.js file and copy in the starter code below.
import React from "react";
import springboot from "../api/springboot";
import "./App.css";const ServerStat = {
UP: {
color: "green"
},
DOWN: {
color: "red"
}
};class App extends React.Component {
state = { server: "" };render() {
return (
<div className="main">
<div className="ui card">
<div className="content">
<h3>Spring Boot Server Monitor</h3>
</div>
<i className="massive server icon" />
</div>
</div>
);
}
}export default App;
We are using a class based component because we want to make use of state. We want to use the server object stored inside state to keep track of the server status. Remember we want the server icon color to be either green (up) or red (down) and this will reflect the server status.
We need to render our App component so we can see the changes we’ve made so far in the browser. Let’s add the code below in the index.js file.
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";ReactDOM.render(<App />, document.querySelector("#root"));
Your application should now look like this:
Looking good so far but the server icon is not telling us anything useful yet.
We need to contact the Spring boot actuator endpoint at http://localhost:8080/actuator/health so we are able to check the service status. To do this we will be using the axios HTTP client.
Let’s install axios with the following command:
$ npm install axios --save
Open up springboot.js and copy the code below. What we are doing here is creating an instance of axios that we will use in our App component. axios returns a promise containing the result from the HTTP request.
import axios from "axios";export default axios.create({
baseURL: "http://localhost:8080"
});
Now, let’s create an arrow function called checkServerHealth() inside the App class component. We need to perform a GET request to /actuator/health. Notice that we didn’t have to specify http://localhost:8080/actuator/health because we already configured the axios instance above with the baseURL.
checkServerHealth = async () => {
try {
await springboot.get("/actuator/health");
this.setState({ server: ServerStat["UP"] });
} catch (error) {
this.setState({ server: ServerStat["DOWN"] });
}
};
To handle the promise returned from axios we will use async/await. We need to specify async because our function will definitely return a Promise. await will eventually return a result once the promise is settled. I personally like using async/await because I feel it makes my code look cleaner. So once there are no problems getting a response from the /actuator/health endpoint, we use setState() to update the server object with the color green signaling that the service is up. If we can’t resolve the promise, therefore no result, we set the color to red signaling that we can’t contact the spring boot service.
Now, let’s update the render() method. this.state.server will be updated with the appropriate color whenever we call the checkServerHealth() async function. We want to update our UI so we can dynamically see changes to the server icon color.
render() {
const { color } = this.state.server;return (
<div className="main">
<div className="ui card">
<div className="content">
<h3>Spring Boot Server Monitor</h3>
</div>
<i className={`massive server icon ${color}`}/>
</div>
</div>
);
}
}
Now, if the spring boot service goes down in the next 5 minutes for example, we want to be notified almost immediately. We also want to be notified when it comes back online. So, we will need to be checking the server status from time to time to get real time updates. To support this function, we will use JavaScript’s setInterval() function to trigger the checkServerHealth() function every 800ms. This logic will be triggered immediately after the App component is mounted. Notice that we are passing an arrow function to setInterval(). This is because we want this to refer to the App class component.
componentDidMount() {
setInterval(() => this.checkServerHealth(), 800);
}
Great! Open up your browser and everything should work.
But Wait! The spring boot service is up but the server icon is red!!!! If this is the case, check the browser console for an error like:
This is because we are trying to access the resource from a different origin.To allow our react application to contact the service we need to allow it through. Add these lines of code in src/main/resources/application.properties in the spring boot project.
management.endpoints.web.cors.allowed-origins=http://localhost:3000
management.endpoints.web.cors.allowed-methods=GET
Restart the spring boot service. You should notice the server icon color change to green almost immediately. Try stopping the spring boot service and observe the server icon change back to red.
You did it!
I hope you liked this article and it has been helpful to you! You can find all the code for this tutorial here.
Cheers!