mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 12:48:00 +00:00
Add new hardware and software metrics (#11062)
* Add new hardware and software metrics * Move sysinfo tests into `mod tests` * Correct a typo in a comment * Remove unnecessary `nix` dependency * Fix the version tests * Add a `--disable-hardware-benchmarks` CLI argument * Disable hardware benchmarks in the integration tests * Remove unused import * Fix benchmarks compilation * Move code to a new `sc-sysinfo` crate * Correct `impl_version` comment * Move `--disable-hardware-benchmarks` to the chain-specific bin crate * Move printing out of hardware bench results to `sc-sysinfo` * Move hardware benchmarks to a separate messages; trigger them manually * Rename some of the fields in the `HwBench` struct * Revert changes to the telemetry crate; manually send hwbench messages * Move sysinfo logs into the sysinfo crate * Move the `TARGET_OS_*` constants into the sysinfo crate * Minor cleanups * Move the `HwBench` struct to the sysinfo crate * Derive `Clone` for `HwBench` * Fix broken telemetry connection notification stream * Prevent the telemetry connection notifiers from leaking if they're disconnected * Turn the telemetry notification failure log into a debug log * Rename `--disable-hardware-benchmarks` to `--no-hardware-benchmarks`
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2022 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use regex::Regex;
|
||||
use sc_telemetry::SysInfo;
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn read_file(path: &str) -> Option<String> {
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(data) => Some(data),
|
||||
Err(error) => {
|
||||
log::warn!("Failed to read '{}': {}", path, error);
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn extract<T>(data: &str, regex: &str) -> Option<T>
|
||||
where
|
||||
T: std::str::FromStr,
|
||||
{
|
||||
Regex::new(regex)
|
||||
.expect("regex is correct; qed")
|
||||
.captures(&data)?
|
||||
.get(1)?
|
||||
.as_str()
|
||||
.parse()
|
||||
.ok()
|
||||
}
|
||||
|
||||
const LINUX_REGEX_CPU: &str = r#"(?m)^model name\s*:\s*([^\n]+)"#;
|
||||
const LINUX_REGEX_PHYSICAL_ID: &str = r#"(?m)^physical id\s*:\s*(\d+)"#;
|
||||
const LINUX_REGEX_CORE_ID: &str = r#"(?m)^core id\s*:\s*(\d+)"#;
|
||||
const LINUX_REGEX_HYPERVISOR: &str = r#"(?m)^flags\s*:.+?\bhypervisor\b"#;
|
||||
const LINUX_REGEX_MEMORY: &str = r#"(?m)^MemTotal:\s*(\d+) kB"#;
|
||||
const LINUX_REGEX_DISTRO: &str = r#"(?m)^PRETTY_NAME\s*=\s*"?(.+?)"?$"#;
|
||||
|
||||
pub fn gather_linux_sysinfo(sysinfo: &mut SysInfo) {
|
||||
if let Some(data) = read_file("/proc/cpuinfo") {
|
||||
sysinfo.cpu = extract(&data, LINUX_REGEX_CPU);
|
||||
sysinfo.is_virtual_machine =
|
||||
Some(Regex::new(LINUX_REGEX_HYPERVISOR).unwrap().is_match(&data));
|
||||
|
||||
// The /proc/cpuinfo returns a list of all of the hardware threads.
|
||||
//
|
||||
// Here we extract all of the unique {CPU ID, core ID} pairs to get
|
||||
// the total number of cores.
|
||||
let mut set: HashSet<(u32, u32)> = HashSet::new();
|
||||
for chunk in data.split("\n\n") {
|
||||
let pid = extract(chunk, LINUX_REGEX_PHYSICAL_ID);
|
||||
let cid = extract(chunk, LINUX_REGEX_CORE_ID);
|
||||
if let (Some(pid), Some(cid)) = (pid, cid) {
|
||||
set.insert((pid, cid));
|
||||
}
|
||||
}
|
||||
|
||||
if !set.is_empty() {
|
||||
sysinfo.core_count = Some(set.len() as u32);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(data) = read_file("/proc/meminfo") {
|
||||
sysinfo.memory = extract(&data, LINUX_REGEX_MEMORY).map(|memory: u64| memory * 1024);
|
||||
}
|
||||
|
||||
if let Some(data) = read_file("/etc/os-release") {
|
||||
sysinfo.linux_distro = extract(&data, LINUX_REGEX_DISTRO);
|
||||
}
|
||||
|
||||
// NOTE: We don't use the `nix` crate to call this since it doesn't
|
||||
// currently check for errors.
|
||||
unsafe {
|
||||
// SAFETY: The `utsname` is full of byte arrays, so this is safe.
|
||||
let mut uname: libc::utsname = std::mem::zeroed();
|
||||
if libc::uname(&mut uname) < 0 {
|
||||
log::warn!("uname failed: {}", std::io::Error::last_os_error());
|
||||
} else {
|
||||
let length =
|
||||
uname.release.iter().position(|&byte| byte == 0).unwrap_or(uname.release.len());
|
||||
let release = std::slice::from_raw_parts(uname.release.as_ptr().cast(), length);
|
||||
if let Ok(release) = std::str::from_utf8(release) {
|
||||
sysinfo.linux_kernel = Some(release.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user