20260609 CIR区分fresh和cached验证输入
This commit is contained in:
@@ -352,11 +352,24 @@ impl Histogram {
|
||||
struct CirMetrics {
|
||||
version: u32,
|
||||
objects: u64,
|
||||
fresh_objects: u64,
|
||||
cached_objects: u64,
|
||||
trust_anchors: u64,
|
||||
rejected_objects: u64,
|
||||
fresh_rejected_objects: u64,
|
||||
cached_rejected_objects: u64,
|
||||
object_list_sha256: String,
|
||||
fresh_object_list_sha256: String,
|
||||
cached_object_list_sha256: String,
|
||||
reject_list_sha256: String,
|
||||
fresh_reject_list_sha256: String,
|
||||
cached_reject_list_sha256: String,
|
||||
objects_by_type: BTreeMap<String, u64>,
|
||||
fresh_objects_by_type: BTreeMap<String, u64>,
|
||||
cached_objects_by_type: BTreeMap<String, u64>,
|
||||
rejected_objects_by_type: BTreeMap<String, u64>,
|
||||
fresh_rejected_objects_by_type: BTreeMap<String, u64>,
|
||||
cached_rejected_objects_by_type: BTreeMap<String, u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
@@ -973,25 +986,62 @@ fn parse_cir(path: &Path, snapshot: &mut MetricsSnapshot) {
|
||||
{
|
||||
Ok(cir) => {
|
||||
let mut objects_by_type = BTreeMap::new();
|
||||
for object in &cir.objects {
|
||||
for object in cir.validated_objects() {
|
||||
*objects_by_type
|
||||
.entry(object_type_from_uri(&object.rsync_uri))
|
||||
.or_default() += 1;
|
||||
}
|
||||
let mut fresh_objects_by_type = BTreeMap::new();
|
||||
for object in &cir.fresh_validated_objects {
|
||||
*fresh_objects_by_type
|
||||
.entry(object_type_from_uri(&object.rsync_uri))
|
||||
.or_default() += 1;
|
||||
}
|
||||
let mut cached_objects_by_type = BTreeMap::new();
|
||||
for object in &cir.cached_validated_objects {
|
||||
*cached_objects_by_type
|
||||
.entry(object_type_from_uri(&object.rsync_uri))
|
||||
.or_default() += 1;
|
||||
}
|
||||
let mut rejected_objects_by_type = BTreeMap::new();
|
||||
for object in &cir.rejected_objects {
|
||||
for object in cir.rejected_objects() {
|
||||
*rejected_objects_by_type
|
||||
.entry(object_type_from_uri(&object.object_uri))
|
||||
.or_default() += 1;
|
||||
}
|
||||
let mut fresh_rejected_objects_by_type = BTreeMap::new();
|
||||
for object in &cir.fresh_rejected_objects {
|
||||
*fresh_rejected_objects_by_type
|
||||
.entry(object_type_from_uri(&object.object_uri))
|
||||
.or_default() += 1;
|
||||
}
|
||||
let mut cached_rejected_objects_by_type = BTreeMap::new();
|
||||
for object in &cir.cached_rejected_objects {
|
||||
*cached_rejected_objects_by_type
|
||||
.entry(object_type_from_uri(&object.object_uri))
|
||||
.or_default() += 1;
|
||||
}
|
||||
snapshot.cir = Some(CirMetrics {
|
||||
version: cir.version,
|
||||
objects: cir.objects.len() as u64,
|
||||
objects: cir.validated_object_count() as u64,
|
||||
fresh_objects: cir.fresh_validated_objects.len() as u64,
|
||||
cached_objects: cir.cached_validated_objects.len() as u64,
|
||||
trust_anchors: cir.trust_anchors.len() as u64,
|
||||
rejected_objects: cir.rejected_objects.len() as u64,
|
||||
rejected_objects: cir.rejected_object_count() as u64,
|
||||
fresh_rejected_objects: cir.fresh_rejected_objects.len() as u64,
|
||||
cached_rejected_objects: cir.cached_rejected_objects.len() as u64,
|
||||
object_list_sha256: hex::encode(&cir.object_list_sha256),
|
||||
fresh_object_list_sha256: hex::encode(&cir.fresh_object_list_sha256),
|
||||
cached_object_list_sha256: hex::encode(&cir.cached_object_list_sha256),
|
||||
reject_list_sha256: hex::encode(&cir.reject_list_sha256),
|
||||
fresh_reject_list_sha256: hex::encode(&cir.fresh_reject_list_sha256),
|
||||
cached_reject_list_sha256: hex::encode(&cir.cached_reject_list_sha256),
|
||||
objects_by_type,
|
||||
fresh_objects_by_type,
|
||||
cached_objects_by_type,
|
||||
rejected_objects_by_type,
|
||||
fresh_rejected_objects_by_type,
|
||||
cached_rejected_objects_by_type,
|
||||
});
|
||||
}
|
||||
Err(err) => snapshot
|
||||
@@ -1580,6 +1630,14 @@ fn render_cir_metrics(writer: &mut PromWriter<'_>, instance: &str, cir: &CirMetr
|
||||
&[label("instance", instance)],
|
||||
cir.objects as f64,
|
||||
);
|
||||
for (source, count) in [("fresh", cir.fresh_objects), ("cached", cir.cached_objects)] {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_objects_by_source",
|
||||
"CIR object count by validation input source",
|
||||
&[label("instance", instance), label("source", source)],
|
||||
count as f64,
|
||||
);
|
||||
}
|
||||
writer.gauge(
|
||||
"ours_rp_cir_trust_anchors",
|
||||
"CIR trust anchor count",
|
||||
@@ -1592,6 +1650,29 @@ fn render_cir_metrics(writer: &mut PromWriter<'_>, instance: &str, cir: &CirMetr
|
||||
&[label("instance", instance)],
|
||||
cir.rejected_objects as f64,
|
||||
);
|
||||
for (source, count) in [
|
||||
("fresh", cir.fresh_rejected_objects),
|
||||
("cached", cir.cached_rejected_objects),
|
||||
] {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_rejected_objects_by_source",
|
||||
"CIR rejected object count by validation input source",
|
||||
&[label("instance", instance), label("source", source)],
|
||||
count as f64,
|
||||
);
|
||||
}
|
||||
for (source, digest) in [
|
||||
("merged", cir.object_list_sha256.as_str()),
|
||||
("fresh", cir.fresh_object_list_sha256.as_str()),
|
||||
("cached", cir.cached_object_list_sha256.as_str()),
|
||||
] {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_object_list_digest_present",
|
||||
"CIR object list digest is present by validation input source",
|
||||
&[label("instance", instance), label("source", source)],
|
||||
if digest.len() == 64 { 1.0 } else { 0.0 },
|
||||
);
|
||||
}
|
||||
writer.gauge(
|
||||
"ours_rp_cir_reject_list_digest_present",
|
||||
"CIR reject list digest is present",
|
||||
@@ -1602,6 +1683,18 @@ fn render_cir_metrics(writer: &mut PromWriter<'_>, instance: &str, cir: &CirMetr
|
||||
0.0
|
||||
},
|
||||
);
|
||||
for (source, digest) in [
|
||||
("merged", cir.reject_list_sha256.as_str()),
|
||||
("fresh", cir.fresh_reject_list_sha256.as_str()),
|
||||
("cached", cir.cached_reject_list_sha256.as_str()),
|
||||
] {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_reject_list_digest_present_by_source",
|
||||
"CIR reject list digest is present by validation input source",
|
||||
&[label("instance", instance), label("source", source)],
|
||||
if digest.len() == 64 { 1.0 } else { 0.0 },
|
||||
);
|
||||
}
|
||||
for (object_type, count) in &cir.objects_by_type {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_objects_by_type",
|
||||
@@ -1613,6 +1706,23 @@ fn render_cir_metrics(writer: &mut PromWriter<'_>, instance: &str, cir: &CirMetr
|
||||
*count as f64,
|
||||
);
|
||||
}
|
||||
for (source, counts) in [
|
||||
("fresh", &cir.fresh_objects_by_type),
|
||||
("cached", &cir.cached_objects_by_type),
|
||||
] {
|
||||
for (object_type, count) in counts {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_objects_by_source_type",
|
||||
"CIR object count by validation input source and file type",
|
||||
&[
|
||||
label("instance", instance),
|
||||
label("source", source),
|
||||
label("object_type", object_type),
|
||||
],
|
||||
*count as f64,
|
||||
);
|
||||
}
|
||||
}
|
||||
for (object_type, count) in &cir.rejected_objects_by_type {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_rejected_objects_by_type",
|
||||
@@ -1624,6 +1734,23 @@ fn render_cir_metrics(writer: &mut PromWriter<'_>, instance: &str, cir: &CirMetr
|
||||
*count as f64,
|
||||
);
|
||||
}
|
||||
for (source, counts) in [
|
||||
("fresh", &cir.fresh_rejected_objects_by_type),
|
||||
("cached", &cir.cached_rejected_objects_by_type),
|
||||
] {
|
||||
for (object_type, count) in counts {
|
||||
writer.gauge(
|
||||
"ours_rp_cir_rejected_objects_by_source_type",
|
||||
"CIR rejected object count by validation input source and file type",
|
||||
&[
|
||||
label("instance", instance),
|
||||
label("source", source),
|
||||
label("object_type", object_type),
|
||||
],
|
||||
*count as f64,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_ccr_metrics(writer: &mut PromWriter<'_>, instance: &str, ccr: &CcrMetrics) {
|
||||
@@ -2092,8 +2219,8 @@ mod tests {
|
||||
encode_content_info,
|
||||
};
|
||||
use crate::cir::{
|
||||
CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirRejectedObject,
|
||||
CirTrustAnchor, compute_reject_list_sha256, encode_cir, sha256,
|
||||
CanonicalInputRepresentation, CirObject, CirRejectedObject, CirTrustAnchor, encode_cir,
|
||||
sha256,
|
||||
};
|
||||
use tempfile::TempDir;
|
||||
|
||||
@@ -2154,7 +2281,7 @@ mod tests {
|
||||
assert!(snapshot.repo_stats[0].sync_success);
|
||||
assert_eq!(snapshot.repo_stats[0].download_bytes, 333);
|
||||
assert_eq!(snapshot.top_pp_by_object_count[0].object_count, 2);
|
||||
assert_eq!(snapshot.cir.as_ref().unwrap().objects, 1);
|
||||
assert_eq!(snapshot.cir.as_ref().unwrap().objects, 2);
|
||||
assert_eq!(snapshot.ccr.as_ref().unwrap().state_items["tas"], 1);
|
||||
let metrics = render_metrics(&snapshot);
|
||||
assert!(metrics.contains("ours_rp_repository_info"));
|
||||
@@ -2162,12 +2289,29 @@ mod tests {
|
||||
assert!(metrics.contains("ours_rp_repository_download_bytes"));
|
||||
assert!(metrics.contains("ours_rp_large_publication_points"));
|
||||
assert!(metrics.contains("ours_rp_cir_objects"));
|
||||
assert!(metrics.contains("ours_rp_cir_objects_by_source"));
|
||||
assert!(metrics.contains("ours_rp_cir_rejected_objects_by_source"));
|
||||
assert!(metrics.contains("ours_rp_cir_objects_by_source_type"));
|
||||
assert!(metrics.contains("ours_rp_cir_rejected_objects_by_source_type"));
|
||||
assert!(metrics.contains("ours_rp_cir_object_list_digest_present"));
|
||||
assert!(metrics.contains("ours_rp_cir_reject_list_digest_present_by_source"));
|
||||
assert!(metrics.contains("ours_rp_ccr_state_items"));
|
||||
assert!(
|
||||
metrics.contains(r#"ours_rp_cir_objects_by_source{instance="test",source="fresh"} 2"#)
|
||||
);
|
||||
assert!(
|
||||
metrics.contains(r#"ours_rp_cir_objects_by_source{instance="test",source="cached"} 0"#)
|
||||
);
|
||||
assert!(metrics.contains(
|
||||
r#"ours_rp_cir_rejected_objects_by_source{instance="test",source="fresh"} 1"#
|
||||
));
|
||||
assert!(metrics.contains(r#"ours_rp_vrps{instance="test",kind="total"} 3"#));
|
||||
assert!(metrics.contains(r#"ours_rp_vrps{instance="test",kind="unique"} 2"#));
|
||||
let status = render_status_json(&snapshot).expect("status");
|
||||
assert!(status.contains("topPublicationPointsByObjectCount"));
|
||||
assert!(status.contains(r#""vrpsUnique": 2"#));
|
||||
assert!(status.contains(r#""freshObjects": 2"#));
|
||||
assert!(status.contains(r#""cachedObjects": 0"#));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2186,30 +2330,33 @@ mod tests {
|
||||
object_uri: "rsync://repo.example/a/bad.roa".to_string(),
|
||||
reason: Some("bad".to_string()),
|
||||
}];
|
||||
let cir = CanonicalInputRepresentation {
|
||||
version: crate::cir::CIR_VERSION_V3,
|
||||
hash_alg: CirHashAlgorithm::Sha256,
|
||||
validation_time: time::OffsetDateTime::parse(
|
||||
let cir = CanonicalInputRepresentation::new_v4(
|
||||
time::OffsetDateTime::parse(
|
||||
"2026-05-25T00:00:00Z",
|
||||
&time::format_description::well_known::Rfc3339,
|
||||
)
|
||||
.unwrap(),
|
||||
objects: vec![CirObject {
|
||||
rsync_uri: "rsync://repo.example/a/a.roa".to_string(),
|
||||
sha256: vec![1; 32],
|
||||
}],
|
||||
trust_anchors: vec![CirTrustAnchor {
|
||||
vec![
|
||||
CirObject {
|
||||
rsync_uri: "rsync://repo.example/a/a.roa".to_string(),
|
||||
sha256: vec![1; 32],
|
||||
},
|
||||
CirObject {
|
||||
rsync_uri: "rsync://repo.example/a/bad.roa".to_string(),
|
||||
sha256: vec![2; 32],
|
||||
},
|
||||
],
|
||||
Vec::new(),
|
||||
vec![CirTrustAnchor {
|
||||
ta_rsync_uri: "rsync://repo.example/ta.cer".to_string(),
|
||||
tal_uri: "https://tal.example/tal.tal".to_string(),
|
||||
tal_bytes: b"rsync://repo.example/ta.cer\n\nAQID\n".to_vec(),
|
||||
ta_certificate_der: b"ta".to_vec(),
|
||||
ta_certificate_sha256: sha256(b"ta"),
|
||||
}],
|
||||
reject_list_sha256: compute_reject_list_sha256(
|
||||
rejected.iter().map(|item| item.object_uri.as_str()),
|
||||
),
|
||||
rejected_objects: rejected,
|
||||
};
|
||||
rejected,
|
||||
Vec::new(),
|
||||
);
|
||||
encode_cir(&cir).expect("encode cir")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user