Skip to content

Commit

Permalink
Add sub-module for reading tc stats (#8210)
Browse files Browse the repository at this point in the history
Summary:
- Adds the sub-crate for reading `tc` stats
- Uses `netlink-packet-route` library which reads `qdisc`s via rtnetlink

Result:
```sh
$ below dump tc -b '5s ago'
Datetime            Interface   Kind       Queue Length   Bps        Pps        Bytes      Packets    Backlog    Drops      Requeues   Overlimits   MaxPacket   EcnMark    NewFlowsLen   OldFlowsLen   CeMark     DropOverlimit   NewFlowCount   MemoryUsage   DropOvermemory   Target     Limit      Interval   Ecn        Quantum    CeThreshold   DropBatchSize   MemoryLimit   Flows      Timestamp
2024-01-30 20:24:31 lo          noqueue    0              0.0 B/s    0/s        0.0 B/s    0/s        0/s        0/s        0/s        0/s          ?           ?          ?             ?             ?          ?               ?              ?             ?                ?          ?          ?          ?          ?          ?             ?               ?             ?          1706646271
2024-01-30 20:24:31 ens5        mq         0              0.0 B/s    0/s        167 B/s    2/s        0/s        0/s        0/s        0/s          ?           ?          ?             ?             ?          ?               ?              ?             ?                ?          ?          ?          ?          ?          ?             ?               ?             ?          1706646271
2024-01-30 20:24:31 ens5        fq_codel   0              0.0 B/s    0/s        0.0 B/s    0/s        0/s        0/s        0/s        0/s          110         0          0             0             0          0/s             0/s            0/s           0/s              4999       10240      99999      1          1514       0             64              33554432      0/s        1706646271
2024-01-30 20:24:31 ens5        fq_codel   0              0.0 B/s    0/s        167 B/s    2/s        0/s        0/s        0/s        0/s          182         0          0             0             0          0/s             0/s            0/s           0/s              4999       10240      99999      1          1514       0             64              33554432      0/s        1706646271
```

Pull Request resolved: #8210

Reviewed By: lnyng

Differential Revision: D56263764

Pulled By: brianc118

fbshipit-source-id: bc225ddd29ddd81fa34d0f0f106177f4a1e2d4b9
  • Loading branch information
mmynk authored and facebook-github-bot committed Apr 25, 2024
1 parent 5ad32a5 commit 4acd748
Show file tree
Hide file tree
Showing 23 changed files with 1,715 additions and 13 deletions.
99 changes: 87 additions & 12 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,
)
}
}
}

0 comments on commit 4acd748

Please sign in to comment.