💾 Archived View for nanako.mooo.com › gemlog › 2024-04-19-a.gmi captured on 2024-06-16 at 12:45:22. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2024-05-10)
-=-=-=-=-=-=-
So in my last post I mentioned how my usual over-arching workflow was to do my big "main" project for a while, release said project, and then take some time off to work on smaller projects/itches. Well, I did just that and wrote the system monitor that I mentioned! The project is called RemiMonitor and is actually composed of a daemon (RemiMond), a frontend client (YandereMon), and a library that ties them together (RemiMonitor).
The first v0.1.0 release isn't quite out yet, but I hope to have it published this weekend.
Oh, and it's all written in the Crystal programming language <3
RemiMonitor source code repository
(18KB) Screenshot of YandereMon monitoring two systems
(79.5MB) Video demonstration of YandereMon
The overall goal of the project was not to have the end-all-be-all monitoring solution, or to get super detailed information about running processes, but instead to have a good way to see "at a glance" the basics of what's going on with multiple machines. To that end, it's been highly inspired by GKrellM (which I absolutely love), but with an emphasis on multiple systems, and on a TUI interface.
Reducing CPU and RAM usage was also a goal for RemiMonitor, and I feel like I've accomplished that so far. Both RemiMond and YandereMon use almost no CPU time, and also minimize their RAM usage as much as possible. Each one effectively uses about 3-4 MB of RAM on my x86-64 systems, and I almost never see it use more than 0.8% CPU when I watch them in htop. There's still a few places I want to optimize them, however, so future releases may improve this even more.
The "RemiMonitor Daemon" (RemiMond) is what's responsible for actually collecting the system data. The idea is that you run an instance of it on each machine you want to monitor, and then each one listens for client connections. Communication with clients happens over TLS and each client gets handled on its own thread. Internally the daemon is split up into individual monitors, where each one runs on its own thread and is responsible for monitoring one aspect of the system. Initially there are monitors for the following:
It also collects a few pieces of information once at startup such as the running kernel version, hostname, CPU architecture, and number of CPU cores.
The daemon will lack any sort of authentication for v0.1.0, but you are able to whitelist the IPs of clients so that only specific clients can connect. True authentication is planned for a future release.
The frontend client is called YandereMon ("Yandere" for short) and is a TUI program that uses S-Lang for its terminal interface. YandereMon can connect to multiple RemiMond instances, and thus monitor multiple machines at the same time. Each machine gets its own thread, too, and YandereMon can also gracefully handle them dropping in and out. It's able to display the uptime, kernel version, CPU architecture, CPU usage, processes, RAM, swap, network usage, and disk space.
RemiMond and YandereMon are both pretty simple. They just talk to each other, and YandereMon shows the information in a clear way. The real magic happens in the communication protocol that units them, and the library that implements it: RemiMonitor.
Communication is entirely in binary, and starts when YandereMon connects to RemiMond. A TLSv1.3 connection is opened, and then YandereMon sends a Hello Message. Once the server verifies this message, it responds with an Initial Connection Message, which contains a few pieces of information such as the number of CPUs, the CPU architecture, and so on. After this, the client sends a special Update Request any time it wants new data from RemiMond. The daemon then responds with an Update Response, which contains the data from all of its monitors.
The Update Response is essentially a simple binary serialization format. Each section of the message starts with a monitor Type ID indicating what kind of monitor data is about to follow. Then comes the number of data fields, followed by the data fields themselves. Each field is prepended by a Data Type ID.
The design of the Update Response is such that new monitors, or new data fields, can be added without breaking backwards compatibility. Update Responses are optionally compressed with LZ4.
The library implements this protocol, as well as some helper functions. It also implements all of the monitors.
Because everything is designed in a modular way, this means that alternate clients or daemons can be written. So if you want a nice Gtk4 client, go for it! As long as you speak the protocol properly, RemiMond won't care. Or if you want to implement your own daemon, that's fine, too. RemiMond, YandereMon, and the RemiMonitor library are considered the reference implementations of the RemiMonitor Protocol.
Current specification of the RemiMonitor Protocol
RemiMonitor is essentially just a small project that I want to tinker with when I'm not working on Benben. It scratches an itch I've had for a long time, and was just meant to be fun to implement. I'll continue to maintain and update it.
Once its first release is out, I plan to go back to Benben, where I have some interesting plans for the future... new Gemlog on that soon ^_^
--------- Page served by Aya https://nanako.mooo.com/fossil/aya/ Aya is under the GNU Affero GPLv3 license