|
1 | 1 | package websocket |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "encoding/json" |
5 | 6 | "fmt" |
6 | | - "sort" |
7 | 7 | "strings" |
8 | | - "sync" |
9 | 8 | "time" |
10 | 9 |
|
11 | 10 | "github.com/1Panel-dev/1Panel/agent/utils/common" |
12 | | - |
13 | 11 | "github.com/1Panel-dev/1Panel/agent/global" |
14 | 12 | "github.com/1Panel-dev/1Panel/agent/utils/files" |
15 | 13 | "github.com/shirou/gopsutil/v4/host" |
@@ -156,93 +154,85 @@ func getDownloadProcess(progress DownloadProgress) (res []byte, err error) { |
156 | 154 | return |
157 | 155 | } |
158 | 156 |
|
| 157 | +func handleProcessData(proc *process.Process, processConfig *PsProcessConfig, pidConnections map[int32][]net.ConnectionStat) *PsProcessData { |
| 158 | + if processConfig.Pid > 0 && processConfig.Pid != proc.Pid { |
| 159 | + return nil |
| 160 | + } |
| 161 | + procData := PsProcessData{ |
| 162 | + PID: proc.Pid, |
| 163 | + } |
| 164 | + if procName, err := proc.Name(); err == nil { |
| 165 | + procData.Name = procName |
| 166 | + } else { |
| 167 | + procData.Name = "<UNKNOWN>" |
| 168 | + } |
| 169 | + if processConfig.Name != "" && !strings.Contains(procData.Name, processConfig.Name) { |
| 170 | + return nil |
| 171 | + } |
| 172 | + if username, err := proc.Username(); err == nil { |
| 173 | + procData.Username = username |
| 174 | + } |
| 175 | + if processConfig.Username != "" && !strings.Contains(procData.Username, processConfig.Username) { |
| 176 | + return nil |
| 177 | + } |
| 178 | + procData.PPID, _ = proc.Ppid() |
| 179 | + statusArray, _ := proc.Status() |
| 180 | + if len(statusArray) > 0 { |
| 181 | + procData.Status = strings.Join(statusArray, ",") |
| 182 | + } |
| 183 | + createTime, procErr := proc.CreateTime() |
| 184 | + if procErr == nil { |
| 185 | + t := time.Unix(createTime/1000, 0) |
| 186 | + procData.StartTime = t.Format("2006-1-2 15:04:05") |
| 187 | + } |
| 188 | + procData.NumThreads, _ = proc.NumThreads() |
| 189 | + procData.CpuValue, _ = proc.CPUPercent() |
| 190 | + procData.CpuPercent = fmt.Sprintf("%.2f%%", procData.CpuValue) |
| 191 | + |
| 192 | + if memInfo, err := proc.MemoryInfo(); err == nil { |
| 193 | + procData.RssValue = memInfo.RSS |
| 194 | + procData.Rss = common.FormatBytes(memInfo.RSS) |
| 195 | + } else { |
| 196 | + procData.RssValue = 0 |
| 197 | + } |
| 198 | + |
| 199 | + if connections, ok := pidConnections[proc.Pid]; ok { |
| 200 | + procData.NumConnections = len(connections) |
| 201 | + } |
| 202 | + |
| 203 | + return &procData |
| 204 | +} |
| 205 | + |
159 | 206 | func getProcessData(processConfig PsProcessConfig) (res []byte, err error) { |
160 | | - var processes []*process.Process |
161 | | - processes, err = process.Processes() |
| 207 | + ctx := context.Background() |
| 208 | + |
| 209 | + processes, err := process.ProcessesWithContext(ctx) |
162 | 210 | if err != nil { |
163 | 211 | return |
164 | 212 | } |
165 | 213 |
|
166 | | - var ( |
167 | | - result []PsProcessData |
168 | | - resultMutex sync.Mutex |
169 | | - wg sync.WaitGroup |
170 | | - numWorkers = 4 |
171 | | - ) |
172 | | - |
173 | | - handleData := func(proc *process.Process) { |
174 | | - procData := PsProcessData{ |
175 | | - PID: proc.Pid, |
176 | | - } |
177 | | - if processConfig.Pid > 0 && processConfig.Pid != proc.Pid { |
178 | | - return |
179 | | - } |
180 | | - if procName, err := proc.Name(); err == nil { |
181 | | - procData.Name = procName |
182 | | - } else { |
183 | | - procData.Name = "<UNKNOWN>" |
184 | | - } |
185 | | - if processConfig.Name != "" && !strings.Contains(procData.Name, processConfig.Name) { |
186 | | - return |
187 | | - } |
188 | | - if username, err := proc.Username(); err == nil { |
189 | | - procData.Username = username |
190 | | - } |
191 | | - if processConfig.Username != "" && !strings.Contains(procData.Username, processConfig.Username) { |
192 | | - return |
193 | | - } |
194 | | - procData.PPID, _ = proc.Ppid() |
195 | | - statusArray, _ := proc.Status() |
196 | | - if len(statusArray) > 0 { |
197 | | - procData.Status = strings.Join(statusArray, ",") |
198 | | - } |
199 | | - createTime, procErr := proc.CreateTime() |
200 | | - if procErr == nil { |
201 | | - t := time.Unix(createTime/1000, 0) |
202 | | - procData.StartTime = t.Format("2006-1-2 15:04:05") |
203 | | - } |
204 | | - procData.NumThreads, _ = proc.NumThreads() |
205 | | - procData.CpuValue, _ = proc.CPUPercent() |
206 | | - procData.CpuPercent = fmt.Sprintf("%.2f", procData.CpuValue) + "%" |
207 | | - |
208 | | - if memInfo, err := proc.MemoryInfo(); err == nil { |
209 | | - procData.RssValue = memInfo.RSS |
210 | | - procData.Rss = common.FormatBytes(memInfo.RSS) |
211 | | - } else { |
212 | | - procData.RssValue = 0 |
213 | | - } |
| 214 | + connections, err := net.ConnectionsMaxWithContext(ctx, "all", 32768) |
| 215 | + if err != nil { |
| 216 | + return |
| 217 | + } |
214 | 218 |
|
215 | | - if connections, err := proc.Connections(); err == nil { |
216 | | - procData.NumConnections = len(connections) |
| 219 | + pidConnections := make(map[int32][]net.ConnectionStat, len(processes)) |
| 220 | + for _, conn := range connections { |
| 221 | + if conn.Pid == 0 { |
| 222 | + continue |
217 | 223 | } |
218 | | - |
219 | | - resultMutex.Lock() |
220 | | - result = append(result, procData) |
221 | | - resultMutex.Unlock() |
| 224 | + pidConnections[conn.Pid] = append(pidConnections[conn.Pid], conn) |
222 | 225 | } |
223 | 226 |
|
224 | | - chunkSize := (len(processes) + numWorkers - 1) / numWorkers |
225 | | - for i := 0; i < numWorkers; i++ { |
226 | | - wg.Add(1) |
227 | | - start := i * chunkSize |
228 | | - end := (i + 1) * chunkSize |
229 | | - if end > len(processes) { |
230 | | - end = len(processes) |
231 | | - } |
| 227 | + result := make([]PsProcessData, 0, len(processes)) |
232 | 228 |
|
233 | | - go func(start, end int) { |
234 | | - defer wg.Done() |
235 | | - for j := start; j < end; j++ { |
236 | | - handleData(processes[j]) |
237 | | - } |
238 | | - }(start, end) |
| 229 | + for _, proc := range processes { |
| 230 | + procData := handleProcessData(proc, &processConfig, pidConnections) |
| 231 | + if procData != nil { |
| 232 | + result = append(result, *procData) |
| 233 | + } |
239 | 234 | } |
240 | 235 |
|
241 | | - wg.Wait() |
242 | | - |
243 | | - sort.Slice(result, func(i, j int) bool { |
244 | | - return result[i].PID < result[j].PID |
245 | | - }) |
246 | 236 | res, err = json.Marshal(result) |
247 | 237 | return |
248 | 238 | } |
|
0 commit comments