From bc43d687a03714685f88f1df0df14655f1a9e18a Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Tue, 11 May 2021 15:37:23 +0200 Subject: [PATCH] More work on packages, plugins and tests. --- client/build.gradle | 14 +++-- .../java/org/sysmon/client/Application.java | 6 +- .../org/sysmon/client/ClientRouteBuilder.java | 20 +++++- gradle.properties | 7 ++- plugins/build.gradle | 31 ++++++++- .../plugins/sysmon_aix/AixDiskExtension.java | 5 ++ .../sysmon_aix/AixProcessorExtension.java | 23 ++++++- .../plugins/sysmon_aix/AixProcessorStat.java | 63 ++++++++++++------- .../src/test/groovy/AixProcessorTest.groovy | 25 +++++++- .../{lparstat.txt => lparstat-aix.txt} | 0 .../src/test/resources/lparstat-linux.txt | 7 +++ .../sysmon_linux/LinuxDiskExtension.java | 8 ++- .../sysmon_linux/LinuxMemoryExtension.java | 45 ++++++++++--- .../sysmon_linux/LinuxProcessorExtension.java | 5 ++ .../src/test/groovy/LinuxMemoryTest.groovy | 23 +++++++ .../src/test/resources/meminfo.txt | 51 +++++++++++++++ server/build.gradle | 15 ++++- .../java/org/sysmon/server/Application.java | 20 ++++-- .../org/sysmon/server/ServerRouteBuilder.java | 8 ++- .../src/main/resources/application.properties | 2 +- .../org/sysmon/shared/MetricExtension.java | 1 + .../java/org/sysmon/shared/PluginHelper.java | 9 +++ 22 files changed, 330 insertions(+), 58 deletions(-) rename plugins/sysmon-aix/src/test/resources/{lparstat.txt => lparstat-aix.txt} (100%) create mode 100644 plugins/sysmon-aix/src/test/resources/lparstat-linux.txt create mode 100644 plugins/sysmon-linux/src/test/groovy/LinuxMemoryTest.groovy create mode 100644 plugins/sysmon-linux/src/test/resources/meminfo.txt diff --git a/client/build.gradle b/client/build.gradle index 46055e5..178c0d4 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -1,15 +1,14 @@ plugins { id 'application' - id "com.github.johnrengelman.shadow" version "6.1.0" + id "com.github.johnrengelman.shadow" version "7.0.0" id "net.nemerosa.versioning" version "2.14.0" - id "nebula.ospackage" version "8.4.1" + id "nebula.ospackage" version "8.5.6" } dependencies { testImplementation project(':shared') implementation project(':shared') - implementation project(':plugins') annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") implementation group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}" @@ -48,7 +47,7 @@ ospackage { user = 'root' packager = "Mark Nellemann " - into '/opt/sysmon-client' + into '/opt/sysmon/client' from(shadowJar.outputs.files) { into 'lib' @@ -90,3 +89,10 @@ jar { ) } } + +shadowJar { + archiveBaseName.set('sysmon-client') + archiveClassifier.set('') + archiveVersion.set('') + mergeServiceFiles() // Tell plugin to merge duplicate service files +} \ No newline at end of file diff --git a/client/src/main/java/org/sysmon/client/Application.java b/client/src/main/java/org/sysmon/client/Application.java index 146b751..097ef74 100644 --- a/client/src/main/java/org/sysmon/client/Application.java +++ b/client/src/main/java/org/sysmon/client/Application.java @@ -8,10 +8,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; +import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; +import java.util.Properties; import java.util.concurrent.Callable; @CommandLine.Command(name = "sysmon-client", mixinStandardHelpOptions = true) @@ -22,9 +24,11 @@ public class Application implements Callable { @CommandLine.Option(names = { "-s", "--server-url" }, description = "Server URL (default: ${DEFAULT-VALUE}).", defaultValue = "http://127.0.0.1:9925/metrics", paramLabel = "") private URL serverUrl; - @CommandLine.Option(names = { "-n", "--hostname" }, description = "Client hostname.", paramLabel = "") + @CommandLine.Option(names = { "-n", "--hostname" }, description = "Client hostname (default: ).", paramLabel = "") private String hostname; + @CommandLine.Option(names = { "-p", "--plugins" }, description = "Plugin jar path (default: ${DEFAULT-VALUE}).", paramLabel = "", defaultValue = "/opt/sysmon/plugins") + private File plugins; public static void main(String... args) { int exitCode = new CommandLine(new Application()).execute(args); diff --git a/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java b/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java index 5398792..41a5f79 100644 --- a/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java +++ b/client/src/main/java/org/sysmon/client/ClientRouteBuilder.java @@ -11,7 +11,11 @@ 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.util.ArrayList; import java.util.List; +import java.util.Properties; public class ClientRouteBuilder extends RouteBuilder { @@ -22,17 +26,29 @@ public class ClientRouteBuilder extends RouteBuilder { Registry registry = getContext().getRegistry(); - PluginManager pluginManager = new JarPluginManager(); + Path[] pluginpaths = { new File("/opt/sysmon/plugins").toPath() }; + + PluginManager pluginManager = new JarPluginManager(pluginpaths); pluginManager.loadPlugins(); pluginManager.startPlugins(); + List providers = new ArrayList<>(); List metricExtensions = pluginManager.getExtensions(MetricExtension.class); for (MetricExtension ext : metricExtensions) { + if(ext.isSupported()) { + + String provides = ext.getProvides(); + if(providers.contains(provides)) { + log.warn("Skipping extension (already provided): " + ext.getName()); + continue; + } + log.info(">>> Enabling extension: " + ext.getDescription()); + providers.add(provides); // Setup Camel route for this extension - from("timer:collect?period=30000") + from("timer:collect?fixedRate=true&period=30s") .bean(ext, "getMetrics") //.doTry() .process(new MetricEnrichProcessor(registry)) diff --git a/gradle.properties b/gradle.properties index 5e2fb28..7431dd5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,7 @@ +group=org.sysmon +version=0.0.1-SNAPSHOT + pf4jVersion=3.6.0 slf4jVersion=1.7.30 -camelVersion=3.7.3 -picocliVersion=4.6.1 \ No newline at end of file +camelVersion=3.7.4 +picocliVersion=4.6.1 diff --git a/plugins/build.gradle b/plugins/build.gradle index c88be84..cfe30a7 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -1,3 +1,7 @@ +plugins { + id "nebula.ospackage" version "8.5.6" +} + subprojects { apply plugin: 'java' apply plugin: 'groovy' @@ -49,4 +53,29 @@ task customCleanUp(type:Delete) { delete "output" } -tasks.clean.dependsOn(tasks.customCleanUp) \ No newline at end of file +tasks.clean.dependsOn(tasks.customCleanUp) + + +apply plugin: 'nebula.ospackage' +ospackage { + packageName = 'sysmon-plugins' + release = '1' + user = 'root' + packager = "Mark Nellemann " + + into '/opt/sysmon/plugins' + + from('output/') { + into '' + } + +} + +buildRpm { + dependsOn assemble + os = "LINUX" +} + +buildDeb { + dependsOn assemble +} 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 d6aaef0..0ec1fc9 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 @@ -17,6 +17,11 @@ public class AixDiskExtension implements MetricExtension { return "aix-disk"; } + @Override + public String getProvides() { + return "disk"; + } + @Override public String getDescription() { return "AIX Disk Metrics (TODO)"; diff --git a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorExtension.java b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorExtension.java index b441ae3..d61b387 100644 --- a/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorExtension.java +++ b/plugins/sysmon-aix/src/main/java/org/sysmon/plugins/sysmon_aix/AixProcessorExtension.java @@ -8,7 +8,7 @@ import org.sysmon.shared.MetricExtension; import org.sysmon.shared.MetricResult; import org.sysmon.shared.PluginHelper; -import java.util.HashMap; +import java.io.File; import java.util.List; import java.util.Map; @@ -19,7 +19,19 @@ public class AixProcessorExtension implements MetricExtension { @Override public boolean isSupported() { - return System.getProperty("os.name").toLowerCase().contains("aix"); + + String osArch = System.getProperty("os.arch").toLowerCase(); + if(!osArch.startsWith("ppc64")) { + log.warn("Wrong os arch: " + osArch); + return false; + } + + if(!PluginHelper.canExecute("lparstat")) { + log.warn("No lparstat command found."); + return false; + } + + return true; } @Override @@ -27,6 +39,11 @@ public class AixProcessorExtension implements MetricExtension { return "aix-processor"; } + @Override + public String getProvides() { + return "processor"; + } + @Override public String getDescription() { return "AIX Processor Metrics"; @@ -35,7 +52,7 @@ public class AixProcessorExtension implements MetricExtension { @Override public MetricResult getMetrics() { - List vmstat = PluginHelper.executeCommand("/usr/bin/lparstat 1 1"); + List vmstat = PluginHelper.executeCommand("lparstat 1 1"); AixProcessorStat processorStat = processCommandOutput(vmstat); Map tagsMap = processorStat.getTags(); 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 43b51dc..3df6d9a 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 @@ -13,7 +13,12 @@ public class AixProcessorStat { private static final Logger log = LoggerFactory.getLogger(AixProcessorStat.class); - private final Pattern pattern = Pattern.compile("^System configuration: type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+)MB psize=(\\d+) ent=(\\d+\\.?\\d*)"); + // 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*)"); + + // 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*)"); + private String type; private String mode; @@ -31,34 +36,44 @@ 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) { - System configuration: type=Shared mode=Uncapped smt=8 lcpu=8 mem=4096MB psize=19 ent=0.50 + Pattern p; + for (String line : lines) { - - %user %sys %wait %idle physc %entc lbusy vcsw phint %nsp %utcyc - ----- ----- ------ ------ ----- ----- ------ ----- ----- ----- ------ - 0.1 0.0 0.0 99.9 0.00 0.2 1.9 37441986 316 149 33.06 - */ - AixProcessorStat(List vmstatLines) { - - for(String line : vmstatLines) { - Matcher matcher = pattern.matcher(line); - if (matcher.find() && matcher.groupCount() == 7) { - type=matcher.group(1); - mode=matcher.group(2); - smt = Integer.parseInt(matcher.group(3)); - lcpu = Integer.parseInt(matcher.group(4)); - psize = Integer.parseInt(matcher.group(5)); - ent = Float.parseFloat(matcher.group(7)); - break; + if (line.startsWith("System configuration:")) { + p = patternAix; + Matcher matcher = patternAix.matcher(line); + if (matcher.find() && matcher.groupCount() == 7) { + type = matcher.group(1); + mode = matcher.group(2); + smt = Integer.parseInt(matcher.group(3)); + lcpu = Integer.parseInt(matcher.group(4)); + psize = Integer.parseInt(matcher.group(5)); + ent = Float.parseFloat(matcher.group(7)); + } } + + if (line.startsWith("type=")) { + //type=Shared mode=Uncapped smt=8 lcpu=4 mem=4101120 kB cpus=24 ent=4.00 + + Matcher matcher = patternLinux.matcher(line); + if (matcher.find() && matcher.groupCount() == 7) { + type = matcher.group(1); + mode = matcher.group(2); + smt = Integer.parseInt(matcher.group(3)); + lcpu = Integer.parseInt(matcher.group(4)); + psize = Integer.parseInt(matcher.group(6)); + ent = Float.parseFloat(matcher.group(7)); + } + } + } - String vmstat = vmstatLines.get(vmstatLines.size() -1); - String[] splitStr = vmstat.trim().split("\\s+"); - if(splitStr.length != 11) { - throw new UnsupportedOperationException("vmstat string error: " + splitStr.length); + String lparstat = lines.get(lines.size() -1); + String[] splitStr = lparstat.trim().split("\\s+"); + if(splitStr.length < 9) { + throw new UnsupportedOperationException("lparstat string error: " + lparstat); } this.user = Float.parseFloat(splitStr[0]); diff --git a/plugins/sysmon-aix/src/test/groovy/AixProcessorTest.groovy b/plugins/sysmon-aix/src/test/groovy/AixProcessorTest.groovy index 35d3937..a0d9f95 100644 --- a/plugins/sysmon-aix/src/test/groovy/AixProcessorTest.groovy +++ b/plugins/sysmon-aix/src/test/groovy/AixProcessorTest.groovy @@ -4,10 +4,10 @@ import spock.lang.Specification class AixProcessorTest extends Specification { - void "test lparstat output processing"() { + void "test AIX lparstat output processing"() { setup: - def testFile = new File(getClass().getResource('/lparstat.txt').toURI()) + def testFile = new File(getClass().getResource('/lparstat-aix.txt').toURI()) List lines = testFile.readLines("UTF-8") when: @@ -24,4 +24,25 @@ 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") + + when: + AixProcessorExtension extension = new AixProcessorExtension() + AixProcessorStat stats = extension.processCommandOutput(lines) + + then: + stats.getUser() == 0.03f + stats.getSys() == 0.0f + stats.getWait() == 0.0f + stats.getIdle() == 99.97f + stats.getFields().get("ent") == 4.00f + stats.getTags().get("mode") == "Uncapped" + stats.getTags().get("type") == "Shared" + + } + } diff --git a/plugins/sysmon-aix/src/test/resources/lparstat.txt b/plugins/sysmon-aix/src/test/resources/lparstat-aix.txt similarity index 100% rename from plugins/sysmon-aix/src/test/resources/lparstat.txt rename to plugins/sysmon-aix/src/test/resources/lparstat-aix.txt diff --git a/plugins/sysmon-aix/src/test/resources/lparstat-linux.txt b/plugins/sysmon-aix/src/test/resources/lparstat-linux.txt new file mode 100644 index 0000000..7ae42d0 --- /dev/null +++ b/plugins/sysmon-aix/src/test/resources/lparstat-linux.txt @@ -0,0 +1,7 @@ + +System Configuration +type=Shared mode=Uncapped smt=8 lcpu=4 mem=4101120 kB cpus=24 ent=4.00 + +%user %sys %wait %idle physc %entc lbusy vcsw phint +----- ----- ----- ----- ----- ----- ----- ----- ----- + 0.03 0.00 0.00 99.97 0.000000 0.000000 0.03 445478301 18863 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 bce8138..b941a16 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 @@ -27,7 +27,8 @@ public class LinuxDiskExtension implements MetricExtension { @Override public boolean isSupported() { - return System.getProperty("os.name").toLowerCase().contains("linux"); + //return System.getProperty("os.name").toLowerCase().contains("linux"); + return false; // TODO: Not ready yet. } @Override @@ -35,6 +36,11 @@ public class LinuxDiskExtension implements MetricExtension { return "linux-disk"; } + @Override + public String getProvides() { + return "disk"; + } + @Override public String getDescription() { return "Linux Disk Metrics"; diff --git a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxMemoryExtension.java b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxMemoryExtension.java index 2829238..fdeeccb 100644 --- a/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxMemoryExtension.java +++ b/plugins/sysmon-linux/src/main/java/org/sysmon/plugins/sysmon_linux/LinuxMemoryExtension.java @@ -6,6 +6,8 @@ import org.sysmon.shared.MetricExtension; import org.sysmon.shared.MetricResult; import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -31,6 +33,11 @@ public class LinuxMemoryExtension implements MetricExtension { return "linux-memory"; } + @Override + public String getProvides() { + return "memory"; + } + @Override public String getDescription() { return "Linux Memory Metrics"; @@ -42,7 +49,7 @@ public class LinuxMemoryExtension implements MetricExtension { MetricResult result = new MetricResult("memory"); try { - result.setMeasurement(readProcFile()); + result.setMeasurement(processProcFile(readProcFile())); } catch (IOException e) { e.printStackTrace(); } @@ -51,27 +58,51 @@ public class LinuxMemoryExtension implements MetricExtension { } - private Measurement readProcFile() throws IOException { + protected List readProcFile() throws IOException { + List allLines = Files.readAllLines(Paths.get("/proc/meminfo"), StandardCharsets.UTF_8); + return allLines; + } + + protected Measurement processProcFile(List lines) { Map tagsMap = new HashMap<>(); Map fieldsMap = new HashMap<>(); - List allLines = Files.readAllLines(Paths.get("/proc/meminfo"), StandardCharsets.UTF_8); - for (String line : allLines) { + Long total = null; + Long available = null; + + for (String line : lines) { if (line.startsWith("Mem")) { Matcher matcher = pattern.matcher(line); if (matcher.find() && matcher.groupCount() == 2) { + String key = matcher.group(1).substring(3).toLowerCase(); // remove "Mem" and lowercase - Object value = matcher.group(2); - fieldsMap.put(key, value); + String value = matcher.group(2); + + switch (key) { + case "total": + total = Long.parseLong(value); + fieldsMap.put(key, total); + break; + case "available": + available = Long.parseLong(value); + fieldsMap.put(key, available); + break; + } + } } + + } + + if(total != null && available != null) { + BigDecimal usage = BigDecimal.valueOf(((float)(total - available) / total) * 100); + fieldsMap.put("usage", usage.setScale(2, RoundingMode.HALF_EVEN)); } return new Measurement(tagsMap, fieldsMap); } - } \ No newline at end of file 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 a67ea2a..17d32a8 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 @@ -35,6 +35,11 @@ public class LinuxProcessorExtension implements MetricExtension { return "linux-processor"; } + @Override + public String getProvides() { + return "processor"; + } + @Override public String getDescription() { return "Linux Processor Metrics"; diff --git a/plugins/sysmon-linux/src/test/groovy/LinuxMemoryTest.groovy b/plugins/sysmon-linux/src/test/groovy/LinuxMemoryTest.groovy new file mode 100644 index 0000000..a18dea0 --- /dev/null +++ b/plugins/sysmon-linux/src/test/groovy/LinuxMemoryTest.groovy @@ -0,0 +1,23 @@ +import org.sysmon.plugins.sysmon_linux.LinuxMemoryExtension +import org.sysmon.shared.Measurement +import spock.lang.Specification + +class LinuxMemoryTest extends Specification { + + void "test proc file processing"() { + + setup: + def testFile = new File(getClass().getResource('/meminfo.txt').toURI()) + List lines = testFile.readLines("UTF-8") + + when: + LinuxMemoryExtension extension = new LinuxMemoryExtension() + Measurement m = extension.processProcFile(lines); + + then: + m.getFields().get("total") == 16069616 + m.getFields().get("available") == 7968744 + m.getFields().get("usage") == 50.41 + } + +} diff --git a/plugins/sysmon-linux/src/test/resources/meminfo.txt b/plugins/sysmon-linux/src/test/resources/meminfo.txt new file mode 100644 index 0000000..8e4ad53 --- /dev/null +++ b/plugins/sysmon-linux/src/test/resources/meminfo.txt @@ -0,0 +1,51 @@ +MemTotal: 16069616 kB +MemFree: 1587092 kB +MemAvailable: 7968744 kB +Buffers: 463364 kB +Cached: 6808540 kB +SwapCached: 2156 kB +Active: 9179808 kB +Inactive: 4369880 kB +Active(anon): 6366532 kB +Inactive(anon): 761912 kB +Active(file): 2813276 kB +Inactive(file): 3607968 kB +Unevictable: 270200 kB +Mlocked: 48 kB +SwapTotal: 3985404 kB +SwapFree: 3974652 kB +Dirty: 9708 kB +Writeback: 0 kB +AnonPages: 6545944 kB +Mapped: 1948448 kB +Shmem: 852772 kB +KReclaimable: 302640 kB +Slab: 502784 kB +SReclaimable: 302640 kB +SUnreclaim: 200144 kB +KernelStack: 21376 kB +PageTables: 52856 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 12020212 kB +Committed_AS: 14750600 kB +VmallocTotal: 34359738367 kB +VmallocUsed: 42828 kB +VmallocChunk: 0 kB +Percpu: 8320 kB +HardwareCorrupted: 0 kB +AnonHugePages: 0 kB +ShmemHugePages: 0 kB +ShmemPmdMapped: 0 kB +FileHugePages: 0 kB +FilePmdMapped: 0 kB +HugePages_Total: 0 +HugePages_Free: 0 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +Hugepagesize: 2048 kB +Hugetlb: 0 kB +DirectMap4k: 410796 kB +DirectMap2M: 10795008 kB +DirectMap1G: 6291456 kB diff --git a/server/build.gradle b/server/build.gradle index 52858c4..fa17294 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -1,7 +1,7 @@ plugins { id 'application' - id "com.github.johnrengelman.shadow" version "6.1.0" + id "com.github.johnrengelman.shadow" version "7.0.0" id "net.nemerosa.versioning" version "2.14.0" id "nebula.ospackage" version "8.5.6" } @@ -39,7 +39,7 @@ ospackage { user = 'root' packager = "Mark Nellemann " - into '/opt/sysmon-server' + into '/opt/sysmon/server' from(shadowJar.outputs.files) { into 'lib' @@ -69,7 +69,8 @@ buildDeb { dependsOn startShadowScripts } -task aixRpm(type: Rpm) { +task buildRpmAix(type: Rpm) { + dependsOn startShadowScripts os "AIX" } @@ -83,6 +84,14 @@ jar { 'Build-Version' : versioning.info.tag ?: (versioning.info.branch + "-" + versioning.info.build), 'Build-Revision' : versioning.info.commit, 'Build-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ss.SSSZ").toString(), + 'Add-Opens' : 'java.base/java.lang.invoke' // To ignore "Illegal reflective access by retrofit2.Platform" warnings ) } } + +shadowJar { + archiveBaseName.set('sysmon-server') + archiveClassifier.set('') + archiveVersion.set('') + mergeServiceFiles() // Tell plugin to merge duplicate service files +} diff --git a/server/src/main/java/org/sysmon/server/Application.java b/server/src/main/java/org/sysmon/server/Application.java index 701e774..159c776 100644 --- a/server/src/main/java/org/sysmon/server/Application.java +++ b/server/src/main/java/org/sysmon/server/Application.java @@ -1,12 +1,16 @@ package org.sysmon.server; +import org.apache.camel.CamelContext; import org.apache.camel.main.Main; +import org.apache.camel.support.DefaultRegistry; +import org.apache.camel.support.SimpleRegistry; import org.influxdb.InfluxDB; import org.influxdb.InfluxDBFactory; import picocli.CommandLine; import java.io.IOException; import java.net.URL; +import java.util.Properties; import java.util.concurrent.Callable; @CommandLine.Command(name = "sysmon-server", mixinStandardHelpOptions = true) @@ -21,8 +25,11 @@ public class Application implements Callable { @CommandLine.Option(names = { "-p", "--influxdb-pass" }, description = "InfluxDB Password (default: ${DEFAULT-VALUE}).", defaultValue = "", paramLabel = "") private String influxPass; - @CommandLine.Option(names = { "-s", "--server-port" }, description = "Server port (default: ${DEFAULT-VALUE}).", defaultValue = "9925", paramLabel = "") - private String listenPort; + @CommandLine.Option(names = { "-H", "--server-host" }, description = "Server listening address (default: ${DEFAULT-VALUE}).", paramLabel = "") + private String listenHost = "0.0.0.0"; + + @CommandLine.Option(names = { "-P", "--server-port" }, description = "Server listening port (default: ${DEFAULT-VALUE}).", paramLabel = "") + private Integer listenPort = 9925; public static void main(String... args) { @@ -34,14 +41,19 @@ public class Application implements Callable { @Override public Integer call() throws IOException { + Properties properties = new Properties(); + properties.put("http.host", listenHost); + properties.put("http.port", listenPort); + InfluxDB influxConnectionBean = InfluxDBFactory.connect(influxUrl.toString(), influxUser, influxPass); Main main = new Main(); main.bind("myInfluxConnection", influxConnectionBean); - main.bind("myListenPort", Integer.parseInt(listenPort)); + main.bind("http.host", listenHost); + main.bind("http.port", listenPort); + main.bind("properties", properties); main.configure().addRoutesBuilder(ServerRouteBuilder.class); - // now keep the application running until the JVM is terminated (ctrl + c or sigterm) try { main.run(); diff --git a/server/src/main/java/org/sysmon/server/ServerRouteBuilder.java b/server/src/main/java/org/sysmon/server/ServerRouteBuilder.java index c0b1dd3..ce57274 100644 --- a/server/src/main/java/org/sysmon/server/ServerRouteBuilder.java +++ b/server/src/main/java/org/sysmon/server/ServerRouteBuilder.java @@ -5,6 +5,8 @@ import org.apache.camel.model.rest.RestBindingMode; import org.apache.camel.spi.Registry; import org.sysmon.shared.MetricResult; +import java.util.Properties; + public class ServerRouteBuilder extends RouteBuilder { @Override @@ -14,8 +16,8 @@ public class ServerRouteBuilder extends RouteBuilder { restConfiguration().component("jetty") .bindingMode(RestBindingMode.auto) - .host("127.0.0.1") - .port((Integer) registry.lookupByName("myListenPort")); + .host(registry.lookupByNameAndType("http.host", String.class)) + .port(registry.lookupByNameAndType("http.port", Integer.class)); rest() .get("/") @@ -39,7 +41,7 @@ public class ServerRouteBuilder extends RouteBuilder { .log(">>> metric: ${header.hostname} - ${body}") .doTry() .process(new MetricResultToPointProcessor()) - .to("influxdb://myInfluxConnection?databaseName=sysmon&retentionPolicy=autogen") + .to("influxdb://ref.myInfluxConnection?databaseName=sysmon&retentionPolicy=autogen") .doCatch(Exception.class) .log("Error storing metric to InfluxDB: ${exception}") .end(); diff --git a/server/src/main/resources/application.properties b/server/src/main/resources/application.properties index cc7923e..891efb0 100644 --- a/server/src/main/resources/application.properties +++ b/server/src/main/resources/application.properties @@ -27,7 +27,7 @@ camel.main.name = sysmon-server #camel.main.beanIntrospectionLoggingLevel=INFO # run in lightweight mode to be tiny as possible -camel.main.lightweight = true +#camel.main.lightweight = true # and eager load classes #camel.main.eager-classloading = true diff --git a/shared/src/main/java/org/sysmon/shared/MetricExtension.java b/shared/src/main/java/org/sysmon/shared/MetricExtension.java index f618a29..ed525bc 100644 --- a/shared/src/main/java/org/sysmon/shared/MetricExtension.java +++ b/shared/src/main/java/org/sysmon/shared/MetricExtension.java @@ -7,6 +7,7 @@ public interface MetricExtension extends ExtensionPoint { boolean isSupported(); String getName(); + String getProvides(); String getDescription(); MetricResult getMetrics(); diff --git a/shared/src/main/java/org/sysmon/shared/PluginHelper.java b/shared/src/main/java/org/sysmon/shared/PluginHelper.java index a11e77c..2213792 100644 --- a/shared/src/main/java/org/sysmon/shared/PluginHelper.java +++ b/shared/src/main/java/org/sysmon/shared/PluginHelper.java @@ -7,8 +7,12 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Stream; public class PluginHelper { @@ -58,5 +62,10 @@ public class PluginHelper { } + public static boolean canExecute(String cmd) { + return Stream.of(System.getenv("PATH").split(Pattern.quote(File.pathSeparator))) + .map(Paths::get) + .anyMatch(path -> Files.exists(path.resolve(cmd))); + } }