More work on packages, plugins and tests.
This commit is contained in:
parent
088d49c90c
commit
bc43d687a0
|
@ -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 <mark.nellemann@gmail.com>"
|
||||
|
||||
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
|
||||
}
|
|
@ -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<Integer> {
|
|||
@CommandLine.Option(names = { "-s", "--server-url" }, description = "Server URL (default: ${DEFAULT-VALUE}).", defaultValue = "http://127.0.0.1:9925/metrics", paramLabel = "<url>")
|
||||
private URL serverUrl;
|
||||
|
||||
@CommandLine.Option(names = { "-n", "--hostname" }, description = "Client hostname.", paramLabel = "<name>")
|
||||
@CommandLine.Option(names = { "-n", "--hostname" }, description = "Client hostname (default: <hostname>).", paramLabel = "<name>")
|
||||
private String hostname;
|
||||
|
||||
@CommandLine.Option(names = { "-p", "--plugins" }, description = "Plugin jar path (default: ${DEFAULT-VALUE}).", paramLabel = "<path>", defaultValue = "/opt/sysmon/plugins")
|
||||
private File plugins;
|
||||
|
||||
public static void main(String... args) {
|
||||
int exitCode = new CommandLine(new Application()).execute(args);
|
||||
|
|
|
@ -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<String> providers = new ArrayList<>();
|
||||
List<MetricExtension> 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))
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
group=org.sysmon
|
||||
version=0.0.1-SNAPSHOT
|
||||
|
||||
pf4jVersion=3.6.0
|
||||
slf4jVersion=1.7.30
|
||||
camelVersion=3.7.3
|
||||
camelVersion=3.7.4
|
||||
picocliVersion=4.6.1
|
|
@ -1,3 +1,7 @@
|
|||
plugins {
|
||||
id "nebula.ospackage" version "8.5.6"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'groovy'
|
||||
|
@ -50,3 +54,28 @@ task customCleanUp(type:Delete) {
|
|||
}
|
||||
|
||||
tasks.clean.dependsOn(tasks.customCleanUp)
|
||||
|
||||
|
||||
apply plugin: 'nebula.ospackage'
|
||||
ospackage {
|
||||
packageName = 'sysmon-plugins'
|
||||
release = '1'
|
||||
user = 'root'
|
||||
packager = "Mark Nellemann <mark.nellemann@gmail.com>"
|
||||
|
||||
into '/opt/sysmon/plugins'
|
||||
|
||||
from('output/') {
|
||||
into ''
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
buildRpm {
|
||||
dependsOn assemble
|
||||
os = "LINUX"
|
||||
}
|
||||
|
||||
buildDeb {
|
||||
dependsOn assemble
|
||||
}
|
||||
|
|
|
@ -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)";
|
||||
|
|
|
@ -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<String> vmstat = PluginHelper.executeCommand("/usr/bin/lparstat 1 1");
|
||||
List<String> vmstat = PluginHelper.executeCommand("lparstat 1 1");
|
||||
AixProcessorStat processorStat = processCommandOutput(vmstat);
|
||||
|
||||
Map<String, String> tagsMap = processorStat.getTags();
|
||||
|
|
|
@ -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<String> 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<String> 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]);
|
||||
|
|
|
@ -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<String> 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<String> 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"
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
7
plugins/sysmon-aix/src/test/resources/lparstat-linux.txt
Normal file
7
plugins/sysmon-aix/src/test/resources/lparstat-linux.txt
Normal file
|
@ -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
|
|
@ -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";
|
||||
|
|
|
@ -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<String> readProcFile() throws IOException {
|
||||
List<String> allLines = Files.readAllLines(Paths.get("/proc/meminfo"), StandardCharsets.UTF_8);
|
||||
return allLines;
|
||||
}
|
||||
|
||||
protected Measurement processProcFile(List<String> lines) {
|
||||
|
||||
Map<String, String> tagsMap = new HashMap<>();
|
||||
Map<String, Object> fieldsMap = new HashMap<>();
|
||||
|
||||
List<String> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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";
|
||||
|
|
23
plugins/sysmon-linux/src/test/groovy/LinuxMemoryTest.groovy
Normal file
23
plugins/sysmon-linux/src/test/groovy/LinuxMemoryTest.groovy
Normal file
|
@ -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<String> 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
|
||||
}
|
||||
|
||||
}
|
51
plugins/sysmon-linux/src/test/resources/meminfo.txt
Normal file
51
plugins/sysmon-linux/src/test/resources/meminfo.txt
Normal file
|
@ -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
|
|
@ -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 <mark.nellemann@gmail.com>"
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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<Integer> {
|
|||
@CommandLine.Option(names = { "-p", "--influxdb-pass" }, description = "InfluxDB Password (default: ${DEFAULT-VALUE}).", defaultValue = "", paramLabel = "<pass>")
|
||||
private String influxPass;
|
||||
|
||||
@CommandLine.Option(names = { "-s", "--server-port" }, description = "Server port (default: ${DEFAULT-VALUE}).", defaultValue = "9925", paramLabel = "<port>")
|
||||
private String listenPort;
|
||||
@CommandLine.Option(names = { "-H", "--server-host" }, description = "Server listening address (default: ${DEFAULT-VALUE}).", paramLabel = "<addr>")
|
||||
private String listenHost = "0.0.0.0";
|
||||
|
||||
@CommandLine.Option(names = { "-P", "--server-port" }, description = "Server listening port (default: ${DEFAULT-VALUE}).", paramLabel = "<port>")
|
||||
private Integer listenPort = 9925;
|
||||
|
||||
|
||||
public static void main(String... args) {
|
||||
|
@ -34,14 +41,19 @@ public class Application implements Callable<Integer> {
|
|||
@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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ public interface MetricExtension extends ExtensionPoint {
|
|||
boolean isSupported();
|
||||
|
||||
String getName();
|
||||
String getProvides();
|
||||
String getDescription();
|
||||
|
||||
MetricResult getMetrics();
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue