Work on support for groovy scripts.
This commit is contained in:
parent
b07e949fb2
commit
31b494163d
|
@ -2,6 +2,9 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.1.1] - 2022-12-xx
|
||||
- Simplify plugin naming
|
||||
|
||||
## [1.1.0] - 2022-12-17
|
||||
- Lower influx time precision from milliseconds to seconds
|
||||
- requires you to update server and clients to this version.
|
||||
|
|
|
@ -23,6 +23,9 @@ dependencies {
|
|||
exclude(group: "org.slf4j")
|
||||
}
|
||||
|
||||
//implementation "org.apache.groovy:groovy-all:${groovyVersion}" // From version 4.+
|
||||
implementation "org.codehaus.groovy:groovy:${groovyVersion}"
|
||||
|
||||
implementation group: 'org.apache.camel', name: 'camel-core', version: camelVersion
|
||||
implementation group: 'org.apache.camel', name: 'camel-main', version: camelVersion
|
||||
implementation group: 'org.apache.camel', name: 'camel-http', version: camelVersion
|
||||
|
|
3
client/doc/scripts/README.md
Normal file
3
client/doc/scripts/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Example Scripts
|
||||
|
||||
TODO.
|
20
client/doc/scripts/example.groovy
Normal file
20
client/doc/scripts/example.groovy
Normal file
|
@ -0,0 +1,20 @@
|
|||
import sysmon.shared.MetricResult
|
||||
import sysmon.shared.MetricScript
|
||||
import sysmon.shared.Measurement
|
||||
|
||||
class ExampleScript implements MetricScript {
|
||||
|
||||
@Override
|
||||
MetricResult getMetrics() {
|
||||
Map<String,String> tags = new TreeMap<>();
|
||||
Map<String,Object> fields = new TreeMap<>();
|
||||
|
||||
tags.put("location", "blabla");
|
||||
fields.put("temp1", 23);
|
||||
fields.put("temp2", 25);
|
||||
|
||||
Measurement measurement = new Measurement(tags, fields);
|
||||
return new MetricResult("script_example", measurement);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,9 @@
|
|||
### Example configuration with some default values.
|
||||
###
|
||||
|
||||
# Local path for Groovy scripts
|
||||
scripts = "/opt/sysmon/scripts"
|
||||
|
||||
[extension.base_info]
|
||||
enabled = true
|
||||
interval = '60m'
|
||||
|
|
|
@ -14,15 +14,25 @@ import sysmon.shared.ComboResult;
|
|||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
|
||||
import javax.script.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ClientRouteBuilder extends RouteBuilder {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ClientRouteBuilder.class);
|
||||
|
||||
private final Set<String> scriptFiles = new HashSet<>();
|
||||
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
|
||||
|
@ -34,12 +44,9 @@ public class ClientRouteBuilder extends RouteBuilder {
|
|||
pluginManager.loadPlugins();
|
||||
pluginManager.startPlugins();
|
||||
|
||||
List<String> providers = new ArrayList<>();
|
||||
List<MetricExtension> metricExtensions = pluginManager.getExtensions(MetricExtension.class);
|
||||
for (MetricExtension ext : metricExtensions) {
|
||||
|
||||
final String name = ext.getName();
|
||||
final String provides = ext.getProvides();
|
||||
|
||||
// Load configuration if available
|
||||
if(configuration.isForExtension(name)) {
|
||||
|
@ -48,33 +55,10 @@ public class ClientRouteBuilder extends RouteBuilder {
|
|||
}
|
||||
|
||||
if(ext.isSupported() && ext.isEnabled()) {
|
||||
|
||||
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
|
||||
// a unique timer name gives the timer it's own thread, otherwise it's a shared thread for other timers with same name.
|
||||
String timerName = ext.isThreaded() ? ext.getProvides() : "default";
|
||||
String timerInterval = (ext.getInterval() != null) ? ext.getInterval() : "30s";
|
||||
from("timer:"+timerName+"?fixedRate=true&period="+timerInterval)
|
||||
.bean(ext, "getMetrics")
|
||||
.outputType(MetricResult.class)
|
||||
.process(new MetricEnrichProcessor(registry))
|
||||
.choice().when(exchangeProperty("skip").isEqualTo(true))
|
||||
.log(LoggingLevel.WARN,"Skipping empty measurement.")
|
||||
.stop()
|
||||
.otherwise()
|
||||
.log("${body}")
|
||||
.to("seda:metrics?discardWhenFull=true");
|
||||
addExtensionRoute(ext);
|
||||
} else {
|
||||
log.info("Skipping extension (not supported or disabled): " + ext.getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
from("seda:metrics?purgeWhenStopping=true")
|
||||
|
@ -97,7 +81,97 @@ public class ClientRouteBuilder extends RouteBuilder {
|
|||
.log(LoggingLevel.WARN,"Error: ${exception.message}.")
|
||||
.end();
|
||||
|
||||
// Find all local scripts
|
||||
String scriptsPath = configuration.getScriptPath();
|
||||
if(scriptsPath != null && Files.isDirectory(Paths.get(scriptsPath))) {
|
||||
try {
|
||||
scriptFiles.addAll(listFilesByExtension(scriptsPath, "groovy"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the local scripts
|
||||
for (String scriptFile : scriptFiles) {
|
||||
try {
|
||||
ScriptWrapper scriptWrapper = new ScriptWrapper(scriptsPath, scriptFile);
|
||||
addScriptRoute(scriptWrapper);
|
||||
} catch(Exception e) {
|
||||
log.error("configure() - script error: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void addScriptRoute(ScriptWrapper script) {
|
||||
Registry registry = getContext().getRegistry();
|
||||
|
||||
from("timer:scripts?fixedRate=true&period=30s")
|
||||
.bean(script, "run")
|
||||
.outputType(MetricResult.class)
|
||||
.process(new MetricEnrichProcessor(registry))
|
||||
.choice().when(exchangeProperty("skip").isEqualTo(true))
|
||||
.log(LoggingLevel.WARN, "Skipping empty measurement.")
|
||||
.stop()
|
||||
.otherwise()
|
||||
.log("${body}")
|
||||
.to("seda:metrics?discardWhenFull=true");
|
||||
}
|
||||
|
||||
|
||||
void addExtensionRoute(MetricExtension ext) {
|
||||
|
||||
Registry registry = getContext().getRegistry();
|
||||
|
||||
// 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.
|
||||
String timerName = ext.isThreaded() ? ext.getName() : "default";
|
||||
String timerInterval = (ext.getInterval() != null) ? ext.getInterval() : "30s";
|
||||
from("timer:" + timerName + "?fixedRate=true&period=" + timerInterval)
|
||||
.bean(ext, "getMetrics")
|
||||
.outputType(MetricResult.class)
|
||||
.process(new MetricEnrichProcessor(registry))
|
||||
.choice().when(exchangeProperty("skip").isEqualTo(true))
|
||||
.log(LoggingLevel.WARN, "Skipping empty measurement.")
|
||||
.stop()
|
||||
.otherwise()
|
||||
.log("${body}")
|
||||
.to("seda:metrics?discardWhenFull=true");
|
||||
}
|
||||
|
||||
|
||||
List<String> findScripts(String location) {
|
||||
log.info("Looking for scripts in: {}", location);
|
||||
List<String> scripts = new ArrayList<>();
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
List<ScriptEngineFactory> factoryList = manager.getEngineFactories();
|
||||
for (ScriptEngineFactory factory : factoryList) {
|
||||
log.info("findScripts() - Supporting: {}", factory.getLanguageName());
|
||||
for(String ex : factory.getExtensions()) {
|
||||
log.info("findScripts() - Extension: {}", ex);
|
||||
try {
|
||||
scripts.addAll(listFilesByExtension(location, ex));
|
||||
log.warn(scripts.toString());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return scripts;
|
||||
}
|
||||
|
||||
|
||||
Set<String> listFilesByExtension(String dir, String ext) throws IOException {
|
||||
try (Stream<Path> stream = Files.list(Paths.get(dir))) {
|
||||
return stream
|
||||
.filter(file -> !Files.isDirectory(file))
|
||||
.map(Path::getFileName)
|
||||
.map(Path::toString)
|
||||
.filter(s -> s.endsWith(ext))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,4 +65,10 @@ public final class Configuration {
|
|||
return map;
|
||||
}
|
||||
|
||||
|
||||
String getScriptPath() {
|
||||
return result.getString("scripts");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
40
client/src/main/java/sysmon/client/ScriptWrapper.java
Normal file
40
client/src/main/java/sysmon/client/ScriptWrapper.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package sysmon.client;
|
||||
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import groovy.lang.GroovyObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sysmon.shared.MetricResult;
|
||||
import sysmon.shared.MetricScript;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ScriptWrapper {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ScriptWrapper.class);
|
||||
|
||||
private final static GroovyClassLoader loader = new GroovyClassLoader();
|
||||
|
||||
private GroovyObject script;
|
||||
|
||||
public ScriptWrapper(String scriptPath, String scriptFile) {
|
||||
try {
|
||||
Class scriptClass = loader.parseClass(new File(scriptPath, scriptFile));
|
||||
script = (GroovyObject) scriptClass.newInstance();
|
||||
} catch (IOException |InstantiationException | IllegalAccessException e) {
|
||||
log.error("ScriptWrapper() - error: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MetricResult run() {
|
||||
MetricResult result = null;
|
||||
if (script != null && script instanceof MetricScript) {
|
||||
result = (MetricResult) script.invokeMethod("getMetrics", null);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -2,6 +2,5 @@
|
|||
|
||||
Collection of standard sysmon plugins for use with the client.
|
||||
|
||||
- [base](os-base/README.md) - Base OS metrics (uses [oshi](https://github.com/oshi/oshi))
|
||||
- [aix](os-aix/README.md) - AIX (and IBM Power) specific metrics
|
||||
- [linux](os-linux/README.md) - Linux specific metrics
|
||||
- [base](base/README.md) - Base OS metrics (uses [oshi](https://github.com/oshi/oshi))
|
||||
- [power](power/README.md) - IBM Power specific metrics
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pluginId=sysmon-base
|
||||
pluginClass=sysmon.plugins.os_base.BasePlugin
|
||||
pluginClass=sysmon.plugins.base.BasePlugin
|
||||
pluginDependencies=
|
||||
pluginDescription=Base OS metrics where supported.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -18,7 +18,6 @@ public class BaseDiskExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_disk";
|
||||
private final String provides = "disk";
|
||||
private final String description = "Base Disk Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -57,11 +56,6 @@ public class BaseDiskExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -19,7 +19,6 @@ public class BaseFilesystemExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_filesystem";
|
||||
private final String provides = "filesystem";
|
||||
private final String description = "Base Filesystem Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -67,11 +66,6 @@ public class BaseFilesystemExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -19,7 +19,6 @@ public class BaseInfoExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_info";
|
||||
private final String provides = "info";
|
||||
private final String description = "Base System Information";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -52,11 +51,6 @@ public class BaseInfoExtension implements MetricExtension {
|
|||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInterval() { return interval; }
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -8,7 +8,6 @@ import sysmon.shared.Measurement;
|
|||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -19,7 +18,6 @@ public class BaseLoadExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_load";
|
||||
private final String provides = "load";
|
||||
private final String description = "Base Load Average Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -55,11 +53,6 @@ public class BaseLoadExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -8,7 +8,6 @@ import sysmon.shared.Measurement;
|
|||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -19,7 +18,6 @@ public class BaseMemoryExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_memory";
|
||||
private final String provides = "memory";
|
||||
private final String description = "Base Memory Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -56,11 +54,6 @@ public class BaseMemoryExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -8,7 +8,6 @@ import sysmon.shared.Measurement;
|
|||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -19,7 +18,6 @@ public class BaseNetstatExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_netstat";
|
||||
private final String provides = "netstat";
|
||||
private final String description = "Base Netstat Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -56,11 +54,6 @@ public class BaseNetstatExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -18,7 +18,6 @@ public class BaseNetworkExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_network";
|
||||
private final String provides = "network";
|
||||
private final String description = "Base Network Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -57,11 +56,6 @@ public class BaseNetworkExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -18,7 +18,6 @@ public class BaseProcessExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_process";
|
||||
private final String provides = "process";
|
||||
private final String description = "Base Process Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -75,11 +74,6 @@ public class BaseProcessExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_base;
|
||||
package sysmon.plugins.base;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -10,7 +10,6 @@ import sysmon.shared.MetricExtension;
|
|||
import sysmon.shared.MetricResult;
|
||||
import sysmon.shared.PluginHelper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -21,7 +20,6 @@ public class BaseProcessorExtension implements MetricExtension {
|
|||
|
||||
// Extension details
|
||||
private final String name = "base_processor";
|
||||
private final String provides = "processor";
|
||||
private final String description = "Base Processor Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
|
@ -58,11 +56,6 @@ public class BaseProcessorExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
|
@ -1,6 +0,0 @@
|
|||
pluginId=sysmon-aix
|
||||
pluginClass=sysmon.plugins.os_aix.AixPlugin
|
||||
pluginVersion=0.0.1
|
||||
pluginProvider=System Monitor
|
||||
pluginDependencies=
|
||||
pluginDescription=Collects AIX OS metrics.
|
|
@ -1,18 +0,0 @@
|
|||
package sysmon.plugins.os_aix;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.pf4j.Plugin;
|
||||
import org.pf4j.PluginWrapper;
|
||||
|
||||
public class AixPlugin extends Plugin {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AixPlugin.class);
|
||||
|
||||
public AixPlugin(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# IBM i Plugin
|
||||
|
||||
This is just for testing purposes.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://sourceforge.net/projects/jt400/ and http://jt400.sourceforge.net/
|
||||
implementation group: 'net.sf.jt400', name: 'jt400', version: '11.0'
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
pluginId=sysmon-ibmi
|
||||
pluginClass=sysmon.plugins.os_ibmi.IbmIPlugin
|
||||
pluginDependencies=
|
||||
pluginDescription=Collects IBM-i OS metrics.
|
|
@ -1,97 +0,0 @@
|
|||
package sysmon.plugins.os_ibmi;
|
||||
|
||||
import com.ibm.as400.access.AS400;
|
||||
import com.ibm.as400.access.SystemStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.pf4j.Plugin;
|
||||
import org.pf4j.PluginWrapper;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class IbmIPlugin extends Plugin {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(IbmIPlugin.class);
|
||||
|
||||
private static AS400 as400;
|
||||
private static SystemStatus systemStatus;
|
||||
private static Connection connection;
|
||||
|
||||
|
||||
public IbmIPlugin(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
public static AS400 getAS400() {
|
||||
|
||||
if(as400 != null) {
|
||||
return as400;
|
||||
}
|
||||
|
||||
// Check platform
|
||||
String osArch = System.getProperty("os.arch").toLowerCase();
|
||||
String osName = System.getProperty("os.name").toLowerCase();
|
||||
if(!osArch.equals("ppc64") && !osName.equals("os/400")) {
|
||||
log.info("getAS400() - OS Arch: {}", osArch);
|
||||
log.info("getAS400() - OS Name: {}", osName);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
as400 = new AS400("localhost", "*CURRENT");
|
||||
//as400 = new AS400("localhost", "*LOCAL");
|
||||
//as400 = new AS400("10.32.64.142");
|
||||
return as400;
|
||||
} catch (Exception exception) {
|
||||
log.error("getAS400() - {}", exception.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static SystemStatus getSystemStatus() {
|
||||
|
||||
if(systemStatus != null) {
|
||||
return systemStatus;
|
||||
}
|
||||
|
||||
try {
|
||||
if (as400 == null) {
|
||||
as400 = IbmIPlugin.getAS400();
|
||||
}
|
||||
if(systemStatus == null && as400 != null) {
|
||||
systemStatus = new SystemStatus(as400);
|
||||
return systemStatus;
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
log.error("getSystemStatus() - {}", exception.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Connection getConnection() {
|
||||
|
||||
if(connection != null) {
|
||||
return connection;
|
||||
}
|
||||
|
||||
try {
|
||||
DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());
|
||||
connection = DriverManager.getConnection("jdbc:as400://localhost");
|
||||
return connection;
|
||||
} catch (SQLException exception) {
|
||||
log.error("getConnection() - {}", exception.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
package sysmon.plugins.os_ibmi;
|
||||
|
||||
import com.ibm.as400.access.*;
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sysmon.shared.Measurement;
|
||||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
//@Extension
|
||||
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 boolean threaded = false;
|
||||
private String interval = "10s";
|
||||
|
||||
private SystemStatus systemStatus;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreaded() {
|
||||
return threaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
systemStatus = IbmIPlugin.getSystemStatus();
|
||||
return systemStatus != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(Map<String, Object> map) {
|
||||
if (map.containsKey("enabled")) {
|
||||
enabled = (boolean) map.get("enabled");
|
||||
}
|
||||
if(map.containsKey("threaded")) {
|
||||
threaded = (boolean) map.get("threaded");
|
||||
}
|
||||
if(map.containsKey("interval")) {
|
||||
interval = (String) map.get("interval");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
|
||||
if(systemStatus == null) {
|
||||
log.warn("getMetrics() - no system or status");
|
||||
return null;
|
||||
}
|
||||
|
||||
/* const hSql = "select
|
||||
SERVER_NAME,
|
||||
HTTP_FUNCTION,
|
||||
SERVER_NORMAL_CONNECTIONS,
|
||||
SERVER_ACTIVE_THREADS,
|
||||
SERVER_IDLE_THREADS,
|
||||
BYTES_RECEIVED,
|
||||
BYTES_SENT,
|
||||
NONCACHE_PROCESSING_TIME,
|
||||
CACHE_PROCESSING_TIME
|
||||
from
|
||||
QSYS2.HTTP_SERVER_INFO";
|
||||
*/
|
||||
|
||||
try {
|
||||
int jobsInSystem = systemStatus.getJobsInSystem();
|
||||
log.info("Jobs In System: {}", jobsInSystem);
|
||||
|
||||
int batchJobsRunning = systemStatus.getBatchJobsRunning();
|
||||
log.info("Batch Jobs Running: {}", batchJobsRunning);
|
||||
|
||||
int activeThreads = systemStatus.getActiveThreadsInSystem();
|
||||
log.info("Active Threads: {}", activeThreads);
|
||||
|
||||
int activeJobs = systemStatus.getActiveJobsInSystem();
|
||||
log.info("Active Jobs: {}", activeJobs);
|
||||
|
||||
int onlineUsers = systemStatus.getUsersCurrentSignedOn();
|
||||
log.info("Online Users: {}", onlineUsers);
|
||||
|
||||
// The storage capacity of the system auxiliary storage pool (ASP1) in MBytes.
|
||||
long systemAsp = systemStatus.getSystemASP();
|
||||
|
||||
System.out.println("Current Processing Capacity :" + systemStatus.getCurrentProcessingCapacity());
|
||||
System.out.println("ASPUsed:" + systemStatus.getPercentSystemASPUsed());
|
||||
System.out.println("Temp Addresses Used:" + systemStatus.getPercentTemporaryAddresses());
|
||||
|
||||
|
||||
TreeMap<String, Object> fieldsMap = new TreeMap<String, Object>() {{
|
||||
put("jobs_total", jobsInSystem);
|
||||
put("jobs_running", batchJobsRunning);
|
||||
put("jobs_active", activeJobs);
|
||||
put("threads", activeThreads);
|
||||
put("users", onlineUsers);
|
||||
|
||||
}};
|
||||
return new MetricResult(name, new Measurement(new TreeMap<>(), fieldsMap));
|
||||
|
||||
} catch (AS400SecurityException | ErrorCompletingRequestException | InterruptedException | IOException | ObjectDoesNotExistException e) {
|
||||
log.error("getMetrics() {}", e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# Linux Plugins
|
||||
|
||||
## Components
|
||||
|
||||
### Network Sockets
|
||||
|
||||
Collects statistics from */proc/net/sockstats*.
|
|
@ -1,2 +0,0 @@
|
|||
plugins {
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
pluginId=sysmon-linux
|
||||
pluginClass=sysmon.plugins.os_linux.LinuxPlugin
|
||||
pluginDependencies=
|
||||
pluginDescription=Linux OS Metrics.
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
package sysmon.plugins.os_linux;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sysmon.shared.Measurement;
|
||||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
import sysmon.shared.PluginHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
// Disabled
|
||||
//@Extension
|
||||
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;
|
||||
private boolean threaded = false;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreaded() {
|
||||
return threaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
|
||||
if(!System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
log.warn("Requires Linux.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(PluginHelper.notExecutable("netstat")) {
|
||||
log.warn("Requires the 'netstat' command.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInterval() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(Map<String, Object> map) {
|
||||
if (map.containsKey("enabled")) {
|
||||
enabled = (boolean) map.get("enabled");
|
||||
}
|
||||
if(map.containsKey("threaded")) {
|
||||
threaded = (boolean) map.get("threaded");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetricResult getMetrics() throws Exception {
|
||||
|
||||
TreeMap<String, String> tagsMap;
|
||||
TreeMap<String, Object> fieldsMap;
|
||||
|
||||
try (InputStream inputStream = PluginHelper.executeCommand("netstat -s")) {
|
||||
LinuxNetstatParser parser = processCommandOutput(inputStream);
|
||||
tagsMap = parser.getTags();
|
||||
fieldsMap = parser.getFields();
|
||||
}
|
||||
|
||||
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
|
||||
}
|
||||
|
||||
|
||||
protected LinuxNetstatParser processCommandOutput(InputStream input) throws IOException {
|
||||
return new LinuxNetstatParser(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
package sysmon.plugins.os_linux;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class LinuxNetstatParser {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LinuxNetstatParser.class);
|
||||
|
||||
private long ipTotalPacketsReceived;
|
||||
private long ipForwarded;
|
||||
private long ipIncomingPacketsDiscarded;
|
||||
private long ipOutgoingPacketsDropped;
|
||||
|
||||
private long tcpConnectionsEstablished;
|
||||
private long tcpSegmentsReceived;
|
||||
private long tcpSegmentsSent;
|
||||
|
||||
private long udpPacketsReceived;
|
||||
private long udpPacketsSent;
|
||||
|
||||
|
||||
public LinuxNetstatParser(InputStream inputStream) throws IOException {
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
while (reader.ready()) {
|
||||
String line = reader.readLine();
|
||||
log.debug("LinuxNetstatParser() - Line: " + line);
|
||||
|
||||
if(line.startsWith("Ip:")) {
|
||||
parseIp(reader);
|
||||
}
|
||||
|
||||
if(line.startsWith("Tcp:")) {
|
||||
parseTcp(reader);
|
||||
}
|
||||
|
||||
if(line.startsWith("Udp:")) {
|
||||
parseUdp(reader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
|
||||
protected void parseIp(BufferedReader reader) throws IOException {
|
||||
|
||||
while (reader.ready()) {
|
||||
reader.mark(64);
|
||||
String line = reader.readLine();
|
||||
|
||||
if(!line.startsWith(" ")) {
|
||||
reader.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
line = line.trim();
|
||||
|
||||
if(line.matches("(\\d+) total packets received")) {
|
||||
ipTotalPacketsReceived = getFirstLong(line);
|
||||
}
|
||||
|
||||
if(line.matches("(\\d+) forwarded")) {
|
||||
ipForwarded = getFirstLong(line);
|
||||
}
|
||||
|
||||
if(line.matches("(\\d+) incoming packets discarded")) {
|
||||
ipIncomingPacketsDiscarded = getFirstLong(line);
|
||||
}
|
||||
|
||||
if(line.matches("(\\d+) outgoing packets dropped")) {
|
||||
ipOutgoingPacketsDropped = getFirstLong(line);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void parseTcp(BufferedReader reader) throws IOException {
|
||||
|
||||
while (reader.ready()) {
|
||||
reader.mark(64);
|
||||
String line = reader.readLine();
|
||||
|
||||
if(!line.startsWith(" ")) {
|
||||
reader.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
line = line.trim();
|
||||
|
||||
if(line.matches("(\\d+) connections established")) {
|
||||
tcpConnectionsEstablished = getFirstLong(line);
|
||||
}
|
||||
|
||||
if(line.matches("(\\d+) segments received")) {
|
||||
tcpSegmentsReceived = getFirstLong(line);
|
||||
}
|
||||
|
||||
if(line.matches("(\\d+) segments sent out")) {
|
||||
tcpSegmentsSent = getFirstLong(line);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void parseUdp(BufferedReader reader) throws IOException {
|
||||
|
||||
while (reader.ready()) {
|
||||
reader.mark(64);
|
||||
String line = reader.readLine();
|
||||
|
||||
if(!line.startsWith(" ")) {
|
||||
reader.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
line = line.trim();
|
||||
|
||||
if(line.matches("(\\d+) packets received")) {
|
||||
udpPacketsReceived = getFirstLong(line);
|
||||
}
|
||||
|
||||
if(line.matches("(\\d+) packets sent")) {
|
||||
udpPacketsSent = getFirstLong(line);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public TreeMap<String, String> getTags() {
|
||||
return new TreeMap<>();
|
||||
}
|
||||
|
||||
public TreeMap<String, Object> getFields() {
|
||||
return new TreeMap<String, Object>() {{
|
||||
put("ip_forwarded", ipForwarded);
|
||||
put("ip_received", ipTotalPacketsReceived);
|
||||
put("ip_dropped", ipOutgoingPacketsDropped);
|
||||
put("ip_discarded", ipIncomingPacketsDiscarded);
|
||||
put("tcp_connections", tcpConnectionsEstablished);
|
||||
put("tcp_pkts_recv", tcpSegmentsReceived);
|
||||
put("tcp_pkts_sent", tcpSegmentsSent);
|
||||
put("udp_pkts_recv", udpPacketsReceived);
|
||||
put("udp_pkts_sent", udpPacketsSent);
|
||||
}};
|
||||
}
|
||||
|
||||
private Long getFirstLong(String line) {
|
||||
return Long.parseLong(line.substring(0, line.indexOf(" ")));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package sysmon.plugins.os_linux;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.pf4j.Plugin;
|
||||
import org.pf4j.PluginWrapper;
|
||||
|
||||
|
||||
public class LinuxPlugin extends Plugin {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LinuxPlugin.class);
|
||||
|
||||
public LinuxPlugin(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package sysmon.plugins.os_linux;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sysmon.shared.Measurement;
|
||||
import sysmon.shared.MetricExtension;
|
||||
import sysmon.shared.MetricResult;
|
||||
import sysmon.shared.PluginHelper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Extension
|
||||
public class LinuxSocketExtension implements MetricExtension {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LinuxSocketExtension.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;
|
||||
private boolean threaded = false;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThreaded() {
|
||||
return threaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
|
||||
if(!System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
log.debug("Requires Linux.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInterval() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(Map<String, Object> map) {
|
||||
if (map.containsKey("enabled")) {
|
||||
enabled = (boolean) map.get("enabled");
|
||||
}
|
||||
if(map.containsKey("threaded")) {
|
||||
threaded = (boolean) map.get("threaded");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
|
||||
LinuxSocketStat sockStat = processSockOutput(PluginHelper.readFile("/proc/net/sockstat"));
|
||||
|
||||
TreeMap<String, String> tagsMap = sockStat.getTags();
|
||||
TreeMap<String, Object> fieldsMap = sockStat.getFields();
|
||||
|
||||
log.debug("getMetrics() - tags: {}, fields: {}", tagsMap, fieldsMap);
|
||||
return new MetricResult(name, new Measurement(tagsMap, fieldsMap));
|
||||
}
|
||||
|
||||
protected LinuxSocketStat processSockOutput(List<String> inputLines) {
|
||||
return new LinuxSocketStat(inputLines);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package sysmon.plugins.os_linux;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class LinuxSocketStat {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LinuxSocketStat.class);
|
||||
|
||||
private static final Pattern pattern1 = Pattern.compile("^sockets: used (\\d+)");
|
||||
private static final Pattern pattern2 = Pattern.compile("^TCP: inuse (\\d+) orphan (\\d+) tw (\\d+) alloc (\\d+) mem (\\d+)");
|
||||
private static final Pattern pattern3 = Pattern.compile("^UDP: inuse (\\d+) mem (\\d+)");
|
||||
|
||||
private long sockets;
|
||||
private long tcp_inuse;
|
||||
private long tcp_orphan;
|
||||
private long tcp_tw;
|
||||
private long tcp_alloc;
|
||||
private long tcp_mem;
|
||||
private long udp_inuse;
|
||||
private long udp_mem;
|
||||
|
||||
/*
|
||||
sockets: used 1238
|
||||
TCP: inuse 52 orphan 0 tw 18 alloc 55 mem 7
|
||||
UDP: inuse 11 mem 10
|
||||
UDPLITE: inuse 0
|
||||
RAW: inuse 0
|
||||
FRAG: inuse 0 memory 0
|
||||
*/
|
||||
|
||||
|
||||
LinuxSocketStat(List<String> lines) {
|
||||
|
||||
Matcher matcher;
|
||||
for(String line : lines) {
|
||||
String proto = line.substring(0, line.indexOf(':'));
|
||||
|
||||
switch (proto) {
|
||||
case "sockets":
|
||||
matcher = pattern1.matcher(line);
|
||||
if (matcher.matches() && matcher.groupCount() == 1) {
|
||||
sockets = Long.parseLong(matcher.group(1));
|
||||
}
|
||||
break;
|
||||
|
||||
case "TCP":
|
||||
matcher = pattern2.matcher(line);
|
||||
if (matcher.matches() && matcher.groupCount() == 5) {
|
||||
tcp_inuse = Long.parseLong(matcher.group(1));
|
||||
tcp_orphan = Long.parseLong(matcher.group(2));
|
||||
tcp_tw = Long.parseLong(matcher.group(3));
|
||||
tcp_alloc = Long.parseLong(matcher.group(4));
|
||||
tcp_mem = Long.parseLong(matcher.group(5));
|
||||
}
|
||||
break;
|
||||
|
||||
case "UDP":
|
||||
matcher = pattern3.matcher(line);
|
||||
if (matcher.matches() && matcher.groupCount() == 2) {
|
||||
udp_inuse = Long.parseLong(matcher.group(1));
|
||||
udp_mem = Long.parseLong(matcher.group(2));
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public TreeMap<String, String> getTags() {
|
||||
return new TreeMap<>();
|
||||
}
|
||||
|
||||
|
||||
public TreeMap<String, Object> getFields() {
|
||||
return new TreeMap<String, Object>() {{
|
||||
put("sockets", sockets);
|
||||
put("tcp_inuse", tcp_inuse);
|
||||
put("tcp_alloc", tcp_alloc);
|
||||
put("tcp_orphan", tcp_orphan);
|
||||
put("tcp_mem", tcp_mem);
|
||||
put("tcp_tw", tcp_tw);
|
||||
put("udp_inuse", udp_inuse);
|
||||
put("udp_mem", udp_mem);
|
||||
}};
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import spock.lang.Specification
|
||||
import sysmon.plugins.os_linux.LinuxNetstatParser
|
||||
|
||||
class LinuxNetstatTest extends Specification {
|
||||
|
||||
void "test netstat parsing"() {
|
||||
|
||||
setup:
|
||||
InputStream inputStream = getClass().getResourceAsStream('/netstat-linux.txt')
|
||||
|
||||
when:
|
||||
LinuxNetstatParser parser = new LinuxNetstatParser(inputStream)
|
||||
|
||||
then:
|
||||
parser.getFields().size() > 0
|
||||
parser.getFields().get('ip_received') == 109772L
|
||||
parser.getFields().get('ip_dropped') == 70L
|
||||
parser.getFields().get('ip_discarded') == 0L
|
||||
parser.getFields().get('tcp_pkts_sent') == 89891L
|
||||
parser.getFields().get('tcp_pkts_recv') == 86167L
|
||||
parser.getFields().get('udp_pkts_sent') == 10682L
|
||||
parser.getFields().get('udp_pkts_recv') == 31928L
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
import spock.lang.Specification
|
||||
import sysmon.plugins.os_linux.LinuxSocketExtension
|
||||
import sysmon.plugins.os_linux.LinuxSocketStat
|
||||
|
||||
class LinuxNetworkTest extends Specification {
|
||||
|
||||
void "test /proc/net/sockstat parsing"() {
|
||||
|
||||
setup:
|
||||
def testFile = new File(getClass().getResource('/proc_net_sockstat.txt').toURI())
|
||||
List<String> lines = testFile.readLines("UTF-8")
|
||||
|
||||
when:
|
||||
LinuxSocketExtension extension = new LinuxSocketExtension()
|
||||
LinuxSocketStat stats = extension.processSockOutput(lines)
|
||||
|
||||
then:
|
||||
stats.getFields().get("sockets") == 1238L
|
||||
stats.getFields().get("tcp_inuse") == 52L
|
||||
stats.getFields().get("tcp_orphan") == 0L
|
||||
stats.getFields().get("tcp_alloc") == 55L
|
||||
stats.getFields().get("tcp_mem") == 7l
|
||||
stats.getFields().get("tcp_tw") == 18L
|
||||
stats.getFields().get("udp_inuse") == 11L
|
||||
stats.getFields().get("udp_mem") == 10L
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
Ip:
|
||||
Forwarding: 1
|
||||
109772 total packets received
|
||||
1 with invalid addresses
|
||||
0 forwarded
|
||||
0 incoming packets discarded
|
||||
109769 incoming packets delivered
|
||||
103916 requests sent out
|
||||
70 outgoing packets dropped
|
||||
1 dropped because of missing route
|
||||
Icmp:
|
||||
52 ICMP messages received
|
||||
0 input ICMP message failed
|
||||
ICMP input histogram:
|
||||
destination unreachable: 40
|
||||
echo requests: 12
|
||||
108 ICMP messages sent
|
||||
0 ICMP messages failed
|
||||
ICMP output histogram:
|
||||
destination unreachable: 96
|
||||
echo replies: 12
|
||||
IcmpMsg:
|
||||
InType3: 40
|
||||
InType8: 12
|
||||
OutType0: 12
|
||||
OutType3: 96
|
||||
Tcp:
|
||||
3142 active connection openings
|
||||
5 passive connection openings
|
||||
2105 failed connection attempts
|
||||
193 connection resets received
|
||||
70 connections established
|
||||
86167 segments received
|
||||
89891 segments sent out
|
||||
184 segments retransmitted
|
||||
3 bad segments received
|
||||
2735 resets sent
|
||||
Udp:
|
||||
31928 packets received
|
||||
96 packets to unknown port received
|
||||
0 packet receive errors
|
||||
10682 packets sent
|
||||
0 receive buffer errors
|
||||
0 send buffer errors
|
||||
IgnoredMulti: 22
|
||||
UdpLite:
|
||||
TcpExt:
|
||||
30 packets pruned from receive queue because of socket buffer overrun
|
||||
178 TCP sockets finished time wait in fast timer
|
||||
426 delayed acks sent
|
||||
1 delayed acks further delayed because of locked socket
|
||||
Quick ack mode was activated 1059 times
|
||||
45809 packet headers predicted
|
||||
7293 acknowledgments not containing data payload received
|
||||
7659 predicted acknowledgments
|
||||
TCPSackRecovery: 3
|
||||
Detected reordering 4 times using SACK
|
||||
TCPDSACKUndo: 1
|
||||
1 congestion windows recovered without slow start after partial ack
|
||||
TCPLostRetransmit: 82
|
||||
3 timeouts after reno fast retransmit
|
||||
1 timeouts in loss state
|
||||
3 fast retransmits
|
||||
3 retransmits in slow start
|
||||
TCPTimeouts: 129
|
||||
TCPLossProbes: 69
|
||||
TCPLossProbeRecovery: 10
|
||||
TCPBacklogCoalesce: 450
|
||||
TCPDSACKOldSent: 991
|
||||
TCPDSACKOfoSent: 6
|
||||
TCPDSACKRecv: 45
|
||||
202 connections reset due to unexpected data
|
||||
147 connections reset due to early user close
|
||||
13 connections aborted due to timeout
|
||||
TCPDSACKIgnoredNoUndo: 10
|
||||
TCPSackShifted: 1
|
||||
TCPSackMerged: 1
|
||||
TCPSackShiftFallback: 9
|
||||
TCPRcvCoalesce: 5338
|
||||
TCPOFOQueue: 793
|
||||
TCPOFOMerge: 6
|
||||
TCPChallengeACK: 3
|
||||
TCPSYNChallenge: 3
|
||||
TCPSpuriousRtxHostQueues: 6
|
||||
TCPAutoCorking: 710
|
||||
TCPFromZeroWindowAdv: 1
|
||||
TCPToZeroWindowAdv: 1
|
||||
TCPWantZeroWindowAdv: 4
|
||||
TCPSynRetrans: 98
|
||||
TCPOrigDataSent: 19048
|
||||
TCPHystartTrainDetect: 3
|
||||
TCPHystartTrainCwnd: 54
|
||||
TCPHystartDelayDetect: 1
|
||||
TCPHystartDelayCwnd: 24
|
||||
TCPACKSkippedSeq: 1
|
||||
TCPKeepAlive: 2595
|
||||
TCPDelivered: 20025
|
||||
TCPAckCompressed: 260
|
||||
TcpTimeoutRehash: 116
|
||||
IpExt:
|
||||
InMcastPkts: 2257
|
||||
OutMcastPkts: 480
|
||||
InBcastPkts: 98
|
||||
OutBcastPkts: 78
|
||||
InOctets: 147193028
|
||||
OutOctets: 14723163
|
||||
InMcastOctets: 478599
|
||||
OutMcastOctets: 73462
|
||||
InBcastOctets: 10094
|
||||
OutBcastOctets: 5580
|
||||
InNoECTPkts: 177661
|
||||
MPTcpExt:
|
|
@ -1,6 +0,0 @@
|
|||
sockets: used 1238
|
||||
TCP: inuse 52 orphan 0 tw 18 alloc 55 mem 7
|
||||
UDP: inuse 11 mem 10
|
||||
UDPLITE: inuse 0
|
||||
RAW: inuse 0
|
||||
FRAG: inuse 0 memory 0
|
6
plugins/power/gradle.properties
Normal file
6
plugins/power/gradle.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
pluginId=sysmon-power
|
||||
pluginClass=sysmon.plugins.power.PowerPlugin
|
||||
pluginVersion=0.0.1
|
||||
pluginProvider=System Monitor
|
||||
pluginDependencies=
|
||||
pluginDescription=Collects IBM Power specific metrics.
|
|
@ -0,0 +1,18 @@
|
|||
package sysmon.plugins.power;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.pf4j.Plugin;
|
||||
import org.pf4j.PluginWrapper;
|
||||
|
||||
public class PowerPlugin extends Plugin {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PowerPlugin.class);
|
||||
|
||||
public PowerPlugin(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_aix;
|
||||
package sysmon.plugins.power;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -10,19 +10,17 @@ import sysmon.shared.PluginHelper;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Extension
|
||||
public class AixProcessorExtension implements MetricExtension {
|
||||
public class PowerProcessorExtension implements MetricExtension {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AixProcessorExtension.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(PowerProcessorExtension.class);
|
||||
|
||||
// Extension details
|
||||
private final String name = "aix_processor";
|
||||
private final String provides = "lpar_processor";
|
||||
private final String description = "AIX Processor Metrics";
|
||||
private final String name = "power_processor";
|
||||
private final String description = "IBM Power Processor Metrics";
|
||||
|
||||
// Configuration / Options
|
||||
private boolean enabled = true;
|
||||
|
@ -66,11 +64,6 @@ public class AixProcessorExtension implements MetricExtension {
|
|||
return interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvides() {
|
||||
return provides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
|
@ -96,7 +89,7 @@ public class AixProcessorExtension implements MetricExtension {
|
|||
TreeMap<String, Object> fieldsMap = null;
|
||||
|
||||
try (InputStream buf = PluginHelper.executeCommand("lparstat 3 1")) {
|
||||
AixProcessorStat processorStat = processCommandOutput(buf);
|
||||
PowerProcessorStat processorStat = processCommandOutput(buf);
|
||||
tagsMap = processorStat.getTags();
|
||||
fieldsMap = processorStat.getFields();
|
||||
} catch (IOException e) {
|
||||
|
@ -108,8 +101,8 @@ public class AixProcessorExtension implements MetricExtension {
|
|||
}
|
||||
|
||||
|
||||
protected AixProcessorStat processCommandOutput(InputStream input) throws IOException {
|
||||
return new AixProcessorStat(input);
|
||||
protected PowerProcessorStat processCommandOutput(InputStream input) throws IOException {
|
||||
return new PowerProcessorStat(input);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package sysmon.plugins.os_aix;
|
||||
package sysmon.plugins.power;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -8,15 +8,14 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AixProcessorStat {
|
||||
public class PowerProcessorStat {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AixProcessorStat.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(PowerProcessorStat.class);
|
||||
|
||||
// System configuration: type=Shared mode=Uncapped smt=8 lcpu=8 mem=4096MB psize=19 ent=0.50
|
||||
private static final Pattern patternAixShared = Pattern.compile("^System configuration: type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+)MB psize=(\\d+) ent=(\\d+\\.?\\d*)");
|
||||
|
@ -47,7 +46,7 @@ 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.
|
||||
|
||||
|
||||
public AixProcessorStat(InputStream inputStream) throws IOException {
|
||||
public PowerProcessorStat(InputStream inputStream) throws IOException {
|
||||
|
||||
String lastLine = null;
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
|
@ -1,8 +1,8 @@
|
|||
import sysmon.plugins.os_aix.AixProcessorExtension
|
||||
import sysmon.plugins.os_aix.AixProcessorStat
|
||||
import sysmon.plugins.power.PowerProcessorExtension
|
||||
import sysmon.plugins.power.PowerProcessorStat
|
||||
import spock.lang.Specification
|
||||
|
||||
class AixProcessorTest extends Specification {
|
||||
class PowerProcessorTest extends Specification {
|
||||
|
||||
void "test AIX lparstat shared output processing"() {
|
||||
|
||||
|
@ -10,8 +10,8 @@ class AixProcessorTest extends Specification {
|
|||
InputStream inputStream = getClass().getResourceAsStream('/lparstat-aix-shared.txt')
|
||||
|
||||
when:
|
||||
AixProcessorExtension extension = new AixProcessorExtension()
|
||||
AixProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
PowerProcessorExtension extension = new PowerProcessorExtension()
|
||||
PowerProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
|
||||
then:
|
||||
stats.getUser() == 83.7f
|
||||
|
@ -30,8 +30,8 @@ class AixProcessorTest extends Specification {
|
|||
InputStream inputStream = getClass().getResourceAsStream('/lparstat-aix-dedicated-donating.txt')
|
||||
|
||||
when:
|
||||
AixProcessorExtension extension = new AixProcessorExtension()
|
||||
AixProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
PowerProcessorExtension extension = new PowerProcessorExtension()
|
||||
PowerProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
|
||||
then:
|
||||
stats.getUser() == 0.1f
|
||||
|
@ -51,8 +51,8 @@ class AixProcessorTest extends Specification {
|
|||
InputStream inputStream = getClass().getResourceAsStream('/lparstat-aix-dedicated-capped.txt')
|
||||
|
||||
when:
|
||||
AixProcessorExtension extension = new AixProcessorExtension()
|
||||
AixProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
PowerProcessorExtension extension = new PowerProcessorExtension()
|
||||
PowerProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
|
||||
then:
|
||||
stats.getUser() == 0.0f
|
||||
|
@ -71,8 +71,8 @@ class AixProcessorTest extends Specification {
|
|||
InputStream inputStream = getClass().getResourceAsStream('/lparstat-linux.txt')
|
||||
|
||||
when:
|
||||
AixProcessorExtension extension = new AixProcessorExtension()
|
||||
AixProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
PowerProcessorExtension extension = new PowerProcessorExtension()
|
||||
PowerProcessorStat stats = extension.processCommandOutput(inputStream)
|
||||
|
||||
then:
|
||||
stats.getUser() == 0.03f
|
|
@ -12,7 +12,6 @@ public interface MetricExtension extends ExtensionPoint {
|
|||
|
||||
String getName();
|
||||
String getInterval();
|
||||
String getProvides();
|
||||
String getDescription();
|
||||
|
||||
void setConfiguration(Map<String, Object> map);
|
||||
|
|
7
shared/src/main/java/sysmon/shared/MetricScript.java
Normal file
7
shared/src/main/java/sysmon/shared/MetricScript.java
Normal file
|
@ -0,0 +1,7 @@
|
|||
package sysmon.shared;
|
||||
|
||||
public interface MetricScript {
|
||||
|
||||
MetricResult getMetrics();
|
||||
|
||||
}
|
Loading…
Reference in a new issue