Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
wip: draft radicle-metrics crate
✗ CI failure shishqa committed 5 months ago
commit 62b5141254b08dfdece4b8f2dd8bb7acf16726c9
parent 6d0c571ea9998dd98bf10cc191848029f5210d8a
2 passed 1 failed (3 total) View logs
3 files changed +140 -0
modified Cargo.lock
@@ -2972,6 +2972,18 @@ dependencies = [
]

[[package]]
+
name = "radicle-metrics"
+
version = "0.17.0"
+
dependencies = [
+
 "anyhow",
+
 "clap",
+
 "pretty_assertions",
+
 "radicle",
+
 "serde",
+
 "serde_json",
+
]
+

+
[[package]]
name = "radicle-node"
version = "0.16.0"
dependencies = [
added crates/radicle-metrics/Cargo.toml
@@ -0,0 +1,27 @@
+
[package]
+
name = "radicle-metrics"
+
description = "Radicle Metrics"
+
homepage.workspace = true
+
license.workspace = true
+
version = "0.17.0"
+
authors = ["shishqa <shishqa.main@gmail.com>"]
+
edition.workspace = true
+
rust-version.workspace = true
+

+
[[bin]]
+
name = "radicle-metrics"
+
path = "src/main.rs"
+

+
[dependencies]
+
anyhow = "1"
+
clap = { version = "4.5.44", features = ["derive"] }
+
radicle = { workspace = true, features = ["logger", "schemars"] }
+
serde = { workspace = true }
+
serde_json = { workspace = true }
+

+
[dev-dependencies]
+
pretty_assertions = { workspace = true }
+
radicle = { workspace = true, features = ["test"] }
+

+
[lints]
+
workspace = true
added crates/radicle-metrics/src/main.rs
@@ -0,0 +1,101 @@
+
use anyhow::Context;
+

+
use clap::Parser;
+

+
use radicle::storage::ReadStorage;
+
use serde::Serialize;
+

+
use radicle::cob::common::Timestamp;
+
use radicle::cob::issue::cache::Issues;
+
use radicle::cob::stream::CobStream;
+

+
pub const NAME: &str = "radicle-metrics";
+

+
#[derive(Parser, Debug)]
+
#[command(name = NAME)]
+
struct CliArgs {}
+

+
#[derive(Default, Serialize)]
+
#[serde(rename_all = "camelCase")]
+
struct Point {
+
    value: i64,
+
    timestamp: Option<Timestamp>,
+
    labels: std::collections::BTreeMap<String, String>,
+
}
+

+
#[derive(Default, Serialize)]
+
#[serde(rename_all = "camelCase")]
+
struct Stats {
+
    points: Vec<Point>,
+
}
+

+
fn main() -> anyhow::Result<()> {
+
    let profile = radicle::profile::Profile::load().context("profile::load")?;
+
    let storage = &profile.storage;
+
    let mut stats = Stats::default();
+

+
    for repo in storage.repositories().context("repositories")? {
+
        let rid = repo.rid.to_string();
+

+
        let repo = storage
+
            .repository(repo.rid)
+
            .context(format!("load {}", rid))?;
+
        let issues = profile
+
            .issues(&repo)
+
            .context(format!("issues for {}", rid))?;
+

+
        for issue in issues.list().context(format!("list issues for {}", rid))? {
+
            let issue = issue.context(format!("read issue {}", rid))?;
+
            let stream = radicle::cob::issue::IssueStream::init(issue.0, &repo);
+

+
            stats.points.push(Point {
+
                value: 1,
+
                timestamp: Some(issue.1.timestamp()),
+
                labels: std::collections::BTreeMap::from([
+
                    ("name".to_string(), "issues.open".to_string()),
+
                    ("rid".to_string(), rid.clone()),
+
                    ("issue".to_string(), issue.0.to_string()),
+
                ]),
+
            });
+

+
            for op in stream.all()? {
+
                let op = op?;
+
                op.id;
+

+
                for action in op.actions {
+
                    if let radicle::cob::issue::Action::Lifecycle { state } = action {
+
                        match state {
+
                            radicle::cob::issue::State::Open => {
+
                                stats.points.push(Point {
+
                                    value: 1,
+
                                    timestamp: Some(op.timestamp),
+
                                    labels: std::collections::BTreeMap::from([
+
                                        ("name".to_string(), "issues.open".to_string()),
+
                                        ("rid".to_string(), rid.clone()),
+
                                        ("issue".to_string(), issue.0.to_string()),
+
                                    ]),
+
                                });
+
                            }
+
                            radicle::cob::issue::State::Closed { .. } => {
+
                                stats.points.push(Point {
+
                                    value: -1,
+
                                    timestamp: Some(op.timestamp),
+
                                    labels: std::collections::BTreeMap::from([
+
                                        ("name".to_string(), "issues.open".to_string()),
+
                                        ("rid".to_string(), rid.clone()),
+
                                        ("issue".to_string(), issue.0.to_string()),
+
                                    ]),
+
                                });
+
                            }
+
                        }
+
                    }
+
                }
+
            }
+
        }
+
    }
+

+
    let output = serde_json::to_string(&stats)?;
+
    println!("{}", output);
+

+
    Ok(())
+
}