pingap_performance/
process.rs1use bytesize::ByteSize;
16use memory_stats::memory_stats;
17use serde::{Deserialize, Serialize};
18use std::process;
19use std::sync::LazyLock;
20use std::sync::atomic::{AtomicI32, AtomicU64, Ordering};
21use sysinfo::MemoryRefreshKind;
22use sysinfo::{RefreshKind, System};
23
24static ACCEPTED: LazyLock<AtomicU64> = LazyLock::new(|| AtomicU64::new(0));
25static PROCESSING: LazyLock<AtomicI32> = LazyLock::new(|| AtomicI32::new(0));
26
27pub fn accept_request() {
30 ACCEPTED.fetch_add(1, Ordering::Relaxed);
31 PROCESSING.fetch_add(1, Ordering::Relaxed);
32}
33
34pub fn end_request() {
37 PROCESSING.fetch_sub(1, Ordering::Relaxed);
38}
39
40pub fn get_processing_accepted() -> (i32, u64) {
46 let processing = PROCESSING.load(Ordering::Relaxed);
47 let accepted = ACCEPTED.load(Ordering::Relaxed);
48 (processing, accepted)
49}
50
51#[derive(Serialize, Deserialize, Debug)]
52pub struct ProcessSystemInfo {
53 pub memory_mb: usize,
55 pub memory: String,
57 pub arch: String,
59 pub cpus: usize,
61 pub physical_cpus: usize,
63 pub total_memory: String,
65 pub used_memory: String,
67 pub kernel: String,
69 pub pid: u32,
71 pub threads: i64,
73 pub fd_count: usize,
75 pub tcp_count: usize,
77 pub tcp6_count: usize,
79}
80
81pub fn get_process_system_info() -> ProcessSystemInfo {
84 let pid = process::id();
85
86 cfg_if::cfg_if! {
87 if #[cfg(target_os = "linux")] {
88 let (fd_count, tcp_count, tcp6_count, threads) = if let Ok(p) = procfs::process::Process::new(pid as i32) {
89 let mut threads = -1_i64;
90 if let Ok(stat) = p.stat() {
91 threads = stat.num_threads;
92 }
93 (
94 p.fd_count().unwrap_or_default(),
95 p.tcp().unwrap_or_default().len(),
96 p.tcp6().unwrap_or_default().len(),
97 threads,
98 )
99 } else {
100 (0, 0, 0, -1_i64)
101 };
102 } else {
103 let (fd_count, tcp_count, tcp6_count, threads) = (0, 0, 0, -1_i64);
104 }
105 }
106
107 let mut memory = "".to_string();
108 let mut memory_mb = 0;
109 if let Some(value) = memory_stats() {
110 memory_mb = value.physical_mem / (1024 * 1024);
111 memory = ByteSize(value.physical_mem as u64).to_string();
112 }
113 let cpus = num_cpus::get();
114 let physical_cpus = num_cpus::get_physical();
115 let kind = MemoryRefreshKind::nothing().with_ram();
116 let mut sys =
117 System::new_with_specifics(RefreshKind::nothing().with_memory(kind));
118 sys.refresh_memory();
119
120 ProcessSystemInfo {
121 memory,
122 memory_mb,
123 arch: System::cpu_arch(),
124 cpus,
125 physical_cpus,
126 kernel: System::kernel_version().unwrap_or_default(),
127 total_memory: ByteSize(sys.total_memory()).to_string(),
128 used_memory: ByteSize(sys.used_memory()).to_string(),
129 pid,
130 threads,
131 fd_count,
132 tcp_count,
133 tcp6_count,
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use pretty_assertions::assert_eq;
141
142 #[test]
143 fn test_get_process_system_info() {
144 let info = get_process_system_info();
145 assert_eq!(true, info.memory_mb > 0);
146 assert_eq!(true, !info.memory.is_empty());
147 assert_eq!(true, !info.arch.is_empty());
148 assert_eq!(true, info.cpus > 0);
149 assert_eq!(true, info.physical_cpus > 0);
150 assert_eq!(true, !info.kernel.is_empty());
151 assert_eq!(true, info.pid != 0);
152 }
153
154 #[test]
155 fn test_get_processing_accepted() {
156 let (processing, accepted) = get_processing_accepted();
157 assert_eq!(processing, 0);
158 assert_eq!(accepted, 0);
159 accept_request();
160 let (processing, accepted) = get_processing_accepted();
161 assert_eq!(processing, 1);
162 assert_eq!(accepted, 1);
163 end_request();
164 let (processing, accepted) = get_processing_accepted();
165 assert_eq!(processing, 0);
166 assert_eq!(accepted, 1);
167 }
168}