1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package psiprobe.controllers.oshi;
36
37 import jakarta.servlet.http.HttpServletRequest;
38 import jakarta.servlet.http.HttpServletResponse;
39
40 import java.time.Instant;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.List;
44 import java.util.Map.Entry;
45
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Value;
49 import org.springframework.stereotype.Controller;
50 import org.springframework.web.bind.annotation.RequestMapping;
51 import org.springframework.web.servlet.ModelAndView;
52
53 import oshi.PlatformEnum;
54 import oshi.SystemInfo;
55 import oshi.hardware.CentralProcessor;
56 import oshi.hardware.CentralProcessor.PhysicalProcessor;
57 import oshi.hardware.CentralProcessor.TickType;
58 import oshi.hardware.ComputerSystem;
59 import oshi.hardware.Display;
60 import oshi.hardware.GlobalMemory;
61 import oshi.hardware.GraphicsCard;
62 import oshi.hardware.HWDiskStore;
63 import oshi.hardware.HWPartition;
64 import oshi.hardware.HardwareAbstractionLayer;
65 import oshi.hardware.LogicalVolumeGroup;
66 import oshi.hardware.NetworkIF;
67 import oshi.hardware.PhysicalMemory;
68 import oshi.hardware.PowerSource;
69 import oshi.hardware.Sensors;
70 import oshi.hardware.SoundCard;
71 import oshi.hardware.UsbDevice;
72 import oshi.hardware.VirtualMemory;
73 import oshi.software.os.FileSystem;
74 import oshi.software.os.InternetProtocolStats;
75 import oshi.software.os.NetworkParams;
76 import oshi.software.os.OSFileStore;
77 import oshi.software.os.OSProcess;
78 import oshi.software.os.OSService;
79 import oshi.software.os.OSSession;
80 import oshi.software.os.OperatingSystem;
81 import oshi.software.os.OperatingSystem.ProcessFiltering;
82 import oshi.software.os.OperatingSystem.ProcessSorting;
83 import oshi.util.FormatUtil;
84 import oshi.util.Util;
85
86 import psiprobe.controllers.AbstractTomcatContainerController;
87
88
89
90
91
92
93 @Controller
94 public class OshiController extends AbstractTomcatContainerController {
95
96
97 private static final Logger logger = LoggerFactory.getLogger(OshiController.class);
98
99
100 private static List<String> oshi = new ArrayList<>();
101
102 @RequestMapping(path = "/adm/oshi.htm")
103 @Override
104 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
105 throws Exception {
106 return super.handleRequest(request, response);
107 }
108
109 @Override
110 protected ModelAndView handleRequestInternal(HttpServletRequest request,
111 HttpServletResponse response) throws Exception {
112
113 if (!oshi.isEmpty()) {
114 ModelAndView mv = new ModelAndView(getViewName());
115 mv.addObject("oshi", oshi);
116 return mv;
117 }
118
119
120 oshi.add(
121 "Oshi results are performed as a system dump to screen here using Oshi SystemInfoTest logic.");
122 oshi.add(
123 "Please be advised this is experimental in use and is slow. Resulting data is entirely cached.");
124 oshi.add("Issues with library should be directed to https://github.com/oshi/oshi");
125 oshi.add("For issues with our library usage of Oshi, please submit pull requests");
126 oshi.add("");
127 oshi.add("");
128
129 this.initialize();
130
131 ModelAndView mv = new ModelAndView(getViewName());
132 mv.addObject("oshi", oshi);
133 return mv;
134 }
135
136 @Value("oshi")
137 @Override
138 public void setViewName(String viewName) {
139 super.setViewName(viewName);
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 private void initialize() {
160 logger.debug("Initializing System...");
161 SystemInfo si = new SystemInfo();
162
163
164 if (PlatformEnum.UNKNOWN.equals(SystemInfo.getCurrentPlatform())) {
165 logger.error("Oshi not supported on current platform");
166 oshi.add("Oshi not supported on current platform");
167 oshi.add("");
168 return;
169 }
170
171 HardwareAbstractionLayer hal = si.getHardware();
172 OperatingSystem os = si.getOperatingSystem();
173
174 printOperatingSystem(os);
175
176 logger.debug("Checking computer system...");
177 printComputerSystem(hal.getComputerSystem());
178
179 logger.debug("Checking Processor...");
180 printProcessor(hal.getProcessor());
181
182 logger.debug("Checking Memory...");
183 printMemory(hal.getMemory());
184
185 logger.debug("Checking CPU...");
186 printCpu(hal.getProcessor());
187
188 logger.debug("Checking Processes...");
189 printProcesses(os, hal.getMemory());
190
191 logger.debug("Checking Services...");
192 printServices(os);
193
194 logger.debug("Checking Sensors...");
195 printSensors(hal.getSensors());
196
197 logger.debug("Checking Power sources...");
198 printPowerSources(hal.getPowerSources());
199
200 logger.debug("Checking Disks...");
201 printDisks(hal.getDiskStores());
202
203 logger.debug("Checking Logical Volume Groups ...");
204 printLogicalVolumegroups(hal.getLogicalVolumeGroups());
205
206 logger.debug("Checking File System...");
207 printFileSystem(os.getFileSystem());
208
209 logger.debug("Checking Network interfaces...");
210 printNetworkInterfaces(hal.getNetworkIFs());
211
212 logger.debug("Checking Network parameters...");
213 printNetworkParameters(os.getNetworkParams());
214
215 logger.debug("Checking IP statistics...");
216 printInternetProtocolStats(os.getInternetProtocolStats());
217
218 logger.debug("Checking Displays...");
219 printDisplays(hal.getDisplays());
220
221 logger.debug("Checking USB Devices...");
222 printUsbDevices(hal.getUsbDevices(true));
223
224 logger.debug("Checking Sound Cards...");
225 printSoundCards(hal.getSoundCards());
226
227 logger.debug("Checking Graphics Cards...");
228 printGraphicsCards(hal.getGraphicsCards());
229
230
231 oshi.add("Finished Operating System and Hardware Info Dump");
232
233 StringBuilder output = new StringBuilder();
234 for (String element : oshi) {
235 output.append(element);
236
237 if (!"\n".equals(element)) {
238 output.append('\n');
239 }
240 }
241 logger.info("Printing Operating System and Hardware Info:{}{}", '\n', output);
242 }
243
244
245
246
247
248
249 private static void printOperatingSystem(final OperatingSystem operatingSystem) {
250 oshi.add(String.valueOf(operatingSystem));
251 oshi.add("Booted: " + Instant.ofEpochSecond(operatingSystem.getSystemBootTime()));
252 oshi.add("Uptime: " + FormatUtil.formatElapsedSecs(operatingSystem.getSystemUptime()));
253 oshi.add(
254 "Running with" + (operatingSystem.isElevated() ? "" : "out") + " elevated permissions.");
255 oshi.add("Sessions:");
256 for (OSSession s : operatingSystem.getSessions()) {
257 oshi.add(" " + s.toString());
258 }
259 }
260
261
262
263
264
265
266 private static void printComputerSystem(final ComputerSystem computerSystem) {
267 oshi.add("System: " + computerSystem.toString());
268 oshi.add(" Firmware: " + computerSystem.getFirmware().toString());
269 oshi.add(" Baseboard: " + computerSystem.getBaseboard().toString());
270 }
271
272
273
274
275
276
277 private static void printProcessor(CentralProcessor processor) {
278 oshi.add(processor.toString());
279 oshi.add(" Cores:");
280 for (PhysicalProcessor p : processor.getPhysicalProcessors()) {
281 oshi.add(
282 " " + (processor.getPhysicalPackageCount() > 1 ? p.getPhysicalPackageNumber() + "," : "")
283 + p.getPhysicalProcessorNumber() + ": efficiency=" + p.getEfficiency() + ", id="
284 + p.getIdString());
285 }
286 }
287
288
289
290
291
292
293 private static void printMemory(GlobalMemory memory) {
294 oshi.add("Physical Memory: \n " + memory.toString());
295 VirtualMemory vm = memory.getVirtualMemory();
296 oshi.add("Virtual Memory: \n " + vm.toString());
297 List<PhysicalMemory> pmList = memory.getPhysicalMemory();
298 if (!pmList.isEmpty()) {
299 oshi.add("Physical Memory: ");
300 for (PhysicalMemory pm : pmList) {
301 oshi.add(" " + pm.toString());
302 }
303 }
304 }
305
306
307
308
309
310
311 private static void printCpu(CentralProcessor processor) {
312 oshi.add("Context Switches/Interrupts: " + processor.getContextSwitches() + " / "
313 + processor.getInterrupts());
314
315 long[] prevTicks = processor.getSystemCpuLoadTicks();
316 oshi.add("CPU, IOWait, and IRQ ticks @ 0 sec:" + Arrays.toString(prevTicks));
317
318 Util.sleep(1000);
319 long[] ticks = processor.getSystemCpuLoadTicks();
320 oshi.add("CPU, IOWait, and IRQ ticks @ 1 sec:" + Arrays.toString(ticks));
321 long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
322 long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
323 long sys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
324 long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
325 long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
326 long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
327 long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
328 long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
329 long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal;
330
331 oshi.add(String.format(
332 "User: %.1f%% Nice: %.1f%% System: %.1f%% Idle: %.1f%% IOwait: %.1f%% IRQ: %.1f%% SoftIRQ: %.1f%% Steal: %.1f%%",
333 100d * user / totalCpu, 100d * nice / totalCpu, 100d * sys / totalCpu,
334 100d * idle / totalCpu, 100d * iowait / totalCpu, 100d * irq / totalCpu,
335 100d * softirq / totalCpu, 100d * steal / totalCpu));
336 oshi.add(
337 String.format("CPU load: %.1f%%", processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100));
338 double[] loadAverage = processor.getSystemLoadAverage(3);
339 oshi.add("CPU load averages:"
340 + (loadAverage[0] < 0 ? " N/A" : String.format(" %.2f", loadAverage[0]))
341 + (loadAverage[1] < 0 ? " N/A" : String.format(" %.2f", loadAverage[1]))
342 + (loadAverage[2] < 0 ? " N/A" : String.format(" %.2f", loadAverage[2])));
343
344 StringBuilder procCpu = new StringBuilder("CPU load per processor:");
345 long[][] prevProcTicks = processor.getProcessorCpuLoadTicks();
346 double[] load = processor.getProcessorCpuLoadBetweenTicks(prevProcTicks);
347 for (double avg : load) {
348 procCpu.append(String.format(" %.1f%%", avg * 100));
349 }
350 oshi.add(procCpu.toString());
351 long freq = processor.getProcessorIdentifier().getVendorFreq();
352 if (freq > 0) {
353 oshi.add("Vendor Frequency: " + FormatUtil.formatHertz(freq));
354 }
355 freq = processor.getMaxFreq();
356 if (freq > 0) {
357 oshi.add("Max Frequency: " + FormatUtil.formatHertz(freq));
358 }
359 long[] freqs = processor.getCurrentFreq();
360 if (freqs[0] > 0) {
361 StringBuilder sb = new StringBuilder("Current Frequencies: ");
362 for (int i = 0; i < freqs.length; i++) {
363 if (i > 0) {
364 sb.append(", ");
365 }
366 sb.append(FormatUtil.formatHertz(freqs[i]));
367 }
368 oshi.add(sb.toString());
369 }
370 }
371
372
373
374
375
376
377
378 private static void printProcesses(OperatingSystem os, GlobalMemory memory) {
379 OSProcess myProc = os.getProcess(os.getProcessId());
380
381 oshi.add("My PID: " + myProc.getProcessID() + " with affinity "
382 + Long.toBinaryString(myProc.getAffinityMask()));
383 oshi.add("Processes: " + os.getProcessCount() + ", Threads: " + os.getThreadCount());
384
385 List<OSProcess> procs =
386 os.getProcesses(ProcessFiltering.ALL_PROCESSES, ProcessSorting.CPU_DESC, 5);
387 oshi.add(" PID %CPU %MEM VSZ RSS Name");
388 for (int i = 0; i < procs.size() && i < 5; i++) {
389 OSProcess p = procs.get(i);
390 oshi.add(String.format(" %5d %5.1f %4.1f %9s %9s %s", p.getProcessID(),
391 100d * (p.getKernelTime() + p.getUserTime()) / p.getUpTime(),
392 100d * p.getResidentSetSize() / memory.getTotal(),
393 FormatUtil.formatBytes(p.getVirtualSize()),
394 FormatUtil.formatBytes(p.getResidentSetSize()), p.getName()));
395 }
396 OSProcess p = os.getProcess(os.getProcessId());
397 oshi.add("Current process arguments: ");
398 for (String s : p.getArguments()) {
399 oshi.add(" " + s);
400 }
401 oshi.add("Current process environment: ");
402 for (Entry<String, String> e : p.getEnvironmentVariables().entrySet()) {
403 oshi.add(" " + e.getKey() + '=' + e.getValue());
404 }
405 }
406
407
408
409
410
411
412 private static void printServices(OperatingSystem os) {
413 oshi.add("Services: ");
414 oshi.add(" PID State Name");
415
416 int i = 0;
417 for (OSService s : os.getServices()) {
418 if (s.getState().equals(OSService.State.RUNNING) && i++ < 5) {
419 oshi.add(String.format(" %5d %7s %s", s.getProcessID(), s.getState(), s.getName()));
420 }
421 }
422 i = 0;
423 for (OSService s : os.getServices()) {
424 if (s.getState().equals(OSService.State.STOPPED) && i++ < 5) {
425 oshi.add(String.format(" %5d %7s %s", s.getProcessID(), s.getState(), s.getName()));
426 }
427 }
428 }
429
430
431
432
433
434
435 private static void printSensors(Sensors sensors) {
436 oshi.add("Sensors: " + sensors.toString());
437 }
438
439
440
441
442
443
444 private static void printPowerSources(List<PowerSource> list) {
445 StringBuilder sb = new StringBuilder("Power Sources: ");
446 if (list.isEmpty()) {
447 sb.append("Unknown");
448 }
449 for (PowerSource powerSource : list) {
450 sb.append("\n ").append(powerSource.toString());
451 }
452 oshi.add(sb.toString());
453 }
454
455
456
457
458
459
460 private static void printDisks(List<HWDiskStore> list) {
461 oshi.add("Disks:");
462 for (HWDiskStore disk : list) {
463 oshi.add(" " + disk.toString());
464
465 List<HWPartition> partitions = disk.getPartitions();
466 for (HWPartition part : partitions) {
467 oshi.add(" |-- " + part.toString());
468 }
469 }
470
471 }
472
473
474
475
476
477
478 private static void printLogicalVolumegroups(List<LogicalVolumeGroup> list) {
479 if (!list.isEmpty()) {
480 oshi.add("Logical Volume Groups:");
481 for (LogicalVolumeGroup lvg : list) {
482 oshi.add(" " + lvg.toString());
483 }
484 }
485 }
486
487
488
489
490
491
492 private static void printFileSystem(FileSystem fileSystem) {
493 oshi.add("File System:");
494
495 oshi.add(String.format(" File Descriptors: %d/%d", fileSystem.getOpenFileDescriptors(),
496 fileSystem.getMaxFileDescriptors()));
497
498 for (OSFileStore fs : fileSystem.getFileStores()) {
499 long usable = fs.getUsableSpace();
500 long total = fs.getTotalSpace();
501 oshi.add(String.format(
502 " %s (%s) [%s] %s of %s free (%.1f%%), %s of %s files free (%.1f%%) is %s "
503 + (fs.getLogicalVolume() != null && fs.getLogicalVolume().length() > 0 ? "[%s]"
504 : "%s")
505 + " and is mounted at %s",
506 fs.getName(), fs.getDescription().isEmpty() ? "file system" : fs.getDescription(),
507 fs.getType(), FormatUtil.formatBytes(usable), FormatUtil.formatBytes(fs.getTotalSpace()),
508 100d * usable / total, FormatUtil.formatValue(fs.getFreeInodes(), ""),
509 FormatUtil.formatValue(fs.getTotalInodes(), ""),
510 100d * fs.getFreeInodes() / fs.getTotalInodes(), fs.getVolume(), fs.getLogicalVolume(),
511 fs.getMount()));
512 }
513 }
514
515
516
517
518
519
520 private static void printNetworkInterfaces(List<NetworkIF> list) {
521 StringBuilder sb = new StringBuilder("Network Interfaces:");
522 if (list.isEmpty()) {
523 sb.append(" Unknown");
524 } else {
525 for (NetworkIF net : list) {
526 sb.append("\n ").append(net.toString());
527 }
528 }
529 oshi.add(sb.toString());
530 }
531
532
533
534
535
536
537 private static void printNetworkParameters(NetworkParams networkParams) {
538 oshi.add("Network parameters:\n " + networkParams.toString());
539 }
540
541
542
543
544
545
546 private static void printInternetProtocolStats(InternetProtocolStats internetProtocolStats) {
547 oshi.add("Internet Protocol statistics:");
548 oshi.add(" TCPv4: " + internetProtocolStats.getTCPv4Stats());
549 oshi.add(" TCPv6: " + internetProtocolStats.getTCPv6Stats());
550 oshi.add(" UDPv4: " + internetProtocolStats.getUDPv4Stats());
551 oshi.add(" UDPv6: " + internetProtocolStats.getUDPv6Stats());
552 }
553
554
555
556
557
558
559 private static void printDisplays(List<Display> list) {
560 oshi.add("Displays:");
561 int i = 0;
562 for (Display display : list) {
563 oshi.add(" Display " + i + ":");
564 oshi.add(String.valueOf(display));
565 i++;
566 }
567 }
568
569
570
571
572
573
574 private static void printUsbDevices(List<UsbDevice> list) {
575 oshi.add("USB Devices:");
576 for (UsbDevice usbDevice : list) {
577 oshi.add(String.valueOf(usbDevice));
578 }
579 }
580
581
582
583
584
585
586 private static void printSoundCards(List<SoundCard> list) {
587 oshi.add("Sound Cards:");
588 for (SoundCard card : list) {
589 oshi.add(" " + String.valueOf(card));
590 }
591 }
592
593
594
595
596
597
598 private static void printGraphicsCards(List<GraphicsCard> list) {
599 oshi.add("Graphics Cards:");
600 if (list.isEmpty()) {
601 oshi.add(" None detected.");
602 } else {
603 for (GraphicsCard card : list) {
604 oshi.add(" " + String.valueOf(card));
605 }
606 }
607 }
608
609 }