Add BGP vs ROAs stats to prometheus. (#245)

This commit is contained in:
Tim Bruijnzeels
2020-06-10 12:54:16 +02:00
parent f8e41e305f
commit b5904c8f8c
4 changed files with 172 additions and 6 deletions
+52 -1
View File
@@ -1891,13 +1891,15 @@ impl CertAuthIssues {
pub struct CertAuthStats {
roa_count: usize,
child_count: usize,
bgp_stats: BgpStats,
}
impl CertAuthStats {
pub fn new(roa_count: usize, child_count: usize) -> Self {
pub fn new(roa_count: usize, child_count: usize, bgp_stats: BgpStats) -> Self {
CertAuthStats {
roa_count,
child_count,
bgp_stats,
}
}
@@ -1908,6 +1910,55 @@ impl CertAuthStats {
pub fn child_count(&self) -> usize {
self.child_count
}
pub fn bgp_stats(&self) -> &BgpStats {
&self.bgp_stats
}
}
//------------ BgpStats ------------------------------------------------------
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct BgpStats {
pub announcements_valid: usize,
pub announcements_invalid_asn: usize,
pub announcements_invalid_length: usize,
pub announcements_not_found: usize,
pub roas_stale: usize,
}
impl Default for BgpStats {
fn default() -> Self {
BgpStats {
announcements_valid: 0,
announcements_invalid_asn: 0,
announcements_invalid_length: 0,
announcements_not_found: 0,
roas_stale: 0,
}
}
}
impl BgpStats {
pub fn increment_valid(&mut self) {
self.announcements_valid += 1;
}
pub fn increment_invalid_asn(&mut self) {
self.announcements_invalid_asn += 1;
}
pub fn increment_invalid_length(&mut self) {
self.announcements_invalid_length += 1;
}
pub fn increment_not_found(&mut self) {
self.announcements_not_found += 1;
}
pub fn increment_stale(&mut self) {
self.roas_stale += 1;
}
}
//------------ ResSetErr -----------------------------------------------------
+18 -1
View File
@@ -2,7 +2,7 @@ use std::cmp::Ordering;
use std::collections::HashMap;
use std::fmt;
use crate::commons::api::RoaDefinition;
use crate::commons::api::{BgpStats, RoaDefinition};
use crate::commons::bgp::Announcement;
//------------ BgpAnalysisReport -------------------------------------------
@@ -32,6 +32,23 @@ impl BgpAnalysisReport {
}
}
impl From<BgpAnalysisReport> for BgpStats {
fn from(r: BgpAnalysisReport) -> BgpStats {
let mut stats = BgpStats::default();
for e in r.0.iter() {
match e.state {
BgpAnalysisState::AnnouncementValid => stats.increment_valid(),
BgpAnalysisState::AnnouncementInvalidAsn => stats.increment_invalid_asn(),
BgpAnalysisState::AnnouncementInvalidLength => stats.increment_invalid_length(),
BgpAnalysisState::AnnouncementNotFound => stats.increment_not_found(),
BgpAnalysisState::RoaStale => stats.increment_stale(),
_ => {} // nothing to see, move along
}
}
stats
}
}
impl fmt::Display for BgpAnalysisReport {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let entries = self.entries();
+95 -2
View File
@@ -19,8 +19,8 @@ use hyper::service::{make_service_fn, service_fn};
use hyper::Method;
use crate::commons::api::{
ChildHandle, CommandHistoryCriteria, Handle, ParentCaContact, ParentCaReq, ParentHandle,
PublisherList, RepositoryUpdate,
BgpStats, ChildHandle, CommandHistoryCriteria, Handle, ParentCaContact, ParentCaReq,
ParentHandle, PublisherList, RepositoryUpdate,
};
use crate::commons::error::Error;
use crate::commons::remote::rfc8183;
@@ -29,6 +29,7 @@ use crate::daemon::http::statics::statics;
use crate::daemon::http::{tls, tls_keys, HttpResponse, Request, RequestPath, RoutingResult};
use crate::daemon::krillserver::KrillServer;
use crate::upgrades::{post_start_upgrade, pre_start_upgrade};
use std::collections::HashMap;
//------------ State -----------------------------------------------------
@@ -175,6 +176,28 @@ pub async fn metrics(req: Request) -> RoutingResult {
let server = req.state();
let server = server.read().await;
struct AllBgpStats {
announcements_valid: HashMap<Handle, usize>,
announcements_invalid_asn: HashMap<Handle, usize>,
announcements_invalid_length: HashMap<Handle, usize>,
announcements_not_found: HashMap<Handle, usize>,
roas_stale: HashMap<Handle, usize>,
}
impl AllBgpStats {
fn add_ca(&mut self, ca: &Handle, stats: &BgpStats) {
self.announcements_valid
.insert(ca.clone(), stats.announcements_valid);
self.announcements_invalid_asn
.insert(ca.clone(), stats.announcements_invalid_asn);
self.announcements_invalid_length
.insert(ca.clone(), stats.announcements_invalid_length);
self.announcements_not_found
.insert(ca.clone(), stats.announcements_not_found);
self.roas_stale.insert(ca.clone(), stats.roas_stale);
}
}
let mut res = String::new();
let info = server.server_info();
@@ -277,6 +300,76 @@ pub async fn metrics(req: Request) -> RoutingResult {
));
}
// Aggregate ROA vs BGP stats per status
let mut all_bgp_stats = AllBgpStats {
announcements_valid: HashMap::new(),
announcements_invalid_asn: HashMap::new(),
announcements_invalid_length: HashMap::new(),
announcements_not_found: HashMap::new(),
roas_stale: HashMap::new(),
};
for (ca, status) in cas_status.iter() {
all_bgp_stats.add_ca(ca, status.bgp_stats());
}
res.push_str("\n");
res.push_str("# HELP krill_cas_bgp_announcements_valid number of valid announcements\n");
res.push_str("# TYPE krill_cas_bgp_announcements_valid gauge\n");
for (ca, nr) in all_bgp_stats.announcements_valid.iter() {
res.push_str(&format!(
"krill_cas_bgp_announcements_valid{{ca=\"{}\"}} {}\n",
ca, nr
));
}
res.push_str("\n");
res.push_str(
"# HELP krill_cas_bgp_announcements_invalid_asn number of announcements from an invalid asn\n",
);
res.push_str("# TYPE krill_cas_bgp_announcements_invalid_asn gauge\n");
for (ca, nr) in all_bgp_stats.announcements_invalid_asn.iter() {
res.push_str(&format!(
"krill_cas_bgp_announcements_invalid_asn{{ca=\"{}\"}} {}\n",
ca, nr
));
}
res.push_str("\n");
res.push_str(
"# HELP krill_cas_bgp_announcements_invalid_length number of announcements which are too specific for asn\n",
);
res.push_str("# TYPE krill_cas_bgp_announcements_invalid_length gauge\n");
for (ca, nr) in all_bgp_stats.announcements_invalid_length.iter() {
res.push_str(&format!(
"krill_cas_bgp_announcements_invalid_length{{ca=\"{}\"}} {}\n",
ca, nr
));
}
res.push_str("\n");
res.push_str(
"# HELP krill_cas_bgp_announcements_not_found number of announcements which are not covered by ROAs by this CA\n",
);
res.push_str("# TYPE krill_cas_bgp_announcements_not_found gauge\n");
for (ca, nr) in all_bgp_stats.announcements_not_found.iter() {
res.push_str(&format!(
"krill_cas_bgp_announcements_not_found{{ca=\"{}\"}} {}\n",
ca, nr
));
}
res.push_str("\n");
res.push_str(
"# HELP krill_cas_bgp_roas_stale number of ROAs for this CA for which no announcements are seen\n",
);
res.push_str("# TYPE krill_cas_bgp_roas_stale gauge\n");
for (ca, nr) in all_bgp_stats.roas_stale.iter() {
res.push_str(&format!(
"krill_cas_bgp_roas_stale{{ca=\"{}\"}} {}\n",
ca, nr
));
}
Ok(HttpResponse::text(res.into_bytes()))
} else {
Err(req)
+7 -2
View File
@@ -438,12 +438,17 @@ impl KrillServer {
for ca in self.caserver.ca_list().cas() {
// can't fail really, but to be sure
if let Ok(ca) = self.caserver.get_ca(ca.handle()) {
let roa_count = ca.roa_definitions().len();
let roas = ca.roa_definitions();
let roa_count = roas.len();
let child_count = ca.children().count();
let bgp_report = self
.bgp_analyser
.analyse(roas.as_slice(), &ca.all_resources());
res.insert(
ca.handle().clone(),
CertAuthStats::new(roa_count, child_count),
CertAuthStats::new(roa_count, child_count, bgp_report.into()),
);
}
}