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:
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,
|
UnixSocketServer, BUS_SOCKET_PATH,
|
||||||
};
|
};
|
||||||
pub use tc_handle::TcHandle;
|
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 program_control;
|
||||||
mod shaped_devices_tracker;
|
mod shaped_devices_tracker;
|
||||||
mod throughput_tracker;
|
mod throughput_tracker;
|
||||||
|
mod anonymous_usage;
|
||||||
mod tuning;
|
mod tuning;
|
||||||
mod validation;
|
mod validation;
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -69,7 +70,8 @@ async fn main() -> Result<()> {
|
|||||||
join!(
|
join!(
|
||||||
spawn_queue_structure_monitor(),
|
spawn_queue_structure_monitor(),
|
||||||
shaped_devices_tracker::shaped_devices_watcher(),
|
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();
|
throughput_tracker::spawn_throughput_monitor();
|
||||||
spawn_queue_monitor();
|
spawn_queue_monitor();
|
||||||
|
|||||||
Reference in New Issue
Block a user