loading...

Creating PULSE — A developer-friendly server monitoring tool (Part 9)

mattkingshott profile image Matt Kingshott 👨🏻‍💻 Originally published at Medium on ・4 min read

Facebook’s Prineville Data Server Center

Creating PULSE — A developer-friendly server monitoring tool (Part 9)

This is part of a weekly development blog series, where I will document the creation of an application from the initial idea through to its deployment on a scalable architecture. Even as an experienced developer, I find these stories to be interesting and I usually pick up a tip or two, so if you’d like to come along, and hopefully benefit in some way, let’s dig in!

NOTICE : Pulse has now launched and is available to use. You can create an account by visiting https://pulse.alphametric.co

Rounding out the feature set (for developers)

Pulse originally began its life by being designed to fulfil the need of another system I was developing. That system, as part of its customer on-boarding process would provision a new server, then install the app and configure it.

Since this whole process is automated, and since customers could choose to sign-up at any time, I needed to integrate the final element, which was a robust server monitoring tool.

Like many developers, in the past, I just sort of kept a general eye on what was going on with my servers, but in a situation where there could be dozens or even hundreds of servers, this wasn’t going to be practical.

So, I looked into the existing monitoring tools… after picking myself off the floor when I saw the pricing system, I discovered that integration was not going to be simple. I couldn’t just run a few commands through a shell script and be done. It was more complicated than that. Plus, I’d have to learn how to use these monoliths, and frankly, I didn’t have the inclination to do so.

In short, what I wanted was this:

An affordable, API-driven monitoring tool that I could easily integrate into the server provisioning process.

Pulse already has the ability to manage everything through the browser. Now, it was time to add that missing feature, API support.

Adding API routes and done (well, almost)

Since I had already written controllers for the browser-based functionality, all I really had to do, was add the API routes, copy over some of the existing web controller code and modify the responses that are sent back (JSON).

Here’s a list of the routes that form the API system:

/api/v1/servers
/api/v1/servers/show
/api/v1/servers/store
/api/v1/servers/script
/api/v1/servers/update
/api/v1/servers/destroy

/api/v1/clusters
/api/v1/clusters/show
/api/v1/clusters/store
/api/v1/clusters/update
/api/v1/clusters/destroy

/api/v1/nodes/store
/api/v1/nodes/destroy

/api/v1/monitors/store
/api/v1/monitors/update
/api/v1/monitors/destroy

/api/v1/logs

/api/v1/lists/channels
/api/v1/lists/watchers
/api/v1/lists/timezones

They should, for the most part, be familiar to anyone with a solid grasp of the RESTful approach to the MVC pattern. In essence, the API allows you to do everything you could need. Here’s a breakdown:

  1. Servers  — View all server monitoring profiles, view one, add one, update one, delete one and get the shell script content for one.
  2. Clusters  — View all clusters, view one, add one, update one, delete one.
  3. Nodes  — Add a server (node) to a cluster, remove one from a cluster.
  4. Monitors  — Add a monitor to a server profile, update one or delete one.
  5. Logs  — View a subset of logs for a given server using a given date range.
  6. Lists  — View the ID values for channels, watchers and time zones. These are used elsewhere in the API, so I needed to make them available.

Discovering API Resources

Laravel includes a feature known as API resources that allows you to take a model or collection of models and transform them into an array. This allows you to perform any additional processing, organise and format the attributes, as well as exclude any that you don’t want to return to the user.

I made extensive use of these to reduce the number of database queries involved when returning large amounts of data. Here’s an example of the resource method used to render out a monitor:

The toArray() method on the MonitorResource

I used two helper methods to get the related models for the monitor’s watcher and channel. These helpers read from the cache rather than execute two more database queries to pull in the models.

I also applied the useful when() method, which is part of the API resource. It allows you to only include an item in the array if the condition is met.

For threshold, it’s particularly relevant as, if you’re monitoring a service, there is no threshold. It’s either running or it isn’t. So, we don’t need to return it.

The same is true for the notification route. If you’ve selected none, then we don’t need to include it in the response.

Wrapping Up

Well, that’s it for this week. Next up, we’ll be taking a looking at a few final tweaks, as well as covering the test suite that Pulse uses to confirm that all of its features are working as expected.

All that is coming in next week’s article. In the mean time, be sure to follow me here on Medium, and also on Twitter for more frequent updates.

NOTICE : Pulse has now launched and is available to use. You can create an account by visiting https://pulse.alphametric.co

Thanks, and happy coding!

Posted on Feb 26 '19 by:

mattkingshott profile

Matt Kingshott 👨🏻‍💻

@mattkingshott

Founder. Developer. Writer. Lunatic. Created Pulse, IodineJS, Axiom, and more. #PHP #Laravel #Vue #TailwindCSS

Discussion

markdown guide