|
1 | 1 | mod system_information; |
2 | 2 |
|
3 | | -use local_ip_address::list_afinet_netifas; |
4 | | -use std::collections::{HashMap, HashSet}; |
5 | | -use sysinfo::{Disks, System}; |
6 | | - |
7 | | -use crate::system_information::{SystemInformation, SystemNetworkInfo}; |
8 | | -use hickory_resolver::system_conf::read_system_conf; |
9 | | -use hickory_resolver::Resolver; |
10 | | -use std::net::IpAddr; |
11 | | -use std::time::Duration; |
12 | | - |
13 | | -fn main() { |
14 | | - // Please note that we use "new_all" to ensure that all list of |
15 | | - // components, network interfaces, disks and users are already |
16 | | - // filled! |
17 | | - let sys = System::new_all(); |
18 | | - |
19 | | - let disks = Disks::new_with_refreshed_list(); |
20 | | - let disks = disks |
21 | | - .into_iter() |
22 | | - .map(|disk| system_information::Disk::from(disk)) |
23 | | - .collect(); |
24 | | - |
25 | | - let system_network_information = get_network_info(); |
26 | | - |
27 | | - let current_uid = users::get_current_uid(); |
28 | | - let current_gid = users::get_current_gid(); |
29 | | - let current_user = users::get_user_by_uid(current_uid).unwrap(); |
30 | | - |
31 | | - |
32 | | - let system_information = SystemInformation { |
33 | | - cpu_count: sys.cpus().len(), |
34 | | - physical_core_count: sys.physical_core_count(), |
35 | | - |
36 | | - total_memory: sys.total_memory(), |
37 | | - free_memory: sys.free_memory(), |
38 | | - available_memory: sys.available_memory(), |
39 | | - used_memory: sys.used_memory(), |
40 | | - |
41 | | - total_swap: sys.total_swap(), |
42 | | - free_swap: sys.free_swap(), |
43 | | - used_swap: sys.used_swap(), |
44 | | - |
45 | | - total_memory_cgroup: sys.cgroup_limits().map(|limit| limit.total_memory), |
46 | | - free_memory_cgroup: sys.cgroup_limits().map(|limit| limit.free_memory), |
47 | | - free_swap_cgroup: sys.cgroup_limits().map(|limit| limit.free_swap), |
48 | | - |
49 | | - system_name: System::name(), |
50 | | - kernel_version: System::kernel_version(), |
51 | | - os_version: System::long_os_version(), |
52 | | - host_name: System::host_name(), |
53 | | - cpu_arch: System::cpu_arch(), |
54 | | - |
55 | | - disks, |
56 | | - |
57 | | - network_information: system_network_information, |
58 | | - |
59 | | - |
60 | | - // Adding current user, UID, and GID info |
61 | | - current_user: current_user.name().to_str().unwrap().to_string(), |
62 | | - current_uid, |
63 | | - current_gid, |
64 | | - }; |
65 | | - |
66 | | - let serialized = serde_json::to_string_pretty(&system_information).unwrap(); |
67 | | - println!("{}", serialized); |
68 | | - |
69 | | - // TODO: |
70 | | - // Current time |
71 | | - // SElinux/AppArmor |
72 | | - // Maybe env variables (may contain secrets) |
73 | | - // dmesg/syslog? |
74 | | - // capabilities? |
75 | | - // downward API |
76 | | - // Somehow get the custom resources logged? |
77 | | - |
78 | | - // Things left out for now because it doesn't seem too useful: |
79 | | - // - Running processes |
80 | | - // - Uptime/boot time |
81 | | - // - Load average |
82 | | - // - Network utilization |
83 | | - // - Users/Groups |
| 3 | +use clap::{crate_description, crate_version, Parser}; |
| 4 | +use stackable_operator::logging::TracingTarget; |
| 5 | +use std::path::PathBuf; |
| 6 | + |
| 7 | +use crate::system_information::SystemInformation; |
| 8 | +use std::time::Instant; |
| 9 | + |
| 10 | +const APP_NAME: &str = "containerdebug"; |
| 11 | + |
| 12 | +/// Collects and prints helpful debugging information about the environment that it is running in. |
| 13 | +#[derive(clap::Parser)] |
| 14 | +struct Opts { |
| 15 | + /// Loop every DURATION, instead of shutting down once completed (default DURATION: 1m) |
| 16 | + #[clap( |
| 17 | + long = "loop", |
| 18 | + value_name = "INTERVAL", |
| 19 | + default_missing_value = "1m", |
| 20 | + num_args = 0..=1, |
| 21 | + require_equals = true, |
| 22 | + )] |
| 23 | + loop_interval: Option<stackable_operator::time::Duration>, |
| 24 | + |
| 25 | + #[clap(long, short = 'o')] |
| 26 | + output: Option<PathBuf>, |
| 27 | + |
| 28 | + /// Tracing log collector system |
| 29 | + #[arg(long, env, default_value_t, value_enum)] |
| 30 | + pub tracing_target: TracingTarget, |
84 | 31 | } |
85 | 32 |
|
86 | | -fn get_network_info() -> SystemNetworkInfo { |
87 | | - /* |
88 | | - let resolver = Resolver::from_system_conf() |
89 | | - .map_err(|e| e.to_string()) |
90 | | - .unwrap(); |
91 | | - */ |
92 | | - let (resolver_config, mut resolver_opts) = read_system_conf().unwrap(); |
93 | | - resolver_opts.timeout = Duration::from_secs(5); |
94 | | - let resolver = Resolver::new(resolver_config, resolver_opts).unwrap(); |
95 | | - |
96 | | - let interfaces = match list_afinet_netifas() { |
97 | | - Ok(netifs) => { |
98 | | - let mut interface_map = std::collections::HashMap::new(); |
99 | | - |
100 | | - // Iterate over the network interfaces and group them by name |
101 | | - // An interface may appear multiple times if it has multiple IP addresses (e.g. IPv4 and IPv6) |
102 | | - for (name, ip_addr) in netifs { |
103 | | - interface_map |
104 | | - .entry(name) |
105 | | - .or_insert_with(Vec::new) |
106 | | - .push(ip_addr); |
107 | | - } |
108 | | - interface_map |
109 | | - } |
110 | | - Err(_) => HashMap::new(), |
111 | | - }; |
| 33 | +mod built_info { |
| 34 | + include!(concat!(env!("OUT_DIR"), "/built.rs")); |
| 35 | +} |
112 | 36 |
|
113 | | - let mut ip_set: HashSet<IpAddr> = HashSet::new(); |
114 | | - for (_, ip_addrs) in interfaces.iter() { |
115 | | - for ip_addr in ip_addrs { |
116 | | - ip_set.insert(ip_addr.clone()); |
| 37 | +fn main() { |
| 38 | + let opts = Opts::parse(); |
| 39 | + stackable_operator::logging::initialize_logging( |
| 40 | + "CONTAINERDEBUG_LOG", |
| 41 | + APP_NAME, |
| 42 | + opts.tracing_target, |
| 43 | + ); |
| 44 | + stackable_operator::utils::print_startup_string( |
| 45 | + crate_description!(), |
| 46 | + crate_version!(), |
| 47 | + built_info::GIT_VERSION, |
| 48 | + built_info::TARGET, |
| 49 | + built_info::BUILT_TIME_UTC, |
| 50 | + built_info::RUSTC_VERSION, |
| 51 | + ); |
| 52 | + |
| 53 | + let mut next_run = Instant::now(); |
| 54 | + loop { |
| 55 | + let next_run_sleep = next_run.saturating_duration_since(Instant::now()); |
| 56 | + if !next_run_sleep.is_zero() { |
| 57 | + tracing::info!(?next_run, "scheduling next run..."); |
117 | 58 | } |
118 | | - } |
| 59 | + std::thread::sleep(next_run_sleep); |
119 | 60 |
|
120 | | - let mut reverse_lookups = HashMap::new(); |
121 | | - for ip in ip_set { |
122 | | - if let Ok(result) = resolver.reverse_lookup(ip) { |
123 | | - for ptr_record in result { |
124 | | - let hostname = ptr_record.to_utf8(); |
125 | | - reverse_lookups |
126 | | - .entry(ip) |
127 | | - .or_insert_with(Vec::new) |
128 | | - .push(hostname); |
129 | | - } |
130 | | - } |
131 | | - } |
| 61 | + let system_information = SystemInformation::collect(); |
132 | 62 |
|
133 | | - let mut hostname_set: HashSet<String> = HashSet::new(); |
134 | | - for (_, hostnames) in reverse_lookups.iter() { |
135 | | - for hostname in hostnames { |
136 | | - hostname_set.insert(hostname.clone()); |
| 63 | + let serialized = serde_json::to_string_pretty(&system_information).unwrap(); |
| 64 | + // println!("{serialized}"); |
| 65 | + if let Some(output_path) = &opts.output { |
| 66 | + std::fs::write(output_path, &serialized).unwrap(); |
137 | 67 | } |
138 | | - } |
139 | 68 |
|
140 | | - let mut forward_lookups = HashMap::new(); |
141 | | - for hostname in hostname_set { |
142 | | - if let Ok(result) = resolver.lookup_ip(hostname.clone()) { |
143 | | - for ip_addr in result { |
144 | | - forward_lookups |
145 | | - .entry(hostname.clone()) |
146 | | - .or_insert_with(Vec::new) |
147 | | - .push(ip_addr); |
148 | | - } |
| 69 | + match opts.loop_interval { |
| 70 | + Some(interval) => next_run += interval, |
| 71 | + None => break, |
149 | 72 | } |
150 | 73 | } |
151 | | - |
152 | | - let system_network_information = SystemNetworkInfo { |
153 | | - network_interfaces: interfaces, |
154 | | - reverse_lookups, |
155 | | - forward_lookups, |
156 | | - }; |
157 | | - system_network_information |
158 | 74 | } |
0 commit comments