Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sub-module for reading tc stats #8210

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 75 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ members = [
"below/render",
"below/resctrlfs",
"below/store",
"below/tc",
"below/view",
]
resolver = "2"
2 changes: 2 additions & 0 deletions below/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub struct BelowConfig {
pub btrfs_min_pct: f64,
pub enable_ethtool_stats: bool,
pub enable_resctrl_stats: bool,
pub enable_tc_stats: bool,
}

impl Default for BelowConfig {
Expand All @@ -63,6 +64,7 @@ impl Default for BelowConfig {
btrfs_min_pct: btrfs::DEFAULT_MIN_PCT,
enable_ethtool_stats: false,
enable_resctrl_stats: false,
enable_tc_stats: false,
}
}
}
Expand Down
87 changes: 87 additions & 0 deletions below/dump/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use model::SingleDiskModelFieldId;
use model::SingleNetModelFieldId;
use model::SingleProcessModelFieldId;
use model::SingleQueueModelFieldId;
use model::SingleTcModelFieldId;
use model::SystemModelFieldId;
use once_cell::sync::Lazy;
use regex::Regex;
Expand Down Expand Up @@ -1036,6 +1037,81 @@ $ below dump ethtool-queue -b "08:30:00" -e "08:30:30" -O json
)
});

/// Represents the fields of the tc model.
#[derive(
Clone,
Debug,
PartialEq,
below_derive::EnumFromStr,
below_derive::EnumToString
)]
pub enum TcAggField {
Stats,
XStats,
QDisc,
}

impl AggField<SingleTcModelFieldId> for TcAggField {
fn expand(&self, _detail: bool) -> Vec<SingleTcModelFieldId> {
use model::SingleTcModelFieldId as FieldId;

match self {
Self::Stats => vec![
FieldId::Interface,
FieldId::Kind,
FieldId::Qlen,
FieldId::Bps,
FieldId::Pps,
FieldId::BytesPerSec,
FieldId::PacketsPerSec,
FieldId::BacklogPerSec,
FieldId::DropsPerSec,
FieldId::RequeuesPerSec,
FieldId::OverlimitsPerSec,
],
Self::XStats => enum_iterator::all::<model::XStatsModelFieldId>()
.map(FieldId::Xstats)
.collect::<Vec<_>>(),
Self::QDisc => enum_iterator::all::<model::QDiscModelFieldId>()
.map(FieldId::Qdisc)
.collect::<Vec<_>>(),
}
}
}

pub type TcOptionField = DumpOptionField<SingleTcModelFieldId, TcAggField>;

pub static DEFAULT_TC_FIELDS: &[TcOptionField] = &[
DumpOptionField::Unit(DumpField::Common(CommonField::Datetime)),
DumpOptionField::Agg(TcAggField::Stats),
DumpOptionField::Agg(TcAggField::XStats),
DumpOptionField::Agg(TcAggField::QDisc),
DumpOptionField::Unit(DumpField::Common(CommonField::Timestamp)),
];

const TC_ABOUT: &str = "Dump the tc related stats with qdiscs";

/// Generated about message for tc (traffic control) dump so supported fields are up-to-date.
static TC_LONG_ABOUT: Lazy<String> = Lazy::new(|| {
format!(
r#"{about}
********************** Available fields **********************
{common_fields}, {tc_fields}.
********************** Aggregated fields **********************
* --detail: no effect.
* --default: includes [{default_fields}].
* --everything: includes everything (equivalent to --default --detail).
********************** Example Commands **********************
Example:
$ below dump tc -b "08:30:00" -e "08:30:30" -O json
"#,
about = TC_ABOUT,
common_fields = join(enum_iterator::all::<CommonField>()),
tc_fields = join(enum_iterator::all::<SingleTcModelFieldId>()),
default_fields = join(DEFAULT_TC_FIELDS.to_owned()),
)
});

make_option! (OutputFormat {
"raw": Raw,
"csv": Csv,
Expand Down Expand Up @@ -1219,4 +1295,15 @@ pub enum DumpCommand {
#[clap(long, short, conflicts_with("fields"))]
pattern: Option<String>,
},
#[clap(about = TC_ABOUT, long_about = TC_LONG_ABOUT.as_str())]
Tc {
/// Select which fields to display and in what order.
#[clap(short, long)]
fields: Option<Vec<TcOptionField>>,
#[clap(flatten)]
opts: GeneralOpt,
/// Saved pattern in the dumprc file under [tc] section.
#[clap(long, short, conflicts_with("fields"))]
pattern: Option<String>,
},
}
38 changes: 38 additions & 0 deletions below/dump/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub mod network;
pub mod print;
pub mod process;
pub mod system;
pub mod tc;
pub mod tmain;
pub mod transport;

Expand Down Expand Up @@ -117,6 +118,7 @@ pub type IfaceField = DumpField<model::SingleNetModelFieldId>;
// Essentially the same as NetworkField
pub type TransportField = DumpField<model::NetworkModelFieldId>;
pub type EthtoolQueueField = DumpField<model::SingleQueueModelFieldId>;
pub type TcField = DumpField<model::SingleTcModelFieldId>;

fn get_advance(
logger: slog::Logger,
Expand Down Expand Up @@ -559,5 +561,41 @@ pub fn run(
errs,
)
}
DumpCommand::Tc {
fields,
opts,
pattern,
} => {
let (time_begin, time_end, advance) =
get_advance(logger, dir, host, port, snapshot, &opts)?;
let detail = opts.everything || opts.detail;
let fields = if let Some(pattern_key) = pattern {
parse_pattern(filename, pattern_key, "tc")
} else {
fields
};
let fields = expand_fields(
match fields.as_ref() {
Some(fields) => fields,
_ => command::DEFAULT_TC_FIELDS,
},
detail,
);
let tc = tc::Tc::new(&opts, fields);
let mut output: Box<dyn Write> = match opts.output.as_ref() {
Some(file_path) => Box::new(File::create(file_path)?),
None => Box::new(io::stdout()),
};
dump_timeseries(
advance,
time_begin,
time_end,
&tc,
output.as_mut(),
opts.output_format,
opts.br,
errs,
)
}
}
}
Loading
Loading