capsula_capture_machine/
lib.rs1mod config;
2mod error;
3
4use crate::error::MachineHookError;
5use capsula_core::captured::Captured;
6use capsula_core::error::CapsulaResult;
7use capsula_core::hook::{Hook, HookFactory, RuntimeParams};
8use config::{MachineHookConfig, MachineHookFactory};
9use sysinfo::{CpuRefreshKind, MemoryRefreshKind, RefreshKind, System};
10
11pub const KEY: &str = "capture-machine";
12
13#[derive(Debug, Default)]
14pub struct MachineHook;
15
16#[derive(Debug)]
17pub struct CpuInfo {
18 name: String,
19 vender_id: String,
20 brand: String,
21 frequency_mhz: u64,
22}
23
24#[derive(Debug)]
25pub struct MachineCaptured {
26 pub os: String,
27 pub os_version: String,
28 pub kernel_version: String,
29 pub architecture: String,
30 pub cpus: Vec<CpuInfo>,
31 pub total_memory: usize,
33 pub hostname: String,
35}
36
37impl Hook for MachineHook {
38 type Config = MachineHookConfig;
39 type Output = MachineCaptured;
40
41 fn id(&self) -> String {
42 KEY.to_string()
43 }
44
45 fn config(&self) -> &Self::Config {
46 &MachineHookConfig {}
47 }
48
49 fn run(&self, _params: &RuntimeParams) -> CapsulaResult<Self::Output> {
50 let os = System::name().ok_or(MachineHookError::OsInfoError)?;
51 let os_version = System::os_version().ok_or(MachineHookError::OsInfoError)?;
52 let kernel_version = System::kernel_version().ok_or(MachineHookError::OsInfoError)?;
53 let architecture = std::env::consts::ARCH.to_string();
54
55 let system = System::new_with_specifics(
56 RefreshKind::nothing()
57 .with_cpu(CpuRefreshKind::nothing().with_frequency())
58 .with_memory(MemoryRefreshKind::nothing().with_ram()),
59 );
60 let cpus = system
61 .cpus()
62 .iter()
63 .map(|cpu| CpuInfo {
64 name: cpu.name().to_string(),
65 vender_id: cpu.vendor_id().to_string(),
66 brand: cpu.brand().to_string(),
67 frequency_mhz: cpu.frequency(),
68 })
69 .collect::<Vec<_>>();
70
71 let total_memory = system.total_memory();
72 let hostname = System::host_name().ok_or(MachineHookError::HostnameError)?;
73
74 Ok(MachineCaptured {
75 os,
76 os_version,
77 kernel_version,
78 architecture,
79 cpus,
80 total_memory: total_memory as usize,
81 hostname,
82 })
83 }
84}
85
86impl Captured for MachineCaptured {
87 fn to_json(&self) -> serde_json::Value {
88 serde_json::json!({
89 "os": self.os,
90 "os_version": self.os_version,
91 "kernel_version": self.kernel_version,
92 "architecture": self.architecture,
93 "cpus": self.cpus.iter().map(|cpu| {
94 serde_json::json!({
95 "name": cpu.name,
96 "vender_id": cpu.vender_id,
97 "brand": cpu.brand,
98 "frequency_mhz": cpu.frequency_mhz,
99 })
100 }).collect::<Vec<_>>(),
101 "total_memory": self.total_memory,
102 "hostname": self.hostname,
103 })
104 }
105}
106
107pub fn create_factory() -> Box<dyn HookFactory> {
108 Box::new(MachineHookFactory)
109}