prometheus_exporter_base 1.4.0

Prometheus Rust exporters base crate with optional boilerplate
Documentation
use clap::{crate_authors, crate_name, crate_version, value_parser, Arg, ArgAction};
use log::{info, trace};
use prometheus_exporter_base::prelude::*;
use std::env;
use std::fs::read_dir;
use std::net::SocketAddr;

#[derive(Debug, Clone, Default)]
struct MyOptions {}

fn calculate_file_size(path: &str) -> Result<u64, std::io::Error> {
    let mut total_size: u64 = 0;
    for entry in read_dir(path)? {
        let p = entry?.path();
        if p.is_file() {
            total_size += p.metadata()?.len();
        }
    }

    Ok(total_size)
}

#[tokio::main]
async fn main() {
    let matches = clap::Command::new(crate_name!())
        .version(crate_version!())
        .author(crate_authors!("\n"))
        .arg(
            Arg::new("port")
                .short('p')
                .help("exporter port")
                .value_parser(value_parser!(u16))
                .default_value("32148"),
        )
        .arg(
            Arg::new("verbose")
                .short('v')
                .help("verbose logging")
                .action(ArgAction::Count),
        )
        .get_matches();

    if matches.get_count("verbose") > 0 {
        env::set_var(
            "RUST_LOG",
            format!("folder_size=trace,{}=trace", crate_name!()),
        );
    } else {
        env::set_var(
            "RUST_LOG",
            format!("folder_size=info,{}=info", crate_name!()),
        );
    }
    env_logger::init();

    info!("using matches: {:?}", matches);

    let bind: u16 = *matches.get_one("port").unwrap();
    let addr: SocketAddr = ([0, 0, 0, 0], bind).into();

    let server_options = ServerOptions {
        addr,
        authorization: Authorization::None,
    };
    println!("starting exporter with options {:?}", addr);

    render_prometheus(
        server_options,
        MyOptions::default(),
        |request, options| async move {
            trace!(
                "in our render_prometheus(request == {:?}, options == {:?})",
                request,
                options
            );

            let mut pc = PrometheusMetric::build()
                .with_name("folder_size")
                .with_metric_type(MetricType::Counter)
                .with_help("Size of the folder")
                .build();

            for folder in &vec!["/var/log", "/tmp"] {
                pc.render_and_append_instance(
                    &PrometheusInstance::new()
                        .with_label("folder", folder.as_ref())
                        .with_value(
                            calculate_file_size(folder).expect("cannot calculate folder size"),
                        )
                        .with_current_timestamp()
                        .expect("error getting the current UNIX epoch"),
                );
            }

            Ok(pc.render())
        },
    )
    .await;
}