Hi, I'm Steve! This site is an always-in-progress repository for my thoughts and ideas. You'll generally find me writing about sustainability 🍃, urbanism 🏙️, programming 💾, vegan cooking 🍛, and whatever else pops into my mind ✨.

Monitoring an HTTP service with Clojure and Babashka
February 14, 2023

Over the last few months of running I've run into a few issues with my Postgres service crashing and taking the instance down with it. I haven't always noticed this downtime quickly, as I either need to try and fail to load up Mastodon or have someone ping me to ask what's going on. This called for a simple monitoring solution: a script that would periodically ping the Mastodon instance and monitor the HTTP status code. If it returns 200 OK all is good, however any non-200 response should notify me so I can investigate.

There are probably a bazillion SaaS companies that are willing to do this for me, or there is the obvious answer of throwing together a Python script. Instead, I decicided to continue down a recent wormhole I've been going down and write something in Clojure.

Starting a new project with lein new seemed like a good first step, however I quickly realized that spinning up a full-on JVM instance would be way overkill for a simple script that just needs to ping a server, write a log, and send a notification. Instead, I took this as an opportunity to try Babashka: a lightweight Clojure implementation more suitable for scripting tasks. With Babashka I can get the quick spin-up time of something like a Python script while also reaping the benefits of Clojure's syntax and libraries.

I've published the repository on SourceHut, but you can jump straight to the implementation here.

The tl;dr is that the script pings the server, writes the result to a sqlite file (so I can easily query up/downtime logs), and sends a push notification to my phone (via PushOver) when it detectes something awry. I've also implemented a mechanism that ensures I only receive alerts once per hour, as I don't particularly want this job to blast my phone away if the instance goes down overnight.

Overall I was really happy with Babashka. It was super simple to set up for both my development environment and the server I'm running the job on. This project also pushed me to switch from vim-fireplace to conjure for my nvim <-> REPL integration, which was a day-and-night difference. I thought fireplace was the standard REPL integration for using LISP on vim, but Conjure has been much more powerful in its native key mappings + integrations with some of the new features of Neovim.

Being relatively new to Clojure, I'd also love some feedback on my code. If you have any suggestions on how I might do things differently (either in terms of syntax or method) drop me an email.