Let’s build a custom prometheus exporter in Rust

Tanisha Banik
3 min readSep 22, 2022

--

This blog is about how one can build their very own custom define prometheus exporter in Rust. Prometheus is a graduated, open-source CNCF project, used for events/system monitoring and alerting. It records real-time metrics in the form of a time series database, LevelDB, and is built using a HTTP pull model, with flexible queries using PromQL and real-time alerting rules.

Why:

There are different kinds of metrics available for system information, system logs, CPU, Memory and so on, but sometimes our use-case might require us to expose certain metrics on certain ports and that’s where custom exporters come into play.

For more info, visit: https://prometheus.io/docs/instrumenting/writing_exporters/

Prerequisites:

  1. Rust

Goal:

The aim here is to build a very simple exporter which can scrape metrics like folder size, file count of that folder, disk usage, memory usage from the local system. Moreover, it should send desktop notifications based on if the metrics have crossed a certain threshold on regular intervals until the issue is resolved.

Crates (Lib in rust) used:

  1. SysInfo, a crate used for getting system info
  2. Notify_Rust, a crate for sending desktop notifications or pop-ups
  3. Fs_Extra, a crate for extracting a dir info
  4. Prometheus_Exporter, a helper crate for exporting prometheus metrics via http
  5. SocketAddr, part of the std crate in rust, it represents an IPv4 or IPv6 address
  6. Read_dir, part of the std crate in rust, it returns an iterator to the directory name passed
  7. Env_Logger, a crate for implementing logger, via environment variables
  8. Log, a crate which provides an API abstracting the actual logging implementation

Our Exporter:

First, let’s import the required crates in our program

cfg , is a macro in rust, which here defines to use all unix systems except for macos. The calculate_folder_size_and_count function simply returns the folder size and files count in that folder from the path, variable passed as an argument.

To know more about macros, visit: https://doc.rust-lang.org/book/ch19-06-macros.html

Here, under the main function, we define the logger from default environment using env_loggercrate. We configure our webserver listening on port 9050 and running on localhost. We create an instance of the exporter, and define here std::time::Duration::from_millis(10000) , after how many seconds will the metrics get updated, here it is 10s.

From lines 14:21, we extract the metrics. From lines 23:25, we have used register_guage!, a macro, to display single numerical values and can also be be used for incremental and decremental values and registers the metrics to default registry.

Here, we have introduced a loop for collecting and updating the metrics continuously.

let sys = System::new_all(), is for defining a new instance of System , which will extract the system information.

Lines 11:12, are for converting the values to KB , line 14 calculates the total used memory. Lines 20:25, 31:36, 43:48, 53:58, are defined for sending notifications if the metric values crosses a value. Lines, 18, 29, 62, 63, 67 are for setting the metric_types with the current values calcuated.

Now, as we have added the metrics to our prometheus exporter, we can create useful dashboards using tools such as Grafana for visualising our metrics as a time series database.

Demo Link:

https://www.youtube.com/watch?v=eovTUYOSAVY

--

--