From 0973c974accd563a85c425377b2ae67cee6d4cee Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Fri, 28 May 2021 15:52:33 +0200 Subject: [PATCH 1/6] Work on base/common metrics. --- build.gradle | 1 + client/build.gradle | 4 + plugins/build.gradle | 5 + plugins/os-aix/build.gradle | 3 - .../plugins/os_aix/AixDiskExtension.java | 91 ----------- .../sysmon/plugins/os_aix/AixDiskStat.java | 53 ------- .../plugins/os_aix/AixMemoryExtension.java | 68 -------- .../sysmon/plugins/os_aix/AixMemoryStat.java | 60 ------- .../plugins/os_aix/AixProcessorExtension.java | 4 +- .../os-aix/src/test/groovy/AixDiskTest.groovy | 26 ---- .../src/test/groovy/AixMemoryTest.groovy | 29 ---- plugins/os-aix/src/test/resources/iostat.txt | 3 - .../os-aix/src/test/resources/mpstat-v.txt | 15 -- plugins/os-aix/src/test/resources/svmon.txt | 6 - .../os-aix/src/test/resources/vmstat-Iwt.txt | 7 - plugins/os-base/README.md | 36 +++++ plugins/os-base/build.gradle | 2 + plugins/os-base/gradle.properties | 7 + .../plugins/os_base/BaseDiskExtension.java | 87 +++++++++++ .../plugins/os_base/BaseMemoryExtension.java | 72 +++++++++ .../plugins/os_base/BaseNetworkExtension.java | 89 +++++++++++ .../sysmon/plugins/os_base/BasePlugin.java | 17 ++ .../os_base/BaseProcessorExtension.java | 111 +++++++++++++ .../src/test/resources/free.txt | 0 .../src/test/resources/meminfo.txt | 0 .../src/test/resources/proc_diskstats1.txt | 0 .../src/test/resources/proc_diskstats2.txt | 0 .../src/test/resources/proc_net_dev1.txt | 0 .../src/test/resources/proc_net_dev2.txt | 0 .../src/test/resources/proc_net_sockstat.txt | 6 + .../src/test/resources/proc_stats1.txt | 0 .../src/test/resources/proc_stats2.txt | 0 plugins/os-linux/README.md | 12 +- plugins/os-linux/gradle.properties | 2 +- .../plugins/os_linux/LinuxDiskExtension.java | 88 ----------- .../plugins/os_linux/LinuxDiskProcLine.java | 146 ------------------ .../plugins/os_linux/LinuxDiskStat.java | 39 ----- .../os_linux/LinuxMemoryExtension.java | 67 -------- .../plugins/os_linux/LinuxMemoryStat.java | 63 -------- .../plugins/os_linux/LinuxNetworkDevStat.java | 105 ------------- .../os_linux/LinuxNetworkExtension.java | 16 +- .../os_linux/LinuxProcessorExtension.java | 95 ------------ .../os_linux/LinuxProcessorProcLine.java | 95 ------------ .../plugins/os_linux/LinuxProcessorStat.java | 60 ------- .../src/test/groovy/LinuxDiskTest.groovy | 43 ------ .../src/test/groovy/LinuxMemoryTest.groovy | 28 ---- .../src/test/groovy/LinuxNetworkTest.groovy | 41 ----- .../src/test/groovy/LinuxProcessorTest.groovy | 48 ------ 48 files changed, 451 insertions(+), 1299 deletions(-) delete mode 100644 plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskExtension.java delete mode 100644 plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskStat.java delete mode 100644 plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryExtension.java delete mode 100644 plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryStat.java delete mode 100644 plugins/os-aix/src/test/groovy/AixDiskTest.groovy delete mode 100644 plugins/os-aix/src/test/groovy/AixMemoryTest.groovy delete mode 100644 plugins/os-aix/src/test/resources/iostat.txt delete mode 100644 plugins/os-aix/src/test/resources/mpstat-v.txt delete mode 100644 plugins/os-aix/src/test/resources/svmon.txt delete mode 100644 plugins/os-aix/src/test/resources/vmstat-Iwt.txt create mode 100644 plugins/os-base/README.md create mode 100644 plugins/os-base/build.gradle create mode 100644 plugins/os-base/gradle.properties create mode 100644 plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java create mode 100644 plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java create mode 100644 plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java create mode 100644 plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java create mode 100644 plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java rename plugins/{os-linux => os-base}/src/test/resources/free.txt (100%) rename plugins/{os-linux => os-base}/src/test/resources/meminfo.txt (100%) rename plugins/{os-linux => os-base}/src/test/resources/proc_diskstats1.txt (100%) rename plugins/{os-linux => os-base}/src/test/resources/proc_diskstats2.txt (100%) rename plugins/{os-linux => os-base}/src/test/resources/proc_net_dev1.txt (100%) rename plugins/{os-linux => os-base}/src/test/resources/proc_net_dev2.txt (100%) create mode 100644 plugins/os-base/src/test/resources/proc_net_sockstat.txt rename plugins/{os-linux => os-base}/src/test/resources/proc_stats1.txt (100%) rename plugins/{os-linux => os-base}/src/test/resources/proc_stats2.txt (100%) delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskExtension.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskProcLine.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskStat.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryExtension.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryStat.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkDevStat.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorExtension.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorProcLine.java delete mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorStat.java delete mode 100644 plugins/os-linux/src/test/groovy/LinuxDiskTest.groovy delete mode 100644 plugins/os-linux/src/test/groovy/LinuxMemoryTest.groovy delete mode 100644 plugins/os-linux/src/test/groovy/LinuxProcessorTest.groovy diff --git a/build.gradle b/build.gradle index 33063c7..77fdee7 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ subprojects { implementation "org.slf4j:slf4j-api:${slf4jVersion}" implementation "org.slf4j:slf4j-simple:${slf4jVersion}" + } repositories { diff --git a/client/build.gradle b/client/build.gradle index 19f4750..131cc96 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -19,6 +19,10 @@ dependencies { implementation "info.picocli:picocli:${picocliVersion}" implementation 'org.tomlj:tomlj:1.0.0' + implementation(group: 'com.github.oshi', name: 'oshi-core', version: "5.7.3") { + exclude(group: "org.slf4j") + } + implementation group: 'org.apache.camel', name: 'camel-core', version: camelVersion implementation group: 'org.apache.camel', name: 'camel-main', version: camelVersion implementation group: 'org.apache.camel', name: 'camel-http', version: camelVersion diff --git a/plugins/build.gradle b/plugins/build.gradle index 2611a36..e135ccd 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -20,6 +20,11 @@ subprojects { exclude(group: "org.slf4j") } annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") + + implementation(group: 'com.github.oshi', name: 'oshi-core', version: "5.7.3") { + exclude(group: "org.slf4j") + } + } /* diff --git a/plugins/os-aix/build.gradle b/plugins/os-aix/build.gradle index a76f366..0c41fcb 100644 --- a/plugins/os-aix/build.gradle +++ b/plugins/os-aix/build.gradle @@ -1,6 +1,3 @@ dependencies { - implementation(group: 'com.github.oshi', name: 'oshi-core', version: "5.7.3") { - exclude(group: "org.slf4j") - } } diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskExtension.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskExtension.java deleted file mode 100644 index a986d93..0000000 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskExtension.java +++ /dev/null @@ -1,91 +0,0 @@ -package sysmon.plugins.os_aix; - -import org.pf4j.Extension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import oshi.SystemInfo; -import oshi.hardware.HardwareAbstractionLayer; -import sysmon.shared.Measurement; -import sysmon.shared.MetricExtension; -import sysmon.shared.MetricResult; -import sysmon.shared.PluginHelper; - -import java.util.List; -import java.util.Map; - - -@Extension -public class AixDiskExtension implements MetricExtension { - - private static final Logger log = LoggerFactory.getLogger(AixProcessorExtension.class); - - private final SystemInfo systemInfo; - private final HardwareAbstractionLayer hardwareAbstractionLayer; - - @Override - public boolean isSupported() { - - if(!System.getProperty("os.name").toLowerCase().contains("aix")) { - log.warn("Requires AIX."); - return false; - } - - if(!PluginHelper.canExecute("iostat")) { - log.warn("Requires the 'iostat' command."); - return false; - } - - return true; - } - - - public AixDiskExtension() { - systemInfo = new SystemInfo(); - hardwareAbstractionLayer = systemInfo.getHardware(); - log.warn(systemInfo.getOperatingSystem().toString()); - } - - - @Override - public String getName() { - return "aix-disk"; - } - - @Override - public String getProvides() { - return "disk"; - } - - @Override - public String getDescription() { - return "AIX Disk Metrics"; - } - - @Override - public MetricResult getMetrics() { - - long writeBytes = hardwareAbstractionLayer.getDiskStores().get(0).getWriteBytes(); - log.warn(String.format("Disk 0 - Write Bytes: %d", writeBytes)); - - long readBytes = hardwareAbstractionLayer.getDiskStores().get(0).getReadBytes(); - log.warn(String.format("Disk 0 - Read Bytes: %d", readBytes)); - - long memAvailable = hardwareAbstractionLayer.getMemory().getAvailable(); - log.warn(String.format("Memory - Available: %d", memAvailable)); - - List iostat = PluginHelper.executeCommand("iostat -d 1 1"); - AixDiskStat diskStat = processCommandOutput(iostat); - - Map tagsMap = diskStat.getTags(); - Map fieldsMap = diskStat.getFields(); - - return new MetricResult("disk", new Measurement(tagsMap, fieldsMap)); - } - - - protected AixDiskStat processCommandOutput(List inputLines) { - return new AixDiskStat(inputLines); - } - - -} diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskStat.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskStat.java deleted file mode 100644 index 00b7e6a..0000000 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixDiskStat.java +++ /dev/null @@ -1,53 +0,0 @@ -package sysmon.plugins.os_aix; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class AixDiskStat { - - // Disks: % tm_act Kbps tps Kb_read Kb_wrtn - // hdisk0 1.0 752.0 81.0 740 12 - private final Pattern pattern = Pattern.compile("^(hdisk\\d+)\\s+(\\d+\\.?\\d*)\\s+\\s+(\\d+\\.?\\d*)\\s+\\s+(\\d+\\.?\\d*)\\s+(\\d+)\\s+(\\d+)"); - - //private String device; - //private Float tmAct = 0.0f; // Indicates the percentage of time the physical disk/tape was active (bandwidth utilization for the drive). - private float kbps = 0.0f; // Indicates the amount of data transferred (read or written) to the drive in KB per second. - private float tps = 0.0f; // Indicates the number of transfers per second that were issued to the physical disk/tape. A transfer is an I/O request to the physical disk/tape. Multiple logical requests can be combined into a single I/O request to the disk. A transfer is of indeterminate size. - private long kbRead = 0L; // The total number of KB read. - private long kbWritten = 0L; // The total number of KB written. - - - AixDiskStat(List lines) { - - for (String line : lines) { - if (line.startsWith("hdisk")) { - Matcher matcher = pattern.matcher(line); - if (matcher.find() && matcher.groupCount() == 6) { - //device = matcher.group(1); - //tmAct = Float.parseFloat(matcher.group(2)); - kbps += Float.parseFloat(matcher.group(3)); - tps += Float.parseFloat(matcher.group(4)); - kbRead += Long.parseLong(matcher.group(5)); - kbWritten += Long.parseLong(matcher.group(6)); - } - } - } - - } - - public Map getTags() { - return new HashMap<>(); - } - - public Map getFields() { - Map fields = new HashMap<>(); - fields.put("reads", kbRead * 1024); // from Kb to bytes - fields.put("writes", kbWritten * 1024); // from Kb to bytes - fields.put("kbps", (int) kbps); - fields.put("tps", (int) tps); - return fields; - } -} diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryExtension.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryExtension.java deleted file mode 100644 index 89ad1fb..0000000 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryExtension.java +++ /dev/null @@ -1,68 +0,0 @@ -package sysmon.plugins.os_aix; - -import org.pf4j.Extension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import sysmon.shared.Measurement; -import sysmon.shared.MetricExtension; -import sysmon.shared.MetricResult; -import sysmon.shared.PluginHelper; - -import java.util.List; -import java.util.Map; - -@Extension -public class AixMemoryExtension implements MetricExtension { - - private static final Logger log = LoggerFactory.getLogger(AixMemoryExtension.class); - - @Override - public boolean isSupported() { - - if(!System.getProperty("os.name").toLowerCase().contains("aix")) { - log.warn("Requires AIX."); - return false; - } - - if(!PluginHelper.canExecute("svmon")) { - log.warn("Requires the 'svmon' command."); - return false; - } - - return true; - } - - @Override - public String getName() { - return "aix-memory"; - } - - @Override - public String getProvides() { - return "memory"; - } - - @Override - public String getDescription() { - return "AIX Memory Metrics"; - } - - @Override - public MetricResult getMetrics() { - - //List svmon = PluginHelper.executeCommand("svmon -G -O unit=KB"); - List svmon = PluginHelper.executeCommand("svmon -G -O summary=longreal,unit=KB"); - AixMemoryStat memoryStat = processCommandOutput(svmon); - - Map tagsMap = memoryStat.getTags(); - Map fieldsMap = memoryStat.getFields(); - - return new MetricResult("memory", new Measurement(tagsMap, fieldsMap)); - } - - protected AixMemoryStat processCommandOutput(List inputLines) { - return new AixMemoryStat(inputLines); - } - - -} diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryStat.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryStat.java deleted file mode 100644 index 6935545..0000000 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixMemoryStat.java +++ /dev/null @@ -1,60 +0,0 @@ -package sysmon.plugins.os_aix; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class AixMemoryStat { - - private final Pattern pattern = Pattern.compile("^\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"); - - private long total; - private long used; - private long free; - private long pin; - private long virtual; - private long available; - private long paged; - - AixMemoryStat(List lines) { - for (String line : lines) { - Matcher matcher = pattern.matcher(line); - if (matcher.find() && matcher.groupCount() == 7) { - total = Long.parseLong(matcher.group(1)); - used = Long.parseLong(matcher.group(2)); - free = Long.parseLong(matcher.group(3)); - pin = Long.parseLong(matcher.group(4)); - virtual = Long.parseLong(matcher.group(5)); - available = Long.parseLong(matcher.group(6)); - paged = Long.parseLong(matcher.group(7)); - break; - } - } - } - - - public Map getTags() { - return new HashMap<>(); - } - - - public Map getFields() { - - float usage = ((float) (total - available) / total ) * 100; - //BigDecimal usage = new BigDecimal(tmp).setScale(2, RoundingMode.HALF_UP); - - Map fields = new HashMap<>(); - fields.put("total", total); - fields.put("used", used); - fields.put("free", free); - fields.put("pin", pin); - fields.put("virtual", virtual); - fields.put("available", available); - fields.put("paged", paged); - fields.put("usage", usage); - return fields; - } - -} diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java index b0fd8c4..426e72b 100644 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java @@ -40,7 +40,7 @@ public class AixProcessorExtension implements MetricExtension { @Override public String getProvides() { - return "processor"; + return "processor-lpar"; } @Override @@ -57,7 +57,7 @@ public class AixProcessorExtension implements MetricExtension { Map tagsMap = processorStat.getTags(); Map fieldsMap = processorStat.getFields(); - return new MetricResult("processor", new Measurement(tagsMap, fieldsMap)); + return new MetricResult("processor_lpar", new Measurement(tagsMap, fieldsMap)); } diff --git a/plugins/os-aix/src/test/groovy/AixDiskTest.groovy b/plugins/os-aix/src/test/groovy/AixDiskTest.groovy deleted file mode 100644 index 074f8ad..0000000 --- a/plugins/os-aix/src/test/groovy/AixDiskTest.groovy +++ /dev/null @@ -1,26 +0,0 @@ -import sysmon.plugins.os_aix.AixDiskExtension -import sysmon.plugins.os_aix.AixDiskStat -import spock.lang.Specification - -class AixDiskTest extends Specification { - - void "test AIX iostat output processing"() { - - setup: - def testFile = new File(getClass().getResource('/iostat.txt').toURI()) - List lines = testFile.readLines("UTF-8") - - when: - AixDiskExtension extension = new AixDiskExtension() - AixDiskStat stats = extension.processCommandOutput(lines) - - then: - //stats.getTags().get("device") == "hdisk0" - stats.getFields().get("reads") == 757760L - stats.getFields().get("writes") == 12288L - stats.getFields().get("kbps") == 752L - stats.getFields().get("tps") == 81L - - } - -} diff --git a/plugins/os-aix/src/test/groovy/AixMemoryTest.groovy b/plugins/os-aix/src/test/groovy/AixMemoryTest.groovy deleted file mode 100644 index 8256b80..0000000 --- a/plugins/os-aix/src/test/groovy/AixMemoryTest.groovy +++ /dev/null @@ -1,29 +0,0 @@ -import sysmon.plugins.os_aix.AixMemoryExtension -import sysmon.plugins.os_aix.AixMemoryStat -import spock.lang.Specification - -class AixMemoryTest extends Specification { - - void "test AIX svmon output processing"() { - - setup: - def testFile = new File(getClass().getResource('/svmon.txt').toURI()) - List lines = testFile.readLines("UTF-8") - - when: - AixMemoryExtension extension = new AixMemoryExtension() - AixMemoryStat stats = extension.processCommandOutput(lines) - - then: - stats.getFields().get("total") == 4194304L - stats.getFields().get("used") == 4065060L - stats.getFields().get("free") == 129244L - stats.getFields().get("pin") == 1878240L - stats.getFields().get("virtual") == 2784988L - stats.getFields().get("available") == 1058012L - stats.getFields().get("paged") == 524288L - stats.getFields().get("usage") == 74.775024f - - } - -} diff --git a/plugins/os-aix/src/test/resources/iostat.txt b/plugins/os-aix/src/test/resources/iostat.txt deleted file mode 100644 index 9b0b3b0..0000000 --- a/plugins/os-aix/src/test/resources/iostat.txt +++ /dev/null @@ -1,3 +0,0 @@ -Disks: % tm_act Kbps tps Kb_read Kb_wrtn -cd0 0.0 0.0 0.0 0 0 -hdisk0 1.0 752.0 81.0 740 12 diff --git a/plugins/os-aix/src/test/resources/mpstat-v.txt b/plugins/os-aix/src/test/resources/mpstat-v.txt deleted file mode 100644 index 7922964..0000000 --- a/plugins/os-aix/src/test/resources/mpstat-v.txt +++ /dev/null @@ -1,15 +0,0 @@ - -System configuration: lcpu=8 ent=0.5 mode=Uncapped - - -vcpu lcpu us sy wa id pbusy pc VTB(ms) ----- ---- ---- ---- ----- ----- ----- ----- ------- -0 33.51 5.62 0.11 60.77 0.00[ 39.1%] 0.00[ 0.1%] 1784440 - 0 13.38 3.96 0.05 4.81 0.00[ 17.3%] 0.00[ 22.2%] - - 1 8.41 0.72 0.04 7.59 0.00[ 9.1%] 0.00[ 16.8%] - - 2 5.19 0.35 0.01 6.45 0.00[ 5.5%] 0.00[ 12.0%] - - 3 4.42 0.28 0.01 8.42 0.00[ 4.7%] 0.00[ 13.1%] - - 4 0.57 0.07 0.00 7.47 0.00[ 0.6%] 0.00[ 8.1%] - - 5 0.51 0.06 0.00 9.28 0.00[ 0.6%] 0.00[ 9.8%] - - 6 0.49 0.07 0.00 7.49 0.00[ 0.6%] 0.00[ 8.1%] - - 7 0.54 0.10 0.00 9.26 0.00[ 0.6%] 0.00[ 9.9%] - diff --git a/plugins/os-aix/src/test/resources/svmon.txt b/plugins/os-aix/src/test/resources/svmon.txt deleted file mode 100644 index 8774006..0000000 --- a/plugins/os-aix/src/test/resources/svmon.txt +++ /dev/null @@ -1,6 +0,0 @@ -Unit: KB ------------------------------------------------------------------------- - Memory ------------------------------------------------------------------------- - Size Inuse Free Pin Virtual Available Pgsp - 4194304 4065060 129244 1878240 2784988 1058012 524288 diff --git a/plugins/os-aix/src/test/resources/vmstat-Iwt.txt b/plugins/os-aix/src/test/resources/vmstat-Iwt.txt deleted file mode 100644 index e294e51..0000000 --- a/plugins/os-aix/src/test/resources/vmstat-Iwt.txt +++ /dev/null @@ -1,7 +0,0 @@ - -System configuration: lcpu=8 mem=4096MB ent=0.50 - - kthr memory page faults cpu time ------------ --------------------- ------------------------------------ ------------------ ----------------------- -------- - r b p avm fre fi fo pi po fr sr in sy cs us sy id wa pc ec hr mi se - 2 1 0 633739 130144 0 13 0 0 2 2 7 969 529 0 0 99 0 0.00 0.1 07:53:28 diff --git a/plugins/os-base/README.md b/plugins/os-base/README.md new file mode 100644 index 0000000..6a0bd86 --- /dev/null +++ b/plugins/os-base/README.md @@ -0,0 +1,36 @@ +# Base Plugin + +## Processor Extension + +Reports the following metrics seen: + +- **user** - CPU time spend on user processes. +- **system** -CPU time spend on system processes. +- **iowait** - CPU time spend on waiting (for i/o). +- **idle** - CPU time spend on idle (doing nothing). +- **busy** - CPU time not spend on idle (working). + + +## Memory Extension + +Reports the following metrics, from the *free* command: + +- **total** - The total amount of (installed) memory (in KB). +- **used** - Used memory (calculated as total - free - buffers - cache) (in KB). +- **free** - Unused memory (MemFree and SwapFree in /proc/meminfo) (in KB). +- **shared** - Memory used (mostly) by tmpfs (Shmem in /proc/meminfo) (in KB). +- **buffers** - Sum of buffers and cache (in KB). +- **available** - Estimation of how much memory is available for starting new applications, without swapping (in KB). +- **usage** - Percentage of memory used out of the total amount of memory. + + +## Disk Extension + + +Only reports first device found. Improvements on the TODO. + +Metrics reported are: + +- **device** - Name of device. +- **reads** - The total number of KB read. +- **writes** - The total number of KB written. diff --git a/plugins/os-base/build.gradle b/plugins/os-base/build.gradle new file mode 100644 index 0000000..d18c3d3 --- /dev/null +++ b/plugins/os-base/build.gradle @@ -0,0 +1,2 @@ +plugins { +} \ No newline at end of file diff --git a/plugins/os-base/gradle.properties b/plugins/os-base/gradle.properties new file mode 100644 index 0000000..3aaf9bc --- /dev/null +++ b/plugins/os-base/gradle.properties @@ -0,0 +1,7 @@ +pluginId=sysmon-base +pluginClass=sysmon.plugins.os_base.BasePlugin +pluginVersion=0.0.1 +pluginProvider=System Monitor +pluginDependencies= +pluginDescription=Base OS metrics where supported. + diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java new file mode 100644 index 0000000..477b8e5 --- /dev/null +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java @@ -0,0 +1,87 @@ +package sysmon.plugins.os_base; + +import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import oshi.SystemInfo; +import oshi.hardware.HWDiskStore; +import oshi.hardware.HardwareAbstractionLayer; +import sysmon.shared.Measurement; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Extension +public class BaseDiskExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(BaseDiskExtension.class); + + private SystemInfo systemInfo; + private HardwareAbstractionLayer hardwareAbstractionLayer; + + + @Override + public boolean isSupported() { + + try { + systemInfo = new SystemInfo(); + hardwareAbstractionLayer = systemInfo.getHardware(); + return true; + } catch (UnsupportedOperationException e) { + log.warn(e.getMessage()); + } + + return false; + } + + @Override + public String getName() { + return "base-disk"; + } + + @Override + public String getProvides() { + return "disk"; + } + + @Override + public String getDescription() { + return "Base Disk Metrics"; + } + + + @Override + public MetricResult getMetrics() { + + long writeBytes = 0L; + long readBytes = 0L; + long transferTime = 0L; + long queueLength = 0L; + + Map tagsMap = new HashMap<>(); + Map fieldsMap = new HashMap<>(); + + List diskStores = hardwareAbstractionLayer.getDiskStores(); + for(HWDiskStore store : diskStores) { + String name = store.getName(); + if (name.matches("hdisk[0-9]+") || name.matches("/dev/[sv]d[a-z]{1}") || name.matches("/dev/nvme[0-9]n[0-9]")) { + log.debug("Using device: " + name); + writeBytes += store.getWriteBytes(); + readBytes += store.getReadBytes(); + transferTime += store.getTransferTime(); + queueLength = store.getCurrentQueueLength(); + } + } + + fieldsMap.put("reads", readBytes); + fieldsMap.put("writes", writeBytes); + fieldsMap.put("iotime", transferTime); + fieldsMap.put("queue", queueLength); + + return new MetricResult("disk", new Measurement(tagsMap, fieldsMap)); + } + +} \ No newline at end of file diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java new file mode 100644 index 0000000..4af172a --- /dev/null +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java @@ -0,0 +1,72 @@ +package sysmon.plugins.os_base; + +import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import oshi.SystemInfo; +import oshi.hardware.HardwareAbstractionLayer; +import sysmon.shared.Measurement; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; + +import java.util.HashMap; +import java.util.Map; + +@Extension +public class BaseMemoryExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(BaseMemoryExtension.class); + + private SystemInfo systemInfo; + private HardwareAbstractionLayer hardwareAbstractionLayer; + + @Override + public boolean isSupported() { + + try { + systemInfo = new SystemInfo(); + hardwareAbstractionLayer = systemInfo.getHardware(); + return true; + } catch (UnsupportedOperationException e) { + log.warn(e.getMessage()); + } + + return false; + } + + @Override + public String getName() { + return "base-memory"; + } + + @Override + public String getProvides() { + return "memory"; + } + + @Override + public String getDescription() { + return "Base Memory Metrics"; + } + + @Override + public MetricResult getMetrics() { + + Map tagsMap = new HashMap<>(); + Map fieldsMap = new HashMap<>(); + + long total = hardwareAbstractionLayer.getMemory().getTotal(); + long available = hardwareAbstractionLayer.getMemory().getAvailable(); + float usage = ((float) (total - available) / total ) * 100; + + fieldsMap.put("available", available); + fieldsMap.put("total", total); + fieldsMap.put("usage", usage); + fieldsMap.put("paged", hardwareAbstractionLayer.getMemory().getPageSize()); + fieldsMap.put("virtual", hardwareAbstractionLayer.getMemory().getVirtualMemory().getVirtualInUse()); + + return new MetricResult("memory", new Measurement(tagsMap, fieldsMap)); + } + + +} diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java new file mode 100644 index 0000000..74e67a4 --- /dev/null +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java @@ -0,0 +1,89 @@ +package sysmon.plugins.os_base; + +import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import oshi.SystemInfo; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.hardware.NetworkIF; +import sysmon.shared.Measurement; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Extension +public class BaseNetworkExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(BaseNetworkExtension.class); + + private SystemInfo systemInfo; + private HardwareAbstractionLayer hardwareAbstractionLayer; + + @Override + public boolean isSupported() { + + try { + systemInfo = new SystemInfo(); + hardwareAbstractionLayer = systemInfo.getHardware(); + return true; + } catch (UnsupportedOperationException e) { + log.warn(e.getMessage()); + } + + return false; + } + + @Override + public String getName() { + return "base-network"; + } + + @Override + public String getProvides() { + return "network"; + } + + @Override + public String getDescription() { + return "Base Network Metrics"; + } + + @Override + public MetricResult getMetrics() { + + long rxBytes = 0L; + long rxPackets = 0L; + long rxErrs = 0L; + long txBytes = 0L; + long txPackets = 0L; + long txErrs = 0L; + + Map tagsMap = new HashMap<>(); + Map fieldsMap = new HashMap<>(); + + List interfaces = hardwareAbstractionLayer.getNetworkIFs(); + for(NetworkIF netif : interfaces) { + //String name = netif.getName(); + //log.warn("Device: " + name); + rxPackets += netif.getPacketsRecv(); + txPackets += netif.getPacketsSent(); + rxBytes += netif.getBytesRecv(); + txBytes += netif.getBytesSent(); + rxErrs += netif.getInErrors(); + txErrs += netif.getOutErrors(); + } + + fieldsMap.put("rxPackets", rxPackets); + fieldsMap.put("txPackets", txPackets); + fieldsMap.put("rxBytes", rxBytes); + fieldsMap.put("txBytes", txBytes); + fieldsMap.put("rxErrors", rxErrs); + fieldsMap.put("txErrors", txErrs); + + return new MetricResult("network", new Measurement(tagsMap, fieldsMap)); + } + +} diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java new file mode 100644 index 0000000..203cceb --- /dev/null +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java @@ -0,0 +1,17 @@ +package sysmon.plugins.os_base; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.pf4j.Plugin; +import org.pf4j.PluginWrapper; + + +public class BasePlugin extends Plugin { + + private static final Logger log = LoggerFactory.getLogger(BasePlugin.class); + + public BasePlugin(PluginWrapper wrapper) { + super(wrapper); + } + +} diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java new file mode 100644 index 0000000..ee47348 --- /dev/null +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java @@ -0,0 +1,111 @@ +package sysmon.plugins.os_base; + +import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.HardwareAbstractionLayer; +import sysmon.shared.Measurement; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Extension +public class BaseProcessorExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(BaseProcessorExtension.class); + + private SystemInfo systemInfo; + private HardwareAbstractionLayer hardwareAbstractionLayer; + + @Override + public boolean isSupported() { + + try { + systemInfo = new SystemInfo(); + hardwareAbstractionLayer = systemInfo.getHardware(); + return true; + } catch (UnsupportedOperationException e) { + log.warn(e.getMessage()); + } + + return false; + } + + @Override + public String getName() { + return "base-processor"; + } + + @Override + public String getProvides() { + return "processor"; + } + + @Override + public String getDescription() { + return "Base Processor Metrics"; + } + + + @Override + public MetricResult getMetrics() { + + Map tagsMap = new HashMap<>(); + Map fieldsMap = new HashMap<>(); + + long user = 0L; + long system = 0L; + long steal = 0L; + long irq = 0L; + long softirq = 0L; + long nice = 0L; + long idle = 0L; + long iowait = 0L; + + long[][] ticks = hardwareAbstractionLayer.getProcessor().getProcessorCpuLoadTicks(); + int cores = ticks.length; + //log.warn("Cores: " + cores); + for (long[] tick : ticks) { + nice += tick[CentralProcessor.TickType.NICE.getIndex()]; + user += tick[CentralProcessor.TickType.USER.getIndex()]; + system += tick[CentralProcessor.TickType.SYSTEM.getIndex()]; + steal += tick[CentralProcessor.TickType.STEAL.getIndex()]; + irq += tick[CentralProcessor.TickType.IRQ.getIndex()]; + softirq += tick[CentralProcessor.TickType.SOFTIRQ.getIndex()]; + idle += tick[CentralProcessor.TickType.IDLE.getIndex()]; + iowait += tick[CentralProcessor.TickType.IOWAIT.getIndex()]; + } + + long busy = nice + user + system + steal + irq + softirq; + long nonBusy = idle + iowait; + long total = busy + nonBusy; + + log.info("idle: " + idle); + log.info("iowait: " + iowait); + log.info("busy: " + busy); + log.info("nonBusy: " + nonBusy); + log.info("total: " + total); + + fieldsMap.put("user", (float) user / (float) total); + fieldsMap.put("iowait", (float) iowait / (float) total); + fieldsMap.put("idle", (float) nonBusy / (float) total); + fieldsMap.put("busy", (float) busy / (float) total); + fieldsMap.put("system", (float) system / (float) total); + + log.info(fieldsMap.toString()); + return new MetricResult("processor", new Measurement(tagsMap, fieldsMap)); + } + +} + + diff --git a/plugins/os-linux/src/test/resources/free.txt b/plugins/os-base/src/test/resources/free.txt similarity index 100% rename from plugins/os-linux/src/test/resources/free.txt rename to plugins/os-base/src/test/resources/free.txt diff --git a/plugins/os-linux/src/test/resources/meminfo.txt b/plugins/os-base/src/test/resources/meminfo.txt similarity index 100% rename from plugins/os-linux/src/test/resources/meminfo.txt rename to plugins/os-base/src/test/resources/meminfo.txt diff --git a/plugins/os-linux/src/test/resources/proc_diskstats1.txt b/plugins/os-base/src/test/resources/proc_diskstats1.txt similarity index 100% rename from plugins/os-linux/src/test/resources/proc_diskstats1.txt rename to plugins/os-base/src/test/resources/proc_diskstats1.txt diff --git a/plugins/os-linux/src/test/resources/proc_diskstats2.txt b/plugins/os-base/src/test/resources/proc_diskstats2.txt similarity index 100% rename from plugins/os-linux/src/test/resources/proc_diskstats2.txt rename to plugins/os-base/src/test/resources/proc_diskstats2.txt diff --git a/plugins/os-linux/src/test/resources/proc_net_dev1.txt b/plugins/os-base/src/test/resources/proc_net_dev1.txt similarity index 100% rename from plugins/os-linux/src/test/resources/proc_net_dev1.txt rename to plugins/os-base/src/test/resources/proc_net_dev1.txt diff --git a/plugins/os-linux/src/test/resources/proc_net_dev2.txt b/plugins/os-base/src/test/resources/proc_net_dev2.txt similarity index 100% rename from plugins/os-linux/src/test/resources/proc_net_dev2.txt rename to plugins/os-base/src/test/resources/proc_net_dev2.txt diff --git a/plugins/os-base/src/test/resources/proc_net_sockstat.txt b/plugins/os-base/src/test/resources/proc_net_sockstat.txt new file mode 100644 index 0000000..f0c0afc --- /dev/null +++ b/plugins/os-base/src/test/resources/proc_net_sockstat.txt @@ -0,0 +1,6 @@ +sockets: used 1238 +TCP: inuse 52 orphan 0 tw 18 alloc 55 mem 7 +UDP: inuse 11 mem 10 +UDPLITE: inuse 0 +RAW: inuse 0 +FRAG: inuse 0 memory 0 diff --git a/plugins/os-linux/src/test/resources/proc_stats1.txt b/plugins/os-base/src/test/resources/proc_stats1.txt similarity index 100% rename from plugins/os-linux/src/test/resources/proc_stats1.txt rename to plugins/os-base/src/test/resources/proc_stats1.txt diff --git a/plugins/os-linux/src/test/resources/proc_stats2.txt b/plugins/os-base/src/test/resources/proc_stats2.txt similarity index 100% rename from plugins/os-linux/src/test/resources/proc_stats2.txt rename to plugins/os-base/src/test/resources/proc_stats2.txt diff --git a/plugins/os-linux/README.md b/plugins/os-linux/README.md index 3e23e69..6a0bd86 100644 --- a/plugins/os-linux/README.md +++ b/plugins/os-linux/README.md @@ -1,14 +1,14 @@ -# Linux Plugin +# Base Plugin ## Processor Extension Reports the following metrics seen: -- **user** - Percentage of CPU time spend on user processes. -- **sys** - Percentage of CPU time spend on system processes. -- **wait** - Percentage of CPU time spend on waiting (for i/o). -- **idle** - Percentage of CPU time spend on idle (doing nothing). -- **busy** - Percentage of CPU time not spend on idle (working). +- **user** - CPU time spend on user processes. +- **system** -CPU time spend on system processes. +- **iowait** - CPU time spend on waiting (for i/o). +- **idle** - CPU time spend on idle (doing nothing). +- **busy** - CPU time not spend on idle (working). ## Memory Extension diff --git a/plugins/os-linux/gradle.properties b/plugins/os-linux/gradle.properties index 3a97f32..715d387 100644 --- a/plugins/os-linux/gradle.properties +++ b/plugins/os-linux/gradle.properties @@ -3,5 +3,5 @@ pluginClass=sysmon.plugins.os_linux.LinuxPlugin pluginVersion=0.0.1 pluginProvider=System Monitor pluginDependencies= -pluginDescription=Collects Linux OS metrics. +pluginDescription=Linux OS Metrics. diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskExtension.java deleted file mode 100644 index c46d237..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskExtension.java +++ /dev/null @@ -1,88 +0,0 @@ -package sysmon.plugins.os_linux; - -import org.pf4j.Extension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import sysmon.shared.Measurement; -import sysmon.shared.MetricExtension; -import sysmon.shared.MetricResult; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -@Extension -public class LinuxDiskExtension implements MetricExtension { - - private static final Logger log = LoggerFactory.getLogger(LinuxDiskExtension.class); - - - @Override - public boolean isSupported() { - return System.getProperty("os.name").toLowerCase().contains("linux"); - } - - @Override - public String getName() { - return "linux-disk"; - } - - @Override - public String getProvides() { - return "disk"; - } - - @Override - public String getDescription() { - return "Linux Disk Metrics"; - } - - - @Override - public MetricResult getMetrics() { - - LinuxDiskProcLine proc1 = processFileOutput(readProcFile()); - try { - Thread.sleep(1 * 1000); // TODO: Configure sample collect time - } catch (InterruptedException e) { - log.warn("getMetrics() - sleep interrupted"); - return null; - } - LinuxDiskProcLine proc2 = processFileOutput(readProcFile()); - - LinuxDiskStat stat = new LinuxDiskStat(proc1, proc2); - return new MetricResult("disk", new Measurement(stat.getTags(), stat.getFields())); - } - - - protected List readProcFile() { - - List allLines = new ArrayList<>(); - try { - allLines = Files.readAllLines(Paths.get("/proc/diskstats"), StandardCharsets.UTF_8); - } catch (IOException e) { - log.error(e.getMessage()); - } - return allLines; - } - - - protected LinuxDiskProcLine processFileOutput(List inputLines) { - - List lines = new ArrayList<>(inputLines.size()); - for(String line : inputLines) { - String[] splitStr = line.trim().split("\\s+"); - String device = splitStr[2]; - if (device.matches("[sv]d[a-z]{1}") || device.matches("nvme[0-9]n[0-9]")) { - //log.warn("Going for: " + line); - lines.add(line); - } - } - - return new LinuxDiskProcLine(lines); - } - -} \ No newline at end of file diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskProcLine.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskProcLine.java deleted file mode 100644 index c3b8dff..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskProcLine.java +++ /dev/null @@ -1,146 +0,0 @@ -package sysmon.plugins.os_linux; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -public class LinuxDiskProcLine { - - // Sectors to bytes - each sector is 512 bytes - https://lkml.org/lkml/2015/8/17/269 - private static final int SECTOR_BYTE_SIZE = 512; - - private static final Logger log = LoggerFactory.getLogger(LinuxDiskProcLine.class); - - - /* - == =================================== - 1 major number - 2 minor mumber - 3 device name - 4 reads completed successfully - 5 reads merged - 6 sectors read - 7 time spent reading (ms) - 8 writes completed - 9 writes merged - 10 sectors written - 11 time spent writing (ms) - 12 I/Os currently in progress - 13 time spent doing I/Os (ms) - 14 weighted time spent doing I/Os (ms) - == =================================== - - Kernel 4.18+ appends four more fields for discard - tracking putting the total at 18: - - == =================================== - 15 discards completed successfully - 16 discards merged - 17 sectors discarded - 18 time spent discarding - == =================================== - - Kernel 5.5+ appends two more fields for flush requests: - - == ===================================== - 19 flush requests completed successfully - 20 time spent flushing - == ===================================== - */ - - private long readsCompleted; // successfully - //private long readsMerged; - private long sectorsRead; // 512 bytes pr. sector - private long timeSpentReading; // ms - private long writesCompleted; // successfully - //private long writesMerged; - private long sectorsWritten; // 512 bytes pr. sector - private long timeSpentWriting; // ms - //private long ioInProgress; - private long timeSpentOnIo; // ms - //private long timeSpentOnIoWeighted; - - //private long discardsCompleted; // successfully - //private long discardsMerged; - //private long sectorsDiscarded; // 512 bytes pr. sector - //private long timeSpentDiscarding; // ms - - //private long flushRequestsCompleted; - //private long timeSpentFlushing; // ms - - - public LinuxDiskProcLine(List procLines) { - - for(String procLine : procLines) { - - String[] splitStr = procLine.trim().split("\\s+"); - if (splitStr.length < 14) { - throw new UnsupportedOperationException("Linux proc DISK string error: " + procLine); - } - - //this.major = Integer.parseInt(splitStr[0]); - //this.minor = Integer.parseInt(splitStr[1]); - //this.device = splitStr[2]; - this.readsCompleted += Long.parseLong(splitStr[3]); - //this.readsMerged += Long.parseLong(splitStr[4]); - this.sectorsRead += Long.parseLong(splitStr[5]); - this.timeSpentReading += Long.parseLong(splitStr[6]); - this.writesCompleted += Long.parseLong(splitStr[7]); - //this.writesMerged += Long.parseLong(splitStr[8]); - this.sectorsWritten += Long.parseLong(splitStr[9]); - this.timeSpentWriting += Long.parseLong(splitStr[10]); - //this.ioInProgress += Long.parseLong(splitStr[11]); - this.timeSpentOnIo += Long.parseLong(splitStr[12]); - //this.timeSpentOnIoWeighted += Long.parseLong(splitStr[13]); - - /* - if (splitStr.length >= 18) { - this.discardsCompleted += Long.parseLong(splitStr[10]); - this.discardsMerged += Long.parseLong(splitStr[11]); - this.sectorsDiscarded += Long.parseLong(splitStr[12]); - this.timeSpentDiscarding += Long.parseLong(splitStr[13]); - } else { - this.discardsCompleted = null; - this.discardsMerged = null; - this.sectorsDiscarded = null; - this.timeSpentDiscarding = null; - } - - if (splitStr.length == 20) { - this.flushRequestsCompleted += Long.parseLong(splitStr[14]); - this.timeSpentFlushing += Long.parseLong(splitStr[15]); - } else { - this.flushRequestsCompleted = null; - this.timeSpentFlushing = null; - } - */ - - } - } - - public Long getTimeSpentOnIo() { - return timeSpentOnIo; - } - - public Long getBytesRead() { - return sectorsRead * SECTOR_BYTE_SIZE; - } - - public Long getBytesWritten() { - return sectorsWritten * SECTOR_BYTE_SIZE; - } - - public Long getTimeSpentReading() { - return timeSpentReading; - } - - public Long getTimeSpentWriting() { - return timeSpentWriting; - } - - public Long getTransactions() { - return readsCompleted + writesCompleted; - } - -} diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskStat.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskStat.java deleted file mode 100644 index 71fcb5e..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxDiskStat.java +++ /dev/null @@ -1,39 +0,0 @@ -package sysmon.plugins.os_linux; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.Map; - -public class LinuxDiskStat { - - private String device; - private final long iotime; - private final long reads; - private final long writes; - private final long kbps; - private final long tps; - - LinuxDiskStat(LinuxDiskProcLine proc1, LinuxDiskProcLine proc2) { - iotime = proc2.getTimeSpentOnIo() - proc1.getTimeSpentOnIo(); - writes = proc2.getBytesWritten() - proc1.getBytesWritten(); - reads = proc2.getBytesRead() - proc1.getBytesRead(); - kbps = (writes + reads) / 1024; - tps = proc2.getTransactions() - proc1.getTransactions(); - } - - public Map getTags() { - return new HashMap<>(); - } - - public Map getFields() { - Map fields = new HashMap<>(); - fields.put("iotime", iotime); - fields.put("writes", writes); - fields.put("reads", reads); - fields.put("kbps", kbps); - fields.put("tps", tps); - return fields; - } -} \ No newline at end of file diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryExtension.java deleted file mode 100644 index 5995879..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryExtension.java +++ /dev/null @@ -1,67 +0,0 @@ -package sysmon.plugins.os_linux; - -import org.pf4j.Extension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import sysmon.shared.Measurement; -import sysmon.shared.MetricExtension; -import sysmon.shared.MetricResult; -import sysmon.shared.PluginHelper; - -import java.util.List; -import java.util.Map; - -@Extension -public class LinuxMemoryExtension implements MetricExtension { - - private static final Logger log = LoggerFactory.getLogger(LinuxMemoryExtension.class); - - @Override - public boolean isSupported() { - - if(!System.getProperty("os.name").toLowerCase().contains("linux")) { - log.warn("Requires Linux."); - return false; - } - - if(!PluginHelper.canExecute("free")) { - log.warn("Requires the 'free' command."); - return false; - } - - return true; - } - - @Override - public String getName() { - return "linux-memory"; - } - - @Override - public String getProvides() { - return "memory"; - } - - @Override - public String getDescription() { - return "Linux Memory Metrics"; - } - - @Override - public MetricResult getMetrics() { - - List svmon = PluginHelper.executeCommand("free -k"); - LinuxMemoryStat memoryStat = processCommandOutput(svmon); - - Map tagsMap = memoryStat.getTags(); - Map fieldsMap = memoryStat.getFields(); - - return new MetricResult("memory", new Measurement(tagsMap, fieldsMap)); - } - - protected LinuxMemoryStat processCommandOutput(List inputLines) { - return new LinuxMemoryStat(inputLines); - } - - -} diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryStat.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryStat.java deleted file mode 100644 index d1d863b..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxMemoryStat.java +++ /dev/null @@ -1,63 +0,0 @@ -package sysmon.plugins.os_linux; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class LinuxMemoryStat { - - /* - total used free shared buff/cache available - Mem: 16069172 5896832 4597860 639780 5574480 9192992 - Swap: 3985404 0 3985404 - */ - private static final Pattern pattern = Pattern.compile("^Mem:\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"); - - private long total; - private long used; - private long free; - private long shared; - private long buffers; - private long available; - //private String mode; - - LinuxMemoryStat(List lines) { - for (String line : lines) { - Matcher matcher = pattern.matcher(line); - if (matcher.find() && matcher.groupCount() == 6) { - total = Long.parseLong(matcher.group(1)); - used = Long.parseLong(matcher.group(2)); - free = Long.parseLong(matcher.group(3)); - shared = Long.parseLong(matcher.group(4)); - buffers = Long.parseLong(matcher.group(5)); - available = Long.parseLong(matcher.group(6)); - break; - } - } - } - - - public Map getTags() { - return new HashMap<>(); - } - - - public Map getFields() { - - float usage = ((float) (total - available) / total ) * 100; - //BigDecimal usage = new BigDecimal(tmp).setScale(2, RoundingMode.HALF_UP); - - Map fields = new HashMap<>(); - fields.put("total", total); - fields.put("used", used); - fields.put("free", free); - fields.put("shared", shared); - fields.put("buffers", buffers); - fields.put("available", available); - fields.put("usage", usage); - return fields; - } - -} diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkDevStat.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkDevStat.java deleted file mode 100644 index bdae2e6..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkDevStat.java +++ /dev/null @@ -1,105 +0,0 @@ -package sysmon.plugins.os_linux; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class LinuxNetworkDevStat { - - private static final Logger log = LoggerFactory.getLogger(LinuxNetworkDevStat.class); - - private static final Pattern pattern1 = Pattern.compile("^\\s+([a-z]{2,}[0-9]+):.*"); - private static final Pattern pattern2 = Pattern.compile("^\\s+([a-z]{2,}[0-9]+):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)"); - - private long rxBytes; - private long rxPackets; - private long rxErrs; - - private long txBytes; - private long txPackets; - private long txErrs; - - /* - Inter-| Receive | Transmit - face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed - env2: 657010764 483686 0 0 0 0 0 0 55416850 431020 0 0 0 0 0 0 - env3: 6900272 41836 0 0 0 0 0 0 7667444 41849 0 0 0 0 0 0 - lo: 3098805 14393 0 0 0 0 0 0 3098805 14393 0 0 0 0 0 0 - - */ - - public LinuxNetworkDevStat(List procLines) { - - Matcher matcher1; - Matcher matcher2; - for(String procLine : procLines) { - - matcher1 = pattern1.matcher(procLine); - if(matcher1.matches()) { - - if(matcher1.group(1).equals("lo")) { - continue; - } - - matcher2 = pattern2.matcher(procLine); - if(matcher2.matches() && matcher2.groupCount() == 17) { - - rxBytes += Long.parseLong(matcher2.group(2)); - rxPackets += Long.parseLong(matcher2.group(3)); - rxErrs += Long.parseLong(matcher2.group(4)); - - txBytes += Long.parseLong(matcher2.group(10)); - txPackets += Long.parseLong(matcher2.group(11)); - txErrs += Long.parseLong(matcher2.group(12)); - } - - } - - } - } - - - public long getRxBytes() { - return rxBytes; - } - - public long getRxPackets() { - return rxPackets; - } - - public long getRxErrs() { - return rxErrs; - } - - public long getTxBytes() { - return txBytes; - } - - public long getTxPackets() { - return txPackets; - } - - public long getTxErrs() { - return txErrs; - } - - - public Map getTags() { - return new HashMap<>(); - } - - public Map getFields() { - Map fields = new HashMap<>(); - fields.put("rxBytes", rxBytes); - fields.put("rxPackets", rxPackets); - fields.put("txBytes", txBytes); - fields.put("txPackets", txPackets); - return fields; - } - -} diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java index 1d1b710..666051c 100644 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java +++ b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java @@ -29,39 +29,33 @@ public class LinuxNetworkExtension implements MetricExtension { @Override public String getName() { - return "linux-network"; + return "linux-network-sockets"; } @Override public String getProvides() { - return "network"; + return "network-sockets"; } @Override public String getDescription() { - return "Linux Network Metrics"; + return "Linux Network Socket Metrics"; } @Override public MetricResult getMetrics() { LinuxNetworkSockStat sockStat = processSockOutput(PluginHelper.readFile("/proc/net/sockstat")); - LinuxNetworkDevStat devStat = processDevOutput(PluginHelper.readFile("/proc/net/dev")); Map tagsMap = sockStat.getTags(); Map fieldsMap = sockStat.getFields(); - fieldsMap.putAll(devStat.getFields()); - return new MetricResult("network", new Measurement(tagsMap, fieldsMap)); + return new MetricResult("network_sockets", new Measurement(tagsMap, fieldsMap)); + } protected LinuxNetworkSockStat processSockOutput(List inputLines) { return new LinuxNetworkSockStat(inputLines); } - protected LinuxNetworkDevStat processDevOutput(List inputLines) { - return new LinuxNetworkDevStat(inputLines); - } - - } diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorExtension.java deleted file mode 100644 index cf7cee0..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorExtension.java +++ /dev/null @@ -1,95 +0,0 @@ -package sysmon.plugins.os_linux; - -import org.pf4j.Extension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import sysmon.shared.Measurement; -import sysmon.shared.MetricExtension; -import sysmon.shared.MetricResult; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -@Extension -public class LinuxProcessorExtension implements MetricExtension { - - private static final Logger log = LoggerFactory.getLogger(LinuxProcessorExtension.class); - - private List currentProcessorProc; - private List previousProcessorProc; - - - @Override - public boolean isSupported() { - return System.getProperty("os.name").toLowerCase().contains("linux"); - } - - @Override - public String getName() { - return "linux-processor"; - } - - @Override - public String getProvides() { - return "processor"; - } - - @Override - public String getDescription() { - return "Linux Processor Metrics"; - } - - - @Override - public MetricResult getMetrics() { - - LinuxProcessorProcLine proc1 = processFileOutput(readProcFile()); - - try { - Thread.sleep(1 * 1000); // TODO: Configure sample collect time - } catch (InterruptedException e) { - log.warn("getMetrics() - sleep interrupted"); - return null; - } - - LinuxProcessorProcLine proc2 = processFileOutput(readProcFile()); - - LinuxProcessorStat stat = new LinuxProcessorStat(proc1, proc2); - - return new MetricResult("processor", new Measurement(stat.getTags(), stat.getFields())); - } - - - - protected List readProcFile() { - - List allLines = new ArrayList<>(); - try { - allLines = Files.readAllLines(Paths.get("/proc/stat"), StandardCharsets.UTF_8); - } catch (IOException e) { - log.error(e.getMessage()); - } - return allLines; - - } - - - protected LinuxProcessorProcLine processFileOutput(List inputLines) { - - for(String line : inputLines) { - if(line.matches("^cpu\\S+.*")) { - return new LinuxProcessorProcLine(line); - } - } - - return null; - } - - -} - - diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorProcLine.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorProcLine.java deleted file mode 100644 index 9ba6369..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorProcLine.java +++ /dev/null @@ -1,95 +0,0 @@ -package sysmon.plugins.os_linux; - -public class LinuxProcessorProcLine { - - private final String cpuName; - private final long userTime; - private final long niceTime; - private final long systemTime; - private final long idleTime; - private final long ioWaitTime; - private final long irqTime; - private final long softIrqTime; - private final long stealTime; - private final long guestTime; - private final long guestNiceTime; - - - public LinuxProcessorProcLine(String procString) { - - String[] splitStr = procString.trim().split("\\s+"); - if(splitStr.length != 11) { - throw new UnsupportedOperationException("Linux proc CPU string error: " + procString); - } - - this.cpuName = splitStr[0]; - this.userTime = Long.parseLong(splitStr[1]); - this.niceTime = Long.parseLong(splitStr[2]); - this.systemTime = Long.parseLong(splitStr[3]); - this.idleTime = Long.parseLong(splitStr[4]); - this.ioWaitTime = Long.parseLong(splitStr[5]); - this.irqTime = Long.parseLong(splitStr[6]); - this.softIrqTime = Long.parseLong(splitStr[7]); - this.stealTime = Long.parseLong(splitStr[8]); - this.guestTime = Long.parseLong(splitStr[9]); - this.guestNiceTime = Long.parseLong(splitStr[10]); - - } - - public String getCpuName() { - return cpuName; - } - - public long getUserTime() { - return userTime; - } - - public long getNiceTime() { - return niceTime; - } - - public long getSystemTime() { - return systemTime; - } - - public long getIdleTime() { - return idleTime; - } - - public long getIoWaitTime() { - return ioWaitTime; - } - - public long getIrqTime() { - return irqTime; - } - - public long getSoftIrqTime() { - return softIrqTime; - } - - public long getStealTime() { - return stealTime; - } - - public long getGuestTime() { - return guestTime; - } - - public long getGuestNiceTime() { - return guestNiceTime; - } - - public long getCombinedIdleTime() { - return idleTime + ioWaitTime; - } - - public long getCombinedWorkTime() { - return userTime + niceTime + systemTime + irqTime + softIrqTime + stealTime + guestTime + guestNiceTime; - } - - public long getCombinedTime() { - return getCombinedIdleTime() + getCombinedWorkTime(); - } - -} diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorStat.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorStat.java deleted file mode 100644 index 8b9947e..0000000 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxProcessorStat.java +++ /dev/null @@ -1,60 +0,0 @@ -package sysmon.plugins.os_linux; - -import java.util.HashMap; -import java.util.Map; - -public class LinuxProcessorStat { - - private final float user; - private final float sys; - private final float wait; - private final float idle; - private final float busy; - - public LinuxProcessorStat(LinuxProcessorProcLine previous, LinuxProcessorProcLine current) { - - long workTime = current.getCombinedTime() - previous.getCombinedTime(); - - long busyTime = current.getCombinedIdleTime() - previous.getCombinedIdleTime(); - float busyDiff = (float) (workTime - busyTime) / workTime; - busy = (busyDiff * 100); - - long userTime = current.getUserTime() - previous.getUserTime(); - float userDiff = (float) (workTime - userTime) / workTime; - user = 100 - (userDiff * 100); - - long sysTime = current.getSystemTime() - previous.getSystemTime(); - float sysDiff = (float) (workTime - sysTime) / workTime; - sys = 100 - (sysDiff * 100); - - long waitTime = current.getIoWaitTime() - previous.getIoWaitTime(); - float waitDiff = (float) (workTime - waitTime) / workTime; - wait = 100 - (waitDiff * 100); - - long idleTime = current.getIdleTime() - previous.getIdleTime(); - float idleDiff = (float) (workTime - idleTime) / workTime; - idle = 100 - (idleDiff * 100); - - } - - - public Float getBusy() { - return busy; - } - - public Map getTags() { - return new HashMap<>(); - } - - public Map getFields() { - Map fields = new HashMap<>(); - fields.put("user", user); - fields.put("sys", sys); - fields.put("wait", wait); - fields.put("idle", idle); - fields.put("busy", busy); - return fields; - } - - -} diff --git a/plugins/os-linux/src/test/groovy/LinuxDiskTest.groovy b/plugins/os-linux/src/test/groovy/LinuxDiskTest.groovy deleted file mode 100644 index 5c9cfdf..0000000 --- a/plugins/os-linux/src/test/groovy/LinuxDiskTest.groovy +++ /dev/null @@ -1,43 +0,0 @@ -import sysmon.plugins.os_linux.LinuxDiskExtension -import sysmon.plugins.os_linux.LinuxDiskProcLine -import sysmon.plugins.os_linux.LinuxDiskStat -import spock.lang.Specification - -class LinuxDiskTest extends Specification { - - void "test proc file processing"() { - - setup: - def testFile = new File(getClass().getResource('/proc_diskstats1.txt').toURI()) - List lines = testFile.readLines("UTF-8") - - when: - LinuxDiskExtension extension = new LinuxDiskExtension() - LinuxDiskProcLine procLine = extension.processFileOutput(lines) - - then: - procLine.getTimeSpentOnIo() == 11145860l - } - - - void "test disk utilization"() { - - setup: - def testFile1 = new File(getClass().getResource('/proc_diskstats1.txt').toURI()) - def testFile2 = new File(getClass().getResource('/proc_diskstats2.txt').toURI()) - LinuxDiskExtension extension = new LinuxDiskExtension() - LinuxDiskProcLine procLine1 = extension.processFileOutput(testFile1.readLines()) - LinuxDiskProcLine procLine2 = extension.processFileOutput(testFile2.readLines()) - - when: - LinuxDiskStat diskStat = new LinuxDiskStat(procLine1, procLine2) - - then: - diskStat.getFields().get("iotime") == 180L - diskStat.getFields().get("writes") == 108371968L - diskStat.getFields().get("reads") == 69632L - diskStat.getFields().get("kbps") == 105900.0f - diskStat.getFields().get("tps") == 97.0f - - } -} diff --git a/plugins/os-linux/src/test/groovy/LinuxMemoryTest.groovy b/plugins/os-linux/src/test/groovy/LinuxMemoryTest.groovy deleted file mode 100644 index 1e59068..0000000 --- a/plugins/os-linux/src/test/groovy/LinuxMemoryTest.groovy +++ /dev/null @@ -1,28 +0,0 @@ -import sysmon.plugins.os_linux.LinuxMemoryExtension -import sysmon.plugins.os_linux.LinuxMemoryStat -import spock.lang.Specification - -class LinuxMemoryTest extends Specification { - - void "test Linux free output processing"() { - - setup: - def testFile = new File(getClass().getResource('/free.txt').toURI()) - List lines = testFile.readLines("UTF-8") - - when: - LinuxMemoryExtension extension = new LinuxMemoryExtension() - LinuxMemoryStat stats = extension.processCommandOutput(lines) - - then: - stats.getFields().get("total") == 16069172l - stats.getFields().get("used") == 5896832l - stats.getFields().get("free") == 4597860l - stats.getFields().get("shared") == 639780l - stats.getFields().get("buffers") == 5574480l - stats.getFields().get("available") == 9192992l - stats.getFields().get("usage") == 42.79113f - - } - -} diff --git a/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy b/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy index 9006970..3b1aad1 100644 --- a/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy +++ b/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy @@ -1,5 +1,4 @@ import spock.lang.Specification -import sysmon.plugins.os_linux.LinuxNetworkDevStat import sysmon.plugins.os_linux.LinuxNetworkExtension import sysmon.plugins.os_linux.LinuxNetworkSockStat @@ -27,44 +26,4 @@ class LinuxNetworkTest extends Specification { } - - void "test /proc/net/dev parsing"() { - - setup: - def testFile = new File(getClass().getResource('/proc_net_dev1.txt').toURI()) - List lines = testFile.readLines("UTF-8") - - when: - LinuxNetworkExtension extension = new LinuxNetworkExtension() - LinuxNetworkDevStat procLine = extension.processDevOutput(lines) - - then: - procLine.getRxBytes() == 663911036L - procLine.getRxPackets() == 525522L - procLine.getRxErrs() == 0L - procLine.getTxBytes() == 63084294L - procLine.getTxPackets() == 472869L - procLine.getTxErrs() == 0L - } - - /* - void "test dev utilization"() { - - setup: - def testFile1 = new File(getClass().getResource('/proc_net_dev1.txt').toURI()) - def testFile2 = new File(getClass().getResource('/proc_net_dev2.txt').toURI()) - LinuxNetworkExtension extension = new LinuxNetworkExtension() - LinuxNetworkDevStat procLine1 = extension.processDevOutput(testFile1.readLines()) - LinuxNetworkDevStat procLine2 = extension.processDevOutput(testFile2.readLines()) - - when: - LinuxNetworkDevStat networkDevStat = new LinuxNetworkDevStat(procLine1, procLine2) - - then: - networkDevStat.getFields().get("rxPackets") == 223L - networkDevStat.getFields().get("rxBytes") == 31501L - networkDevStat.getFields().get("txBytes") == 46460L - networkDevStat.getFields().get("txPackets") == 341L - }*/ - } diff --git a/plugins/os-linux/src/test/groovy/LinuxProcessorTest.groovy b/plugins/os-linux/src/test/groovy/LinuxProcessorTest.groovy deleted file mode 100644 index b37f2c2..0000000 --- a/plugins/os-linux/src/test/groovy/LinuxProcessorTest.groovy +++ /dev/null @@ -1,48 +0,0 @@ -import sysmon.plugins.os_linux.LinuxProcessorExtension -import sysmon.plugins.os_linux.LinuxProcessorProcLine -import sysmon.plugins.os_linux.LinuxProcessorStat -import spock.lang.Specification - -class LinuxProcessorTest extends Specification { - - void "test proc file processing"() { - - setup: - def testFile = new File(getClass().getResource('/proc_stats1.txt').toURI()) - List lines = testFile.readLines("UTF-8") - - when: - LinuxProcessorExtension extension = new LinuxProcessorExtension() - LinuxProcessorProcLine procLine = extension.processFileOutput(lines) - - then: - procLine.getSystemTime() == 4686l - procLine.getUserTime() == 27477l - procLine.getIdleTime() == 281276l - procLine.getIoWaitTime() == 252l - - } - - - void "test processor utilization"() { - - setup: - def testFile1 = new File(getClass().getResource('/proc_stats1.txt').toURI()) - def testFile2 = new File(getClass().getResource('/proc_stats2.txt').toURI()) - LinuxProcessorProcLine processorProcLine1 = new LinuxProcessorProcLine(testFile1.readLines().get(0)) - LinuxProcessorProcLine processorProcLine2 = new LinuxProcessorProcLine(testFile2.readLines().get(0)) - - when: - LinuxProcessorStat processorStat = new LinuxProcessorStat(processorProcLine1, processorProcLine2) - - then: - processorStat.getBusy() == 38.001614f - processorStat.getFields().get("user") == 35.6989f - processorStat.getFields().get("sys") == 2.2623215f - processorStat.getFields().get("idle") == 61.823322f - processorStat.getFields().get("wait") == 0.17505646f - - } - - -} From 25e36407903e11748fb95bbc9c2af3206df533e4 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Fri, 28 May 2021 20:35:27 +0200 Subject: [PATCH 2/6] Cleanup logging. --- .../java/sysmon/plugins/os_base/BaseProcessorExtension.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java index ee47348..ce3c800 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java @@ -90,11 +90,13 @@ public class BaseProcessorExtension implements MetricExtension { long nonBusy = idle + iowait; long total = busy + nonBusy; + /* log.info("idle: " + idle); log.info("iowait: " + iowait); log.info("busy: " + busy); log.info("nonBusy: " + nonBusy); log.info("total: " + total); + */ fieldsMap.put("user", (float) user / (float) total); fieldsMap.put("iowait", (float) iowait / (float) total); @@ -102,7 +104,7 @@ public class BaseProcessorExtension implements MetricExtension { fieldsMap.put("busy", (float) busy / (float) total); fieldsMap.put("system", (float) system / (float) total); - log.info(fieldsMap.toString()); + //log.info(fieldsMap.toString()); return new MetricResult("processor", new Measurement(tagsMap, fieldsMap)); } From 3a4a4bdb8afce160f8161b9c0a7270298f065e42 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Mon, 31 May 2021 14:44:48 +0200 Subject: [PATCH 3/6] More work on processor metrics. --- .../sysmon/client/ClientRouteBuilder.java | 2 +- .../plugins/os_base/BaseDiskExtension.java | 1 + .../plugins/os_base/BaseMemoryExtension.java | 1 + .../plugins/os_base/BaseNetworkExtension.java | 1 + .../os_base/BaseProcessorExtension.java | 60 ++++++++----------- .../os_linux/LinuxNetworkExtension.java | 1 + 6 files changed, 30 insertions(+), 36 deletions(-) diff --git a/client/src/main/java/sysmon/client/ClientRouteBuilder.java b/client/src/main/java/sysmon/client/ClientRouteBuilder.java index bf9db77..e17108a 100644 --- a/client/src/main/java/sysmon/client/ClientRouteBuilder.java +++ b/client/src/main/java/sysmon/client/ClientRouteBuilder.java @@ -52,7 +52,7 @@ public class ClientRouteBuilder extends RouteBuilder { //.doTry() .process(new MetricEnrichProcessor(registry)) .choice().when(exchangeProperty("skip").isEqualTo(true)) - .log("Skipping empty: ${body}") + .log("Skipping empty measurement.") .stop() .otherwise() .to("seda:metrics"); diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java index 477b8e5..2f8c433 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java @@ -81,6 +81,7 @@ public class BaseDiskExtension implements MetricExtension { fieldsMap.put("iotime", transferTime); fieldsMap.put("queue", queueLength); + log.debug(fieldsMap.toString()); return new MetricResult("disk", new Measurement(tagsMap, fieldsMap)); } diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java index 4af172a..b73ad48 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java @@ -65,6 +65,7 @@ public class BaseMemoryExtension implements MetricExtension { fieldsMap.put("paged", hardwareAbstractionLayer.getMemory().getPageSize()); fieldsMap.put("virtual", hardwareAbstractionLayer.getMemory().getVirtualMemory().getVirtualInUse()); + log.debug(fieldsMap.toString()); return new MetricResult("memory", new Measurement(tagsMap, fieldsMap)); } diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java index 74e67a4..8b5a7c0 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java @@ -83,6 +83,7 @@ public class BaseNetworkExtension implements MetricExtension { fieldsMap.put("rxErrors", rxErrs); fieldsMap.put("txErrors", txErrs); + log.debug(fieldsMap.toString()); return new MetricResult("network", new Measurement(tagsMap, fieldsMap)); } diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java index ce3c800..9b39018 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java @@ -26,6 +26,7 @@ public class BaseProcessorExtension implements MetricExtension { private SystemInfo systemInfo; private HardwareAbstractionLayer hardwareAbstractionLayer; + private long[] oldTicks; @Override public boolean isSupported() { @@ -63,48 +64,37 @@ public class BaseProcessorExtension implements MetricExtension { Map tagsMap = new HashMap<>(); Map fieldsMap = new HashMap<>(); - long user = 0L; - long system = 0L; - long steal = 0L; - long irq = 0L; - long softirq = 0L; - long nice = 0L; - long idle = 0L; - long iowait = 0L; - - long[][] ticks = hardwareAbstractionLayer.getProcessor().getProcessorCpuLoadTicks(); - int cores = ticks.length; - //log.warn("Cores: " + cores); - for (long[] tick : ticks) { - nice += tick[CentralProcessor.TickType.NICE.getIndex()]; - user += tick[CentralProcessor.TickType.USER.getIndex()]; - system += tick[CentralProcessor.TickType.SYSTEM.getIndex()]; - steal += tick[CentralProcessor.TickType.STEAL.getIndex()]; - irq += tick[CentralProcessor.TickType.IRQ.getIndex()]; - softirq += tick[CentralProcessor.TickType.SOFTIRQ.getIndex()]; - idle += tick[CentralProcessor.TickType.IDLE.getIndex()]; - iowait += tick[CentralProcessor.TickType.IOWAIT.getIndex()]; + long[] ticks = hardwareAbstractionLayer.getProcessor().getSystemCpuLoadTicks(); + if(oldTicks == null || oldTicks.length != ticks.length) { + oldTicks = ticks; + return null; } + long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - oldTicks[CentralProcessor.TickType.NICE.getIndex()]; + long user = ticks[CentralProcessor.TickType.USER.getIndex()] - oldTicks[CentralProcessor.TickType.USER.getIndex()]; + long system = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - oldTicks[CentralProcessor.TickType.SYSTEM.getIndex()]; + long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - oldTicks[CentralProcessor.TickType.STEAL.getIndex()]; + long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - oldTicks[CentralProcessor.TickType.IRQ.getIndex()]; + long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - oldTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()]; + long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - oldTicks[CentralProcessor.TickType.IDLE.getIndex()]; + long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - oldTicks[CentralProcessor.TickType.IOWAIT.getIndex()]; + long busy = nice + user + system + steal + irq + softirq; long nonBusy = idle + iowait; long total = busy + nonBusy; - /* - log.info("idle: " + idle); - log.info("iowait: " + iowait); - log.info("busy: " + busy); - log.info("nonBusy: " + nonBusy); - log.info("total: " + total); - */ + fieldsMap.put("system", ((float) system / (float) total) * 100); + fieldsMap.put("user", ((float) user / (float) total) * 100); + fieldsMap.put("nice", ((float) nice / (float) total) * 100); + fieldsMap.put("iowait", ((float) iowait / (float) total) * 100); + fieldsMap.put("steal", ((float) steal / (float) total) * 100); + fieldsMap.put("irq", ((float) irq / (float) total) * 100); + fieldsMap.put("softirq", ((float) softirq / (float) total) * 100); + fieldsMap.put("idle", ((float) idle / (float) total) * 100); + fieldsMap.put("busy", ((float) busy / (float) total) * 100); - fieldsMap.put("user", (float) user / (float) total); - fieldsMap.put("iowait", (float) iowait / (float) total); - fieldsMap.put("idle", (float) nonBusy / (float) total); - fieldsMap.put("busy", (float) busy / (float) total); - fieldsMap.put("system", (float) system / (float) total); - - //log.info(fieldsMap.toString()); + oldTicks = ticks; + log.debug(fieldsMap.toString()); return new MetricResult("processor", new Measurement(tagsMap, fieldsMap)); } diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java index 666051c..bb842b1 100644 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java +++ b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java @@ -50,6 +50,7 @@ public class LinuxNetworkExtension implements MetricExtension { Map tagsMap = sockStat.getTags(); Map fieldsMap = sockStat.getFields(); + log.debug(fieldsMap.toString()); return new MetricResult("network_sockets", new Measurement(tagsMap, fieldsMap)); } From a5ae0f27003b7cee43dc8fca3898fe94311ab548 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Tue, 8 Jun 2021 20:24:43 +0200 Subject: [PATCH 4/6] Support dedicated lparstat output --- doc/AIX.md | 13 ++++++ doc/sysmon-client.service | 10 +++++ doc/sysmon-server.service | 10 +++++ doc/systemd.md | 12 +++++ plugins/build.gradle | 1 + .../plugins/os_aix/AixProcessorStat.java | 32 +++++++++++--- .../src/test/groovy/AixProcessorTest.groovy | 26 ++++++++++- .../test/resources/lparstat-aix-dedicated.txt | 6 +++ ...arstat-aix.txt => lparstat-aix-shared.txt} | 0 .../sysmon/plugins/os_ibmi/TestExtension.java | 44 +++++++++++++++++++ 10 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 doc/AIX.md create mode 100644 doc/sysmon-client.service create mode 100644 doc/sysmon-server.service create mode 100644 doc/systemd.md create mode 100644 plugins/os-aix/src/test/resources/lparstat-aix-dedicated.txt rename plugins/os-aix/src/test/resources/{lparstat-aix.txt => lparstat-aix-shared.txt} (100%) create mode 100644 plugins/os-ibmi/src/main/java/sysmon/plugins/os_ibmi/TestExtension.java diff --git a/doc/AIX.md b/doc/AIX.md new file mode 100644 index 0000000..c32f79d --- /dev/null +++ b/doc/AIX.md @@ -0,0 +1,13 @@ +# AIX Notes + +## Installation + +```shell +rpm -i --ignoreos sysmon-client.rpm sysmon-plugins.rpm +``` + +## Run automatically at boot + +```shell +mkitab 'sysmon:2:respawn:env JAVA_HOME=/usr/java8_64 /opt/sysmon/client/bin/client -s http://10.20.30.40:9925/metrics >/tmp/sysmon.log 2>&1' +``` diff --git a/doc/sysmon-client.service b/doc/sysmon-client.service new file mode 100644 index 0000000..33d62ce --- /dev/null +++ b/doc/sysmon-client.service @@ -0,0 +1,10 @@ +[Unit] +Description=Sysmon Client Service + +[Service] +TimeoutStartSec=0 +Restart=always +ExecStart=/opt/sysmon/client/bin/client -s http://10.20.30.40:9925/metrics + +[Install] +WantedBy=default.target diff --git a/doc/sysmon-server.service b/doc/sysmon-server.service new file mode 100644 index 0000000..54e3c47 --- /dev/null +++ b/doc/sysmon-server.service @@ -0,0 +1,10 @@ +[Unit] +Description=Sysmon Server Service + +[Service] +TimeoutStartSec=0 +Restart=always +ExecStart=/opt/sysmon/server/bin/server + +[Install] +WantedBy=default.target diff --git a/doc/systemd.md b/doc/systemd.md new file mode 100644 index 0000000..29b5fe2 --- /dev/null +++ b/doc/systemd.md @@ -0,0 +1,12 @@ +# SystemD Notes + +Edit the *sysmon-client.service* file and change the sysmon-server URL accordingly to your environment. + +Setup as systemd service to start automatically at boot: + +```shell +cp sysmon-client.service /etc/systemd/system/ +systemctl daemon-reload +systemctl enable sysmon-client +systemctl restart sysmon-client +``` \ No newline at end of file diff --git a/plugins/build.gradle b/plugins/build.gradle index e135ccd..a55ce2d 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -12,6 +12,7 @@ subprojects { dependencies { testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0' testImplementation "org.slf4j:slf4j-api:${slf4jVersion}" + testImplementation "org.slf4j:slf4j-simple:${slf4jVersion}" testImplementation project(':shared') implementation project(':shared') diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java index df0e575..f545916 100644 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java @@ -1,5 +1,8 @@ package sysmon.plugins.os_aix; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.HashMap; import java.util.List; import java.util.Map; @@ -8,8 +11,13 @@ import java.util.regex.Pattern; public class AixProcessorStat { + private static final Logger log = LoggerFactory.getLogger(AixProcessorStat.class); + // System configuration: type=Shared mode=Uncapped smt=8 lcpu=8 mem=4096MB psize=19 ent=0.50 - private final Pattern patternAix = Pattern.compile("^System configuration: type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+)MB psize=(\\d+) ent=(\\d+\\.?\\d*)"); + private final Pattern patternAixShared = Pattern.compile("^System configuration: type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+)MB psize=(\\d+) ent=(\\d+\\.?\\d*)"); + + // System configuration: type=Dedicated mode=Donating smt=8 lcpu=16 mem=4096MB + private final Pattern patternAixDedicated = Pattern.compile("^System configuration: type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+)MB"); // type=Shared mode=Uncapped smt=8 lcpu=4 mem=4101120 kB cpus=24 ent=4.00 private final Pattern patternLinux = Pattern.compile("^type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+) kB cpus=(\\d+) ent=(\\d+\\.?\\d*)"); @@ -36,7 +44,7 @@ public class AixProcessorStat { for (String line : lines) { if (line.startsWith("System configuration:")) { - Matcher matcher = patternAix.matcher(line); + Matcher matcher = patternAixShared.matcher(line); if (matcher.find() && matcher.groupCount() == 7) { type = matcher.group(1); mode = matcher.group(2); @@ -45,6 +53,13 @@ public class AixProcessorStat { psize = Integer.parseInt(matcher.group(5)); ent = Float.parseFloat(matcher.group(7)); } + matcher = patternAixDedicated.matcher(line); + if (matcher.find() && matcher.groupCount() == 5) { + type = matcher.group(1); + mode = matcher.group(2); + smt = Integer.parseInt(matcher.group(3)); + lcpu = Integer.parseInt(matcher.group(4)); + } } if (line.startsWith("type=")) { @@ -64,7 +79,8 @@ public class AixProcessorStat { String lparstat = lines.get(lines.size() -1); String[] splitStr = lparstat.trim().split("\\s+"); - if(splitStr.length < 9) { + if(type.equalsIgnoreCase("shared") && splitStr.length < 9 || + type.equalsIgnoreCase("dedicated") && splitStr.length < 8) { throw new UnsupportedOperationException("lparstat string error: " + lparstat); } @@ -73,9 +89,13 @@ public class AixProcessorStat { this.wait = Float.parseFloat(splitStr[2]); this.idle = Float.parseFloat(splitStr[3]); this.physc = Float.parseFloat(splitStr[4]); - this.entc = Float.parseFloat(splitStr[5]); - this.lbusy = Float.parseFloat(splitStr[6]); - + if(type.equalsIgnoreCase("shared")) { + this.entc = Float.parseFloat(splitStr[5]); + this.lbusy = Float.parseFloat(splitStr[6]); + } else { + this.entc = 0f; + this.lbusy = 0f; + } } public float getUser() { diff --git a/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy b/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy index dd481b1..c462e84 100644 --- a/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy +++ b/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy @@ -4,10 +4,10 @@ import spock.lang.Specification class AixProcessorTest extends Specification { - void "test AIX lparstat output processing"() { + void "test AIX lparstat shared output processing"() { setup: - def testFile = new File(getClass().getResource('/lparstat-aix.txt').toURI()) + def testFile = new File(getClass().getResource('/lparstat-aix-shared.txt').toURI()) List lines = testFile.readLines("UTF-8") when: @@ -20,9 +20,29 @@ class AixProcessorTest extends Specification { stats.getWait() == 0.0f stats.getIdle() == 13.0f stats.getFields().get("ent") == 0.50f + stats.getFields().get("type") == "Shared" } + void "test AIX lparstat dedicated output processing"() { + + setup: + def testFile = new File(getClass().getResource('/lparstat-aix-dedicated.txt').toURI()) + List lines = testFile.readLines("UTF-8") + + when: + AixProcessorExtension extension = new AixProcessorExtension() + AixProcessorStat stats = extension.processCommandOutput(lines) + + then: + stats.getUser() == 0.1f + stats.getSys() == 0.2f + stats.getWait() == 0.0f + stats.getIdle() == 99.7f + stats.getFields().get("physc") == 0.07f + stats.getFields().get("type") == "Dedicated" + + } void "test Linux lparstat output processing"() { @@ -45,4 +65,6 @@ class AixProcessorTest extends Specification { } + // java.lang.UnsupportedOperationException: lparstat string error: 2.2 1.2 0.0 96.6 0.28 1100 132 24.23 + } diff --git a/plugins/os-aix/src/test/resources/lparstat-aix-dedicated.txt b/plugins/os-aix/src/test/resources/lparstat-aix-dedicated.txt new file mode 100644 index 0000000..ac10634 --- /dev/null +++ b/plugins/os-aix/src/test/resources/lparstat-aix-dedicated.txt @@ -0,0 +1,6 @@ + +System configuration: type=Dedicated mode=Donating smt=8 lcpu=16 mem=4096MB + +%user %sys %wait %idle physc vcsw %nsp %utcyc +----- ----- ------ ------ ----- ----- ----- ------ + 0.1 0.2 0.0 99.7 0.07 1014627468 132 24.21 \ No newline at end of file diff --git a/plugins/os-aix/src/test/resources/lparstat-aix.txt b/plugins/os-aix/src/test/resources/lparstat-aix-shared.txt similarity index 100% rename from plugins/os-aix/src/test/resources/lparstat-aix.txt rename to plugins/os-aix/src/test/resources/lparstat-aix-shared.txt diff --git a/plugins/os-ibmi/src/main/java/sysmon/plugins/os_ibmi/TestExtension.java b/plugins/os-ibmi/src/main/java/sysmon/plugins/os_ibmi/TestExtension.java new file mode 100644 index 0000000..52e0d94 --- /dev/null +++ b/plugins/os-ibmi/src/main/java/sysmon/plugins/os_ibmi/TestExtension.java @@ -0,0 +1,44 @@ +package sysmon.plugins.os_ibmi; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; + +public class TestExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(TestExtension.class); + + + @Override + public boolean isSupported() { + + String osArch = System.getProperty("os.arch").toLowerCase(); + String osName = System.getProperty("os.name").toLowerCase(); + + System.err.println("OS Arch: " + osArch); + System.err.println("OS Name: " + osName); + + return true; + } + + @Override + public String getName() { + return "ibmi-test"; + } + + @Override + public String getProvides() { + return "test"; + } + + @Override + public String getDescription() { + return "IBM i Test Extension"; + } + + @Override + public MetricResult getMetrics() { + return null; + } +} From 30806780e0923d285456140da95c753920d790cb Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Thu, 10 Jun 2021 08:55:03 +0200 Subject: [PATCH 5/6] Netstat output parsing on AIX and Linux. Example dashboard provided. --- .../sysmon/client/ClientRouteBuilder.java | 16 +- doc/AIX.md | 8 + doc/Sysmon-Example-1623307971559.json | 2033 +++++++++++++++++ plugins/build.gradle | 18 +- .../plugins/os_aix/AixNetstatExtension.java | 73 + .../plugins/os_aix/AixNetstatParser.java | 156 ++ .../plugins/os_aix/AixProcessorExtension.java | 19 +- .../plugins/os_aix/AixProcessorStat.java | 20 +- .../src/test/groovy/AixNetstatTest.groovy | 25 + .../src/test/groovy/AixProcessorTest.groovy | 17 +- .../os-aix/src/test/resources/netstat-aix.txt | 157 ++ plugins/os-linux/gradle.properties | 2 - .../os_linux/LinuxNetstatExtension.java | 73 + .../plugins/os_linux/LinuxNetstatParser.java | 168 ++ ...nsion.java => LinuxSockstatExtension.java} | 4 +- .../src/test/groovy/LinuxNetstatTest.groovy | 26 + .../src/test/groovy/LinuxNetworkTest.groovy | 4 +- .../src/test/resources/netstat-linux.txt | 112 + .../sysmon/server/ServerRouteBuilder.java | 4 +- .../java/sysmon/shared/MetricExtension.java | 4 +- .../main/java/sysmon/shared/PluginHelper.java | 21 +- 21 files changed, 2892 insertions(+), 68 deletions(-) create mode 100644 doc/Sysmon-Example-1623307971559.json create mode 100644 plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java create mode 100644 plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatParser.java create mode 100644 plugins/os-aix/src/test/groovy/AixNetstatTest.groovy create mode 100644 plugins/os-aix/src/test/resources/netstat-aix.txt create mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java create mode 100644 plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatParser.java rename plugins/os-linux/src/main/java/sysmon/plugins/os_linux/{LinuxNetworkExtension.java => LinuxSockstatExtension.java} (93%) create mode 100644 plugins/os-linux/src/test/groovy/LinuxNetstatTest.groovy create mode 100644 plugins/os-linux/src/test/resources/netstat-linux.txt diff --git a/client/src/main/java/sysmon/client/ClientRouteBuilder.java b/client/src/main/java/sysmon/client/ClientRouteBuilder.java index e17108a..1d1df3e 100644 --- a/client/src/main/java/sysmon/client/ClientRouteBuilder.java +++ b/client/src/main/java/sysmon/client/ClientRouteBuilder.java @@ -21,7 +21,7 @@ public class ClientRouteBuilder extends RouteBuilder { private static final Logger log = LoggerFactory.getLogger(ClientRouteBuilder.class); @Override - public void configure() throws Exception { + public void configure() { Registry registry = getContext().getRegistry(); @@ -45,9 +45,13 @@ public class ClientRouteBuilder extends RouteBuilder { log.info(">>> Enabling extension: " + ext.getDescription()); providers.add(provides); + + // TODO: Make timer thread configurable + // Setup Camel route for this extension // a unique timer name gives the timer it's own thread, otherwise it's a shared thread for other timers with same name. - from("timer:"+provides+"?fixedRate=true&period=30s") + //from("timer:"+provides+"?fixedRate=true&period=30s") + from("timer:extensions?fixedRate=true&period=30s") .bean(ext, "getMetrics") //.doTry() .process(new MetricEnrichProcessor(registry)) @@ -55,14 +59,16 @@ public class ClientRouteBuilder extends RouteBuilder { .log("Skipping empty measurement.") .stop() .otherwise() - .to("seda:metrics"); + .to("seda:metrics?discardWhenFull=true"); } else { - log.info(">>> Skipping extension: " + ext.getDescription()); + log.info(">>> Skipping extension (not supported here): " + ext.getDescription()); } + } - from("seda:metrics") + // TODO: Make 'concurrentConsumers' configurable + from("seda:metrics?concurrentConsumers=1") .setHeader(Exchange.HTTP_METHOD, constant("POST")) //.setHeader(Exchange.CONTENT_TYPE, constant("application/json")) .doTry() diff --git a/doc/AIX.md b/doc/AIX.md index c32f79d..2bd3c90 100644 --- a/doc/AIX.md +++ b/doc/AIX.md @@ -1,13 +1,21 @@ # AIX Notes +Works on IBM Power VIO (Virtual IO) servers, as well as regular IBM Power AIX installations. + ## Installation +We require Java 8, which should already be installed. +The RPM packages are *"noarch"* Java bytecode, so we can use the **--ignoreos** option to install: + ```shell rpm -i --ignoreos sysmon-client.rpm sysmon-plugins.rpm ``` ## Run automatically at boot +Change the *sysmon-server* URL for your environment. + ```shell mkitab 'sysmon:2:respawn:env JAVA_HOME=/usr/java8_64 /opt/sysmon/client/bin/client -s http://10.20.30.40:9925/metrics >/tmp/sysmon.log 2>&1' +init q ``` diff --git a/doc/Sysmon-Example-1623307971559.json b/doc/Sysmon-Example-1623307971559.json new file mode 100644 index 0000000..0875d93 --- /dev/null +++ b/doc/Sysmon-Example-1623307971559.json @@ -0,0 +1,2033 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 43, + "iteration": 1623307961363, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 4, + "panels": [], + "repeat": "hostname", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "title": "${hostname}", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "InfluxDB-sysmon", + "description": "", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 10, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "processor", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "user" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "user" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "system" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "system" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "steal" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "steal" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "softirq" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "softirq" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "irq" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "irq" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "iowait" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "iowait" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Processor Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "InfluxDB-sysmon", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "processor_lpar.mode" + }, + "properties": [ + { + "id": "displayName", + "value": "Mode" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "processor_lpar.type" + }, + "properties": [ + { + "id": "displayName", + "value": "Type" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "processor_lpar.ent" + }, + "properties": [ + { + "id": "displayName", + "value": "Entitlements" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "processor_lpar.lcpu" + }, + "properties": [ + { + "id": "displayName", + "value": "Logical CPUs" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 10, + "y": 1 + }, + "id": 16, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "value_and_name" + }, + "pluginVersion": "7.5.2", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "processor_lpar", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "mode" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "mode" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "type" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "type" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "ent" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "ent" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "lcpu" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "lcpu" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "LPAR Processor Details", + "type": "stat" + }, + { + "datasource": "InfluxDB-sysmon", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "processor_lpar.entc" + }, + "properties": [ + { + "id": "displayName", + "value": "Consumed Entitlements" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "processor_lpar.physc" + }, + "properties": [ + { + "id": "displayName", + "value": "Consumed Phys. Cores" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "processor_lpar.lbusy" + }, + "properties": [ + { + "id": "displayName", + "value": "Busy Logical CPUs" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 10, + "x": 14, + "y": 1 + }, + "id": 17, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "processor_lpar", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "physc" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "physc" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "lbusy" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "lbusy" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "entc" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "entc" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "LPAR Processor Usage", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "InfluxDB-sysmon", + "fieldConfig": { + "defaults": { + "unit": "bytes" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 10, + "x": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "memory", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "available" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "available" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "paged" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "paged" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "virtual" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "virtual" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "total" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "total" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "InfluxDB-sysmon", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "disk.iotime" + }, + "properties": [ + { + "id": "displayName", + "value": "I/O Time" + }, + { + "id": "unit", + "value": "ms" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "disk.queue" + }, + "properties": [ + { + "id": "displayName", + "value": "Queue" + }, + { + "id": "unit", + "value": "none" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 10, + "y": 8 + }, + "id": 19, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "7.5.2", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "disk", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "iotime" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "iotime" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "queue" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "queue" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Metrics", + "type": "gauge" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "InfluxDB-sysmon", + "fieldConfig": { + "defaults": { + "unit": "binBps" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 10, + "x": 14, + "y": 8 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "disk", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "reads" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "reads" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "writes" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "writes" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "binBps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "InfluxDB-sysmon", + "fieldConfig": { + "defaults": { + "unit": "binBps" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 10, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 18, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.5.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "network", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "txBytes" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "tx" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "rxBytes" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "rx" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "binBps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "InfluxDB-sysmon", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "network_netstat.tcp_connections" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Connections" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_netstat.tcp_pkts_recv" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Segments Recv." + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_netstat.tcp_pkts_sent" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Segments Sent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_netstat.udp_pkts_recv" + }, + "properties": [ + { + "id": "displayName", + "value": "UDP Datagrams Recv." + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_netstat.udp_pkts_sent" + }, + "properties": [ + { + "id": "displayName", + "value": "UDP Datagrams Sent" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 7, + "x": 10, + "y": 15 + }, + "id": 21, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "network_netstat", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "tcp_connections" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "tcp_connections" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_pkts_recv" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "tcp_pkts_recv" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_pkts_sent" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "tcp_pkts_sent" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "udp_pkts_recv" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "udp_pkts_recv" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "udp_pkts_sent" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "udp_pkts_sent" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Statistics", + "type": "stat" + }, + { + "datasource": "InfluxDB-sysmon", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "network_sockets.sockets" + }, + "properties": [ + { + "id": "displayName", + "value": "Sockets" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.tcp_alloc" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Alloc." + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.tcp_inuse" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Inuse" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.tcp_mem" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Mem." + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.tcp_orphan" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Orphaned" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.tcp_tw" + }, + "properties": [ + { + "id": "displayName", + "value": "TCP Time-Wait" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.udp_inuse" + }, + "properties": [ + { + "id": "displayName", + "value": "UDP Inuse" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "network_sockets.udp_mem" + }, + "properties": [ + { + "id": "displayName", + "value": "UDP Mem." + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 7, + "x": 17, + "y": 15 + }, + "id": 22, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.5.2", + "scopedVars": { + "hostname": { + "selected": true, + "text": "S824Rhel71le", + "value": "S824Rhel71le" + } + }, + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "network_sockets", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "sockets" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "sockets" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_alloc" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "tcp_alloc" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_inuse" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "tcp_inuse" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_mem" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "tcp_mem" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_orphan" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "tcp_orphan" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "tcp_tw" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "tcp_tw" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "udp_inuse" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "udp_inuse" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "udp_mem" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "udp_mem" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Network Sockets", + "type": "stat" + } + ], + "refresh": "30s", + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": true, + "tags": [], + "text": [ + "S824Rhel71le" + ], + "value": [ + "S824Rhel71le" + ] + }, + "datasource": "InfluxDB-sysmon", + "definition": "SHOW TAG VALUES FROM \"processor\" WITH KEY = \"hostname\" WHERE time > now() - 24h", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": "Host", + "multi": true, + "name": "hostname", + "options": [], + "query": "SHOW TAG VALUES FROM \"processor\" WITH KEY = \"hostname\" WHERE time > now() - 24h", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now-30s" + }, + "timepicker": { + "nowDelay": "1m", + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Sysmon-Example", + "uid": "QkVPjseMk", + "version": 25 +} \ No newline at end of file diff --git a/plugins/build.gradle b/plugins/build.gradle index a55ce2d..eef612d 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -28,20 +28,6 @@ subprojects { } -/* - jar { - manifest { - attributes( - 'Plugin-Id' : "${pluginId}", - 'Plugin-Class' : "${pluginClass}", - 'Plugin-Version' : "${pluginVersion}", - 'Plugin-Provider' : "${pluginProvider}", - 'Plugin-Description': "${pluginDescription}" - ) - } - - }*/ - task uberJar(type: Jar) { from sourceSets.main.output dependsOn configurations.runtimeClasspath @@ -62,8 +48,8 @@ subprojects { attributes( 'Plugin-Id' : "${pluginId}", 'Plugin-Class' : "${pluginClass}", - 'Plugin-Version' : "${pluginVersion}", - 'Plugin-Provider' : "${pluginProvider}", + 'Plugin-Version' : "${version}", + 'Plugin-Provider' : "System Monitor", 'Plugin-Description': "${pluginDescription}" ) } diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java new file mode 100644 index 0000000..83b0a1a --- /dev/null +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java @@ -0,0 +1,73 @@ +package sysmon.plugins.os_aix; + +import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sysmon.shared.Measurement; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; +import sysmon.shared.PluginHelper; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +@Extension +public class AixNetstatExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(AixNetstatExtension.class); + + @Override + public boolean isSupported() { + + if(!System.getProperty("os.name").toLowerCase().contains("aix")) { + log.warn("Requires AIX."); + return false; + } + + if(!PluginHelper.canExecute("netstat")) { + log.warn("Requires the 'netstat' command."); + return false; + } + + return true; + } + + @Override + public String getName() { + return "aix-network-netstat"; + } + + @Override + public String getProvides() { + return "network-netstat"; + } + + @Override + public String getDescription() { + return "AIX Netstat Metrics"; + } + + @Override + public MetricResult getMetrics() throws Exception { + + Map tagsMap = null; + Map fieldsMap = null; + + try (InputStream buf = PluginHelper.executeCommand("netstat -s -f inet")) { + AixNetstatParser parser = processCommandOutput(buf); + tagsMap = parser.getTags(); + fieldsMap = parser.getFields(); + } + + log.debug(fieldsMap.toString()); + return new MetricResult("network_netstat", new Measurement(tagsMap, fieldsMap)); + } + + + protected AixNetstatParser processCommandOutput(InputStream input) throws IOException { + return new AixNetstatParser(input); + } + +} + diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatParser.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatParser.java new file mode 100644 index 0000000..fad950f --- /dev/null +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatParser.java @@ -0,0 +1,156 @@ +package sysmon.plugins.os_aix; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +public class AixNetstatParser { + + private static final Logger log = LoggerFactory.getLogger(AixNetstatParser.class); + + private long ipTotalPacketsReceived; + private long ipForwarded; + + private long tcpConnectionsEstablished; + private long tcpPacketsReceved; + private long tcpPacketsSent; + + private long udpPacketsReceived; + private long udpPacketsSent; + + + public AixNetstatParser(InputStream inputStream) throws IOException { + + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + while (reader.ready()) { + String line = reader.readLine(); + log.debug("AixNetstatParser() - Line: " + line); + + if(line.startsWith("tcp:")) { + parseTcp(reader); + } + + if(line.startsWith("udp:")) { + parseUdp(reader); + } + + if(line.startsWith("ip:")) { + parseIp(reader); + } + + } + + inputStream.close(); + } + + + protected void parseIp(BufferedReader reader) throws IOException { + + while (reader.ready()) { + reader.mark(64); + String line = reader.readLine(); + + if(!line.startsWith(" ")) { + reader.reset(); + return; + } + + line = line.trim(); + + if(line.matches("(\\d+) total packets received")) { + ipTotalPacketsReceived = getFirstLong(line); + } + + if(line.matches("(\\d+) packets forwarded")) { + ipForwarded = getFirstLong(line); + } + + } + + } + + + protected void parseTcp(BufferedReader reader) throws IOException { + + while (reader.ready()) { + reader.mark(64); + String line = reader.readLine(); + + if(!line.startsWith(" ")) { + reader.reset(); + return; + } + + line = line.trim(); + + if(line.matches("(\\d+) connections established \\(including accepts\\)")) { + tcpConnectionsEstablished = getFirstLong(line); + } + + if(line.matches("(\\d+) packets received")) { + tcpPacketsReceved = getFirstLong(line); + } + + if(line.matches("(\\d+) packets sent")) { + tcpPacketsSent = getFirstLong(line); + } + + } + + } + + protected void parseUdp(BufferedReader reader) throws IOException { + + while (reader.ready()) { + reader.mark(64); + String line = reader.readLine(); + + if(!line.startsWith(" ")) { + reader.reset(); + return; + } + + line = line.trim(); + + if(line.matches("(\\d+) datagrams received")) { + udpPacketsReceived = getFirstLong(line); + } + + if(line.matches("(\\d+) datagrams output")) { + udpPacketsSent = getFirstLong(line); + } + } + + } + + + public Map getTags() { + return new HashMap<>(); + } + + public Map getFields() { + Map fields = new HashMap<>(); + fields.put("ip_forwarded", ipForwarded); + fields.put("ip_received", ipTotalPacketsReceived); + + fields.put("tcp_connections", tcpConnectionsEstablished); + fields.put("tcp_pkts_recv", tcpPacketsReceved); + fields.put("tcp_pkts_sent", tcpPacketsSent); + + fields.put("udp_pkts_recv", udpPacketsReceived); + fields.put("udp_pkts_sent", udpPacketsSent); + + return fields; + } + + private Long getFirstLong(String line) { + return Long.parseLong(line.substring(0, line.indexOf(" "))); + } + +} diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java index 426e72b..b41f301 100644 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorExtension.java @@ -8,6 +8,8 @@ import sysmon.shared.MetricExtension; import sysmon.shared.MetricResult; import sysmon.shared.PluginHelper; +import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.Map; @@ -49,20 +51,23 @@ public class AixProcessorExtension implements MetricExtension { } @Override - public MetricResult getMetrics() { + public MetricResult getMetrics() throws Exception { - List lparstat = PluginHelper.executeCommand("lparstat 1 1"); - AixProcessorStat processorStat = processCommandOutput(lparstat); + Map tagsMap = null; + Map fieldsMap = null; - Map tagsMap = processorStat.getTags(); - Map fieldsMap = processorStat.getFields(); + try (InputStream buf = PluginHelper.executeCommand("lparstat 1 1")) { + AixProcessorStat processorStat = processCommandOutput(buf); + tagsMap = processorStat.getTags(); + fieldsMap = processorStat.getFields(); + } return new MetricResult("processor_lpar", new Measurement(tagsMap, fieldsMap)); } - protected AixProcessorStat processCommandOutput(List inputLines) { - return new AixProcessorStat(inputLines); + protected AixProcessorStat processCommandOutput(InputStream input) throws IOException { + return new AixProcessorStat(input); } diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java index f545916..c1f62b3 100644 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixProcessorStat.java @@ -3,6 +3,10 @@ package sysmon.plugins.os_aix; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -39,9 +43,12 @@ public class AixProcessorStat { private final float lbusy; // Indicates the percentage of logical processor(s) utilization that occurred while executing at the user and system level. - AixProcessorStat(List lines) { + public AixProcessorStat(InputStream inputStream) throws IOException { - for (String line : lines) { + String lastLine = null; + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + while(reader.ready()) { + String line = reader.readLine(); if (line.startsWith("System configuration:")) { Matcher matcher = patternAixShared.matcher(line); @@ -75,13 +82,14 @@ public class AixProcessorStat { } } + lastLine = line; } - String lparstat = lines.get(lines.size() -1); - String[] splitStr = lparstat.trim().split("\\s+"); + //String lparstat = lines.get(lines.size() -1); + String[] splitStr = lastLine.trim().split("\\s+"); if(type.equalsIgnoreCase("shared") && splitStr.length < 9 || type.equalsIgnoreCase("dedicated") && splitStr.length < 8) { - throw new UnsupportedOperationException("lparstat string error: " + lparstat); + throw new UnsupportedOperationException("lparstat string error: " + lastLine); } this.user = Float.parseFloat(splitStr[0]); @@ -96,6 +104,8 @@ public class AixProcessorStat { this.entc = 0f; this.lbusy = 0f; } + + inputStream.close(); } public float getUser() { diff --git a/plugins/os-aix/src/test/groovy/AixNetstatTest.groovy b/plugins/os-aix/src/test/groovy/AixNetstatTest.groovy new file mode 100644 index 0000000..716786b --- /dev/null +++ b/plugins/os-aix/src/test/groovy/AixNetstatTest.groovy @@ -0,0 +1,25 @@ +import spock.lang.Specification +import sysmon.plugins.os_aix.AixNetstatParser + +class AixNetstatTest extends Specification { + + void "test netstat parsing"() { + + setup: + InputStream inputStream = getClass().getResourceAsStream('/netstat-aix.txt'); + + when: + AixNetstatParser parser = new AixNetstatParser(inputStream) + + then: + parser.getFields().size() > 0 + parser.getFields().get('ip_received') == 76229L + parser.getFields().get('ip_forwarded') == 24L + parser.getFields().get('tcp_connections') == 85L + parser.getFields().get('tcp_pkts_sent') == 31274L + parser.getFields().get('tcp_pkts_recv') == 39830L + parser.getFields().get('udp_pkts_sent') == 26332L + parser.getFields().get('udp_pkts_recv') == 34559L + } + +} diff --git a/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy b/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy index c462e84..5b21c5b 100644 --- a/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy +++ b/plugins/os-aix/src/test/groovy/AixProcessorTest.groovy @@ -7,12 +7,11 @@ class AixProcessorTest extends Specification { void "test AIX lparstat shared output processing"() { setup: - def testFile = new File(getClass().getResource('/lparstat-aix-shared.txt').toURI()) - List lines = testFile.readLines("UTF-8") + InputStream inputStream = getClass().getResourceAsStream('/lparstat-aix-shared.txt'); when: AixProcessorExtension extension = new AixProcessorExtension() - AixProcessorStat stats = extension.processCommandOutput(lines) + AixProcessorStat stats = extension.processCommandOutput(inputStream) then: stats.getUser() == 83.7f @@ -27,12 +26,11 @@ class AixProcessorTest extends Specification { void "test AIX lparstat dedicated output processing"() { setup: - def testFile = new File(getClass().getResource('/lparstat-aix-dedicated.txt').toURI()) - List lines = testFile.readLines("UTF-8") + InputStream inputStream = getClass().getResourceAsStream('/lparstat-aix-dedicated.txt'); when: AixProcessorExtension extension = new AixProcessorExtension() - AixProcessorStat stats = extension.processCommandOutput(lines) + AixProcessorStat stats = extension.processCommandOutput(inputStream) then: stats.getUser() == 0.1f @@ -47,12 +45,11 @@ class AixProcessorTest extends Specification { void "test Linux lparstat output processing"() { setup: - def testFile = new File(getClass().getResource('/lparstat-linux.txt').toURI()) - List lines = testFile.readLines("UTF-8") + InputStream inputStream = getClass().getResourceAsStream('/lparstat-linux.txt'); when: AixProcessorExtension extension = new AixProcessorExtension() - AixProcessorStat stats = extension.processCommandOutput(lines) + AixProcessorStat stats = extension.processCommandOutput(inputStream) then: stats.getUser() == 0.03f @@ -65,6 +62,4 @@ class AixProcessorTest extends Specification { } - // java.lang.UnsupportedOperationException: lparstat string error: 2.2 1.2 0.0 96.6 0.28 1100 132 24.23 - } diff --git a/plugins/os-aix/src/test/resources/netstat-aix.txt b/plugins/os-aix/src/test/resources/netstat-aix.txt new file mode 100644 index 0000000..11ea404 --- /dev/null +++ b/plugins/os-aix/src/test/resources/netstat-aix.txt @@ -0,0 +1,157 @@ +icmp: + 12 calls to icmp_error + 0 errors not generated because old message was icmp + Output histogram: + destination unreachable: 12 + 0 messages with bad code fields + 0 messages < minimum length + 0 bad checksums + 0 messages with bad length + Input histogram: + destination unreachable: 3 + 0 message responses generated +igmp: + 0 messages received + 0 messages received with too few bytes + 0 messages received with bad checksum + 0 membership queries received + 0 membership queries received with invalid field(s) + 0 membership reports received + 0 membership reports received with invalid field(s) + 0 membership reports received for groups to which we belong + 2 membership reports sent +tcp: + 31274 packets sent + 27328 data packets (82928168 bytes) + 86 data packets (108992 bytes) retransmitted + 2938 ack-only packets (2698 delayed) + 0 URG only packets + 0 window probe packets + 784 window update packets + 138 control packets + 3812 large sends + 74913716 bytes sent using largesend + 64069 bytes is the biggest largesend + 39830 packets received + 22701 acks (for 82928732 bytes) + 112 duplicate acks + 0 acks for unsent data + 15579 packets (5876585 bytes) received in-sequence + 62 completely duplicate packets (320 bytes) + 57 old duplicate packets + 0 packets with some dup. data (0 bytes duped) + 75 out-of-order packets (6408 bytes) + 0 packets (0 bytes) of data after window + 0 window probes + 1723 window update packets + 0 packets received after close + 0 packets with bad hardware assisted checksum + 0 discarded for bad checksums + 0 discarded for bad header offset fields + 0 discarded because packet too short + 1 discarded by listeners + 0 discarded due to listener's queue full + 3207 ack packet headers correctly predicted + 15050 data packet headers correctly predicted + 63 connection requests + 23 connection accepts + 85 connections established (including accepts) + 114 connections closed (including 0 drops) + 0 connections with ECN capability + 0 times responded to ECN + 0 embryonic connections dropped + 20314 segments updated rtt (of 16791 attempts) + 0 segments with congestion window reduced bit set + 0 segments with congestion experienced bit set + 0 resends due to path MTU discovery + 2 path MTU discovery terminations due to retransmits + 25 retransmit timeouts + 0 connections dropped by rexmit timeout + 4 fast retransmits + 1 when congestion window less than 4 segments + 28 newreno retransmits + 4 times avoided false fast retransmits + 0 persist timeouts + 0 connections dropped due to persist timeout + 0 keepalive timeouts + 0 keepalive probes sent + 0 connections dropped by keepalive + 0 times SACK blocks array is extended + 0 times SACK holes array is extended + 0 packets dropped due to memory allocation failure + 0 connections in timewait reused + 0 delayed ACKs for SYN + 0 delayed ACKs for FIN + 0 send_and_disconnects + 0 spliced connections + 0 spliced connections closed + 0 spliced connections reset + 0 spliced connections timeout + 0 spliced connections persist timeout + 0 spliced connections keepalive timeout + 0 TCP checksum offload disabled during retransmit + 0 Connections dropped due to bad ACKs + 0 Connections dropped due to duplicate SYN packets + 0 fastpath loopback connections + 0 fastpath loopback sent packets (0 bytes) + 0 fastpath loopback received packets (0 bytes) + 0 fake SYN segments dropped + 0 fake RST segments dropped + 0 data injection segments dropped + 0 TCPTR maximum connections dropped + 0 TCPTR connections dropped for no memory + 0 TCPTR maximum per host connections dropped + 0 connections dropped due to max assembly queue depth +udp: + 34559 datagrams received + 0 incomplete headers + 0 bad data length fields + 0 bad checksums + 1849 dropped due to no socket + 8218 broadcast/multicast datagrams dropped due to no socket + 0 socket buffer overflows + 24492 delivered + 26332 datagrams output +ip: + 76229 total packets received + 0 bad header checksums + 0 with size smaller than minimum + 0 with data size < data length + 0 with header length < data size + 0 with data length < header length + 0 with bad options + 0 with incorrect version number + 0 fragments received + 0 fragments dropped (dup or out of space) + 0 fragments dropped after timeout + 0 packets reassembled ok + 72552 packets for this host + 3 packets for unknown/unsupported protocol + 24 packets forwarded + 0 packets not forwardable + 0 redirects sent + 55784 packets sent from this host + 0 packets sent with fabricated ip header + 0 output packets dropped due to no bufs, etc. + 0 output packets discarded due to no route + 0 output datagrams fragmented + 0 fragments created + 0 datagrams that can't be fragmented + 0 IP Multicast packets dropped due to no receiver + 0 successful path MTU discovery cycles + 0 path MTU rediscovery cycles attempted + 0 path MTU discovery no-response estimates + 0 path MTU discovery response timeouts + 0 path MTU discovery decreases detected + 0 path MTU discovery packets sent + 0 path MTU discovery memory allocation failures + 0 ipintrq overflows + 0 with illegal source + 0 packets processed by threads + 0 packets dropped by threads + 0 packets dropped due to the full socket receive buffer + 0 dead gateway detection packets sent + 0 dead gateway detection packet allocation failures + 0 dead gateway detection gateway allocation failures + 0 incoming packets dropped due to MLS filters + 0 packets not sent due to MLS filters diff --git a/plugins/os-linux/gradle.properties b/plugins/os-linux/gradle.properties index 715d387..8f02aac 100644 --- a/plugins/os-linux/gradle.properties +++ b/plugins/os-linux/gradle.properties @@ -1,7 +1,5 @@ pluginId=sysmon-linux pluginClass=sysmon.plugins.os_linux.LinuxPlugin -pluginVersion=0.0.1 -pluginProvider=System Monitor pluginDependencies= pluginDescription=Linux OS Metrics. diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java new file mode 100644 index 0000000..d4a96d3 --- /dev/null +++ b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java @@ -0,0 +1,73 @@ +package sysmon.plugins.os_linux; + +import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sysmon.shared.Measurement; +import sysmon.shared.MetricExtension; +import sysmon.shared.MetricResult; +import sysmon.shared.PluginHelper; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +@Extension +public class LinuxNetstatExtension implements MetricExtension { + + private static final Logger log = LoggerFactory.getLogger(LinuxNetstatExtension.class); + + @Override + public boolean isSupported() { + + if(!System.getProperty("os.name").toLowerCase().contains("linux")) { + log.warn("Requires Linux."); + return false; + } + + if(!PluginHelper.canExecute("netstat")) { + log.warn("Requires the 'netstat' command."); + return false; + } + + return true; + } + + @Override + public String getName() { + return "linux-network-netstat"; + } + + @Override + public String getProvides() { + return "network-netstat"; + } + + @Override + public String getDescription() { + return "Linux Netstat Metrics"; + } + + @Override + public MetricResult getMetrics() throws Exception { + + Map tagsMap = null; + Map fieldsMap = null; + + try (InputStream inputStream = PluginHelper.executeCommand("netstat -s")) { + LinuxNetstatParser parser = processCommandOutput(inputStream); + tagsMap = parser.getTags(); + fieldsMap = parser.getFields(); + } + + log.debug(fieldsMap.toString()); + return new MetricResult("network_netstat", new Measurement(tagsMap, fieldsMap)); + } + + + protected LinuxNetstatParser processCommandOutput(InputStream input) throws IOException { + return new LinuxNetstatParser(input); + } + +} + diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatParser.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatParser.java new file mode 100644 index 0000000..a46883a --- /dev/null +++ b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatParser.java @@ -0,0 +1,168 @@ +package sysmon.plugins.os_linux; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +public class LinuxNetstatParser { + + private static final Logger log = LoggerFactory.getLogger(LinuxNetstatParser.class); + + private long ipTotalPacketsReceived; + private long ipForwarded; + private long ipIncomingPacketsDiscarded; + private long ipOutgoingPacketsDropped; + + private long tcpConnectionsEstablished; + private long tcpSegmentsReceived; + private long tcpSegmentsSent; + + private long udpPacketsReceived; + private long udpPacketsSent; + + + public LinuxNetstatParser(InputStream inputStream) throws IOException { + + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + while (reader.ready()) { + String line = reader.readLine(); + log.debug("LinuxNetstatParser() - Line: " + line); + + if(line.startsWith("Ip:")) { + parseIp(reader); + } + + if(line.startsWith("Tcp:")) { + parseTcp(reader); + } + + if(line.startsWith("Udp:")) { + parseUdp(reader); + } + + } + + inputStream.close(); + } + + + protected void parseIp(BufferedReader reader) throws IOException { + + while (reader.ready()) { + reader.mark(64); + String line = reader.readLine(); + + if(!line.startsWith(" ")) { + reader.reset(); + return; + } + + line = line.trim(); + + if(line.matches("(\\d+) total packets received")) { + ipTotalPacketsReceived = getFirstLong(line); + } + + if(line.matches("(\\d+) forwarded")) { + ipForwarded = getFirstLong(line); + } + + if(line.matches("(\\d+) incoming packets discarded")) { + ipIncomingPacketsDiscarded = getFirstLong(line); + } + + if(line.matches("(\\d+) outgoing packets dropped")) { + ipOutgoingPacketsDropped = getFirstLong(line); + } + + } + + } + + + protected void parseTcp(BufferedReader reader) throws IOException { + + while (reader.ready()) { + reader.mark(64); + String line = reader.readLine(); + + if(!line.startsWith(" ")) { + reader.reset(); + return; + } + + line = line.trim(); + + if(line.matches("(\\d+) connections established")) { + tcpConnectionsEstablished = getFirstLong(line); + } + + if(line.matches("(\\d+) segments received")) { + tcpSegmentsReceived = getFirstLong(line); + } + + if(line.matches("(\\d+) segments sent out")) { + tcpSegmentsSent = getFirstLong(line); + } + + } + + } + + protected void parseUdp(BufferedReader reader) throws IOException { + + while (reader.ready()) { + reader.mark(64); + String line = reader.readLine(); + + if(!line.startsWith(" ")) { + reader.reset(); + return; + } + + line = line.trim(); + + if(line.matches("(\\d+) packets received")) { + udpPacketsReceived = getFirstLong(line); + } + + if(line.matches("(\\d+) packets sent")) { + udpPacketsSent = getFirstLong(line); + } + } + + } + + + public Map getTags() { + return new HashMap<>(); + } + + public Map getFields() { + Map fields = new HashMap<>(); + fields.put("ip_forwarded", ipForwarded); + fields.put("ip_received", ipTotalPacketsReceived); + fields.put("ip_dropped", ipOutgoingPacketsDropped); + fields.put("ip_discarded", ipIncomingPacketsDiscarded); + + fields.put("tcp_connections", tcpConnectionsEstablished); + fields.put("tcp_pkts_recv", tcpSegmentsReceived); + fields.put("tcp_pkts_sent", tcpSegmentsSent); + + fields.put("udp_pkts_recv", udpPacketsReceived); + fields.put("udp_pkts_sent", udpPacketsSent); + + return fields; + } + + private Long getFirstLong(String line) { + return Long.parseLong(line.substring(0, line.indexOf(" "))); + } + +} diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxSockstatExtension.java similarity index 93% rename from plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java rename to plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxSockstatExtension.java index bb842b1..772ff83 100644 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetworkExtension.java +++ b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxSockstatExtension.java @@ -12,9 +12,9 @@ import java.util.List; import java.util.Map; @Extension -public class LinuxNetworkExtension implements MetricExtension { +public class LinuxSockstatExtension implements MetricExtension { - private static final Logger log = LoggerFactory.getLogger(LinuxNetworkExtension.class); + private static final Logger log = LoggerFactory.getLogger(LinuxSockstatExtension.class); @Override public boolean isSupported() { diff --git a/plugins/os-linux/src/test/groovy/LinuxNetstatTest.groovy b/plugins/os-linux/src/test/groovy/LinuxNetstatTest.groovy new file mode 100644 index 0000000..4d3e91d --- /dev/null +++ b/plugins/os-linux/src/test/groovy/LinuxNetstatTest.groovy @@ -0,0 +1,26 @@ +import spock.lang.Specification +import sysmon.plugins.os_linux.LinuxNetstatParser + +class LinuxNetstatTest extends Specification { + + void "test netstat parsing"() { + + setup: + InputStream inputStream = getClass().getResourceAsStream('/netstat-linux.txt'); + + when: + LinuxNetstatParser parser = new LinuxNetstatParser(inputStream) + + then: + parser.getFields().size() > 0 + parser.getFields().get('ip_received') == 109772L + parser.getFields().get('ip_dropped') == 70L + parser.getFields().get('ip_discarded') == 0L + parser.getFields().get('tcp_pkts_sent') == 89891L + parser.getFields().get('tcp_pkts_recv') == 86167L + parser.getFields().get('udp_pkts_sent') == 10682L + parser.getFields().get('udp_pkts_recv') == 31928L + + } + +} diff --git a/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy b/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy index 3b1aad1..9e81d93 100644 --- a/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy +++ b/plugins/os-linux/src/test/groovy/LinuxNetworkTest.groovy @@ -1,5 +1,5 @@ import spock.lang.Specification -import sysmon.plugins.os_linux.LinuxNetworkExtension +import sysmon.plugins.os_linux.LinuxSockstatExtension import sysmon.plugins.os_linux.LinuxNetworkSockStat class LinuxNetworkTest extends Specification { @@ -11,7 +11,7 @@ class LinuxNetworkTest extends Specification { List lines = testFile.readLines("UTF-8") when: - LinuxNetworkExtension extension = new LinuxNetworkExtension() + LinuxSockstatExtension extension = new LinuxSockstatExtension() LinuxNetworkSockStat stats = extension.processSockOutput(lines) then: diff --git a/plugins/os-linux/src/test/resources/netstat-linux.txt b/plugins/os-linux/src/test/resources/netstat-linux.txt new file mode 100644 index 0000000..68674bc --- /dev/null +++ b/plugins/os-linux/src/test/resources/netstat-linux.txt @@ -0,0 +1,112 @@ +Ip: + Forwarding: 1 + 109772 total packets received + 1 with invalid addresses + 0 forwarded + 0 incoming packets discarded + 109769 incoming packets delivered + 103916 requests sent out + 70 outgoing packets dropped + 1 dropped because of missing route +Icmp: + 52 ICMP messages received + 0 input ICMP message failed + ICMP input histogram: + destination unreachable: 40 + echo requests: 12 + 108 ICMP messages sent + 0 ICMP messages failed + ICMP output histogram: + destination unreachable: 96 + echo replies: 12 +IcmpMsg: + InType3: 40 + InType8: 12 + OutType0: 12 + OutType3: 96 +Tcp: + 3142 active connection openings + 5 passive connection openings + 2105 failed connection attempts + 193 connection resets received + 70 connections established + 86167 segments received + 89891 segments sent out + 184 segments retransmitted + 3 bad segments received + 2735 resets sent +Udp: + 31928 packets received + 96 packets to unknown port received + 0 packet receive errors + 10682 packets sent + 0 receive buffer errors + 0 send buffer errors + IgnoredMulti: 22 +UdpLite: +TcpExt: + 30 packets pruned from receive queue because of socket buffer overrun + 178 TCP sockets finished time wait in fast timer + 426 delayed acks sent + 1 delayed acks further delayed because of locked socket + Quick ack mode was activated 1059 times + 45809 packet headers predicted + 7293 acknowledgments not containing data payload received + 7659 predicted acknowledgments + TCPSackRecovery: 3 + Detected reordering 4 times using SACK + TCPDSACKUndo: 1 + 1 congestion windows recovered without slow start after partial ack + TCPLostRetransmit: 82 + 3 timeouts after reno fast retransmit + 1 timeouts in loss state + 3 fast retransmits + 3 retransmits in slow start + TCPTimeouts: 129 + TCPLossProbes: 69 + TCPLossProbeRecovery: 10 + TCPBacklogCoalesce: 450 + TCPDSACKOldSent: 991 + TCPDSACKOfoSent: 6 + TCPDSACKRecv: 45 + 202 connections reset due to unexpected data + 147 connections reset due to early user close + 13 connections aborted due to timeout + TCPDSACKIgnoredNoUndo: 10 + TCPSackShifted: 1 + TCPSackMerged: 1 + TCPSackShiftFallback: 9 + TCPRcvCoalesce: 5338 + TCPOFOQueue: 793 + TCPOFOMerge: 6 + TCPChallengeACK: 3 + TCPSYNChallenge: 3 + TCPSpuriousRtxHostQueues: 6 + TCPAutoCorking: 710 + TCPFromZeroWindowAdv: 1 + TCPToZeroWindowAdv: 1 + TCPWantZeroWindowAdv: 4 + TCPSynRetrans: 98 + TCPOrigDataSent: 19048 + TCPHystartTrainDetect: 3 + TCPHystartTrainCwnd: 54 + TCPHystartDelayDetect: 1 + TCPHystartDelayCwnd: 24 + TCPACKSkippedSeq: 1 + TCPKeepAlive: 2595 + TCPDelivered: 20025 + TCPAckCompressed: 260 + TcpTimeoutRehash: 116 +IpExt: + InMcastPkts: 2257 + OutMcastPkts: 480 + InBcastPkts: 98 + OutBcastPkts: 78 + InOctets: 147193028 + OutOctets: 14723163 + InMcastOctets: 478599 + OutMcastOctets: 73462 + InBcastOctets: 10094 + OutBcastOctets: 5580 + InNoECTPkts: 177661 +MPTcpExt: diff --git a/server/src/main/java/sysmon/server/ServerRouteBuilder.java b/server/src/main/java/sysmon/server/ServerRouteBuilder.java index d80d032..9442696 100644 --- a/server/src/main/java/sysmon/server/ServerRouteBuilder.java +++ b/server/src/main/java/sysmon/server/ServerRouteBuilder.java @@ -36,9 +36,11 @@ public class ServerRouteBuilder extends RouteBuilder { .to("seda:inbound") .endRest(); + //from("seda:inbound").log("Got metric from: ${header.component}").to("mock:sink"); - from("seda:inbound") + // TODO: Make 'concurrentConsumers' configurable + from("seda:inbound?concurrentConsumers=5") .log(">>> metric: ${header.hostname} - ${body}") .doTry() .process(new MetricResultToPointProcessor()) diff --git a/shared/src/main/java/sysmon/shared/MetricExtension.java b/shared/src/main/java/sysmon/shared/MetricExtension.java index bf00944..4130a21 100644 --- a/shared/src/main/java/sysmon/shared/MetricExtension.java +++ b/shared/src/main/java/sysmon/shared/MetricExtension.java @@ -2,6 +2,8 @@ package sysmon.shared; import org.pf4j.ExtensionPoint; +import java.io.IOException; + public interface MetricExtension extends ExtensionPoint { boolean isSupported(); @@ -10,5 +12,5 @@ public interface MetricExtension extends ExtensionPoint { String getProvides(); String getDescription(); - MetricResult getMetrics(); + MetricResult getMetrics() throws Exception; } diff --git a/shared/src/main/java/sysmon/shared/PluginHelper.java b/shared/src/main/java/sysmon/shared/PluginHelper.java index e3f2811..a1dc1d8 100644 --- a/shared/src/main/java/sysmon/shared/PluginHelper.java +++ b/shared/src/main/java/sysmon/shared/PluginHelper.java @@ -3,10 +3,7 @@ package sysmon.shared; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -23,10 +20,9 @@ public class PluginHelper { .toLowerCase().startsWith("windows"); - public static List executeCommand(String... cmd) { - - List outputLines = new ArrayList<>(); + public static InputStream executeCommand(String... cmd) { + InputStream inputStream = null; ProcessBuilder builder = new ProcessBuilder(); if (isWindows) { builder.command("cmd.exe", "/c"); @@ -40,15 +36,8 @@ public class PluginHelper { builder.directory(new File(System.getProperty("user.home"))); try { - Process process = builder.start(); - BufferedReader reader = - new BufferedReader(new InputStreamReader(process.getInputStream())); - - String line; - while ((line = reader.readLine()) != null) { - outputLines.add(line); - } + inputStream = process.getInputStream(); int exitCode = process.waitFor(); if(exitCode > 0) { @@ -59,7 +48,7 @@ public class PluginHelper { e.printStackTrace(); } - return outputLines; + return inputStream; } From 13cc0bbcfc7c5ef289ff7009c7ae1ee27667c519 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Fri, 11 Jun 2021 02:21:32 +0200 Subject: [PATCH 6/6] Disable netstat extension. Update example dashboard. --- README.md | 15 +- ...9.json => Sysmon Agent-1623356330000.json} | 769 ++++++------------ gradle.properties | 2 +- .../plugins/os_aix/AixNetstatExtension.java | 3 +- .../plugins/os_base/BaseDiskExtension.java | 13 +- .../plugins/os_base/BaseMemoryExtension.java | 13 +- .../plugins/os_base/BaseNetworkExtension.java | 13 +- .../sysmon/plugins/os_base/BasePlugin.java | 22 + .../os_base/BaseProcessorExtension.java | 13 +- .../os_linux/LinuxNetstatExtension.java | 3 +- 10 files changed, 280 insertions(+), 586 deletions(-) rename doc/{Sysmon-Example-1623307971559.json => Sysmon Agent-1623356330000.json} (80%) diff --git a/README.md b/README.md index e59346f..783b480 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,20 @@ Java based system monitoring solution with support for plugins. +- Example Grafana [dashboard](https://bitbucket.org/mnellemann/sysmon/downloads/sysmon-example-dashboard.png) showing metrics from a host running *sysmon*. -## Client +## Components -Runs on your hosts and collects metrics. Metrics are aggregated and sent to the central *server*. +### Client + +Runs on your hosts and collects metrics, which are sent to the central *server*. -## Server +### Server -Receives aggregated measurements from clients and saves metrics into InfluxDB. +Receives aggregated metrics from clients and saves these into InfluxDB. -## Plugins +### Plugins -Loaded by the client and provides extensions for doing the actual metric monitoring. \ No newline at end of file +Loaded by the client and provides extensions for doing the actual collecting of metrics. \ No newline at end of file diff --git a/doc/Sysmon-Example-1623307971559.json b/doc/Sysmon Agent-1623356330000.json similarity index 80% rename from doc/Sysmon-Example-1623307971559.json rename to doc/Sysmon Agent-1623356330000.json index 0875d93..8424464 100644 --- a/doc/Sysmon-Example-1623307971559.json +++ b/doc/Sysmon Agent-1623356330000.json @@ -1,4 +1,46 @@ { + "__inputs": [ + { + "name": "DS_INFLUXDB-SYSMON", + "label": "InfluxDB-sysmon", + "description": "", + "type": "datasource", + "pluginId": "influxdb", + "pluginName": "InfluxDB" + } + ], + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "8.0.0" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph (old)", + "version": "" + }, + { + "type": "datasource", + "id": "influxdb", + "name": "InfluxDB", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + } + ], "annotations": { "list": [ { @@ -12,11 +54,12 @@ } ] }, + "description": "Metrics from within host / guest / partition.", "editable": true, "gnetId": null, "graphTooltip": 0, - "id": 43, - "iteration": 1623307961363, + "id": null, + "iteration": 1623356323404, "links": [], "panels": [ { @@ -31,13 +74,6 @@ "id": 4, "panels": [], "repeat": "hostname", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, "title": "${hostname}", "type": "row" }, @@ -46,16 +82,12 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", "description": "", - "fieldConfig": { - "defaults": {}, - "overrides": [] - }, "fill": 1, "fillGradient": 0, "gridPos": { - "h": 7, + "h": 10, "w": 10, "x": 0, "y": 1 @@ -78,17 +110,10 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "7.5.2", + "pluginVersion": "8.0.0", "pointradius": 2, "points": false, "renderer": "flot", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, "seriesOverrides": [], "spaceLength": 10, "stack": true, @@ -275,7 +300,7 @@ } }, { - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", "description": "", "fieldConfig": { "defaults": { @@ -349,7 +374,7 @@ ] }, "gridPos": { - "h": 7, + "h": 3, "w": 4, "x": 10, "y": 1 @@ -370,14 +395,7 @@ "text": {}, "textMode": "value_and_name" }, - "pluginVersion": "7.5.2", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, + "pluginVersion": "8.0.0", "targets": [ { "groupBy": [ @@ -484,11 +502,11 @@ ], "timeFrom": null, "timeShift": null, - "title": "LPAR Processor Details", + "title": "Power LPAR Details", "type": "stat" }, { - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", "description": "", "fieldConfig": { "defaults": { @@ -547,7 +565,7 @@ ] }, "gridPos": { - "h": 7, + "h": 10, "w": 10, "x": 14, "y": 1 @@ -568,14 +586,7 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "7.5.2", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, + "pluginVersion": "8.0.0", "targets": [ { "groupBy": [ @@ -664,15 +675,168 @@ ], "timeFrom": null, "timeShift": null, - "title": "LPAR Processor Usage", + "title": "Power LPAR Processor Usage", "type": "stat" }, + { + "datasource": "${DS_INFLUXDB-SYSMON}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "disk.iotime" + }, + "properties": [ + { + "id": "displayName", + "value": "I/O Time" + }, + { + "id": "unit", + "value": "ms" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "disk.queue" + }, + "properties": [ + { + "id": "displayName", + "value": "Queue" + }, + { + "id": "unit", + "value": "none" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 4, + "x": 10, + "y": 4 + }, + "id": 19, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.0.0", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "linear" + ], + "type": "fill" + } + ], + "measurement": "disk", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "iotime" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "1s" + ], + "type": "non_negative_derivative" + }, + { + "params": [ + "iotime" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "queue" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + }, + { + "params": [ + "queue" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "hostname", + "operator": "=~", + "value": "/^$hostname$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Disk Metrics", + "type": "gauge" + }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", "fieldConfig": { "defaults": { "unit": "bytes" @@ -682,10 +846,10 @@ "fill": 1, "fillGradient": 0, "gridPos": { - "h": 7, + "h": 10, "w": 10, "x": 0, - "y": 8 + "y": 11 }, "hiddenSeries": false, "id": 8, @@ -705,17 +869,10 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "7.5.2", + "pluginVersion": "8.0.0", "pointradius": 2, "points": false, "renderer": "flot", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, "seriesOverrides": [], "spaceLength": 10, "stack": false, @@ -865,172 +1022,12 @@ "alignLevel": null } }, - { - "datasource": "InfluxDB-sysmon", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "disk.iotime" - }, - "properties": [ - { - "id": "displayName", - "value": "I/O Time" - }, - { - "id": "unit", - "value": "ms" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "disk.queue" - }, - "properties": [ - { - "id": "displayName", - "value": "Queue" - }, - { - "id": "unit", - "value": "none" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 4, - "x": 10, - "y": 8 - }, - "id": 19, - "options": { - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "text": {} - }, - "pluginVersion": "7.5.2", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, - "targets": [ - { - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "linear" - ], - "type": "fill" - } - ], - "measurement": "disk", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "iotime" - ], - "type": "field" - }, - { - "params": [], - "type": "last" - }, - { - "params": [ - "1s" - ], - "type": "non_negative_derivative" - }, - { - "params": [ - "iotime" - ], - "type": "alias" - } - ], - [ - { - "params": [ - "queue" - ], - "type": "field" - }, - { - "params": [], - "type": "last" - }, - { - "params": [ - "queue" - ], - "type": "alias" - } - ] - ], - "tags": [ - { - "key": "hostname", - "operator": "=~", - "value": "/^$hostname$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Disk Metrics", - "type": "gauge" - }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", "fieldConfig": { "defaults": { "unit": "binBps" @@ -1040,10 +1037,10 @@ "fill": 1, "fillGradient": 0, "gridPos": { - "h": 7, - "w": 10, - "x": 14, - "y": 8 + "h": 10, + "w": 14, + "x": 10, + "y": 11 }, "hiddenSeries": false, "id": 10, @@ -1063,17 +1060,10 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "7.5.2", + "pluginVersion": "8.0.0", "pointradius": 2, "points": false, "renderer": "flot", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, "seriesOverrides": [], "spaceLength": 10, "stack": false, @@ -1204,7 +1194,7 @@ "bars": false, "dashLength": 10, "dashes": false, - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", "fieldConfig": { "defaults": { "unit": "binBps" @@ -1214,10 +1204,10 @@ "fill": 1, "fillGradient": 0, "gridPos": { - "h": 7, + "h": 11, "w": 10, "x": 0, - "y": 15 + "y": 21 }, "hiddenSeries": false, "id": 18, @@ -1237,17 +1227,10 @@ "alertThreshold": true }, "percentage": false, - "pluginVersion": "7.5.2", + "pluginVersion": "8.0.0", "pointradius": 2, "points": false, "renderer": "flot", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, "seriesOverrides": [], "spaceLength": 10, "stack": false, @@ -1374,271 +1357,8 @@ } }, { - "datasource": "InfluxDB-sysmon", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "decimals": 2, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "none" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "network_netstat.tcp_connections" - }, - "properties": [ - { - "id": "displayName", - "value": "TCP Connections" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "network_netstat.tcp_pkts_recv" - }, - "properties": [ - { - "id": "displayName", - "value": "TCP Segments Recv." - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "network_netstat.tcp_pkts_sent" - }, - "properties": [ - { - "id": "displayName", - "value": "TCP Segments Sent" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "network_netstat.udp_pkts_recv" - }, - "properties": [ - { - "id": "displayName", - "value": "UDP Datagrams Recv." - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "network_netstat.udp_pkts_sent" - }, - "properties": [ - { - "id": "displayName", - "value": "UDP Datagrams Sent" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 7, - "x": 10, - "y": 15 - }, - "id": 21, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "text": {}, - "textMode": "auto" - }, - "pluginVersion": "7.5.2", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, - "targets": [ - { - "groupBy": [ - { - "params": [ - "$__interval" - ], - "type": "time" - }, - { - "params": [ - "linear" - ], - "type": "fill" - } - ], - "measurement": "network_netstat", - "orderByTime": "ASC", - "policy": "default", - "refId": "A", - "resultFormat": "time_series", - "select": [ - [ - { - "params": [ - "tcp_connections" - ], - "type": "field" - }, - { - "params": [], - "type": "last" - }, - { - "params": [ - "tcp_connections" - ], - "type": "alias" - } - ], - [ - { - "params": [ - "tcp_pkts_recv" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "1s" - ], - "type": "non_negative_derivative" - }, - { - "params": [ - "tcp_pkts_recv" - ], - "type": "alias" - } - ], - [ - { - "params": [ - "tcp_pkts_sent" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "1s" - ], - "type": "non_negative_derivative" - }, - { - "params": [ - "tcp_pkts_sent" - ], - "type": "alias" - } - ], - [ - { - "params": [ - "udp_pkts_recv" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "1s" - ], - "type": "non_negative_derivative" - }, - { - "params": [ - "udp_pkts_recv" - ], - "type": "alias" - } - ], - [ - { - "params": [ - "udp_pkts_sent" - ], - "type": "field" - }, - { - "params": [], - "type": "mean" - }, - { - "params": [ - "1s" - ], - "type": "non_negative_derivative" - }, - { - "params": [ - "udp_pkts_sent" - ], - "type": "alias" - } - ] - ], - "tags": [ - { - "key": "hostname", - "operator": "=~", - "value": "/^$hostname$/" - } - ] - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Network Statistics", - "type": "stat" - }, - { - "datasource": "InfluxDB-sysmon", + "datasource": "${DS_INFLUXDB-SYSMON}", + "description": "", "fieldConfig": { "defaults": { "color": { @@ -1756,10 +1476,10 @@ ] }, "gridPos": { - "h": 7, - "w": 7, - "x": 17, - "y": 15 + "h": 11, + "w": 14, + "x": 10, + "y": 21 }, "id": 22, "options": { @@ -1777,14 +1497,7 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "7.5.2", - "scopedVars": { - "hostname": { - "selected": true, - "text": "S824Rhel71le", - "value": "S824Rhel71le" - } - }, + "pluginVersion": "8.0.0", "targets": [ { "groupBy": [ @@ -1963,29 +1676,20 @@ ], "timeFrom": null, "timeShift": null, - "title": "Network Sockets", + "title": "Network Sockets (Linux)", "type": "stat" } ], "refresh": "30s", - "schemaVersion": 27, + "schemaVersion": 30, "style": "dark", "tags": [], "templating": { "list": [ { "allValue": null, - "current": { - "selected": true, - "tags": [], - "text": [ - "S824Rhel71le" - ], - "value": [ - "S824Rhel71le" - ] - }, - "datasource": "InfluxDB-sysmon", + "current": {}, + "datasource": "${DS_INFLUXDB-SYSMON}", "definition": "SHOW TAG VALUES FROM \"processor\" WITH KEY = \"hostname\" WHERE time > now() - 24h", "description": null, "error": null, @@ -2001,7 +1705,6 @@ "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", - "tags": [], "tagsQuery": "", "type": "query", "useTags": false @@ -2027,7 +1730,7 @@ ] }, "timezone": "", - "title": "Sysmon-Example", + "title": "Sysmon Agent", "uid": "QkVPjseMk", - "version": 25 + "version": 30 } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index df1734b..970fc1b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=0.0.2 +version=0.0.3 pf4jVersion=3.6.0 slf4jVersion=1.7.30 camelVersion=3.7.4 diff --git a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java index 83b0a1a..007410a 100644 --- a/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java +++ b/plugins/os-aix/src/main/java/sysmon/plugins/os_aix/AixNetstatExtension.java @@ -12,7 +12,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; -@Extension +// Disabled +//@Extension public class AixNetstatExtension implements MetricExtension { private static final Logger log = LoggerFactory.getLogger(AixNetstatExtension.class); diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java index 2f8c433..8fe5353 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseDiskExtension.java @@ -19,22 +19,13 @@ public class BaseDiskExtension implements MetricExtension { private static final Logger log = LoggerFactory.getLogger(BaseDiskExtension.class); - private SystemInfo systemInfo; private HardwareAbstractionLayer hardwareAbstractionLayer; @Override public boolean isSupported() { - - try { - systemInfo = new SystemInfo(); - hardwareAbstractionLayer = systemInfo.getHardware(); - return true; - } catch (UnsupportedOperationException e) { - log.warn(e.getMessage()); - } - - return false; + hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer(); + return hardwareAbstractionLayer != null; } @Override diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java index b73ad48..024c46a 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseMemoryExtension.java @@ -17,21 +17,12 @@ public class BaseMemoryExtension implements MetricExtension { private static final Logger log = LoggerFactory.getLogger(BaseMemoryExtension.class); - private SystemInfo systemInfo; private HardwareAbstractionLayer hardwareAbstractionLayer; @Override public boolean isSupported() { - - try { - systemInfo = new SystemInfo(); - hardwareAbstractionLayer = systemInfo.getHardware(); - return true; - } catch (UnsupportedOperationException e) { - log.warn(e.getMessage()); - } - - return false; + hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer(); + return hardwareAbstractionLayer != null; } @Override diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java index 8b5a7c0..a16efba 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseNetworkExtension.java @@ -19,21 +19,12 @@ public class BaseNetworkExtension implements MetricExtension { private static final Logger log = LoggerFactory.getLogger(BaseNetworkExtension.class); - private SystemInfo systemInfo; private HardwareAbstractionLayer hardwareAbstractionLayer; @Override public boolean isSupported() { - - try { - systemInfo = new SystemInfo(); - hardwareAbstractionLayer = systemInfo.getHardware(); - return true; - } catch (UnsupportedOperationException e) { - log.warn(e.getMessage()); - } - - return false; + hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer(); + return hardwareAbstractionLayer != null; } @Override diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java index 203cceb..87f193e 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BasePlugin.java @@ -4,14 +4,36 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.pf4j.Plugin; import org.pf4j.PluginWrapper; +import oshi.SystemInfo; +import oshi.hardware.HardwareAbstractionLayer; public class BasePlugin extends Plugin { private static final Logger log = LoggerFactory.getLogger(BasePlugin.class); + private static SystemInfo systemInfo; + private static HardwareAbstractionLayer hardwareAbstractionLayer; + public BasePlugin(PluginWrapper wrapper) { super(wrapper); } + public static HardwareAbstractionLayer getHardwareAbstractionLayer() { + + try { + if(systemInfo == null) { + systemInfo = new SystemInfo(); + } + if(hardwareAbstractionLayer == null) { + hardwareAbstractionLayer = systemInfo.getHardware(); + } + + } catch (UnsupportedOperationException e) { + log.warn(e.getMessage()); + } + + return hardwareAbstractionLayer; + } + } diff --git a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java index 9b39018..c444fc6 100644 --- a/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java +++ b/plugins/os-base/src/main/java/sysmon/plugins/os_base/BaseProcessorExtension.java @@ -24,22 +24,13 @@ public class BaseProcessorExtension implements MetricExtension { private static final Logger log = LoggerFactory.getLogger(BaseProcessorExtension.class); - private SystemInfo systemInfo; private HardwareAbstractionLayer hardwareAbstractionLayer; private long[] oldTicks; @Override public boolean isSupported() { - - try { - systemInfo = new SystemInfo(); - hardwareAbstractionLayer = systemInfo.getHardware(); - return true; - } catch (UnsupportedOperationException e) { - log.warn(e.getMessage()); - } - - return false; + hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer(); + return hardwareAbstractionLayer != null; } @Override diff --git a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java index d4a96d3..0a1d80b 100644 --- a/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java +++ b/plugins/os-linux/src/main/java/sysmon/plugins/os_linux/LinuxNetstatExtension.java @@ -12,7 +12,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; -@Extension +// Disabled +//@Extension public class LinuxNetstatExtension implements MetricExtension { private static final Logger log = LoggerFactory.getLogger(LinuxNetstatExtension.class);