diff --git a/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java b/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java index 63c96d0..0a29ace 100644 --- a/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java +++ b/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java @@ -11,12 +11,10 @@ import org.slf4j.LoggerFactory; import org.sysmon.shared.MetricExtension; import org.sysmon.shared.MetricResult; -import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.Properties; public class ClientRouteBuilder extends RouteBuilder { @@ -48,7 +46,8 @@ public class ClientRouteBuilder extends RouteBuilder { providers.add(provides); // Setup Camel route for this extension - from("timer:collect?fixedRate=true&period=30s") + // 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=10s") .bean(ext, "getMetrics") //.doTry() .process(new MetricEnrichProcessor(registry)) diff --git a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskExtension.java b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskExtension.java index 0605f47..871d509 100644 --- a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskExtension.java +++ b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskExtension.java @@ -1,17 +1,35 @@ package org.sysmon.plugins.sysmon_aix; import org.pf4j.Extension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sysmon.shared.Measurement; import org.sysmon.shared.MetricExtension; import org.sysmon.shared.MetricResult; +import org.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); + @Override public boolean isSupported() { - // TODO: Implement - //return System.getProperty("os.name").toLowerCase().contains("aix"); - return false; + + 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; } @Override @@ -26,12 +44,25 @@ public class AixDiskExtension implements MetricExtension { @Override public String getDescription() { - return "AIX Disk Metrics (TODO)"; + return "AIX Disk Metrics"; } @Override public MetricResult getMetrics() { - return new MetricResult("disk"); + + List iostat = PluginHelper.executeCommand("iostat -d"); + AixDiskStat diskStat = processCommandOutput(iostat); + + Map tagsMap = diskStat.getTags(); + Map fieldsMap = diskStat.getFields(); + + return new MetricResult("disk", new Measurement(tagsMap, fieldsMap)); } -} \ No newline at end of file + + protected AixDiskStat processCommandOutput(List inputLines) { + return new AixDiskStat(inputLines); + } + + +} diff --git a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskStat.java b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskStat.java new file mode 100644 index 0000000..2928d7e --- /dev/null +++ b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixDiskStat.java @@ -0,0 +1,65 @@ +package org.sysmon.plugins.sysmon_aix; + +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 AixDiskStat { + + private static final Logger log = LoggerFactory.getLogger(AixProcessorStat.class); + + // 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; // Indicates the percentage of time the physical disk/tape was active (bandwidth utilization for the drive). + private Float kbps; // Indicates the amount of data transferred (read or written) to the drive in KB per second. + private Float tps; // 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; // The total number of KB read. + private Long kbWritten; // 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)); + break; + } + + } + + } + + } + + public Map getTags() { + Map tags = new HashMap<>(); + tags.put("device", device); + return tags; + } + + public Map getFields() { + Map fields = new HashMap<>(); + fields.put("reads", kbRead * 1024); // from Kb to b + fields.put("writes", kbWritten * 1024); // from Kb to b + + + return fields; + } +} diff --git a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorStat.java b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorStat.java index 3df6d9a..0e037b1 100644 --- a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorStat.java +++ b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorStat.java @@ -38,11 +38,9 @@ public class AixProcessorStat { AixProcessorStat(List lines) { - Pattern p; for (String line : lines) { if (line.startsWith("System configuration:")) { - p = patternAix; Matcher matcher = patternAix.matcher(line); if (matcher.find() && matcher.groupCount() == 7) { type = matcher.group(1); diff --git a/plugins/sysmon-aix/src/test/groovy/AixDiskTest.groovy b/plugins/sysmon-aix/src/test/groovy/AixDiskTest.groovy new file mode 100644 index 0000000..1ef80c3 --- /dev/null +++ b/plugins/sysmon-aix/src/test/groovy/AixDiskTest.groovy @@ -0,0 +1,24 @@ +import org.sysmon.plugins.sysmon_aix.AixDiskExtension +import org.sysmon.plugins.sysmon_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 + + } + +} diff --git a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskExtension.java b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskExtension.java index 312bdcf..adcee51 100644 --- a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskExtension.java +++ b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskExtension.java @@ -53,7 +53,7 @@ public class LinuxDiskExtension implements MetricExtension { } LinuxDiskProcLine proc2 = processFileOutput(readProcFile()); - LinuxDiskStat stat = new LinuxDiskStat(proc2, proc1); + LinuxDiskStat stat = new LinuxDiskStat(proc1, proc2); System.err.println("FOOBAR"); return new MetricResult("disk", new Measurement(stat.getTags(), stat.getFields())); } diff --git a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskProcLine.java b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskProcLine.java index 2d8bd24..c307c8c 100644 --- a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskProcLine.java +++ b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskProcLine.java @@ -1,6 +1,10 @@ package org.sysmon.plugins.sysmon_linux; public class LinuxDiskProcLine { + + // Sectors to bytes - each sector is 512 bytes - https://lkml.org/lkml/2015/8/17/269 + static final private int SECTOR_BYTE_SIZE = 512; + /* == =================================== 1 major number @@ -113,12 +117,12 @@ public class LinuxDiskProcLine { return timeSpentOnIo; } - public Long getSectorsRead() { - return sectorsRead; + public Long getBytesRead() { + return sectorsRead * SECTOR_BYTE_SIZE; } - public Long getSectorsWritten() { - return sectorsWritten; + public Long getBytesWritten() { + return sectorsWritten * SECTOR_BYTE_SIZE; } public Long getTimeSpentReading() { diff --git a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskStat.java b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskStat.java index a72cc78..c8caed1 100644 --- a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskStat.java +++ b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxDiskStat.java @@ -21,8 +21,8 @@ public class LinuxDiskStat { device = proc1.getDevice(); iotime = proc2.getTimeSpentOnIo() - proc1.getTimeSpentOnIo(); - writes = proc2.getSectorsWritten() - proc1.getSectorsWritten(); - reads = proc2.getSectorsRead() - proc1.getSectorsRead(); + writes = proc2.getBytesWritten() - proc1.getBytesWritten(); + reads = proc2.getBytesRead() - proc1.getBytesRead(); } diff --git a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorExtension.java b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorExtension.java index 17d32a8..58a2c72 100644 --- a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorExtension.java +++ b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorExtension.java @@ -60,7 +60,7 @@ public class LinuxProcessorExtension implements MetricExtension { LinuxProcessorProcLine proc2 = processFileOutput(readProcFile()); - LinuxProcessorStat stat = new LinuxProcessorStat(proc2, proc1); + LinuxProcessorStat stat = new LinuxProcessorStat(proc1, proc2); return new MetricResult("processor", new Measurement(stat.getTags(), stat.getFields())); } diff --git a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorStat.java b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorStat.java index 63c7d28..f051ed3 100644 --- a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorStat.java +++ b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxProcessorStat.java @@ -11,7 +11,7 @@ public class LinuxProcessorStat { private final float idle; private final float busy; - public LinuxProcessorStat(LinuxProcessorProcLine current, LinuxProcessorProcLine previous) { + public LinuxProcessorStat(LinuxProcessorProcLine previous, LinuxProcessorProcLine current) { long workTime = current.getCombinedTime() - previous.getCombinedTime(); diff --git a/plugins/sysmon-linux/src/test/groovy/LinuxDiskTest.groovy b/plugins/sysmon-linux/src/test/groovy/LinuxDiskTest.groovy index a788405..5a60a8e 100644 --- a/plugins/sysmon-linux/src/test/groovy/LinuxDiskTest.groovy +++ b/plugins/sysmon-linux/src/test/groovy/LinuxDiskTest.groovy @@ -36,8 +36,8 @@ class LinuxDiskTest extends Specification { then: diskStat.getTags().get("device") == "nvme0n1" diskStat.getFields().get("iotime") == 272l - diskStat.getFields().get("writes") == 78920l - diskStat.getFields().get("reads") == 0l + diskStat.getFields().get("writes") == 40407040l + diskStat.getFields().get("reads") == 80896l } } diff --git a/plugins/sysmon-linux/src/test/resources/diskstats2.txt b/plugins/sysmon-linux/src/test/resources/diskstats2.txt index 6635a81..ec601ce 100644 --- a/plugins/sysmon-linux/src/test/resources/diskstats2.txt +++ b/plugins/sysmon-linux/src/test/resources/diskstats2.txt @@ -6,7 +6,7 @@ 7 5 loop5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 6 loop6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 7 loop7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 259 0 nvme0n1 89537 20714 7233785 14446 44354 46795 4305594 42289 0 79832 58659 0 0 0 0 2078 1923 + 259 0 nvme0n1 89537 20714 7233943 14446 44354 46795 4305594 42289 0 79832 58659 0 0 0 0 2078 1923 259 1 nvme0n1p1 126 510 7421 38 2 0 2 0 0 84 38 0 0 0 0 0 0 259 2 nvme0n1p2 100 0 7383 20 14 13 216 12 0 100 32 0 0 0 0 0 0 259 3 nvme0n1p3 89207 20204 7213629 14363 42263 46782 4305376 40338 0 79728 54701 0 0 0 0 0 0