diff --git a/Cargo.lock b/Cargo.lock index 0b7e9be..426fa8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,7 +78,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -88,9 +88,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + [[package]] name = "autocfg" version = "1.3.0" @@ -187,6 +193,37 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "env_filter" version = "0.1.2" @@ -210,6 +247,27 @@ dependencies = [ "log", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -254,7 +312,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -325,6 +383,16 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -365,7 +433,16 @@ dependencies = [ "hermit-abi", "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", ] [[package]] @@ -415,6 +492,21 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "pcap" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "499125886165f62fbc0c095ead9189b253f48eb1c5fcab49f81a270f2f220652" +dependencies = [ + "bitflags 1.3.2", + "errno", + "libc", + "libloading", + "pkg-config", + "regex", + "windows-sys 0.36.1", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -427,6 +519,12 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + [[package]] name = "proc-macro2" version = "1.0.86" @@ -445,6 +543,26 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redis" version = "0.25.4" @@ -502,13 +620,16 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" name = "runner-rs" version = "0.5.5" dependencies = [ + "anyhow", "chrono", "env_logger", "inotify", "log", + "pcap", "redis", "serde", "serde_json", + "sysinfo", "tokio", ] @@ -596,7 +717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -610,6 +731,20 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sysinfo" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ae3f4f7d64646c46c4cae4e3f01d1c5d255c7406fdd7c7f999a94e488791" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -640,7 +775,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -753,6 +888,38 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -762,6 +929,62 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -778,13 +1001,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -793,12 +1016,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -811,12 +1046,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -829,6 +1076,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index cac2a04..5432f63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,11 +7,14 @@ edition = "2021" debug = true [dependencies] +anyhow = "1.0.93" chrono = "0.4.38" env_logger = "0.11.3" inotify = "0.10.2" log = "0.4.22" +pcap = "2.2.0" redis = "0.25.4" serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.118" +sysinfo = "0.32.0" tokio = { version = "1.38.0", features = ["full", "time"] } diff --git a/src/options/config.rs b/src/options/config.rs index cce619d..c678655 100644 --- a/src/options/config.rs +++ b/src/options/config.rs @@ -1,6 +1,6 @@ use crate::options::structs::*; use log::{error, info, warn}; -use redis::{Client, Commands, Connection, PubSub, RedisResult}; +use redis::{Client, Commands, Connection, RedisResult}; use std::fs::OpenOptions; use std::io::Write; use std::os::unix::process::CommandExt; diff --git a/src/options/structs.rs b/src/options/structs.rs index 5687443..55020c1 100644 --- a/src/options/structs.rs +++ b/src/options/structs.rs @@ -1,3 +1,4 @@ +use std::net::Ipv4Addr; use serde::{Deserialize, Serialize}; /// # an Error enum (next will be deleted and replaced) @@ -80,3 +81,77 @@ pub struct FIleTriggers { #[serde(rename = "onChange")] pub on_change: String, } + +/// +/// +#[derive(Debug, Clone)] +pub struct Metrics { + pub container_metrics : ContainerMetrics, + pub processes_metrics : Vec, + // pub net_metrics : Vec, +} +impl Metrics { + pub fn new(cm: ContainerMetrics, prm: Vec) -> Self { + Metrics { + container_metrics : cm, + processes_metrics : prm, + // net_metrics : net, + } + } +} + + +/// +/// +#[derive(Debug, Clone)] +pub struct ContainerMetrics { + pub cpu_load : f32, + pub ram_load : f32, + // pub net_activity : ??? + pub processes : Vec, +} + +impl ContainerMetrics { + pub fn new(cpu: f32, ram: f32, subsystems: Vec,) -> Self{ + ContainerMetrics { + cpu_load : cpu, + ram_load : ram, + processes : subsystems, + } + } +} + +/// +/// +#[derive(Debug, Clone)] +pub struct ProcessMetrics { + pub cpu_load : f32, + pub ram_load : f32, +} + +impl ProcessMetrics { + pub fn new(cpu: f32, ram: f32) -> Self { + ProcessMetrics { + cpu_load : cpu, + ram_load : ram, + } + } +} + +#[derive(Debug, Clone)] +pub struct PacketInfo { + protocol : String, + dst_ip : Ipv4Addr, + src_ip : Ipv4Addr, + size : usize, +} +impl PacketInfo { + pub fn new(prt: String, dest: Ipv4Addr, src: Ipv4Addr, size_of_packet: usize) -> Self { + PacketInfo { + protocol : prt, + dst_ip : dest, + src_ip : src, + size : size_of_packet, + } + } +} \ No newline at end of file diff --git a/src/utils/metrics.rs b/src/utils/metrics.rs index 09722fa..221ca5f 100644 --- a/src/utils/metrics.rs +++ b/src/utils/metrics.rs @@ -1,9 +1,121 @@ -// module needed to get metrics such as -// cpu load, memmory load and net activity +// submodule needed to get metrics such as +// cpu load, ram/rom load and net activity -// -// code will be here -// +use std::sync::Mutex; +use std::{str::FromStr, sync::Arc}; +use crate::options::structs::TrackingProcess; +use sysinfo::{Pid, Process, System}; +use tokio::join; +use crate::utils::prcs::get_pid; +use crate::options::structs::{ProcessMetrics, ContainerMetrics, PacketInfo}; +use pcap::{Device, Capture, Active}; +use std::net::Ipv4Addr; +use anyhow::{Result, Ok}; + +type PacketBuffer = Arc>>; + +// init_metrics_grubber - fn for initializing +// loop for unstoppable grubbing metrics. +// +// input : vec of processes +// output : Err if it cant create grubbers | Ok on finish +// initiator : main thread +// managing : object of unix-socket reader +// depends on : network activity +// !! FOR PROCESS !! +// pub async fn init_metrics_grubber(prcs: Arc>) { +pub async fn init_metrics_grubber() { + let mut system = System::new(); + // let mut buffer: Vec = vec![]; + // let shared_buf: PacketBuffer = Arc::new(Mutex::new(buffer)); + + system.refresh_all(); + // let temp = String::from_utf8(get_pid("systemd").await.unwrap().stdout).unwrap(); + // let prc = system.process(Pid::from_str(&temp).unwrap()).unwrap(); + // prc. + // let _ = capture_packets(shared_buf.clone()).await; +} + +async fn gather_metrics(proc: Arc) { + +} + +// DEPRECATED : for net monitoring +// async fn capture_packets(buffer: PacketBuffer) -> Result<()> { +// let mut cap = Capture::from_device(Device::lookup()?.unwrap())? +// .promisc(true) +// .open()?; + +// cap.filter("not broadcast and not multicast", true)?; + +// while let core::result::Result::Ok(packet) = cap.next_packet() { +// if let Some((src, dst, prot)) = get_packet_info(&packet.data).await { +// let packet_info = PacketInfo::new(String::from(prot), dst, src, packet.header.len as usize); +// let mut locked_buffer = buffer.lock().unwrap(); +// println!("{:?}", &packet_info); +// locked_buffer.push(packet_info); +// } +// } +// Ok(()) +// } +// async fn get_packet_info(data: &[u8]) -> Option<(Ipv4Addr, Ipv4Addr, &str)> { +// if data.len() >= 20 { +// let src_ip = Ipv4Addr::new(data[12], data[13], data[14], data[15]); +// let dst_ip = Ipv4Addr::new(data[16], data[17], data[18], data[19]); +// let protocol = match data[9] { +// 1 => "ICMP", +// 6 => "TCP", +// 17 => "UDP", +// _ => "Unknown", +// }; + +// Some((src_ip, dst_ip, protocol)) +// } else { +// None +// } +// } + + +// !!! +// for container (whole system metrics) +async fn get_all_container_metrics(sys: Arc, prcs: Arc>) -> ContainerMetrics { + let metrics = join!( + get_cpu_metrics_container(sys.clone()), + get_ram_metrics_container(sys.clone()), + get_subsystems(prcs.clone()) + ); + ContainerMetrics::new(metrics.0, metrics.1, metrics.2) +} +async fn get_cpu_metrics_container(sys: Arc) -> f32 { + sys.global_cpu_usage() +} +async fn get_ram_metrics_container(sys: Arc) -> f32 { + (sys.used_memory() / sys.total_memory()) as f32 * 100.0 +} +// async fn get_mem_metrics_container(sys: Arc) -> f32 { +// sys. +// } +async fn get_subsystems(prcs: Arc>) -> Vec { + prcs.iter().map(|process| process.name.clone()).collect() +} + +// !!! +// for process (process metrics) +// % +async fn get_all_metrics_process(proc: Arc, sys: Arc) -> ProcessMetrics { + let metrics = join!( + get_cpu_metrics_process(proc.clone()), + get_ram_metrics_process(proc.clone(), sys.clone()) + ); + ProcessMetrics::new(metrics.0, metrics.1) +} +async fn get_cpu_metrics_process(proc: Arc) -> f32 { + proc.cpu_usage() +} +// % +async fn get_ram_metrics_process(proc: Arc, sys: Arc) -> f32 { + (proc.memory() as f64 / sys.total_memory() as f64) as f32 * 100.0 as f32 +} #[cfg(test)] mod metrics_unittets {