1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
use std::collections::HashMap; use libcantal::{Counter, Integer, Collection, Visitor, Name, NameVisitor}; pub struct Process { pub started: Counter, pub failures: Counter, pub deaths: Counter, pub running: Integer, } pub struct Metrics { pub restarts: Counter, pub sandboxes: Integer, pub containers: Integer, pub queue: Integer, pub started: Counter, pub failures: Counter, pub deaths: Counter, pub running: Integer, pub unknown: Integer, pub processes: HashMap<(String, String), Process>, } pub struct MasterName(&'static str); pub struct GlobalName(&'static str); pub struct ProcessName<'a>(&'a str, &'a str, &'static str); impl Metrics { pub fn new() -> Metrics { Metrics { restarts: Counter::new(), sandboxes: Integer::new(), containers: Integer::new(), started: Counter::new(), failures: Counter::new(), deaths: Counter::new(), running: Integer::new(), unknown: Integer::new(), queue: Integer::new(), processes: HashMap::new(), } } } impl Process { pub fn new() -> Process { Process { started: Counter::new(), failures: Counter::new(), deaths: Counter::new(), running: Integer::new(), } } } impl Collection for Metrics { fn visit<'x>(&'x self, visitor: &mut Visitor<'x>) { visitor.metric(&MasterName("restarts"), &self.restarts); visitor.metric(&MasterName("sandboxes"), &self.sandboxes); visitor.metric(&MasterName("containers"), &self.containers); visitor.metric(&MasterName("queue"), &self.queue); visitor.metric(&GlobalName("started"), &self.started); visitor.metric(&GlobalName("failures"), &self.failures); visitor.metric(&GlobalName("deaths"), &self.deaths); visitor.metric(&GlobalName("running"), &self.running); for (&(ref g, ref n), ref p) in &self.processes { visitor.metric(&ProcessName(g, n, "started"), &p.started); visitor.metric(&ProcessName(g, n, "failures"), &p.failures); visitor.metric(&ProcessName(g, n, "deaths"), &p.deaths); visitor.metric(&ProcessName(g, n, "running"), &p.running); } } } impl Name for MasterName { fn get(&self, key: &str) -> Option<&str> { match key { "group" => Some("master"), "metric" => Some(self.0), _ => None, } } fn visit(&self, s: &mut NameVisitor) { s.visit_pair("group", "master"); s.visit_pair("metric", self.0); } } impl Name for GlobalName { fn get(&self, key: &str) -> Option<&str> { match key { "group" => Some("containers"), "metric" => Some(self.0), _ => None, } } fn visit(&self, s: &mut NameVisitor) { s.visit_pair("group", "containers"); s.visit_pair("metric", self.0); } } impl<'a> Name for ProcessName<'a> { fn get(&self, _key: &str) -> Option<&str> { unimplemented!(); } fn visit(&self, s: &mut NameVisitor) { s.visit_pair("group", &format!("processes.{}.{}", self.0, self.1)); s.visit_pair("metric", self.2); } }