Skip to content

EX-10319: Added lnetctl global show#130

Open
palash3 wants to merge 1 commit into
mainfrom
paljain/add_lustre_global_show
Open

EX-10319: Added lnetctl global show#130
palash3 wants to merge 1 commit into
mainfrom
paljain/add_lustre_global_show

Conversation

@palash3

@palash3 palash3 commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Fixes: EX-10319

This pull request extends the Lustre collector and exporter to support parsing and reporting the LNet global health sensitivity and per-network health values. It introduces new parsing functions, updates data structures, and integrates the new metrics into the exporter output, enabling more comprehensive health monitoring.

LNet health metrics support:

  • Added parsing and reporting of the health_value for each network interface in LNetStats, updating the enum and parser logic to include this metric. [1] [2] [3] [4]
  • Introduced parsing of the lnetctl global show output, including a new LNetGlobal struct and associated parser, to extract and report the health_sensitivity value. [1] [2] [3] [4]

Integration and threading:

  • Updated the main collector logic to spawn a thread for collecting lnetctl global show output, parse it, and append its records to the final result. [1] [2] [3]

Exporter enhancements:

  • Modified the exporter to dump the lnetctl global show output and included a new metric family for health_value. [1] [2] [3]

Testing and snapshots:

  • Added and updated test snapshots to verify parsing of health_value and health_sensitivity from both net and global outputs. [1] [2] [3] [4] [5] [6] [7] [8]

These changes collectively provide improved visibility into LNet health, both at the interface and global levels, and ensure the new metrics are accessible via the exporter and collector.

Example output of lustre_collector:

[
  {
    "LNetStat": {
      "HealthValue": {
        "nid": "0@lo",
        "param": "health_value",
        "value": 1000
      }
    }
  },
  {
    "LNetStat": {
      "HealthValue": {
        "nid": "10.73.20.11@tcp",
        "param": "health_value",
        "value": 1000
      }
    }
  },
  {
    "LNetStat": {
      "HealthSensitiveValue": {
        "param": "health_sensitivity",
        "value": 100
      }
    }
  }

Example of output from lustrefs-exporter:

# HELP lustre_health_value Lustre health value.
# TYPE lustre_health_value gauge
lustre_health_value{nid="0@lo"} 1000
lustre_health_value{nid="10.73.20.11@tcp"} 1000
# HELP lustre_health_sensitivity Lustre health sensitivity.
# TYPE lustre_health_sensitivity gauge
lustre_health_sensitivity{} 100

@codecov

codecov Bot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.57009% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.28%. Comparing base (652bfb7) to head (9e4b388).

Files with missing lines Patch % Lines
lustre-collector/src/main.rs 0.00% 14 Missing ⚠️
lustrefs-exporter/src/routes.rs 73.07% 0 Missing and 7 partials ⚠️
lustrefs-exporter/src/lib.rs 50.00% 0 Missing and 2 partials ⚠️
lustre-collector/src/lnetctl_parser.rs 97.67% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #130      +/-   ##
==========================================
- Coverage   94.57%   94.28%   -0.30%     
==========================================
  Files          46       46              
  Lines        6107     6214     +107     
  Branches     6107     6214     +107     
==========================================
+ Hits         5776     5859      +83     
- Misses        256      270      +14     
- Partials       75       85      +10     
Flag Coverage Δ
2_14_0_ddn133 35.27% <0.00%> (-0.37%) ⬇️
2_14_0_ddn145 37.03% <0.00%> (-0.39%) ⬇️
all-tests 94.28% <77.57%> (-0.30%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Mar 19, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Branchpaljain/add_lustre_global_show
Testbedci-runner
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
nanoseconds (ns)
(Result Δ%)
Lower Boundary
nanoseconds (ns)
(Limit %)
Upper Boundary
nanoseconds (ns)
(Limit %)
parse_benchmarks/combine_performance📈 view plot
🚷 view threshold
128,390,000.00 ns
(-47.06%)Baseline: 242,510,050.00 ns
-677,085,841.16 ns
(-527.37%)
1,162,105,941.16 ns
(11.05%)
🐰 View full continuous benchmarking report in Bencher

@github-actions

github-actions Bot commented Mar 19, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Branchpaljain/add_lustre_global_show
Testbedci-runner

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
BenchmarkD1 Miss Ratemisses (%)D1mrmisses (reads) x 1e3D1mwmisses (writes) x 1e3DLmrmisses (reads)DLmwmisses (writes) x 1e3Drreads x 1e6Dwwrites x 1e6Estimated Cyclescycles x 1e6I1 Miss Ratemisses (%)I1mrmisses (reads) x 1e3ILmrmisses (reads)InstructionsBenchmark Result
instructions x 1e6
(Result Δ%)
Lower Boundary
instructions x 1e6
(Limit %)
Upper Boundary
instructions x 1e6
(Limit %)
L1 Hit Ratehits (%)L1 Hitshits x 1e6LL Hit Ratehits (%)LL Hitshits x 1e3LL Miss Ratemisses (%)LLd Miss Ratemisses (%)LLi Miss Ratemisses (%)RAM Hit Ratehits (%)RAM Hitshits x 1e3Total read+writereads/writes x 1e6
lustre_metrics::memory_benches::bench_encode_lustre_metrics with_setup:generate_records()📈 view plot
⚠️ NO THRESHOLD
0.92 %📈 view plot
⚠️ NO THRESHOLD
24.97 reads x 1e3📈 view plot
⚠️ NO THRESHOLD
8.95 writes x 1e3📈 view plot
⚠️ NO THRESHOLD
122.00 reads📈 view plot
⚠️ NO THRESHOLD
6.48 writes x 1e3📈 view plot
⚠️ NO THRESHOLD
2.47 x 1e6📈 view plot
⚠️ NO THRESHOLD
1.23 x 1e6📈 view plot
⚠️ NO THRESHOLD
14.82 x 1e6📈 view plot
⚠️ NO THRESHOLD
0.01 %📈 view plot
⚠️ NO THRESHOLD
1.08 reads x 1e3📈 view plot
⚠️ NO THRESHOLD
922.00 reads📈 view plot
🚷 view threshold
10.76 x 1e6
(-18.83%)Baseline: 13.26 x 1e6
2.53 x 1e6
(23.49%)
23.99 x 1e6
(44.86%)
📈 view plot
⚠️ NO THRESHOLD
99.76 %📈 view plot
⚠️ NO THRESHOLD
14.42 x 1e6📈 view plot
⚠️ NO THRESHOLD
0.19 %📈 view plot
⚠️ NO THRESHOLD
27.48 x 1e3📈 view plot
⚠️ NO THRESHOLD
0.05 %📈 view plot
⚠️ NO THRESHOLD
0.18 %📈 view plot
⚠️ NO THRESHOLD
0.01 %📈 view plot
⚠️ NO THRESHOLD
0.05 %📈 view plot
⚠️ NO THRESHOLD
7.52 x 1e3📈 view plot
⚠️ NO THRESHOLD
14.46 x 1e6
🐰 View full continuous benchmarking report in Bencher

@github-actions

github-actions Bot commented Mar 19, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Branchpaljain/add_lustre_global_show
Testbedci-runner

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
Benchmarkavg_runtime_rss_mibMeasure (MiB)avg_runtime_virtual_mibMeasure (MiB)end_rss_mibMeasure (MiB)end_virtual_mibMeasure (MiB)memory_growth_mibMeasure (MiB)peak_over_start_rss_ratioMeasure (units)peak_over_start_virtual_ratioMeasure (units)peak_rss_mibBenchmark Result
Measure (MiB)
(Result Δ%)
Lower Boundary
Measure (MiB)
(Limit %)
Upper Boundary
Measure (MiB)
(Limit %)
peak_virtual_mibMeasure (MiB)start_rss_mibMeasure (MiB)start_virtual_mibMeasure (MiB)virtual_growth_mibMeasure (MiB)
scrape_allocations📈 view plot
⚠️ NO THRESHOLD
40.92 MiB📈 view plot
⚠️ NO THRESHOLD
870.28 MiB📈 view plot
⚠️ NO THRESHOLD
40.97 MiB📈 view plot
⚠️ NO THRESHOLD
870.33 MiB📈 view plot
⚠️ NO THRESHOLD
0.30 MiB📈 view plot
⚠️ NO THRESHOLD
1.03 units📈 view plot
⚠️ NO THRESHOLD
1.02 units📈 view plot
🚷 view threshold
42.44 MiB
(-44.11%)Baseline: 75.93 MiB
-131.60 MiB
(-310.08%)
283.47 MiB
(14.97%)
📈 view plot
⚠️ NO THRESHOLD
878.89 MiB📈 view plot
⚠️ NO THRESHOLD
40.67 MiB📈 view plot
⚠️ NO THRESHOLD
864.98 MiB📈 view plot
⚠️ NO THRESHOLD
5.35 MiB
🐰 View full continuous benchmarking report in Bencher

@palash3 palash3 force-pushed the paljain/add_lustre_global_show branch from ec28f23 to f044e7a Compare March 19, 2026 20:53
@flei-ddn flei-ddn force-pushed the paljain/add_lustre_global_show branch from f044e7a to 3433c6b Compare April 30, 2026 05:58
@flei-ddn flei-ddn self-assigned this Apr 30, 2026
@palash3 palash3 requested review from breuhan and johnsonw May 6, 2026 06:08
@flei-ddn flei-ddn changed the title Added lnetctl global show EX-10319: Added lnetctl global show May 21, 2026
@flei-ddn flei-ddn force-pushed the paljain/add_lustre_global_show branch 2 times, most recently from 23d92a0 to bf45465 Compare May 21, 2026 02:33
@breuhan

breuhan commented May 27, 2026

Copy link
Copy Markdown
Contributor

Looks pretty straight forward to me. Just lets check codecoverage

@breuhan breuhan closed this May 27, 2026
@breuhan breuhan reopened this May 27, 2026
@flei-ddn flei-ddn force-pushed the paljain/add_lustre_global_show branch 2 times, most recently from d3b478c to c726217 Compare May 27, 2026 08:27
@flei-ddn

Copy link
Copy Markdown

Looks pretty straight forward to me. Just lets check codecoverage

All the uncovered lines can only be covered when lustre_collector command is run or metrics data is read from lustrefs_exporter. They cannot be covered by unit test. All the partial covered code is the error branch of rust code.

@ip1981

ip1981 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Oh, you touch my tralala 🤪

Screenshot_2026-05-27-10-54-35-155_com yandex browser-edit

Comment thread lustrefs-exporter/src/lib.rs
@breuhan

breuhan commented May 29, 2026

Copy link
Copy Markdown
Contributor

Looks pretty straight forward to me. Just lets check codecoverage

All the uncovered lines can only be covered when lustre_collector command is run or metrics data is read from lustrefs_exporter. They cannot be covered by unit test. All the partial covered code is the error branch of rust code.

I don't understand. Why don't we do it then?

@flei-ddn flei-ddn force-pushed the paljain/add_lustre_global_show branch from c726217 to 93ec562 Compare June 2, 2026 07:04
@flei-ddn

flei-ddn commented Jun 2, 2026

Copy link
Copy Markdown

@breuhan
It seems that lustre-collector/src/main.rs is never covered by any tests, so I won't be adding tests for the new code in this file.
For other files in lustrefs-exporter, new test cases have been added to cover all lines. Some lines are only partially covered because the error branches are ignored.

Is this acceptable now?

@flei-ddn flei-ddn requested review from breuhan, flei-ddn and ip1981 July 8, 2026 11:51
@palash3

palash3 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

For other files in lustrefs-exporter, new test cases have been added to cover all lines. Some lines are only partially covered because the error branches are ignored.

@breuhan any comments ?

@palash3 palash3 requested review from spoutn1k and removed request for ip1981 July 9, 2026 06:51
Add health_value metrics for each inteface.
Add health_sensitiviy metrics from 'lnetctl global show'.

Co-authored-by: Feng Lei <flei@ddn.com>
@flei-ddn flei-ddn force-pushed the paljain/add_lustre_global_show branch from 93ec562 to 9e4b388 Compare July 13, 2026 03:24
struct LnetGlobalShow {
global: Option<LNetGlobal>,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this ?

Comment on lines +125 to +130
let y: LnetGlobalShow = yaml_serde::from_slice(xs)?;

Ok(y.global
.map(|x| build_lnetctl_global_show(&x))
.unwrap_or_default())
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let y: LnetGlobalShow = yaml_serde::from_slice(xs)?;
Ok(y.global
.map(|x| build_lnetctl_global_show(&x))
.unwrap_or_default())
}
let y: Option<LNetGlobal> = yaml_serde::from_slice(xs)?;
Ok(y.map(|x| build_lnetctl_global_show(&x)).unwrap_or_default())
}

fn get_lnetctl_global_show_output() -> Result<Vec<u8>, LustreCollectorError> {
let r = Command::new("lnetctl").arg("global").arg("show").output()?;

Ok(r.stdout)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We completely ignore failure here. I am not saying this has to be done here but the whole project has this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants