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

Commit

Permalink
Add mdd metrics (#66)
Browse files Browse the repository at this point in the history
* Add mdd metrics

Add missing snapshot

* Update src/mdd_parser.rs

---------

Co-authored-by: Joe Grund <jgrund@whamcloud.io>
  • Loading branch information
RDruon and jgrund authored May 8, 2024
1 parent a00a767 commit 76653d7
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 3 deletions.
7 changes: 7 additions & 0 deletions fixtures/mdd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mdd.ai400x2-MDT0000.changelog_users=
current_index: 0
ID index (idle) mask
cl1 0 (327)
mdd.ai400x2-MDT0001.changelog_users=
current_index: 0
ID index (idle) mask
7 changes: 7 additions & 0 deletions src/fixtures/valid/valid.txt
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,10 @@ req_active 1 samples [reqs] 1 1 1 1
req_timeout 1 samples [secs] 15 15 15 225
reqbuf_avail 3 samples [bufs] 1 1 3 3
ldlm_bl_callback 1 samples [usecs] 16 16 16 256
mdd.ai400x2-MDT0000.changelog_users=
current_index: 0
ID index (idle) mask
cl1 0 (327)
mdd.ai400x2-MDT0001.changelog_users=
current_index: 0
ID index (idle) mask
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub(crate) mod exports_parser;
pub(crate) mod ldlm;
pub(crate) mod llite;
mod lnetctl_parser;
mod mdd_parser;
mod mds;
pub mod mgs;
mod node_stats_parsers;
Expand Down
147 changes: 147 additions & 0 deletions src/mdd_parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright (c) 2024 DDN. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use crate::{
base_parsers::{digits, param, period, target, till_newline, till_period},
types::{Param, Record, Target, TargetStat, TargetStats, TargetVariant},
ChangeLogUser, ChangelogStat,
};
use combine::{
attempt, choice,
error::{ParseError, StreamError},
many,
parser::char::{newline, spaces, string},
stream::{Stream, StreamErrorFor},
token, Parser,
};

pub(crate) const MDD: &str = "mdd";
pub(crate) const CHANGELOG_USERS: &str = "changelog_users";
pub(crate) fn params() -> Vec<String> {
vec![format!("{MDD}.*.{CHANGELOG_USERS}")]
}

#[derive(Debug)]
enum MddStat {
/// Changelog stat
ChangeLog(ChangelogStat),
}

fn target_and_variant<I>() -> impl Parser<I, Output = (Target, TargetVariant)>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
(
attempt(string("mdd").skip(till_period())).skip(period()),
target().skip(period()),
)
.and_then(move |(_, x)| -> Result<_, _> {
let variant = match (&x).try_into() {
Ok(x) => x,
Err(e) => return Err(StreamErrorFor::<I>::other(e)),
};

Ok((x, variant))
})
.message("while parsing target_and_variant")
}

fn table_headers<I>() -> impl Parser<I, Output = ()>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
(string("ID"), till_newline()).map(|_| ())
}

fn table_rows<I>() -> impl Parser<I, Output = Vec<ChangeLogUser>>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
many(attempt((
target(),
spaces(),
digits(),
spaces(),
token('('),
digits(),
token(')'),
till_newline().skip(newline()),
)))
.map(|x: Vec<_>| {
x.iter()
.map(|x| ChangeLogUser {
user: x.0.to_string(),
index: x.2,
idle_secs: x.5,
})
.collect()
})
}

fn mdd_stat<I>() -> impl Parser<I, Output = (Param, MddStat)>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
choice(((
param(CHANGELOG_USERS),
(
newline(),
string("current_index: "),
digits(),
newline(),
table_headers(),
newline(),
table_rows(),
)
.map(|(_, _, x, _, _, _, y)| {
MddStat::ChangeLog(ChangelogStat {
current_index: x,
users: y,
})
}),
)
.message("while parsing changelog"),))
}

pub(crate) fn parse<I>() -> impl Parser<I, Output = Record>
where
I: Stream<Token = char>,
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
(target_and_variant(), mdd_stat())
.map(|((target, kind), (param, stat))| match stat {
MddStat::ChangeLog(value) => TargetStats::Changelog(TargetStat {
kind,
target,
param,
value,
}),
})
.map(Record::Target)
.message("while parsing mdd")
}

#[cfg(test)]
mod tests {
use combine::{many, EasyParser};
use insta::assert_debug_snapshot;

use super::*;

#[test]
fn test_mdd_stats() {
static FIXTURE: &str = include_str!("../fixtures/mdd.txt");

let result = many::<Vec<_>, _, _>(parse())
.easy_parse(FIXTURE)
.map_err(|err| err.map_position(|p| p.translate_position(FIXTURE)))
.unwrap();

assert_debug_snapshot!(result);
}
}
4 changes: 3 additions & 1 deletion src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.

use crate::{
ldlm, llite,
ldlm, llite, mdd_parser,
mds::{self, client_count_parser},
mgs::mgs_parser,
osd_parser, oss, top_level_parser,
Expand All @@ -21,6 +21,7 @@ pub fn params() -> Vec<String> {
.chain(mds::params())
.chain(ldlm::params())
.chain(llite::params())
.chain(mdd_parser::params())
.collect()
}

Expand All @@ -38,6 +39,7 @@ where
mds::parse().map(|x| vec![x]),
ldlm::parse().map(|x| vec![x]),
llite::parse().map(|x| vec![x]),
mdd_parser::parse().map(|x| vec![x]),
)))
.map(|xs: Vec<_>| xs.into_iter().flatten().collect())
}
Expand Down
49 changes: 49 additions & 0 deletions src/snapshots/lustre_collector__mdd_parser__tests__mdd_stats.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
source: src/mdd_parser.rs
expression: result
---
(
[
Target(
Changelog(
TargetStat {
kind: Mdt,
param: Param(
"changelog_users",
),
target: Target(
"ai400x2-MDT0000",
),
value: ChangelogStat {
current_index: 0,
users: [
ChangeLogUser {
user: "cl1",
index: 0,
idle_secs: 327,
},
],
},
},
),
),
Target(
Changelog(
TargetStat {
kind: Mdt,
param: Param(
"changelog_users",
),
target: Target(
"ai400x2-MDT0001",
),
value: ChangelogStat {
current_index: 0,
users: [],
},
},
),
),
],
"",
)
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 @@ -59,4 +59,5 @@ expression: params()
"ldlm.services.ldlm_canceld.stats",
"ldlm.services.ldlm_cbd.stats",
"llite.*.stats",
"mdd.*.changelog_users",
]
Original file line number Diff line number Diff line change
Expand Up @@ -2629,6 +2629,46 @@ expression: result
],
),
),
Target(
Changelog(
TargetStat {
kind: Mdt,
param: Param(
"changelog_users",
),
target: Target(
"ai400x2-MDT0000",
),
value: ChangelogStat {
current_index: 0,
users: [
ChangeLogUser {
user: "cl1",
index: 0,
idle_secs: 327,
},
],
},
},
),
),
Target(
Changelog(
TargetStat {
kind: Mdt,
param: Param(
"changelog_users",
),
target: Target(
"ai400x2-MDT0001",
),
value: ChangelogStat {
current_index: 0,
users: [],
},
},
),
),
],
"",
)
2 changes: 1 addition & 1 deletion src/snapshots/lustre_collector__tests__params.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
source: src/lib.rs
expression: "xs.join(\" \")"
---
memused memused_max lnet_memused health_check mdt.*.exports.*.uuid osd-*.*.filesfree osd-*.*.filestotal osd-*.*.fstype osd-*.*.kbytesavail osd-*.*.kbytesfree osd-*.*.kbytestotal osd-*.*.brw_stats mgs.*.mgs.stats mgs.*.mgs.threads_max mgs.*.mgs.threads_min mgs.*.mgs.threads_started mgs.*.num_exports obdfilter.*OST*.job_stats obdfilter.*OST*.stats obdfilter.*OST*.num_exports obdfilter.*OST*.tot_dirty obdfilter.*OST*.tot_granted obdfilter.*OST*.tot_pending obdfilter.*OST*.exports.*.stats ost.OSS.ost.stats ost.OSS.ost_io.stats ost.OSS.ost_create.stats ost.OSS.ost_out.stats ost.OSS.ost_seq.stats mds.MDS.mdt.stats mds.MDS.mdt_fld.stats mds.MDS.mdt_io.stats mds.MDS.mdt_out.stats mds.MDS.mdt_readpage.stats mds.MDS.mdt_seqm.stats mds.MDS.mdt_seqs.stats mds.MDS.mdt_setattr.stats mdt.*.job_stats mdt.*.md_stats mdt.*MDT*.num_exports mdt.*MDT*.exports.*.stats ldlm.namespaces.{mdt-,filter-}*.contended_locks ldlm.namespaces.{mdt-,filter-}*.contention_seconds ldlm.namespaces.{mdt-,filter-}*.ctime_age_limit ldlm.namespaces.{mdt-,filter-}*.early_lock_cancel ldlm.namespaces.{mdt-,filter-}*.lock_count ldlm.namespaces.{mdt-,filter-}*.lock_timeouts ldlm.namespaces.{mdt-,filter-}*.lock_unused_count ldlm.namespaces.{mdt-,filter-}*.lru_max_age ldlm.namespaces.{mdt-,filter-}*.lru_size ldlm.namespaces.{mdt-,filter-}*.max_nolock_bytes ldlm.namespaces.{mdt-,filter-}*.max_parallel_ast ldlm.namespaces.{mdt-,filter-}*.resource_count ldlm.services.ldlm_canceld.stats ldlm.services.ldlm_cbd.stats llite.*.stats
memused memused_max lnet_memused health_check mdt.*.exports.*.uuid osd-*.*.filesfree osd-*.*.filestotal osd-*.*.fstype osd-*.*.kbytesavail osd-*.*.kbytesfree osd-*.*.kbytestotal osd-*.*.brw_stats mgs.*.mgs.stats mgs.*.mgs.threads_max mgs.*.mgs.threads_min mgs.*.mgs.threads_started mgs.*.num_exports obdfilter.*OST*.job_stats obdfilter.*OST*.stats obdfilter.*OST*.num_exports obdfilter.*OST*.tot_dirty obdfilter.*OST*.tot_granted obdfilter.*OST*.tot_pending obdfilter.*OST*.exports.*.stats ost.OSS.ost.stats ost.OSS.ost_io.stats ost.OSS.ost_create.stats ost.OSS.ost_out.stats ost.OSS.ost_seq.stats mds.MDS.mdt.stats mds.MDS.mdt_fld.stats mds.MDS.mdt_io.stats mds.MDS.mdt_out.stats mds.MDS.mdt_readpage.stats mds.MDS.mdt_seqm.stats mds.MDS.mdt_seqs.stats mds.MDS.mdt_setattr.stats mdt.*.job_stats mdt.*.md_stats mdt.*MDT*.num_exports mdt.*MDT*.exports.*.stats ldlm.namespaces.{mdt-,filter-}*.contended_locks ldlm.namespaces.{mdt-,filter-}*.contention_seconds ldlm.namespaces.{mdt-,filter-}*.ctime_age_limit ldlm.namespaces.{mdt-,filter-}*.early_lock_cancel ldlm.namespaces.{mdt-,filter-}*.lock_count ldlm.namespaces.{mdt-,filter-}*.lock_timeouts ldlm.namespaces.{mdt-,filter-}*.lock_unused_count ldlm.namespaces.{mdt-,filter-}*.lru_max_age ldlm.namespaces.{mdt-,filter-}*.lru_size ldlm.namespaces.{mdt-,filter-}*.max_nolock_bytes ldlm.namespaces.{mdt-,filter-}*.max_parallel_ast ldlm.namespaces.{mdt-,filter-}*.resource_count ldlm.services.ldlm_canceld.stats ldlm.services.ldlm_cbd.stats llite.*.stats mdd.*.changelog_users
3 changes: 2 additions & 1 deletion src/stats_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
base_parsers::{digits, not_words, word},
ldlm::LDLM,
llite::LLITE,
mdd_parser::MDD,
mds::mds_parser::MDS,
oss::oss_parser::OST,
time::time_triple,
Expand All @@ -29,7 +30,7 @@ where
I::Error: ParseError<I::Token, I::Range, I::Position>,
{
(
not_words(&["obdfilter", "mgs", "mdt", LDLM, OST, LLITE, MDS]).skip(spaces()),
not_words(&["obdfilter", "mgs", "mdt", LDLM, OST, LLITE, MDS, MDD]).skip(spaces()),
digits(),
spaces().with(string("samples")),
spaces().with(between(token('['), token(']'), word())),
Expand Down
15 changes: 15 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,20 @@ pub struct LNetStatGlobal<T> {
pub value: T,
}

#[derive(PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
/// Changelog stats from parsing `mdd.*.changelog_users`.
pub struct ChangelogStat {
pub current_index: u64,
pub users: Vec<ChangeLogUser>,
}

#[derive(PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
pub struct ChangeLogUser {
pub user: String,
pub index: u64,
pub idle_secs: u64,
}

impl TryFrom<&Target> for TargetVariant {
type Error = LustreCollectorError;

Expand Down Expand Up @@ -561,6 +575,7 @@ pub enum TargetStats {
Llite(LliteStat),
ExportStats(TargetStat<Vec<ExportStats>>),
Mds(MdsStat),
Changelog(TargetStat<ChangelogStat>),
}

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

0 comments on commit 76653d7

Please sign in to comment.