diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs index 234ce8ecbd..4896478234 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs @@ -25,7 +25,8 @@ use subspace_erasure_coding::ErasureCoding; use subspace_farmer::piece_cache::PieceCache; use subspace_farmer::single_disk_farm::farming::FarmingNotification; use subspace_farmer::single_disk_farm::{ - SectorPlottingDetails, SectorUpdate, SingleDiskFarm, SingleDiskFarmError, SingleDiskFarmOptions, + SectorExpirationDetails, SectorPlottingDetails, SectorUpdate, SingleDiskFarm, + SingleDiskFarmError, SingleDiskFarmOptions, }; use subspace_farmer::utils::farmer_piece_getter::FarmerPieceGetter; use subspace_farmer::utils::piece_validator::SegmentCommitmentPieceValidator; @@ -664,6 +665,21 @@ where info!("Finished collecting already plotted pieces successfully"); + for single_disk_farm in single_disk_farms.iter() { + farmer_metrics.update_farm_size( + single_disk_farm.id(), + single_disk_farm.total_sectors_count(), + ); + farmer_metrics.inc_farm_plotted( + single_disk_farm.id(), + single_disk_farm + .plotted_sectors_count() + .await + .try_into() + .unwrap(), + ); + } + let mut single_disk_farms_stream = single_disk_farms .into_iter() .enumerate() @@ -732,6 +748,17 @@ where on_plotted_sector_callback(plotted_sector, old_plotted_sector); farmer_metrics.observe_sector_plotting_time(&single_disk_farm_id, time); farmer_metrics.sector_plotted.inc(); + if old_plotted_sector.is_some() { + farmer_metrics.inc_farm_replotted(&single_disk_farm_id); + } else { + farmer_metrics.inc_farm_plotted(&single_disk_farm_id, 1); + } + } + SectorUpdate::Expiration(SectorExpirationDetails::AboutToExpire) => { + farmer_metrics.inc_farm_about_to_expire(&single_disk_farm_id, 1); + } + SectorUpdate::Expiration(SectorExpirationDetails::Expired) => { + farmer_metrics.inc_farm_expired(&single_disk_farm_id, 1); } _ => {} } diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs index 6be9d3c5ec..88766f9d4a 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/metrics.rs @@ -1,9 +1,11 @@ use prometheus_client::metrics::counter::Counter; use prometheus_client::metrics::family::Family; +use prometheus_client::metrics::gauge::Gauge; use prometheus_client::metrics::histogram::{exponential_buckets, Histogram}; use prometheus_client::registry::{Registry, Unit}; -use std::sync::atomic::AtomicU64; +use std::sync::atomic::{AtomicI64, AtomicU64}; use std::time::Duration; +use subspace_core_primitives::SectorIndex; use subspace_farmer::single_disk_farm::farming::ProvingResult; use subspace_farmer::single_disk_farm::{FarmingError, SingleDiskFarmId}; @@ -16,6 +18,10 @@ pub(super) struct FarmerMetrics { sector_encoding_time: Family, Histogram>, sector_writing_time: Family, Histogram>, sector_plotting_time: Family, Histogram>, + farm_size: Family, Gauge>, + farm_plotted: Family, Gauge>, + farm_expired: Family, Gauge>, + farm_about_to_expire: Family, Gauge>, pub(super) sector_downloading: Counter, pub(super) sector_downloaded: Counter, pub(super) sector_encoding: Counter, @@ -104,6 +110,42 @@ impl FarmerMetrics { sector_plotting_time.clone(), ); + let farm_size = Family::<_, _>::new_with_constructor(Gauge::<_, _>::default); + + sub_registry.register_with_unit( + "farm_size", + "Farm size", + Unit::Other("sectors".to_string()), + farm_size.clone(), + ); + + let farm_plotted = Family::<_, _>::new_with_constructor(Gauge::<_, _>::default); + + sub_registry.register_with_unit( + "farm_plotted", + "Number of plotted farm sectors", + Unit::Other("sectors".to_string()), + farm_plotted.clone(), + ); + + let farm_expired = Family::<_, _>::new_with_constructor(Gauge::<_, _>::default); + + sub_registry.register_with_unit( + "farm_expired", + "Number of expired farm sectors", + Unit::Other("sectors".to_string()), + farm_expired.clone(), + ); + + let farm_about_to_expire = Family::<_, _>::new_with_constructor(Gauge::<_, _>::default); + + sub_registry.register_with_unit( + "farm_about_to_expire", + "Number of farm sectors about to expire", + Unit::Other("sectors".to_string()), + farm_about_to_expire.clone(), + ); + let sector_downloading = Counter::<_, _>::default(); sub_registry.register_with_unit( @@ -184,6 +226,10 @@ impl FarmerMetrics { sector_encoding_time, sector_writing_time, sector_plotting_time, + farm_size, + farm_plotted, + farm_expired, + farm_about_to_expire, sector_downloading, sector_downloaded, sector_encoding, @@ -286,4 +332,100 @@ impl FarmerMetrics { )]) .observe(time.as_secs_f64()); } + + pub(super) fn update_farm_size( + &self, + single_disk_farm_id: &SingleDiskFarmId, + sectors: SectorIndex, + ) { + self.farm_size + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .set(i64::from(sectors)); + } + + pub(super) fn inc_farm_plotted( + &self, + single_disk_farm_id: &SingleDiskFarmId, + sectors: SectorIndex, + ) { + self.farm_plotted + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .inc_by(i64::from(sectors)); + } + + pub(super) fn inc_farm_expired( + &self, + single_disk_farm_id: &SingleDiskFarmId, + sectors: SectorIndex, + ) { + self.farm_expired + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .inc_by(i64::from(sectors)); + self.farm_plotted + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .dec_by(i64::from(sectors)); + } + + pub(super) fn inc_farm_about_to_expire( + &self, + single_disk_farm_id: &SingleDiskFarmId, + sectors: SectorIndex, + ) { + self.farm_about_to_expire + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .inc_by(i64::from(sectors)); + self.farm_plotted + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .dec_by(i64::from(sectors)); + } + + pub(super) fn inc_farm_replotted(&self, single_disk_farm_id: &SingleDiskFarmId) { + self.farm_plotted + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .inc(); + if self + .farm_expired + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .get() + > 0 + { + self.farm_expired + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .dec(); + } else { + self.farm_about_to_expire + .get_or_create(&vec![( + "farm_id".to_string(), + single_disk_farm_id.to_string(), + )]) + .dec(); + } + } }