Merged in development (pull request #9)

Support for configuring extensions.
This commit is contained in:
Mark Nellemann 2021-09-10 20:00:13 +00:00
commit 39d3127437
31 changed files with 437 additions and 126 deletions

View File

@ -19,6 +19,7 @@ subprojects {
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
implementation "org.slf4j:slf4j-simple:${slf4jVersion}"
implementation 'org.tomlj:tomlj:1.0.0'
}

View File

@ -37,11 +37,12 @@ def projectName = "sysmon-client"
application {
// Define the main class for the application.
mainClass.set('sysmon.client.Application')
applicationDefaultJvmArgs = [ "-server", "-XX:+UseG1GC", "-Xmx32m" ]
applicationDefaultJvmArgs = [ "-server", "-Xms16m", "-Xmx32m", "-XX:+UseG1GC" ]
}
run {
systemProperty 'pf4j.pluginsDir', '../plugins/output/'
systemProperty 'sysmon.cfgFile', 'doc/sysmon-client.toml'
}
tasks.named('test') {

View File

@ -4,7 +4,7 @@ Works on IBM Power VIO (Virtual IO) servers, as well as regular IBM Power AIX in
## Installation
We require Java 8, which should already be installed.
We require Java 8, which should already be installed on AIX, or is available to install.
The RPM packages are *"noarch"* Java bytecode, so we can use the **--ignoreos** option to install:
```shell

View File

@ -2,8 +2,8 @@
Description=Sysmon Client Service
[Service]
TimeoutStartSec=0
Restart=always
TimeoutSec=20
Restart=on-failure
ExecStart=/opt/sysmon/client/bin/client -s http://10.20.30.40:9925/metrics
[Install]

View File

@ -0,0 +1,10 @@
# Configuration for sysmon-client
[extension.base_disk]
enabled = false
[extension.base_process]
enabled = true
include = [ "java", "influxd", "grafana-server" ]

View File

@ -4,10 +4,9 @@
package sysmon.client;
import org.apache.camel.main.Main;
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;
@ -17,8 +16,6 @@ import java.util.concurrent.Callable;
@CommandLine.Command(name = "sysmon-client", mixinStandardHelpOptions = true)
public class Application implements Callable<Integer> {
private static final Logger log = LoggerFactory.getLogger(Application.class);
@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;
@ -28,6 +25,9 @@ public class Application implements Callable<Integer> {
@CommandLine.Option(names = { "-p", "--plugin-dir" }, description = "Plugin jar path (default: ${DEFAULT-VALUE}).", paramLabel = "<path>", defaultValue = "/opt/sysmon/plugins")
private String pluginPath;
@CommandLine.Option(names = { "-c", "--conf" }, description = "Configuration file [default: '/etc/sysmon-client.toml'].", paramLabel = "<file>", defaultValue = "/etc/sysmon-client.toml")
private File configurationFile;
public static void main(String... args) {
int exitCode = new CommandLine(new Application()).execute(args);
System.exit(exitCode);
@ -37,6 +37,8 @@ public class Application implements Callable<Integer> {
@Override
public Integer call() throws IOException {
Configuration configuration = new Configuration();
if(hostname == null || hostname.isEmpty()) {
try {
hostname = InetAddress.getLocalHost().getHostName();
@ -51,10 +53,26 @@ public class Application implements Callable<Integer> {
pluginPath = pf4jPluginsDir;
}
String sysmonCfgFile = System.getProperty("sysmon.cfgFile");
if(sysmonCfgFile != null) {
configurationFile = new File(sysmonCfgFile);
}
if(configurationFile.exists()) {
try {
configuration.parse(configurationFile.toPath());
} catch (Exception e) {
System.err.println(e.getMessage());
return 1;
}
}
Main main = new Main();
main.bind("pluginPath", pluginPath);
main.bind("myServerUrl", serverUrl.toString());
main.bind("myHostname", hostname);
main.bind("configuration", configuration);
main.configure().addRoutesBuilder(ClientRouteBuilder.class);
// now keep the application running until the JVM is terminated (ctrl + c or sigterm)
@ -62,6 +80,7 @@ public class Application implements Callable<Integer> {
main.run();
} catch (Exception e) {
System.err.println(e.getMessage());
return 1;
}
return 0;

View File

@ -24,6 +24,7 @@ public class ClientRouteBuilder extends RouteBuilder {
public void configure() {
Registry registry = getContext().getRegistry();
Configuration configuration = (Configuration) registry.lookupByName("configuration");
Path[] pluginpaths = { Paths.get(registry.lookupByNameAndType("pluginPath", String.class)) };
PluginManager pluginManager = new JarPluginManager(pluginpaths);
@ -34,9 +35,18 @@ public class ClientRouteBuilder extends RouteBuilder {
List<MetricExtension> metricExtensions = pluginManager.getExtensions(MetricExtension.class);
for (MetricExtension ext : metricExtensions) {
if(ext.isSupported()) {
final String name = ext.getName();
final String provides = ext.getProvides();
String provides = ext.getProvides();
// Load configuration if available
if(configuration.isForExtension(name)) {
log.info(">>> Loading configuring for extension: " + ext.getDescription());
ext.setConfiguration(configuration.getForExtension(name));
}
if(ext.isSupported() && ext.isEnabled()) {
// Check that another extension has not already been loaded - TODO: Is this required ?
if(providers.contains(provides)) {
log.warn("Skipping extension (already provided): " + ext.getName());
continue;
@ -46,7 +56,7 @@ public class ClientRouteBuilder extends RouteBuilder {
providers.add(provides);
// TODO: Make timer thread configurable
// 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.
@ -62,7 +72,7 @@ public class ClientRouteBuilder extends RouteBuilder {
.otherwise()
.to("seda:metrics?discardWhenFull=true");
} else {
log.info(">>> Skipping extension (not supported here): " + ext.getDescription());
log.info(">>> Skipping extension (not supported or disabled): " + ext.getDescription());
}
}

View File

@ -0,0 +1,64 @@
package sysmon.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tomlj.Toml;
import org.tomlj.TomlParseResult;
import org.tomlj.TomlTable;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public final class Configuration {
private final static Logger log = LoggerFactory.getLogger(Configuration.class);
private TomlParseResult result;
void parse(Path configurationFile) throws IOException {
log.info("Parsing configuration file: " + configurationFile);
result = Toml.parse(configurationFile);
result.errors().forEach(error -> log.error(error.toString()));
}
boolean isForExtension(String extName) {
if(result == null) {
return false;
}
String key = String.format("extension.%s", extName);
return result.contains(key);
}
Map<String, Object> getForExtension(String extName) {
if(result == null) {
log.debug("No configuration file loaded ...");
return null;
}
Map<String, Object> map = new HashMap<>();
String key = String.format("extension.%s", extName);
TomlTable table = result.getTableOrEmpty(key);
table.keySet().forEach( k -> {
if(table.isString(k)) {
map.put(k, table.getString(k));
} else if(table.isBoolean(k)) {
map.put(k, table.getBoolean(k));
} else if(table.isDouble(k)) {
map.put(k, table.getDouble(k));
} else if(table.isArray(k)) {
map.put(k, Objects.requireNonNull(table.getArray(k)).toList());
}
});
return map;
}
}

View File

@ -10,17 +10,11 @@
}
],
"__requires": [
{
"type": "panel",
"id": "gauge",
"name": "Gauge",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "8.0.6"
"version": "8.1.2"
},
{
"type": "datasource",
@ -56,6 +50,12 @@
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
@ -65,7 +65,7 @@
"gnetId": null,
"graphTooltip": 0,
"id": null,
"iteration": 1631013505736,
"iteration": 1631256755587,
"links": [],
"panels": [
{
@ -120,7 +120,7 @@
"showHeader": true,
"sortBy": []
},
"pluginVersion": "8.0.6",
"pluginVersion": "8.1.2",
"targets": [
{
"groupBy": [
@ -286,7 +286,7 @@
"text": {},
"textMode": "auto"
},
"pluginVersion": "8.0.6",
"pluginVersion": "8.1.2",
"targets": [
{
"groupBy": [
@ -377,7 +377,7 @@
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
@ -426,6 +426,10 @@
},
"id": 26,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
@ -433,11 +437,10 @@
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true,
"text": {}
"text": {},
"textMode": "auto"
},
"pluginVersion": "8.0.6",
"pluginVersion": "8.1.2",
"targets": [
{
"groupBy": [
@ -471,10 +474,6 @@
"params": [],
"type": "sum"
},
{
"params": [],
"type": "non_negative_difference"
},
{
"params": [
"read"
@ -493,10 +492,6 @@
"params": [],
"type": "sum"
},
{
"params": [],
"type": "non_negative_difference"
},
{
"params": [
"write"
@ -529,7 +524,7 @@
"timeFrom": null,
"timeShift": null,
"title": "Disk Metrics",
"type": "gauge"
"type": "stat"
},
{
"datasource": "${DS_INFLUXDB-SYSMON}",
@ -890,7 +885,7 @@
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"sort": 5,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
@ -913,14 +908,14 @@
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"sort": 5,
"type": "query"
},
{
"allValue": "",
"allValue": null,
"current": {},
"datasource": "${DS_INFLUXDB-SYSMON}",
"definition": "SHOW TAG VALUES FROM \"base_process\" WITH KEY = \"pid\" WHERE hostname =~ /$hostname/AND \"name\" =~ /$process/ AND time > now() - 60m",
"definition": "SELECT DISTINCT(\"pid\") FROM (SELECT * FROM \"base_process\" WHERE time > now() - 60m AND \"hostname\" =~ /$hostname/ AND \"name\" =~ /$process/)",
"description": null,
"error": null,
"hide": 0,
@ -929,17 +924,17 @@
"multi": false,
"name": "pid",
"options": [],
"query": "SHOW TAG VALUES FROM \"base_process\" WITH KEY = \"pid\" WHERE hostname =~ /$hostname/AND \"name\" =~ /$process/ AND time > now() - 60m",
"refresh": 1,
"query": "SELECT DISTINCT(\"pid\") FROM (SELECT * FROM \"base_process\" WHERE time > now() - 60m AND \"hostname\" =~ /$hostname/ AND \"name\" =~ /$process/)",
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"sort": 3,
"type": "query"
}
]
},
"time": {
"from": "now-3h",
"from": "now-6h",
"to": "now-30s"
},
"timepicker": {
@ -958,5 +953,5 @@
"timezone": "",
"title": "Sysmon - Process Explorer",
"uid": "Vjut5mS7k",
"version": 11
"version": 15
}

View File

@ -1,4 +1,4 @@
version=0.0.9
version=0.0.10
pf4jVersion=3.6.0
slf4jVersion=1.7.32
camelVersion=3.11.1

View File

@ -19,6 +19,20 @@ public class AixNetstatExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(AixNetstatExtension.class);
// Extension details
private final String name = "aix_network_netstat";
private final String provides = "network_netstat";
private final String description = "AIX Netstat Metrics";
// Configuration / Options
private boolean enabled = true;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
@ -37,17 +51,24 @@ public class AixNetstatExtension implements MetricExtension {
@Override
public String getName() {
return "aix_network_netstat";
return name;
}
@Override
public String getProvides() {
return "network_netstat";
return provides;
}
@Override
public String getDescription() {
return "AIX Netstat Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
@ -63,7 +84,7 @@ public class AixNetstatExtension implements MetricExtension {
}
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}

View File

@ -8,7 +8,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class AixNetstatParser {

View File

@ -11,7 +11,6 @@ import sysmon.shared.PluginHelper;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Extension
@ -19,6 +18,20 @@ public class AixProcessorExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(AixProcessorExtension.class);
// Extension details
private final String name = "aix_processor";
private final String provides = "lpar_processor";
private final String description = "AIX Processor Metrics";
// Configuration / Options
private boolean enabled = true;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
@ -38,17 +51,24 @@ public class AixProcessorExtension implements MetricExtension {
@Override
public String getName() {
return "aix_processor";
return name;
}
@Override
public String getProvides() {
return "processor_lpar";
return provides;
}
@Override
public String getDescription() {
return "AIX Processor Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
@ -63,7 +83,7 @@ public class AixProcessorExtension implements MetricExtension {
fieldsMap = processorStat.getFields();
}
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}

View File

@ -8,8 +8,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -86,7 +85,7 @@ public class AixProcessorStat {
}
//String lparstat = lines.get(lines.size() -1);
String[] splitStr = lastLine.trim().split("\\s+");
String[] splitStr = Objects.requireNonNull(lastLine).trim().split("\\s+");
if(type.equalsIgnoreCase("shared") && splitStr.length < 9 ||
type.equalsIgnoreCase("dedicated") && splitStr.length < 8) {
throw new UnsupportedOperationException("lparstat string error: " + lastLine);

View File

@ -35,4 +35,31 @@ Metrics reported are:
- **reads** - The total number of bytes read.
- **writes** - The total number of bytes written.
- **iotime** - Time spent on IO in milliseconds.
- **queue** - Lenght of IO queue.
- **queue** - Lenght of IO queue.
## Process Extension
Reports metrics on one or more running processes.
- **mem_rss** - Resident set memory in bytes.
- **mem_vsz** - Virtual memory in bytes.
- **kernel_time** - Time spent (in milliseconds) in kernel space.
- **user_time** - Time used (in milliseconds) in user space.
- **read_bytes** - Bytes read by process.
- **write_bytes** - Bytes written by process.
- **files** - Files currently open by process.
- **threads** - Running threads.
- **user** - User running the process.
- **group** - Group running the process
- **prio** - Process priority.
### Configuration
The **include** option let's you specify what processes to report for.
```toml
[extension.base_process]
enabled = true # true or false
include = [ "java", "influxd", "grafana-server" ]
```

View File

@ -3,7 +3,6 @@ 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;
@ -19,9 +18,22 @@ public class BaseDiskExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseDiskExtension.class);
// Extension details
private final String name = "base_disk";
private final String provides = "disk";
private final String description = "Base Disk Metrics";
// Configuration / Options
private boolean enabled = true;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer();
@ -30,19 +42,25 @@ public class BaseDiskExtension implements MetricExtension {
@Override
public String getName() {
return "base_disk";
return name;
}
@Override
public String getProvides() {
return "disk";
return provides;
}
@Override
public String getDescription() {
return "Base Disk Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
public MetricResult getMetrics() {
@ -58,7 +76,7 @@ public class BaseDiskExtension implements MetricExtension {
List<HWDiskStore> diskStores = hardwareAbstractionLayer.getDiskStores();
for(HWDiskStore store : diskStores) {
String name = store.getName();
if (name.matches("hdisk[0-9]+") || name.matches("/dev/x?[sv]d[a-z]{1}") || name.matches("/dev/nvme[0-9]n[0-9]")) {
if (name.matches("hdisk[0-9]+") || name.matches("/dev/x?[sv]d[a-z]") || name.matches("/dev/nvme[0-9]n[0-9]")) {
log.debug("Using device: " + name);
writeBytes += store.getWriteBytes();
readBytes += store.getReadBytes();
@ -73,7 +91,7 @@ public class BaseDiskExtension implements MetricExtension {
fieldsMap.put("queue", queueLength);
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}
}

View File

@ -3,7 +3,6 @@ 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;
@ -17,8 +16,22 @@ public class BaseMemoryExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseMemoryExtension.class);
// Extension details
private final String name = "base_memory";
private final String provides = "memory";
private final String description = "Base Memory Metrics";
// Configuration / Options
private boolean enabled = true;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer();
@ -27,17 +40,24 @@ public class BaseMemoryExtension implements MetricExtension {
@Override
public String getName() {
return "base_memory";
return name;
}
@Override
public String getProvides() {
return "memory";
return provides;
}
@Override
public String getDescription() {
return "Base Memory Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
@ -57,7 +77,7 @@ public class BaseMemoryExtension implements MetricExtension {
fieldsMap.put("virtual", hardwareAbstractionLayer.getMemory().getVirtualMemory().getVirtualInUse());
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}

View File

@ -3,7 +3,6 @@ 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;
@ -19,8 +18,22 @@ public class BaseNetworkExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseNetworkExtension.class);
// Extension details
private final String name = "base_network";
private final String provides = "network";
private final String description = "Base Network Metrics";
// Configuration / Options
private boolean enabled = true;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer();
@ -29,17 +42,24 @@ public class BaseNetworkExtension implements MetricExtension {
@Override
public String getName() {
return "base_network";
return name;
}
@Override
public String getProvides() {
return "network";
return provides;
}
@Override
public String getDescription() {
return "Base Network Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
@ -75,7 +95,7 @@ public class BaseNetworkExtension implements MetricExtension {
fieldsMap.put("txErrors", txErrs);
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}
}

View File

@ -9,29 +9,31 @@ import sysmon.shared.Measurement;
import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.*;
@Extension
public class BaseProcessExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseProcessorExtension.class);
// TODO: configurable include-list and/or exclude-list of process names
private final List<String> includeList = new ArrayList<String>() {{
// Extension details
private final String name = "base_process";
private final String provides = "process";
private final String description = "Base Process Metrics";
// Configuration / Options
private boolean enabled = true;
private List<?> includeList = new ArrayList<Object>() {{
add("java");
add("nginx");
add("influxd");
add("dockerd");
add("containerd");
add("mysqld");
add("postgres");
add("grafana-server");
}};
private SystemInfo systemInfo;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
systemInfo = BasePlugin.getSystemInfo();
@ -40,19 +42,29 @@ public class BaseProcessExtension implements MetricExtension {
@Override
public String getName() {
return "base_process";
return name;
}
@Override
public String getProvides() {
return "process";
return provides;
}
@Override
public String getDescription() {
return "Base Process Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if(map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
if(map.containsKey("include")) {
includeList = (List<?>) map.get("include");
}
log.info(includeList.toString());
}
@Override
public MetricResult getMetrics() {
@ -71,7 +83,7 @@ public class BaseProcessExtension implements MetricExtension {
if(!includeList.contains(name)) {
continue;
}
log.debug("pid: " + p.getProcessID() + ", name: " + name + ", virt: " + p.getVirtualSize() + " rss: " + p.getResidentSetSize() + " cmd: " + p.getCommandLine());
log.debug("pid: " + p.getProcessID() + ", name: " + name + ", virt: " + p.getVirtualSize() + " rss: " + p.getResidentSetSize());
HashMap<String, String> tagsMap = new HashMap<>();
HashMap<String, Object> fieldsMap = new HashMap<>();
@ -95,7 +107,7 @@ public class BaseProcessExtension implements MetricExtension {
}
//log.info("Size of measurements: " + measurementList.size());
return new MetricResult(getName(), measurementList);
return new MetricResult(name, measurementList);
}
}

View File

@ -3,20 +3,13 @@ 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
@ -24,9 +17,22 @@ public class BaseProcessorExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseProcessorExtension.class);
// Extension details
private final String name = "base_processor";
private final String provides = "processor";
private final String description = "Base Processor Metrics";
// Configuration / Options
private boolean enabled = true;
private HardwareAbstractionLayer hardwareAbstractionLayer;
private long[] oldTicks;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
hardwareAbstractionLayer = BasePlugin.getHardwareAbstractionLayer();
@ -35,19 +41,25 @@ public class BaseProcessorExtension implements MetricExtension {
@Override
public String getName() {
return "base_processor";
return name;
}
@Override
public String getProvides() {
return "processor";
return provides;
}
@Override
public String getDescription() {
return "Base Processor Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
public MetricResult getMetrics() {
@ -86,7 +98,7 @@ public class BaseProcessorExtension implements MetricExtension {
oldTicks = ticks;
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}
}

View File

@ -8,6 +8,7 @@ import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import java.io.IOException;
import java.util.Map;
// Disable for now...
//@Extension
@ -15,9 +16,23 @@ public class TestExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(TestExtension.class);
// Extension details
private final String name = "ibmi_test";
private final String provides = "ibmi_test";
private final String description = "IBM i Test Metrics";
// Configuration / Options
private boolean enabled = true;
private AS400 as400;
private SystemStatus systemStatus;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
@ -47,17 +62,24 @@ public class TestExtension implements MetricExtension {
@Override
public String getName() {
return "ibmi-test";
return name;
}
@Override
public String getProvides() {
return "test";
return provides;
}
@Override
public String getDescription() {
return "IBM i Test Extension";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override

View File

@ -19,6 +19,20 @@ public class LinuxNetstatExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(LinuxNetstatExtension.class);
// Extension details
private final String name = "linux_network_netstat";
private final String provides = "network_netstat";
private final String description = "Linux Netstat Metrics";
// Configuration / Options
private boolean enabled = true;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
@ -37,17 +51,24 @@ public class LinuxNetstatExtension implements MetricExtension {
@Override
public String getName() {
return "linux_network_netstat";
return name;
}
@Override
public String getProvides() {
return "network_netstat";
return provides;
}
@Override
public String getDescription() {
return "Linux Netstat Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
@ -63,7 +84,7 @@ public class LinuxNetstatExtension implements MetricExtension {
}
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}

View File

@ -8,7 +8,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class LinuxNetstatParser {

View File

@ -5,7 +5,6 @@ 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;

View File

@ -17,6 +17,20 @@ public class LinuxSockstatExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(LinuxSockstatExtension.class);
// Extension details
private final String name = "linux_network_sockets";
private final String provides = "network_sockets";
private final String description = "Linux Network Socket Metrics";
// Configuration / Options
private boolean enabled = true;
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public boolean isSupported() {
@ -30,17 +44,24 @@ public class LinuxSockstatExtension implements MetricExtension {
@Override
public String getName() {
return "linux_network_sockets";
return name;
}
@Override
public String getProvides() {
return "network_sockets";
return provides;
}
@Override
public String getDescription() {
return "Linux Network Socket Metrics";
return description;
}
@Override
public void setConfiguration(Map<String, Object> map) {
if (map.containsKey("enabled")) {
enabled = (boolean) map.get("enabled");
}
}
@Override
@ -52,7 +73,7 @@ public class LinuxSockstatExtension implements MetricExtension {
HashMap<String, Object> fieldsMap = sockStat.getFields();
log.debug(fieldsMap.toString());
return new MetricResult(getName(), new Measurement(tagsMap, fieldsMap));
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
}

View File

@ -28,7 +28,7 @@ def projectName = "sysmon-server"
application {
// Define the main class for the application.
mainClass.set('sysmon.server.Application')
applicationDefaultJvmArgs = [ "-server", "-XX:+UseG1GC", "-Xmx128m" ]
applicationDefaultJvmArgs = [ "-server", "-Xms64m", "-Xmx128m", "-XX:+UseG1GC" ]
}
tasks.named('test') {

View File

@ -2,8 +2,10 @@
Description=Sysmon Server Service
[Service]
TimeoutStartSec=0
Restart=always
#User=nobody
#Group=nobody
TimeoutSec=20
Restart=on-failure
ExecStart=/opt/sysmon/server/bin/server
[Install]

View File

@ -2,9 +2,7 @@ package sysmon.server;
import org.apache.camel.main.Main;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBException;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Query;
import picocli.CommandLine;
import java.io.IOException;

View File

@ -2,8 +2,6 @@ package sysmon.server;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.influxdb.InfluxDbConstants;
import org.apache.camel.component.jackson.JacksonDataFormat;
import org.apache.camel.model.rest.RestBindingMode;
import org.apache.camel.spi.Registry;
import sysmon.shared.MetricResult;
@ -39,7 +37,7 @@ public class ServerRouteBuilder extends RouteBuilder {
.route()
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(202))
.setHeader("Content-Type", constant("application/x-www-form-urlencoded"))
.to("seda:inbound")
.to("seda:inbound?discardWhenFull=true")
.endRest();
fromF("seda:inbound?concurrentConsumers=%s", threads)

View File

@ -2,14 +2,18 @@ package sysmon.shared;
import org.pf4j.ExtensionPoint;
import java.util.Map;
public interface MetricExtension extends ExtensionPoint {
boolean isEnabled();
boolean isSupported();
String getName();
String getProvides();
String getDescription();
void setConfiguration(Map<String, Object> map);
MetricResult getMetrics() throws Exception;
}

View File

@ -3,7 +3,6 @@ package sysmon.shared;
import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MetricResult implements Serializable {