diff options
author | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-12-14 11:49:04 -0800 |
---|---|---|
committer | Facebook GitHub Bot <facebook-github-bot@users.noreply.github.com> | 2023-12-14 11:49:04 -0800 |
commit | 1654f185ee1297f61ddffa595f4d691a2d7134a2 (patch) | |
tree | 780aed3a2a3c2a4c89848b849073bac3972a6bf4 | |
parent | 2a93635bcb797ad3ab45263bf4f9525de442cfb4 (diff) |
cgroupfs: Add Pids controller (#8215)
Summary: Pull Request resolved: https://github.com/facebookincubator/below/pull/8215
Reviewed By: antonis-m
Differential Revision: D52055696
Pulled By: brianc118
fbshipit-source-id: 4c6afc22c89ab21d18b018c5b8294f1f2420375e
-rw-r--r-- | below/cgroupfs/src/lib.rs | 10 | ||||
-rw-r--r-- | below/cgroupfs/src/test.rs | 2 | ||||
-rw-r--r-- | below/dump/src/command.rs | 4 | ||||
-rw-r--r-- | below/model/src/cgroup.rs | 40 | ||||
-rw-r--r-- | below/model/src/collector.rs | 2 | ||||
-rw-r--r-- | below/model/src/common_field_ids.rs | 4 | ||||
-rw-r--r-- | below/model/src/sample.rs | 2 | ||||
-rw-r--r-- | below/render/src/default_configs.rs | 16 | ||||
-rw-r--r-- | below/view/src/cgroup_tabs.rs | 5 |
9 files changed, 83 insertions, 2 deletions
diff --git a/below/cgroupfs/src/lib.rs b/below/cgroupfs/src/lib.rs index 8ca6d27e..2688bdc7 100644 --- a/below/cgroupfs/src/lib.rs +++ b/below/cgroupfs/src/lib.rs @@ -344,6 +344,16 @@ impl CgroupReader { self.read_singleline_controllers("cgroup.subtree_control") } + /// Read pids.current - returning current cgroup number of processes + pub fn read_pids_current(&self) -> Result<u64> { + self.read_singleline_file("pids.current") + } + + /// Read pids.max - returning max cgroup number of processes + pub fn read_pids_max(&self) -> Result<i64> { + self.read_singleline_integer_or_max_stat_file("pids.max") + } + /// Read memory.min - returning memory.min limit in bytes /// Will return -1 if the content is max pub fn read_memory_min(&self) -> Result<i64> { diff --git a/below/cgroupfs/src/test.rs b/below/cgroupfs/src/test.rs index 50111dda..2fea2316 100644 --- a/below/cgroupfs/src/test.rs +++ b/below/cgroupfs/src/test.rs @@ -139,6 +139,7 @@ macro_rules! singleline_integer_or_max_test { }; } +singleline_integer_or_max_test!(read_pids_max, "pids.max"); singleline_integer_or_max_test!(read_memory_min, "memory.min"); singleline_integer_or_max_test!(read_memory_low, "memory.low"); singleline_integer_or_max_test!(read_memory_high, "memory.high"); @@ -146,6 +147,7 @@ singleline_integer_or_max_test!(read_memory_max, "memory.max"); singleline_integer_or_max_test!(read_memory_swap_max, "memory.swap.max"); singleline_integer_or_max_test!(read_memory_zswap_max, "memory.zswap.max"); +test_success!(read_pids_current, "pids.current", b"10000\n", 10000); test_success!(read_cpu_weight, "cpu.weight", b"10000\n", 10000); test_failure!(read_cpu_weight, "cpu.weight", b"5000000000\n"); test_success!( diff --git a/below/dump/src/command.rs b/below/dump/src/command.rs index b633e72c..300a61af 100644 --- a/below/dump/src/command.rs +++ b/below/dump/src/command.rs @@ -549,6 +549,7 @@ pub enum CgroupAggField { Cpu, Mem, Io, + Pids, Pressure, } @@ -557,6 +558,7 @@ impl AggField<SingleCgroupModelFieldId> for CgroupAggField { use model::CgroupCpuModelFieldId as Cpu; use model::CgroupIoModelFieldId as Io; use model::CgroupMemoryModelFieldId as Mem; + use model::CgroupPidsModelFieldId as Pid; use model::CgroupPressureModelFieldId as Pressure; use model::SingleCgroupModelFieldId as FieldId; @@ -565,6 +567,7 @@ impl AggField<SingleCgroupModelFieldId> for CgroupAggField { Self::Cpu => enum_iterator::all::<Cpu>().map(FieldId::Cpu).collect(), Self::Mem => enum_iterator::all::<Mem>().map(FieldId::Mem).collect(), Self::Io => enum_iterator::all::<Io>().map(FieldId::Io).collect(), + Self::Pids => enum_iterator::all::<Pid>().map(FieldId::Pids).collect(), Self::Pressure => enum_iterator::all::<Pressure>() .map(FieldId::Pressure) .collect(), @@ -575,6 +578,7 @@ impl AggField<SingleCgroupModelFieldId> for CgroupAggField { Self::Cpu => vec![FieldId::Cpu(Cpu::UsagePct)], Self::Mem => vec![FieldId::Mem(Mem::Total)], Self::Io => vec![FieldId::Io(Io::RbytesPerSec), FieldId::Io(Io::WbytesPerSec)], + Self::Pids => vec![FieldId::Pids(Pid::TidsCurrent)], Self::Pressure => vec![ FieldId::Pressure(Pressure::CpuSomePct), FieldId::Pressure(Pressure::MemoryFullPct), diff --git a/below/model/src/cgroup.rs b/below/model/src/cgroup.rs index 4917f26b..c0e9aeed 100644 --- a/below/model/src/cgroup.rs +++ b/below/model/src/cgroup.rs @@ -14,7 +14,7 @@ use super::*; -/// Collection of all data local to the cgroup, e.g. its memory/io/cpu usage. +/// Collection of all data local to the cgroup, e.g. its memory/io/cpu/pids usage. /// Nothing about child cgroups or siblings, and therefore "Single" in its name. #[derive(Clone, Debug, Default, Serialize, Deserialize, below_derive::Queriable)] pub struct SingleCgroupModel { @@ -32,6 +32,9 @@ pub struct SingleCgroupModel { #[queriable(preferred_name = mem)] pub memory: Option<CgroupMemoryModel>, #[queriable(subquery)] + #[queriable(preferred_name = pids)] + pub pids: Option<CgroupPidsModel>, + #[queriable(subquery)] #[queriable(preferred_name = io_details)] pub io: Option<BTreeMap<String, CgroupIoModel>>, #[queriable(subquery)] @@ -220,6 +223,8 @@ impl CgroupModel { let memory = Some(CgroupMemoryModel::new(sample, last)); + let pids = Some(CgroupPidsModel::new(sample)); + let pressure = sample .pressure .as_ref() @@ -278,6 +283,7 @@ impl CgroupModel { properties, cpu, memory, + pids, io, io_total, pressure, @@ -720,6 +726,36 @@ impl CgroupMemoryModel { Deserialize, below_derive::Queriable )] +pub struct CgroupPidsModel { + pub tids_current: Option<u64>, +} + +impl std::ops::Add for CgroupPidsModel { + type Output = Self; + + fn add(self, other: Self) -> Self::Output { + Self { + tids_current: opt_add(self.tids_current, other.tids_current), + } + } +} + +impl CgroupPidsModel { + pub fn new(sample: &CgroupSample) -> Self { + let tids_current = sample.tids_current; + CgroupPidsModel { tids_current } + } +} + +#[derive( + Clone, + Debug, + Default, + PartialEq, + Serialize, + Deserialize, + below_derive::Queriable +)] pub struct CgroupPressureModel { pub cpu_some_pct: Option<f64>, pub cpu_full_pct: Option<f64>, @@ -876,6 +912,7 @@ impl CgroupMemoryNumaModel { pub struct CgroupProperties { pub cgroup_controllers: Option<BTreeSet<String>>, pub cgroup_subtree_control: Option<BTreeSet<String>>, + pub tids_max: Option<i64>, pub memory_min: Option<i64>, pub memory_low: Option<i64>, pub memory_high: Option<i64>, @@ -896,6 +933,7 @@ impl CgroupProperties { Self { cgroup_controllers: sample.cgroup_controllers.clone(), cgroup_subtree_control: sample.cgroup_subtree_control.clone(), + tids_max: sample.tids_max, memory_min: sample.memory_min, memory_low: sample.memory_low, memory_high: sample.memory_high, diff --git a/below/model/src/collector.rs b/below/model/src/collector.rs index dd7ab9b5..5e08e34d 100644 --- a/below/model/src/collector.rs +++ b/below/model/src/collector.rs @@ -376,6 +376,8 @@ fn collect_cgroup_sample( Ok(CgroupSample { cpu_stat: wrap(reader.read_cpu_stat())?.map(Into::into), io_stat, + tids_current: wrap(reader.read_pids_current())?, + tids_max: wrap(reader.read_pids_max())?, memory_current: wrap(reader.read_memory_current().map(|v| v as i64))?, memory_stat: wrap(reader.read_memory_stat())?.map(Into::into), pressure: pressure_wrap(reader.read_pressure())?.map(Into::into), diff --git a/below/model/src/common_field_ids.rs b/below/model/src/common_field_ids.rs index 12b8e9e0..59c2b61f 100644 --- a/below/model/src/common_field_ids.rs +++ b/below/model/src/common_field_ids.rs @@ -23,7 +23,7 @@ /// /// This list also servers as documentation for available field ids that could /// be used in other below crates. A test ensures that this list is up-to-date. -pub const COMMON_MODEL_FIELD_IDS: [&str; 408] = [ +pub const COMMON_MODEL_FIELD_IDS: [&str; 410] = [ "system.hostname", "system.kernel_version", "system.os_release", @@ -140,6 +140,7 @@ pub const COMMON_MODEL_FIELD_IDS: [&str; 408] = [ "cgroup.[path:/<cgroup_path>/.]props.cpuset_cpus_effective", "cgroup.[path:/<cgroup_path>/.]props.cpuset_mems", "cgroup.[path:/<cgroup_path>/.]props.cpuset_mems_effective", + "cgroup.[path:/<cgroup_path>/.]props.tids_max", "cgroup.[path:/<cgroup_path>/.]props.memory_high", "cgroup.[path:/<cgroup_path>/.]props.memory_low", "cgroup.[path:/<cgroup_path>/.]props.memory_max", @@ -152,6 +153,7 @@ pub const COMMON_MODEL_FIELD_IDS: [&str; 408] = [ "cgroup.[path:/<cgroup_path>/.]cpu.nr_periods_per_sec", "cgroup.[path:/<cgroup_path>/.]cpu.nr_throttled_per_sec", "cgroup.[path:/<cgroup_path>/.]cpu.throttled_pct", + "cgroup.[path:/<cgroup_path>/.]pids.tids_current", "cgroup.[path:/<cgroup_path>/.]mem.total", "cgroup.[path:/<cgroup_path>/.]mem.swap", "cgroup.[path:/<cgroup_path>/.]mem.anon", diff --git a/below/model/src/sample.rs b/below/model/src/sample.rs index 5788f9e2..603a528c 100644 --- a/below/model/src/sample.rs +++ b/below/model/src/sample.rs @@ -29,6 +29,8 @@ pub struct Sample { pub struct CgroupSample { pub cpu_stat: Option<cgroupfs::CpuStat>, pub io_stat: Option<BTreeMap<String, cgroupfs::IoStat>>, + pub tids_current: Option<u64>, + pub tids_max: Option<i64>, pub memory_current: Option<i64>, pub memory_stat: Option<cgroupfs::MemoryStat>, pub pressure: Option<cgroupfs::Pressure>, diff --git a/below/render/src/default_configs.rs b/below/render/src/default_configs.rs index be35ca48..1bf9ee9d 100644 --- a/below/render/src/default_configs.rs +++ b/below/render/src/default_configs.rs @@ -44,6 +44,7 @@ impl HasRenderConfig for model::SingleCgroupModel { model::CgroupMemoryNumaModel::get_render_config_builder(&field_id.subquery_id) } Props(field_id) => model::CgroupProperties::get_render_config_builder(field_id), + Pids(field_id) => model::CgroupPidsModel::get_render_config_builder(field_id), } } } @@ -154,6 +155,7 @@ impl HasRenderConfigForDump for model::SingleCgroupModel { use model::CgroupCpuModelFieldId::*; use model::CgroupIoModelFieldId::*; use model::CgroupMemoryModelFieldId::*; + use model::CgroupPidsModelFieldId::*; use model::CgroupPressureModelFieldId::*; use model::CgroupStatModelFieldId::*; use model::SingleCgroupModelFieldId::*; @@ -175,6 +177,9 @@ impl HasRenderConfigForDump for model::SingleCgroupModel { NrThrottledPerSec => Some(gauge), ThrottledPct => Some(gauge.unit("percent")), }, + Pids(field_id) => match field_id { + TidsCurrent => Some(counter.unit("count")), + }, Io(field_id) => match field_id { RbytesPerSec => Some(gauge.unit("bytes_per_second")), WbytesPerSec => Some(gauge.unit("bytes_per_second")), @@ -276,6 +281,16 @@ impl HasRenderConfig for model::CgroupCpuModel { } } +impl HasRenderConfig for model::CgroupPidsModel { + fn get_render_config_builder(field_id: &Self::FieldId) -> RenderConfigBuilder { + use model::CgroupPidsModelFieldId::*; + let rc = RenderConfigBuilder::new(); + match field_id { + TidsCurrent => rc.title("Tids Current").format(Precision(1)), + } + } +} + impl HasRenderConfig for model::CgroupIoModel { fn get_render_config_builder(field_id: &Self::FieldId) -> RenderConfigBuilder { use model::CgroupIoModelFieldId::*; @@ -1476,6 +1491,7 @@ impl HasRenderConfig for model::CgroupProperties { // "cpu cpuset hugetlb io memory pids" is 33 chars CgroupControllers => rc.title("Controllers").width(35), CgroupSubtreeControl => rc.title("SubtreeControl").width(35), + TidsMax => rc.title("Tids Max").format(MaxOrReadableSize), MemoryMin => rc.title("Mem Min").format(MaxOrReadableSize), MemoryLow => rc.title("Mem Low").format(MaxOrReadableSize), MemoryHigh => rc.title("Mem High").format(MaxOrReadableSize), diff --git a/below/view/src/cgroup_tabs.rs b/below/view/src/cgroup_tabs.rs index da2798c5..4c23db5a 100644 --- a/below/view/src/cgroup_tabs.rs +++ b/below/view/src/cgroup_tabs.rs @@ -283,6 +283,7 @@ pub mod default_tabs { use model::CgroupMemoryModelFieldId::WorkingsetRestoreFile; use model::CgroupMemoryModelFieldId::Zswap; use model::CgroupMemoryModelFieldId::Zswapped; + use model::CgroupPidsModelFieldId::TidsCurrent; use model::CgroupPressureModelFieldId::CpuFullPct; use model::CgroupPressureModelFieldId::CpuSomePct; use model::CgroupPressureModelFieldId::IoFullPct; @@ -301,6 +302,7 @@ pub mod default_tabs { use model::CgroupPropertiesFieldId::MemoryMin; use model::CgroupPropertiesFieldId::MemorySwapMax; use model::CgroupPropertiesFieldId::MemoryZswapMax; + use model::CgroupPropertiesFieldId::TidsMax; use model::CgroupStatModelFieldId::NrDescendants; use model::CgroupStatModelFieldId::NrDyingDescendants; use model::SingleCgroupModelFieldId::CgroupStat; @@ -308,6 +310,7 @@ pub mod default_tabs { use model::SingleCgroupModelFieldId::Io; use model::SingleCgroupModelFieldId::Mem; use model::SingleCgroupModelFieldId::Name; + use model::SingleCgroupModelFieldId::Pids; use model::SingleCgroupModelFieldId::Pressure; use model::SingleCgroupModelFieldId::Props; use once_cell::sync::Lazy; @@ -333,6 +336,7 @@ pub mod default_tabs { ViewItem::from_default(Io(RwbytesPerSec)), ViewItem::from_default(CgroupStat(NrDescendants)), ViewItem::from_default(CgroupStat(NrDyingDescendants)), + ViewItem::from_default(Pids(TidsCurrent)), ]) }); @@ -437,6 +441,7 @@ pub mod default_tabs { ViewItem::from_default(Props(CpuWeight)), ViewItem::from_default(Props(CpusetCpus)), ViewItem::from_default(Props(CpusetCpusEffective)), + ViewItem::from_default(Props(TidsMax)), ViewItem::from_default(Props(CgroupControllers)), ]) }); |