mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Basic data structures and collection for anonymous usage collection.
This commit is contained in:
parent
5805d9860e
commit
08e7788efb
2
src/rust/lqos_bus/src/anonymous/mod.rs
Normal file
2
src/rust/lqos_bus/src/anonymous/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod v1;
|
||||
pub use v1::*;
|
68
src/rust/lqos_bus/src/anonymous/v1.rs
Normal file
68
src/rust/lqos_bus/src/anonymous/v1.rs
Normal file
@ -0,0 +1,68 @@
|
||||
#[derive(Default, Debug)]
|
||||
|
||||
/// Defines data to be submitted if anonymous usage submission is
|
||||
/// enabled. This is protocol version 1.
|
||||
pub struct AnonymousUsageV1 {
|
||||
/// Total installed RAM (bytes)
|
||||
pub total_memory: u64,
|
||||
|
||||
/// Total available RAM (bytes)
|
||||
pub available_memory: u64,
|
||||
|
||||
/// Linux Kernel Version
|
||||
pub kernel_version: String,
|
||||
|
||||
/// Number of "usable" CPU cores, as used by eBPF. This may not
|
||||
/// be exactly equal to the number of actual cores.
|
||||
pub usable_cores: u32,
|
||||
|
||||
/// CPU brand
|
||||
pub cpu_brand: String,
|
||||
|
||||
/// CPU vendor
|
||||
pub cpu_vendor: String,
|
||||
|
||||
/// CPU frequency
|
||||
pub cpu_frequency: u64,
|
||||
|
||||
/// Installed network cards
|
||||
pub nics: Vec<NicV1>,
|
||||
|
||||
/// SQM setting from the ispConfig.py file
|
||||
pub sqm: String,
|
||||
|
||||
/// Is Monitor-ony mode enabled?
|
||||
pub monitor_mode: bool,
|
||||
|
||||
/// Capacity as specified in ispConfig.py
|
||||
pub total_capacity: (u32, u32),
|
||||
|
||||
/// Generated node capacity from ispConfig.py
|
||||
pub generated_pdn_capacity: (u32, u32),
|
||||
|
||||
/// Number of shaped devices from ShapedDevices.csv
|
||||
pub shaped_device_count: usize,
|
||||
|
||||
/// Number of nodes read from network.json
|
||||
pub net_json_len: usize,
|
||||
}
|
||||
|
||||
|
||||
/// Description of installed NIC (version 1 data)
|
||||
#[derive(Default, Debug)]
|
||||
pub struct NicV1 {
|
||||
/// Description, usually "Ethernet"
|
||||
pub description: String,
|
||||
|
||||
/// Product name as specified by the driver
|
||||
pub product: String,
|
||||
|
||||
/// Vendor as specified by the driver
|
||||
pub vendor: String,
|
||||
|
||||
/// Clock speed, specified by the vendor (may not be accurate)
|
||||
pub clock: String,
|
||||
|
||||
/// NIC possible capacity (as reported by the driver)
|
||||
pub capacity: String,
|
||||
}
|
@ -20,3 +20,6 @@ pub use bus::{
|
||||
UnixSocketServer, BUS_SOCKET_PATH,
|
||||
};
|
||||
pub use tc_handle::TcHandle;
|
||||
|
||||
/// Anonymous Usage Statistics Data Types
|
||||
pub mod anonymous;
|
||||
|
70
src/rust/lqosd/src/anonymous_usage/lshw.rs
Normal file
70
src/rust/lqosd/src/anonymous_usage/lshw.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use std::process::Command;
|
||||
|
||||
use lqos_bus::anonymous::NicV1;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct Nic {
|
||||
pub(crate) description: String,
|
||||
pub(crate) product: String,
|
||||
pub(crate) vendor: String,
|
||||
pub(crate) clock: String,
|
||||
pub(crate) capacity: String,
|
||||
}
|
||||
|
||||
#[allow(clippy::from_over_into)]
|
||||
impl Into<NicV1> for Nic {
|
||||
fn into(self) -> NicV1 {
|
||||
NicV1 {
|
||||
description: self.description,
|
||||
product: self.product,
|
||||
vendor: self.vendor,
|
||||
clock: self.clock,
|
||||
capacity: self.capacity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_nic_info() -> anyhow::Result<Vec<Nic>> {
|
||||
let mut current_nic = None;
|
||||
let mut result = Vec::new();
|
||||
|
||||
let output = Command::new("/bin/lshw")
|
||||
.args(["-C", "network"])
|
||||
.output()?;
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
let lines = stdout.split('\n');
|
||||
for line in lines {
|
||||
let trimmed = line.trim();
|
||||
|
||||
// Starting a new record
|
||||
if trimmed.starts_with("*-network:") {
|
||||
if let Some(nic) = current_nic {
|
||||
result.push(nic);
|
||||
}
|
||||
current_nic = Some(Nic::default());
|
||||
}
|
||||
|
||||
if let Some(mut nic) = current_nic.as_mut() {
|
||||
if let Some(d) = trimmed.strip_prefix("description: ") {
|
||||
nic.description = d.to_string();
|
||||
}
|
||||
if let Some(d) = trimmed.strip_prefix("product: ") {
|
||||
nic.product = d.to_string();
|
||||
}
|
||||
if let Some(d) = trimmed.strip_prefix("vendor: ") {
|
||||
nic.vendor = d.to_string();
|
||||
}
|
||||
if let Some(d) = trimmed.strip_prefix("clock: ") {
|
||||
nic.clock = d.to_string();
|
||||
}
|
||||
if let Some(d) = trimmed.strip_prefix("capacity: ") {
|
||||
nic.capacity = d.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(nic) = current_nic {
|
||||
result.push(nic);
|
||||
}
|
||||
Ok(result)
|
||||
}
|
69
src/rust/lqosd/src/anonymous_usage/mod.rs
Normal file
69
src/rust/lqosd/src/anonymous_usage/mod.rs
Normal file
@ -0,0 +1,69 @@
|
||||
mod lshw;
|
||||
use std::time::Duration;
|
||||
use lqos_bus::anonymous::AnonymousUsageV1;
|
||||
use lqos_config::{EtcLqos, LibreQoSConfig};
|
||||
use lqos_sys::num_possible_cpus;
|
||||
use sysinfo::{System, SystemExt, CpuExt};
|
||||
|
||||
use crate::shaped_devices_tracker::{SHAPED_DEVICES, NETWORK_JSON};
|
||||
|
||||
const SLOW_START_SECS: u64 = 1;
|
||||
const INTERVAL_SECS: u64 = 60 * 60 * 24;
|
||||
|
||||
pub async fn start_anonymous_usage() {
|
||||
if let Ok(cfg) = EtcLqos::load() {
|
||||
if let Some(usage) = cfg.usage_stats {
|
||||
if usage.send_anonymous {
|
||||
std::thread::spawn(|| {
|
||||
std::thread::sleep(Duration::from_secs(SLOW_START_SECS));
|
||||
loop {
|
||||
let _ = anonymous_usage_dump();
|
||||
std::thread::sleep(Duration::from_secs(INTERVAL_SECS));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn anonymous_usage_dump() -> anyhow::Result<()> {
|
||||
let mut data = AnonymousUsageV1::default();
|
||||
let mut sys = System::new_all();
|
||||
sys.refresh_all();
|
||||
data.total_memory = sys.total_memory();
|
||||
data.available_memory = sys.available_memory();
|
||||
if let Some(kernel) = sys.kernel_version() {
|
||||
data.kernel_version = kernel;
|
||||
}
|
||||
if let Ok(cores) = num_possible_cpus() {
|
||||
data.usable_cores = cores;
|
||||
}
|
||||
let cpu = sys.cpus().first();
|
||||
if let Some(cpu) = cpu {
|
||||
data.cpu_brand = cpu.brand().to_string();
|
||||
data.cpu_vendor = cpu.vendor_id().to_string();
|
||||
data.cpu_frequency = cpu.frequency();
|
||||
}
|
||||
for nic in lshw::get_nic_info()? {
|
||||
data.nics.push(nic.into());
|
||||
}
|
||||
|
||||
if let Ok(cfg) = LibreQoSConfig::load() {
|
||||
data.sqm = cfg.sqm;
|
||||
data.monitor_mode = cfg.monitor_mode;
|
||||
data.total_capacity = (
|
||||
cfg.total_download_mbps,
|
||||
cfg.total_upload_mbps,
|
||||
);
|
||||
data.generated_pdn_capacity = (
|
||||
cfg.generated_download_mbps,
|
||||
cfg.generated_upload_mbps,
|
||||
);
|
||||
}
|
||||
|
||||
data.shaped_device_count = SHAPED_DEVICES.read().unwrap().devices.len();
|
||||
data.net_json_len = NETWORK_JSON.read().unwrap().nodes.len();
|
||||
|
||||
println!("{data:#?}");
|
||||
Ok(())
|
||||
}
|
@ -5,6 +5,7 @@ mod lqos_daht_test;
|
||||
mod program_control;
|
||||
mod shaped_devices_tracker;
|
||||
mod throughput_tracker;
|
||||
mod anonymous_usage;
|
||||
mod tuning;
|
||||
mod validation;
|
||||
use crate::{
|
||||
@ -69,7 +70,8 @@ async fn main() -> Result<()> {
|
||||
join!(
|
||||
spawn_queue_structure_monitor(),
|
||||
shaped_devices_tracker::shaped_devices_watcher(),
|
||||
shaped_devices_tracker::network_json_watcher()
|
||||
shaped_devices_tracker::network_json_watcher(),
|
||||
anonymous_usage::start_anonymous_usage(),
|
||||
);
|
||||
throughput_tracker::spawn_throughput_monitor();
|
||||
spawn_queue_monitor();
|
||||
|
Loading…
Reference in New Issue
Block a user