Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Almost working obdfilter exports
Browse files Browse the repository at this point in the history
  • Loading branch information
RDruon committed Jul 7, 2023
1 parent c072527 commit 6514d61
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 4 deletions.
10 changes: 10 additions & 0 deletions src/base_parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ where
.message("while getting param")
}

pub(crate) fn param_period<I>(x: &'static str) -> impl Parser<I, Output = Param>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
attempt(string(x).skip(token('.')))
.map(|x| Param(x.to_string()))
.message("while getting param")
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
6 changes: 6 additions & 0 deletions src/fixtures/valid/should-be-valid.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
obdfilter.ai400x2-OST0000.exports.0@lo.stats=
snapshot_time 1687448377.140066624 secs.nsecs
create 10 samples [usecs] 44 4724 8911 25377661
statfs 5842 samples [usecs] 0 32132 77736 1248293008
get_info 1 samples [usecs] 3541 3541 3541 12538681
obdfilter.ai400-OST0001.num_exports=4
6 changes: 6 additions & 0 deletions src/fixtures/valid/valid-single.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
obdfilter.ai400-OST0001.num_exports=4
obdfilter.ai400x2-OST0000.exports.0@lo.stats=
snapshot_time 1687448377.140066624 secs.nsecs
create 10 samples [usecs] 44 4724 8911 25377661
statfs 5842 samples [usecs] 0 32132 77736 1248293008
get_info 1 samples [usecs] 3541 3541 3541 12538681
49 changes: 45 additions & 4 deletions src/oss/obdfilter_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
// license that can be found in the LICENSE file.

use crate::{
base_parsers::{digits, param, period, target},
base_parsers::{digits, equals, param, param_period, period, target},
oss::job_stats,
stats_parser::stats,
types::{JobStatOst, Param, Record, Stat, Target, TargetStat, TargetStats, TargetVariant},
ExportStats,
};
use combine::{
choice,
error::ParseError,
parser::char::{newline, string},
many, many1,
parser::char::{alpha_num, newline, string},
stream::Stream,
Parser,
token, Parser,
};

pub(crate) const JOBSTATS: &str = "job_stats";
Expand All @@ -24,13 +26,17 @@ pub(crate) const TOT_DIRTY: &str = "tot_dirty";
pub(crate) const TOT_GRANTED: &str = "tot_granted";
pub(crate) const TOT_PENDING: &str = "tot_pending";

pub(crate) const OBD_STATS: [&str; 6] = [
pub(crate) const EXPORTS: &str = "exports";
pub(crate) const EXPORTS_PARAMS: &str = "exports.*.stats";

pub(crate) const OBD_STATS: [&str; 7] = [
JOBSTATS,
STATS,
NUM_EXPORTS,
TOT_DIRTY,
TOT_GRANTED,
TOT_PENDING,
EXPORTS_PARAMS,
];

/// Takes OBD_STATS and produces a list of params for
Expand All @@ -53,10 +59,35 @@ where
.message("while parsing target_name")
}

/// Parses a single obdfilter.*OST*.exports.*.stats line
fn exports_stat<I>() -> impl Parser<I, Output = ExportStats>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
(
many1::<String, _, _>(alpha_num().or(token('@'))).skip(period()),
string("stats").skip(equals()),
stats(),
)
.map(|(nid, _, stats)| ExportStats { nid, stats })
.message("while parsing export_stats")
}

/// Parses multiple obdfilter.*OST*.exports.*.stats lines
fn exports_stats<I>() -> impl Parser<I, Output = Vec<ExportStats>>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
(many(exports_stat())).map(|x| x)
}

#[derive(Debug)]
enum ObdfilterStat {
JobStats(Option<Vec<JobStatOst>>),
Stats(Vec<Stat>),
ExportStats(Vec<ExportStats>),
NumExports(u64),
TotDirty(u64),
TotGranted(u64),
Expand Down Expand Up @@ -90,6 +121,10 @@ where
param(TOT_PENDING),
digits().skip(newline()).map(ObdfilterStat::TotPending),
),
(
param_period(EXPORTS),
exports_stats().map(ObdfilterStat::ExportStats),
),
))
.message("while parsing obdfilter")
}
Expand Down Expand Up @@ -137,6 +172,12 @@ where
param,
value,
}),
ObdfilterStat::ExportStats(value) => TargetStats::ExportStatsOst(TargetStat {
kind: TargetVariant::Ost,
target,
param,
value,
}),
})
.map(Record::Target)
.message("while parsing obdfilter")
Expand Down
23 changes: 23 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,29 @@ osd-ldiskfs.fs2-MDT0000.kbytestotal=1819968
fn test_node_output() {
let x = include_str!("./fixtures/valid/valid.txt");

let result = parse()
.easy_parse(x)
.map_err(|err| err.map_position(|p| p.translate_position(x)))
.unwrap();

assert_debug_snapshot!(result);
}
#[test]
fn test_node_output_single_valid() {
let x = include_str!("./fixtures/valid/valid-single.txt");

let result = parse()
.easy_parse(x)
.map_err(|err| err.map_position(|p| p.translate_position(x)))
.unwrap();

assert_debug_snapshot!(result);
}

#[test]
fn test_node_output_should_be_valid() {
let x = include_str!("./fixtures/valid/should-be-valid.txt");

let result = parse()
.easy_parse(x)
.map_err(|err| err.map_position(|p| p.translate_position(x)))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
source: src/parser.rs
expression: result
---
(
[
Target(
NumExports(
TargetStat {
kind: Ost,
param: Param(
"num_exports",
),
target: Target(
"ai400-OST0001",
),
value: 4,
},
),
),
Target(
ExportStatsOst(
TargetStat {
kind: Ost,
param: Param(
"exports",
),
target: Target(
"ai400x2-OST0000",
),
value: [
ExportStats {
nid: "0@lo",
stats: [
Stat {
name: "create",
units: "usecs",
samples: 10,
min: Some(
44,
),
max: Some(
4724,
),
sum: Some(
8911,
),
sumsquare: Some(
25377661,
),
},
Stat {
name: "statfs",
units: "usecs",
samples: 5842,
min: Some(
0,
),
max: Some(
32132,
),
sum: Some(
77736,
),
sumsquare: Some(
1248293008,
),
},
Stat {
name: "get_info",
units: "usecs",
samples: 1,
min: Some(
3541,
),
max: Some(
3541,
),
sum: Some(
3541,
),
sumsquare: Some(
12538681,
),
},
],
},
],
},
),
),
],
"",
)
1 change: 1 addition & 0 deletions src/snapshots/lustre_collector__parser__tests__params.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ expression: params()
"obdfilter.*OST*.tot_dirty",
"obdfilter.*OST*.tot_granted",
"obdfilter.*OST*.tot_pending",
"obdfilter.*OST*.exports.*.stats",
"mdt.*.job_stats",
"mdt.*.md_stats",
"mdt.*MDT*.num_exports",
Expand Down
7 changes: 7 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ pub struct JobStatsOst {
pub job_stats: Option<Vec<JobStatOst>>,
}

#[derive(PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
pub struct ExportStats {
pub nid: String,
pub stats: Vec<Stat>,
}

/// Used to represent an unsigned timestamp in Lustre.
///
/// Only use this field whne you are sure that the timestamp is unsigned.
Expand Down Expand Up @@ -496,6 +502,7 @@ pub enum TargetStats {
ThreadsMax(TargetStat<u64>),
ThreadsStarted(TargetStat<u64>),
RecoveryStatus(TargetStat<RecoveryStatus>),
ExportStatsOst(TargetStat<Vec<ExportStats>>),
}

#[derive(PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
Expand Down

0 comments on commit 6514d61

Please sign in to comment.