package com.elastic.support.diagnostics.commands; import com.elastic.support.diagnostics.chain.Command; import com.elastic.support.diagnostics.chain.DiagnosticContext; import com.elastic.support.util.SystemProperties; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import oshi.hardware.CentralProcessor.TickType; import oshi.json.SystemInfo; import oshi.json.hardware.*; import oshi.json.software.os.FileSystem; import oshi.json.software.os.*; import oshi.software.os.OperatingSystem.ProcessSort; import oshi.util.FormatUtil; import oshi.util.Util; import java.io.*; import java.util.Arrays; import java.util.List; public class RetrieveSystemDigest implements Command { /** * Calls the OSHI librries to get system specific digest ouput in * JSON format. */ private final Logger logger = LogManager.getLogger(RetrieveSystemDigest.class); public void execute(DiagnosticContext context) { try { SystemInfo si = new SystemInfo(); HardwareAbstractionLayer hal = si.getHardware(); OperatingSystem os = si.getOperatingSystem(); File sysFileJson = new File(context.tempDir + SystemProperties.fileSeparator + "system-digest.json"); OutputStream outputStreamJson = new FileOutputStream(sysFileJson); BufferedWriter jsonWriter = new BufferedWriter(new OutputStreamWriter(outputStreamJson)); String jsonInfo = si.toPrettyJSON(); jsonWriter.write(jsonInfo); jsonWriter.close(); File sysFile = new File(context.tempDir + SystemProperties.fileSeparator + "system-digest.txt"); OutputStream outputStream = new FileOutputStream(sysFile); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream)); printComputerSystem(writer, hal.getComputerSystem()); writer.newLine(); printProcessor(writer, hal.getProcessor()); writer.newLine(); printMemory(writer, hal.getMemory()); writer.newLine(); printCpu(writer, hal.getProcessor()); writer.newLine(); printProcesses(writer, os, hal.getMemory()); writer.newLine(); printDisks(writer, hal.getDiskStores()); writer.newLine(); printFileSystem(writer, os.getFileSystem()); writer.newLine(); printNetworkInterfaces(writer, hal.getNetworkIFs()); writer.newLine(); printNetworkParameters(writer, os.getNetworkParams()); writer.newLine(); writer.close(); logger.info("Finished querying SysInfo."); } catch (final Exception e) { logger.info("Failed saving system-digest.txt file.", e); } } private static void printComputerSystem(BufferedWriter writer, final ComputerSystem computerSystem) throws Exception { writer.write("Computer System"); writer.newLine(); writer.write("----------------"); writer.newLine(); writer.write("manufacturer: " + computerSystem.getManufacturer()); writer.newLine(); writer.write("model: " + computerSystem.getModel()); writer.newLine(); writer.write("serialnumber: " + computerSystem.getSerialNumber()); writer.newLine(); final Firmware firmware = computerSystem.getFirmware(); writer.write("firmware:"); writer.newLine(); writer.write(" manufacturer: " + firmware.getManufacturer()); writer.newLine(); writer.write(" name: " + firmware.getName()); writer.newLine(); writer.write(" description: " + firmware.getDescription()); writer.newLine(); writer.write(" version: " + firmware.getVersion()); writer.newLine(); writer.write(" release date: " + (firmware.getReleaseDate() == null ? "unknown" : firmware.getReleaseDate() == null ? "unknown" : firmware.getReleaseDate())); writer.newLine(); final Baseboard baseboard = computerSystem.getBaseboard(); writer.write("baseboard:"); writer.newLine(); writer.write(" manufacturer: " + baseboard.getManufacturer()); writer.write(" model: " + baseboard.getModel()); writer.newLine(); writer.write(" version: " + baseboard.getVersion()); writer.newLine(); writer.write(" serialnumber: " + baseboard.getSerialNumber()); writer.newLine(); } private static void printProcessor(BufferedWriter writer, CentralProcessor processor) throws Exception { writer.write("Processors"); writer.newLine(); writer.write("----------"); writer.newLine(); writer.write(" " + processor.getPhysicalPackageCount() + " physical CPU package(s)"); writer.newLine(); writer.write(" " + processor.getPhysicalProcessorCount() + " physical CPU core(s)"); writer.newLine(); writer.write(" " + processor.getLogicalProcessorCount() + " logical CPU(s)"); writer.newLine(); writer.write("Identifier: " + processor.getIdentifier()); writer.newLine(); writer.write("ProcessorID: " + processor.getProcessorID()); writer.newLine(); } private static void printProcesses(BufferedWriter writer, OperatingSystem os, GlobalMemory memory) throws Exception { writer.write("Processes"); writer.newLine(); writer.write("----------"); writer.newLine(); writer.write("Processes: " + os.getProcessCount() + ", Threads: " + os.getThreadCount()); writer.newLine(); // Sort by highest CPU List<OSProcess> procs = Arrays.asList(os.getProcesses(os.getProcessCount(), ProcessSort.CPU)); int sz = procs.size(); writer.write("PID %CPU %MEM VSZ RSS Name"); for (int i = 0; i < sz; i++) { OSProcess p = procs.get(i); writer.write(String.format(" %5d %5.1f %4.1f %9s %9s %s%n", p.getProcessID(), 100d * (p.getKernelTime() + p.getUserTime()) / p.getUpTime(), 100d * p.getResidentSetSize() / memory.getTotal(), FormatUtil.formatBytes(p.getVirtualSize()), FormatUtil.formatBytes(p.getResidentSetSize()), p.getName())); } } private static void printMemory(BufferedWriter writer, GlobalMemory memory) throws Exception { writer.write("Memory"); writer.newLine(); writer.write("-------"); writer.newLine(); writer.write("Memory: " + FormatUtil.formatBytes(memory.getAvailable()) + "/" + FormatUtil.formatBytes(memory.getTotal())); writer.newLine(); writer.write("Swap used: " + FormatUtil.formatBytes(memory.getSwapUsed()) + "/" + FormatUtil.formatBytes(memory.getSwapTotal())); writer.newLine(); } private static void printCpu(BufferedWriter writer, CentralProcessor processor) throws Exception { writer.write("CPU"); writer.newLine(); writer.write("---"); writer.newLine(); writer.write("Uptime: " + FormatUtil.formatElapsedSecs(processor.getSystemUptime())); writer.newLine(); writer.write( "Context Switches/Interrupts: " + processor.getContextSwitches() + " / " + processor.getInterrupts()); writer.newLine(); long[] prevTicks = processor.getSystemCpuLoadTicks(); writer.write("CPU, IOWait, and IRQ ticks @ 0 sec:" + Arrays.toString(prevTicks)); writer.newLine(); // Wait a second... Util.sleep(1000); long[] ticks = processor.getSystemCpuLoadTicks(); writer.write("CPU, IOWait, and IRQ ticks @ 1 sec:" + Arrays.toString(ticks)); writer.newLine(); long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; long sys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; long totalCpu = user + nice + sys + idle + iowait + irq + softirq + steal; writer.write(String.format( "User: %.1f%% Nice: %.1f%% System: %.1f%% Idle: %.1f%% IOwait: %.1f%% IRQ: %.1f%% SoftIRQ: %.1f%% Steal: %.1f%%%n", 100d * user / totalCpu, 100d * nice / totalCpu, 100d * sys / totalCpu, 100d * idle / totalCpu, 100d * iowait / totalCpu, 100d * irq / totalCpu, 100d * softirq / totalCpu, 100d * steal / totalCpu)); writer.newLine(); writer.write(String.format("CPU load: %.1f%% (counting ticks)%n", processor.getSystemCpuLoadBetweenTicks() * 100)); writer.write(String.format("CPU load: %.1f%% (OS MXBean)%n", processor.getSystemCpuLoad() * 100)); double[] loadAverage = processor.getSystemLoadAverage(3); writer.write("CPU load averages:" + (loadAverage[0] < 0 ? " N/A" : String.format(" %.2f", loadAverage[0])) + (loadAverage[1] < 0 ? " N/A" : String.format(" %.2f", loadAverage[1])) + (loadAverage[2] < 0 ? " N/A" : String.format(" %.2f", loadAverage[2]))); // per core CPU StringBuilder procCpu = new StringBuilder("CPU load per processor:"); double[] load = processor.getProcessorCpuLoadBetweenTicks(); for (double avg : load) { procCpu.append(String.format(" %.1f%%", avg * 100)); } writer.write(procCpu.toString()); writer.newLine(); } private static void printDisks(BufferedWriter writer, HWDiskStore[] diskStores) throws Exception { writer.write("Disks"); writer.newLine(); writer.write("-----"); writer.newLine(); for (HWDiskStore disk : diskStores) { boolean readwrite = disk.getReads() > 0 || disk.getWrites() > 0; writer.write(String.format(" %s: (model: %s - S/N: %s) size: %s, reads: %s (%s), writes: %s (%s), xfer: %s ms%n", disk.getName(), disk.getModel(), disk.getSerial(), disk.getSize() > 0 ? FormatUtil.formatBytesDecimal(disk.getSize()) : "?", readwrite ? disk.getReads() : "?", readwrite ? FormatUtil.formatBytes(disk.getReadBytes()) : "?", readwrite ? disk.getWrites() : "?", readwrite ? FormatUtil.formatBytes(disk.getWriteBytes()) : "?", readwrite ? disk.getTransferTime() : "?")); HWPartition[] partitions = disk.getPartitions(); if (partitions == null) { continue; } for (HWPartition part : partitions) { writer.write(String.format(" |-- %s: %s (%s) Maj:Min=%d:%d, size: %s%s%n", part.getIdentification(), part.getName(), part.getType(), part.getMajor(), part.getMinor(), FormatUtil.formatBytesDecimal(part.getSize()), part.getMountPoint().isEmpty() ? "" : " @ " + part.getMountPoint())); } } } private static void printFileSystem(BufferedWriter writer, FileSystem fileSystem) throws Exception { writer.write("File System"); writer.newLine(); writer.write("-------------"); writer.newLine(); writer.write(String.format(" File Descriptors: %d/%d%n", fileSystem.getOpenFileDescriptors(), fileSystem.getMaxFileDescriptors())); OSFileStore[] fsArray = fileSystem.getFileStores(); for (OSFileStore fs : fsArray) { long usable = fs.getUsableSpace(); long total = fs.getTotalSpace(); writer.write(String.format(" %s (%s) [%s] %s of %s free (%.1f%%) is %s and is mounted at %s%n", fs.getName(), fs.getDescription().isEmpty() ? "file system" : fs.getDescription(), fs.getType(), FormatUtil.formatBytes(usable), FormatUtil.formatBytes(fs.getTotalSpace()), 100d * usable / total, fs.getVolume(), fs.getMount())); } } private static void printNetworkParameters(BufferedWriter writer, NetworkParams networkParams) throws Exception { writer.write("Network Parameters"); writer.newLine(); writer.write("----------------"); writer.newLine(); writer.write(String.format(" Host name: %s%n", networkParams.getHostName())); writer.write(String.format(" Domain name: %s%n", networkParams.getDomainName())); writer.write(String.format(" DNS servers: %s%n", Arrays.toString(networkParams.getDnsServers()))); writer.write(String.format(" IPv4 Gateway: %s%n", networkParams.getIpv4DefaultGateway())); writer.write(String.format(" IPv6 Gateway: %s%n", networkParams.getIpv6DefaultGateway())); } private static void printNetworkInterfaces(BufferedWriter writer, NetworkIF[] networkIFs) throws Exception { writer.write("Network interfaces"); writer.newLine(); writer.write("----------------"); writer.newLine(); for (NetworkIF net : networkIFs) { writer.write(String.format(" Name: %s (%s)%n", net.getName(), net.getDisplayName())); writer.write(String.format(" MAC Address: %s %n", net.getMacaddr())); writer.write(String.format(" MTU: %s, Speed: %s %n", net.getMTU(), FormatUtil.formatValue(net.getSpeed(), "bps"))); writer.write(String.format(" IPv4: %s %n", Arrays.toString(net.getIPv4addr()))); writer.write(String.format(" IPv6: %s %n", Arrays.toString(net.getIPv6addr()))); boolean hasData = net.getBytesRecv() > 0 || net.getBytesSent() > 0 || net.getPacketsRecv() > 0 || net.getPacketsSent() > 0; writer.write(String.format(" Traffic: received %s/%s%s; transmitted %s/%s%s %n", hasData ? net.getPacketsRecv() + " packets" : "?", hasData ? FormatUtil.formatBytes(net.getBytesRecv()) : "?", hasData ? " (" + net.getInErrors() + " err)" : "", hasData ? net.getPacketsSent() + " packets" : "?", hasData ? FormatUtil.formatBytes(net.getBytesSent()) : "?", hasData ? " (" + net.getOutErrors() + " err)" : "")); } } }