pingap_performance/
process.rs1use bytesize::ByteSize;
16use memory_stats::memory_stats;
17use once_cell::sync::Lazy;
18use pingap_config::get_current_config;
19use serde::{Deserialize, Serialize};
20use std::process;
21use std::sync::atomic::{AtomicI32, AtomicU64, Ordering};
22use sysinfo::MemoryRefreshKind;
23use sysinfo::{RefreshKind, System};
24
25static ACCEPTED: Lazy<AtomicU64> = Lazy::new(|| AtomicU64::new(0));
26static PROCESSING: Lazy<AtomicI32> = Lazy::new(|| AtomicI32::new(0));
27
28pub fn accept_request() {
31 ACCEPTED.fetch_add(1, Ordering::Relaxed);
32 PROCESSING.fetch_add(1, Ordering::Relaxed);
33}
34
35pub fn end_request() {
38 PROCESSING.fetch_sub(1, Ordering::Relaxed);
39}
40
41pub fn get_processing_accepted() -> (i32, u64) {
47 let processing = PROCESSING.load(Ordering::Relaxed);
48 let accepted = ACCEPTED.load(Ordering::Relaxed);
49 (processing, accepted)
50}
51
52#[derive(Serialize, Deserialize, Debug)]
53pub struct ProcessSystemInfo {
54 pub memory_mb: usize,
56 pub memory: String,
58 pub arch: String,
60 pub cpus: usize,
62 pub physical_cpus: usize,
64 pub total_memory: String,
66 pub used_memory: String,
68 pub kernel: String,
70 pub pid: u32,
72 pub threads: usize,
74 pub fd_count: usize,
76 pub tcp_count: usize,
78 pub tcp6_count: usize,
80}
81
82pub fn get_process_system_info() -> ProcessSystemInfo {
85 let current_config = get_current_config();
86 let data =
87 std::fs::read(current_config.basic.get_pid_file()).unwrap_or_default();
88 let mut pid = std::string::String::from_utf8_lossy(&data)
89 .trim()
90 .parse::<u32>()
91 .unwrap_or_default();
92 if pid == 0 {
93 pid = process::id();
94 }
95
96 cfg_if::cfg_if! {
97 if #[cfg(target_os = "linux")] {
98 let mut fd_count = 0;
99 let mut tcp_count = 0;
100 let mut tcp6_count =0;
101 if let Ok(p) = procfs::process::Process::new(pid as i32) {
102 fd_count = p.fd_count().unwrap_or_default();
103 tcp_count = p.tcp().unwrap_or_default().len();
104 tcp6_count = p.tcp6().unwrap_or_default().len();
105 }
106 } else {
107 let fd_count = 0;
108 let tcp_count = 0;
109 let tcp6_count =0;
110 }
111 }
112
113 let mut threads = 0;
114 let cpu_count = num_cpus::get();
115 let mut default_threads = current_config.basic.threads.unwrap_or(1);
116 if default_threads == 0 {
117 default_threads = cpu_count;
118 }
119 for (_, server) in current_config.servers.iter() {
120 let count = server.threads.unwrap_or(1);
121 if count == 0 {
122 threads += default_threads;
123 } else {
124 threads += count;
125 }
126 }
127
128 let mut memory = "".to_string();
129 let mut memory_mb = 0;
130 if let Some(value) = memory_stats() {
131 memory_mb = value.physical_mem / (1024 * 1024);
132 memory = ByteSize(value.physical_mem as u64).to_string();
133 }
134 let cpus = num_cpus::get();
135 let physical_cpus = num_cpus::get_physical();
136 let kind = MemoryRefreshKind::nothing().with_ram();
137 let mut sys =
138 System::new_with_specifics(RefreshKind::nothing().with_memory(kind));
139 sys.refresh_memory();
140
141 ProcessSystemInfo {
142 memory,
143 memory_mb,
144 arch: System::cpu_arch(),
145 cpus,
146 physical_cpus,
147 kernel: System::kernel_version().unwrap_or_default(),
148 total_memory: ByteSize(sys.total_memory()).to_string(),
149 used_memory: ByteSize(sys.used_memory()).to_string(),
150 pid,
151 threads,
152 fd_count,
153 tcp_count,
154 tcp6_count,
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161 use pretty_assertions::assert_eq;
162
163 #[test]
164 fn test_get_process_system_info() {
165 let info = get_process_system_info();
166 assert_eq!(true, info.memory_mb > 0);
167 assert_eq!(true, !info.memory.is_empty());
168 assert_eq!(true, !info.arch.is_empty());
169 assert_eq!(true, info.cpus > 0);
170 assert_eq!(true, info.physical_cpus > 0);
171 assert_eq!(true, !info.kernel.is_empty());
172 assert_eq!(true, info.pid != 0);
173 }
174
175 #[test]
176 fn test_get_processing_accepted() {
177 let (processing, accepted) = get_processing_accepted();
178 assert_eq!(processing, 0);
179 assert_eq!(accepted, 0);
180 accept_request();
181 let (processing, accepted) = get_processing_accepted();
182 assert_eq!(processing, 1);
183 assert_eq!(accepted, 1);
184 end_request();
185 let (processing, accepted) = get_processing_accepted();
186 assert_eq!(processing, 0);
187 assert_eq!(accepted, 1);
188 }
189}