Measurements simplified again, to ensure influxdb route works.
More work on AIX plugin.
This commit is contained in:
parent
ce896b479b
commit
a839304525
|
@ -9,6 +9,7 @@ plugins {
|
|||
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}"
|
||||
|
|
|
@ -4,16 +4,21 @@
|
|||
package org.sysmon.client;
|
||||
|
||||
import org.apache.camel.main.Main;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
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;
|
||||
|
||||
|
@ -31,7 +36,12 @@ public class Application implements Callable<Integer> {
|
|||
public Integer call() throws IOException {
|
||||
|
||||
if(hostname == null || hostname.isEmpty()) {
|
||||
hostname = InetAddress.getLocalHost().getHostName();
|
||||
try {
|
||||
hostname = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
log.warn(e.getMessage());
|
||||
hostname = "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
Main main = new Main();
|
||||
|
|
|
@ -27,7 +27,6 @@ public class ClientRouteBuilder extends RouteBuilder {
|
|||
pluginManager.startPlugins();
|
||||
|
||||
List<MetricExtension> metricExtensions = pluginManager.getExtensions(MetricExtension.class);
|
||||
//log.info(String.format("Found %d extensions for extension point '%s':", metricExtensions.size(), MetricExtension.class.getName()));
|
||||
for (MetricExtension ext : metricExtensions) {
|
||||
if(ext.isSupported()) {
|
||||
log.info(">>> Enabling extension: " + ext.getDescription());
|
||||
|
@ -42,7 +41,6 @@ public class ClientRouteBuilder extends RouteBuilder {
|
|||
.stop()
|
||||
.otherwise()
|
||||
.to("seda:metrics");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public class MetricEnrichProcessor implements Processor {
|
|||
MetricResult metricResult = exchange.getIn().getBody(MetricResult.class);
|
||||
|
||||
// We make sure MetricResults with no measurements are not sent further down the line
|
||||
if(metricResult == null || metricResult.getMeasurements().size() < 1) {
|
||||
if(metricResult == null || metricResult.getMeasurement() == null) {
|
||||
exchange.setProperty("skip", true);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ subprojects {
|
|||
|
||||
task customCleanUp(type:Delete) {
|
||||
delete "output"
|
||||
//delete files("${buildDir}/test/*.jar")
|
||||
}
|
||||
|
||||
tasks.clean.dependsOn(tasks.customCleanUp)
|
|
@ -24,7 +24,7 @@ public class AixDiskExtension implements MetricExtension {
|
|||
|
||||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
return null;
|
||||
return new MetricResult("disk");
|
||||
}
|
||||
|
||||
}
|
|
@ -8,7 +8,6 @@ import org.sysmon.shared.MetricExtension;
|
|||
import org.sysmon.shared.MetricResult;
|
||||
import org.sysmon.shared.PluginHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -36,39 +35,18 @@ public class AixProcessorExtension implements MetricExtension {
|
|||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
|
||||
MetricResult result = new MetricResult("processor");
|
||||
List<Measurement> measurementList = new ArrayList<>();
|
||||
List<String> vmstat = PluginHelper.executeCommand("/usr/bin/lparstat 1 1");
|
||||
AixProcessorStat processorStat = processCommandOutput(vmstat);
|
||||
|
||||
List<String> mpstat = PluginHelper.executeCommand("mpstat", "-a");
|
||||
List<AixProcessorStat> processorStats = processCommandOutput(mpstat);
|
||||
Map<String, String> tagsMap = processorStat.getTags();
|
||||
Map<String, Object> fieldsMap = processorStat.getFields();
|
||||
|
||||
for(AixProcessorStat stat : processorStats) {
|
||||
|
||||
Map<String, String> tagsMap = new HashMap<>();
|
||||
tagsMap.put("cpu", stat.getName());
|
||||
// TODO: entitlements as tag or field ?
|
||||
|
||||
Map<String, Object> fieldsMap = new HashMap<>();
|
||||
fieldsMap.put("utilization", stat.getUtilizationPercentage());
|
||||
|
||||
measurementList.add(new Measurement(tagsMap, fieldsMap));
|
||||
}
|
||||
result.addMeasurements(measurementList);
|
||||
|
||||
return result;
|
||||
return new MetricResult("processor", new Measurement(tagsMap, fieldsMap));
|
||||
}
|
||||
|
||||
|
||||
protected List<AixProcessorStat> processCommandOutput(List<String> inputLines) {
|
||||
List<AixProcessorStat> processorStatList = new ArrayList<>();
|
||||
|
||||
for(String line : inputLines) {
|
||||
if(line.matches("^\\s+[0-9]+\\s+.*")) {
|
||||
processorStatList.add(new AixProcessorStat(line));
|
||||
}
|
||||
}
|
||||
|
||||
return processorStatList;
|
||||
protected AixProcessorStat processCommandOutput(List<String> inputLines) {
|
||||
return new AixProcessorStat(inputLines);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,61 +1,127 @@
|
|||
package org.sysmon.plugins.sysmon_aix;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AixProcessorStat {
|
||||
|
||||
private final String name;
|
||||
private final Float userTime;
|
||||
private final Float systemTime;
|
||||
private final Float waitTime;
|
||||
private final Float idleTime;
|
||||
private static final Logger log = LoggerFactory.getLogger(AixProcessorStat.class);
|
||||
|
||||
AixProcessorStat(String procString) {
|
||||
private final Pattern pattern = Pattern.compile("^System configuration: type=(\\S+) mode=(\\S+) smt=(\\d+) lcpu=(\\d+) mem=(\\d+)MB psize=(\\d+) ent=(\\d+\\.?\\d*)");
|
||||
|
||||
// cpu min maj mpcs mpcr dev soft dec ph cs ics bound rq push S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd sysc us sy wa id pc %ec ilcs vlcs S3hrd S4hrd S5hrd %nsp
|
||||
String[] splitStr = procString.trim().split("\\s+");
|
||||
if(splitStr.length != 35) {
|
||||
throw new UnsupportedOperationException("AIX mpstat CPU string error: " + procString);
|
||||
private String type;
|
||||
private String mode;
|
||||
private Integer smt;
|
||||
private Integer lcpu;
|
||||
private Integer psize;
|
||||
private Float ent;
|
||||
|
||||
private final Float user; // Indicates the percentage of the entitled processing capacity used while executing at the user level (application).
|
||||
private final Float sys; // Indicates the percentage of the entitled processing capacity used while executing at the system level (kernel).
|
||||
private final Float wait; // Indicates the percentage of the entitled processing capacity unused while the partition was idle and had outstanding disk I/O request(s).
|
||||
private final Float idle; // Indicates the percentage of the entitled processing capacity unused while the partition was idle and did not have any outstanding disk I/O request.
|
||||
private final Float physc; // Indicates the number of physical processors consumed.
|
||||
private final Float entc; // Indicates the percentage of the entitled capacity consumed.
|
||||
private final Float lbusy; // Indicates the percentage of logical processor(s) utilization that occurred while executing at the user and system level.
|
||||
|
||||
|
||||
/*
|
||||
|
||||
System configuration: type=Shared mode=Uncapped smt=8 lcpu=8 mem=4096MB psize=19 ent=0.50
|
||||
|
||||
|
||||
%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;
|
||||
}
|
||||
}
|
||||
|
||||
this.name = "cpu" + splitStr[0];
|
||||
this.userTime = Float.parseFloat(splitStr[23]);
|
||||
this.systemTime = Float.parseFloat(splitStr[24]);
|
||||
this.waitTime = Float.parseFloat(splitStr[25]);
|
||||
this.idleTime = Float.parseFloat(splitStr[26]);
|
||||
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);
|
||||
}
|
||||
|
||||
this.user = Float.parseFloat(splitStr[0]);
|
||||
this.sys = Float.parseFloat(splitStr[1]);
|
||||
this.wait = Float.parseFloat(splitStr[2]);
|
||||
this.idle = Float.parseFloat(splitStr[3]);
|
||||
this.physc = Float.parseFloat(splitStr[4]);
|
||||
this.entc = Float.parseFloat(splitStr[5]);
|
||||
this.lbusy = Float.parseFloat(splitStr[6]);
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public Float getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public Float getUserTime() {
|
||||
return userTime;
|
||||
public Float getSys() {
|
||||
return sys;
|
||||
}
|
||||
|
||||
public Float getSystemTime() {
|
||||
return systemTime;
|
||||
public Float getIdle() {
|
||||
return idle;
|
||||
}
|
||||
|
||||
public Float getIdleTime() {
|
||||
return idleTime;
|
||||
public Float getWait() {
|
||||
return wait;
|
||||
}
|
||||
|
||||
public Float getWaitTime() {
|
||||
return waitTime;
|
||||
public Float getPhysc() {
|
||||
return physc;
|
||||
}
|
||||
|
||||
|
||||
public Float getCombinedWorkTime() {
|
||||
return userTime + systemTime;
|
||||
public Float getEntc() {
|
||||
return entc;
|
||||
}
|
||||
|
||||
public Float getCombinedTime() {
|
||||
return getIdleTime() + getCombinedWorkTime();
|
||||
public Float getLbusy() {
|
||||
return lbusy;
|
||||
}
|
||||
|
||||
public float getUtilizationPercentage() {
|
||||
return 100 - idleTime;
|
||||
public float getUsage() {
|
||||
return 100 - idle;
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put("mode", mode);
|
||||
tags.put("type", type);
|
||||
return tags;
|
||||
}
|
||||
|
||||
public Map<String, Object> getFields() {
|
||||
Map<String, Object> fields = new HashMap<>();
|
||||
fields.put("lcpu", lcpu);
|
||||
fields.put("ent", ent);
|
||||
fields.put("user", user);
|
||||
fields.put("sys", sys);
|
||||
fields.put("idle", idle);
|
||||
fields.put("wait", wait);
|
||||
fields.put("physc", physc);
|
||||
fields.put("entc", entc);
|
||||
fields.put("lbusy", lbusy);
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,24 +4,24 @@ import spock.lang.Specification
|
|||
|
||||
class AixProcessorTest extends Specification {
|
||||
|
||||
void "test mpstat output processing"() {
|
||||
void "test lparstat output processing"() {
|
||||
|
||||
setup:
|
||||
def testFile = new File(getClass().getResource('/mpstat1.txt').toURI())
|
||||
def testFile = new File(getClass().getResource('/lparstat.txt').toURI())
|
||||
List<String> lines = testFile.readLines("UTF-8")
|
||||
|
||||
when:
|
||||
AixProcessorExtension extension = new AixProcessorExtension()
|
||||
List<AixProcessorStat> stats = extension.processCommandOutput(lines)
|
||||
AixProcessorStat stats = extension.processCommandOutput(lines)
|
||||
|
||||
then:
|
||||
stats[0].getCombinedWorkTime() == 85.1f
|
||||
stats[0].getCombinedTime() == 100.0f
|
||||
stats[0].getSystemTime() == 18.4f
|
||||
stats[0].getUserTime() == 66.7f
|
||||
stats[0].getWaitTime() == 0.0f
|
||||
stats[0].getIdleTime() == 14.9f
|
||||
stats.getUser() == 83.7f
|
||||
stats.getSys() == 3.3f
|
||||
stats.getWait() == 0.0f
|
||||
stats.getIdle() == 13.0f
|
||||
stats.getFields().get("ent") == 0.50f
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
6
plugins/sysmon-aix/src/test/resources/lparstat.txt
Normal file
6
plugins/sysmon-aix/src/test/resources/lparstat.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
System configuration: type=Shared mode=Uncapped smt=8 lcpu=8 mem=4096MB psize=19 ent=0.50
|
||||
|
||||
%user %sys %wait %idle physc %entc lbusy vcsw phint %nsp %utcyc
|
||||
----- ----- ------ ------ ----- ----- ------ ----- ----- ----- ------
|
||||
83.7 3.3 0.0 13.0 1.00 199.6 66.4 1288 0 149 32.96
|
15
plugins/sysmon-aix/src/test/resources/mpstat-v.txt
Normal file
15
plugins/sysmon-aix/src/test/resources/mpstat-v.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
System configuration: lcpu=8 ent=0.5 mode=Uncapped
|
||||
|
||||
|
||||
vcpu lcpu us sy wa id pbusy pc VTB(ms)
|
||||
---- ---- ---- ---- ----- ----- ----- ----- -------
|
||||
0 33.51 5.62 0.11 60.77 0.00[ 39.1%] 0.00[ 0.1%] 1784440
|
||||
0 13.38 3.96 0.05 4.81 0.00[ 17.3%] 0.00[ 22.2%] -
|
||||
1 8.41 0.72 0.04 7.59 0.00[ 9.1%] 0.00[ 16.8%] -
|
||||
2 5.19 0.35 0.01 6.45 0.00[ 5.5%] 0.00[ 12.0%] -
|
||||
3 4.42 0.28 0.01 8.42 0.00[ 4.7%] 0.00[ 13.1%] -
|
||||
4 0.57 0.07 0.00 7.47 0.00[ 0.6%] 0.00[ 8.1%] -
|
||||
5 0.51 0.06 0.00 9.28 0.00[ 0.6%] 0.00[ 9.8%] -
|
||||
6 0.49 0.07 0.00 7.49 0.00[ 0.6%] 0.00[ 8.1%] -
|
||||
7 0.54 0.10 0.00 9.26 0.00[ 0.6%] 0.00[ 9.9%] -
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
System configuration: lcpu=8 ent=0.2 mode=Uncapped
|
||||
|
||||
cpu min maj mpcs mpcr dev soft dec ph cs ics bound rq push S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd sysc us sy wa id pc %ec ilcs vlcs S3hrd S4hrd S5hrd
|
||||
cpu min maj mpcs mpcr dev soft dec ph cs ics bound rq push S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd sysc us sy wa id pc %ec ilcs vlcs S3hrd S4hrd S5hrd %nsp
|
||||
0 22324631 12995 2450 1 117140 14071941 37427759 4 25044259 445796 1 3 0 0 0 99.9 0.1 0.0 0.0 0.0 0.0 77548535 66.7 18.4 0.0 14.9 0.00 0.1 237843 38774212 100.0 0.0 0.0 150
|
||||
1 275936 176 7 350 68318 1505 3604407 41 31072 25403 0 0 0 0 0 24.5 75.5 0.0 0.0 0.0 0.0 608541 0.2 0.8 0.0 99.0 0.00 0.0 916 3701367 100.0 0.0 0.0 150
|
||||
2 4713 1 0 351 58162 833 2400472 13 24152 23991 0 0 0 0 0 0.7 99.3 0.0 0.0 0.0 0.0 1445 0.0 1.0 0.0 99.0 0.00 0.0 163 2483263 100.0 0.0 0.0 150
|
||||
3 4587 2 0 351 57777 836 2400544 17 24094 23987 0 0 0 0 0 0.7 99.3 0.0 0.0 0.0 0.0 1199 0.0 0.4 0.0 99.6 0.00 0.0 167 2482920 100.0 0.0 0.0 150
|
||||
4 5 0 0 351 56903 784 2400095 16 23999 23965 0 0 0 0 0 0.0 100.0 0.0 0.0 0.0 0.0 7 0.0 1.0 0.0 99.0 0.00 0.0 153 2481522 100.0 0.0 0.0 150
|
||||
5 13 0 0 351 57171 815 2399248 12 23965 23962 0 0 0 0 0 0.0 100.0 0.0 0.0 0.0 0.0 0 0.0 0.4 0.0 99.6 0.00 0.0 145 2480922 100.0 0.0 0.0 150
|
||||
6 23529 102 0 351 56443 805 2401503 6 24217 24124 0 0 0 0 0 0.9 99.1 0.0 0.0 0.0 0.0 461 0.0 1.0 0.0 99.0 0.00 0.0 162 2482459 100.0 0.0 0.0 150
|
||||
7 1523 75 0 351 56335 783 4150673 11 24209 24040 0 0 0 0 0 1.1 98.9 0.0 0.0 0.0 0.0 471 0.0 0.9 0.0 99.1 0.00 0.0 479 4231232 100.0 0.0 0.0 150
|
||||
U - - - - - - - - - - - - - - - - - - - - - - - - 0.0 99.9 0.25 99.8 - - - - -
|
||||
ALL 22634937 13351 2457 2457 528249 14078302 57184701 120 25219967 615268 1 3 0 0 0 99.3 0.7 0.0 0.0 0.0 0.0 78160659 0.0 0.0 0.0 99.9 0.00 0.2 240028 59117897 100.0 0.0 0.0 0
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
System configuration: lcpu=8 ent=0.2 mode=Uncapped
|
||||
|
||||
cpu min maj mpcs mpcr dev soft dec ph cs ics bound rq push S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd sysc us sy wa id pc %ec ilcs vlcs S3hrd S4hrd S5hrd
|
||||
cpu min maj mpcs mpcr dev soft dec ph cs ics bound rq push S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd sysc us sy wa id pc %ec ilcs vlcs S3hrd S4hrd S5hrd %nsp
|
||||
0 22334111 14138 2450 1 117391 14078152 37441241 4 25056579 446411 1 4 0 0 0 99.9 0.1 0.0 0.0 0.0 0.0 77590574 66.7 18.4 0.0 14.9 0.00 0.1 237925 38789423 100.0 0.0 0.0 150
|
||||
1 275936 176 7 350 68538 1505 3605599 41 31080 25411 0 0 0 0 0 24.5 75.5 0.0 0.0 0.0 0.0 608541 0.2 0.8 0.0 99.0 0.00 0.0 916 3702787 100.0 0.0 0.0 150
|
||||
2 4713 1 0 351 58375 833 2401267 13 24160 23999 0 0 0 0 0 0.7 99.3 0.0 0.0 0.0 0.0 1445 0.0 1.0 0.0 99.0 0.00 0.0 163 2484279 100.0 0.0 0.0 150
|
||||
3 4587 2 0 351 57986 836 2401339 17 24102 23995 0 0 0 0 0 0.6 99.4 0.0 0.0 0.0 0.0 1199 0.0 0.4 0.0 99.6 0.00 0.0 167 2483932 100.0 0.0 0.0 150
|
||||
4 5 0 0 351 57114 786 2400891 16 24007 23973 0 0 0 0 0 0.0 100.0 0.0 0.0 0.0 0.0 7 0.0 1.0 0.0 99.0 0.00 0.0 154 2482537 100.0 0.0 0.0 150
|
||||
5 13 0 0 351 57379 815 2400045 12 23973 23970 0 0 0 0 0 0.0 100.0 0.0 0.0 0.0 0.0 0 0.0 0.4 0.0 99.6 0.00 0.0 145 2481936 100.0 0.0 0.0 150
|
||||
6 23529 102 0 351 56651 805 2402300 6 24225 24132 0 0 0 0 0 0.9 99.1 0.0 0.0 0.0 0.0 461 0.0 1.0 0.0 99.0 0.00 0.0 162 2483472 100.0 0.0 0.0 150
|
||||
7 1523 75 0 351 56544 783 4152029 11 24217 24048 0 0 0 0 0 1.1 98.9 0.0 0.0 0.0 0.0 471 0.0 0.9 0.0 99.1 0.00 0.0 479 4232805 100.0 0.0 0.0 150
|
||||
U - - - - - - - - - - - - - - - - - - - - - - - - 0.0 99.9 0.25 99.8 - - - - -
|
||||
ALL 22644417 14494 2457 2457 529978 14084515 57204711 120 25232343 615939 1 4 0 0 0 99.3 0.7 0.0 0.0 0.0 0.0 78202698 0.0 0.0 0.0 99.9 0.00 0.2 240111 59141171 100.0 0.0 0.0 0
|
7
plugins/sysmon-aix/src/test/resources/vmstat-Iwt.txt
Normal file
7
plugins/sysmon-aix/src/test/resources/vmstat-Iwt.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
System configuration: lcpu=8 mem=4096MB ent=0.50
|
||||
|
||||
kthr memory page faults cpu time
|
||||
----------- --------------------- ------------------------------------ ------------------ ----------------------- --------
|
||||
r b p avm fre fi fo pi po fr sr in sy cs us sy id wa pc ec hr mi se
|
||||
2 1 0 633739 130144 0 13 0 0 2 2 7 969 529 0 0 99 0 0.00 0.1 07:53:28
|
|
@ -47,7 +47,7 @@ public class LinuxDiskExtension implements MetricExtension {
|
|||
try {
|
||||
copyCurrentValues();
|
||||
readProcFile();
|
||||
result.addMeasurements(calculate());
|
||||
result.setMeasurement(calculate());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -77,14 +77,15 @@ public class LinuxDiskExtension implements MetricExtension {
|
|||
}
|
||||
|
||||
|
||||
private List<Measurement> calculate() {
|
||||
|
||||
List<Measurement> measurementList = new ArrayList<>();
|
||||
private Measurement calculate() {
|
||||
|
||||
if(previousDiskStats == null || previousDiskStats.size() != currentDiskStats.size()) {
|
||||
return measurementList;
|
||||
return null;
|
||||
}
|
||||
|
||||
HashMap<String, String> tagsMap = new HashMap<>();
|
||||
HashMap<String, Object> fieldsMap = new HashMap<>();
|
||||
|
||||
for(int i = 0; i < currentDiskStats.size(); i++) {
|
||||
|
||||
LinuxDiskStat curStat = currentDiskStats.get(i);
|
||||
|
@ -98,23 +99,16 @@ public class LinuxDiskExtension implements MetricExtension {
|
|||
});
|
||||
|
||||
if(!ignore.get()) {
|
||||
HashMap<String, String> tagsMap = new HashMap<>();
|
||||
tagsMap.put("device", curStat.getDevice());
|
||||
|
||||
HashMap<String, Object> fieldsMap = new HashMap<>();
|
||||
fieldsMap.put("iotime", curStat.getTimeSpentOnIo() - preStat.getTimeSpentOnIo());
|
||||
fieldsMap.put("readtime", curStat.getTimeSpentReading() - preStat.getTimeSpentReading());
|
||||
fieldsMap.put("writetime", curStat.getTimeSpentWriting() - preStat.getTimeSpentWriting());
|
||||
fieldsMap.put("reads", curStat.getSectorsRead() - preStat.getSectorsRead());
|
||||
fieldsMap.put("writes", curStat.getSectorsWritten() - preStat.getSectorsWritten());
|
||||
|
||||
measurementList.add(new Measurement(tagsMap, fieldsMap));
|
||||
|
||||
fieldsMap.put(curStat.getDevice() + "_iotime", curStat.getTimeSpentOnIo() - preStat.getTimeSpentOnIo());
|
||||
//fieldsMap.put(curStat.getDevice() + "_readtime", curStat.getTimeSpentReading() - preStat.getTimeSpentReading());
|
||||
//fieldsMap.put(curStat.getDevice() + "_writetime", curStat.getTimeSpentWriting() - preStat.getTimeSpentWriting());
|
||||
fieldsMap.put(curStat.getDevice() + "_reads", curStat.getSectorsRead() - preStat.getSectorsRead());
|
||||
fieldsMap.put(curStat.getDevice() + "_writes", curStat.getSectorsWritten() - preStat.getSectorsWritten());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return measurementList;
|
||||
return new Measurement(tagsMap, fieldsMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class LinuxMemoryExtension implements MetricExtension {
|
|||
|
||||
MetricResult result = new MetricResult("memory");
|
||||
try {
|
||||
result.addMeasurements(readProcFile());
|
||||
result.setMeasurement(readProcFile());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -51,9 +51,7 @@ public class LinuxMemoryExtension implements MetricExtension {
|
|||
}
|
||||
|
||||
|
||||
private List<Measurement> readProcFile() throws IOException {
|
||||
|
||||
List<Measurement> measurementList = new ArrayList<>();
|
||||
private Measurement readProcFile() throws IOException {
|
||||
|
||||
Map<String, String> tagsMap = new HashMap<>();
|
||||
Map<String, Object> fieldsMap = new HashMap<>();
|
||||
|
@ -73,8 +71,7 @@ public class LinuxMemoryExtension implements MetricExtension {
|
|||
|
||||
}
|
||||
|
||||
measurementList.add(new Measurement(tagsMap, fieldsMap));
|
||||
return measurementList;
|
||||
return new Measurement(tagsMap, fieldsMap);
|
||||
}
|
||||
|
||||
}
|
|
@ -44,31 +44,20 @@ public class LinuxProcessorExtension implements MetricExtension {
|
|||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
|
||||
if(currentProcessorProc != null && currentProcessorProc.size() > 0) {
|
||||
previousProcessorProc = new ArrayList<>(currentProcessorProc);
|
||||
}
|
||||
currentProcessorProc = processFileOutput(readProcFile());
|
||||
LinuxProcessorProcLine proc1 = processFileOutput(readProcFile());
|
||||
|
||||
MetricResult result = new MetricResult("processor");
|
||||
if(previousProcessorProc == null || previousProcessorProc.size() != currentProcessorProc.size()) {
|
||||
return result;
|
||||
try {
|
||||
Thread.sleep(1 * 1000); // TODO: Configure sample collect time
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("getMetrics() - sleep interrupted");
|
||||
return null;
|
||||
}
|
||||
|
||||
LinuxProcessorProcLine proc2 = processFileOutput(readProcFile());
|
||||
|
||||
List<Measurement> measurementList = new ArrayList<>();
|
||||
for(int i = 0; i < currentProcessorProc.size(); i++) {
|
||||
LinuxProcessorStat stat = new LinuxProcessorStat(currentProcessorProc.get(i), previousProcessorProc.get(i));
|
||||
LinuxProcessorStat stat = new LinuxProcessorStat(proc2, proc1);
|
||||
|
||||
Map<String, String> tagsMap = new HashMap<>();
|
||||
tagsMap.put("cpu", stat.getName());
|
||||
|
||||
Map<String, Object> fieldsMap = stat.getFields();
|
||||
|
||||
measurementList.add(new Measurement(tagsMap, fieldsMap));
|
||||
}
|
||||
|
||||
result.addMeasurements(measurementList);
|
||||
return result;
|
||||
return new MetricResult("processor", new Measurement(stat.getTags(), stat.getFields()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,16 +75,15 @@ public class LinuxProcessorExtension implements MetricExtension {
|
|||
}
|
||||
|
||||
|
||||
protected List<LinuxProcessorProcLine> processFileOutput(List<String> inputLines) {
|
||||
protected LinuxProcessorProcLine processFileOutput(List<String> inputLines) {
|
||||
|
||||
List<LinuxProcessorProcLine> processorStats = new ArrayList<>();
|
||||
for(String line : inputLines) {
|
||||
if(line.matches("^cpu\\d+.*")) {
|
||||
processorStats.add(new LinuxProcessorProcLine(line));
|
||||
if(line.matches("^cpu\\S+.*")) {
|
||||
return new LinuxProcessorProcLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
return processorStats;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,11 @@ import java.util.Map;
|
|||
public class LinuxProcessorStat {
|
||||
|
||||
private final String cpuName;
|
||||
private final float utilizationPercentage;
|
||||
//private final float user;
|
||||
//private final float sys;
|
||||
//private final float wait;
|
||||
//private final float idle;
|
||||
private final float busy;
|
||||
|
||||
public LinuxProcessorStat(LinuxProcessorProcLine current, LinuxProcessorProcLine previous) {
|
||||
cpuName = current.getCpuName();
|
||||
|
@ -15,7 +19,9 @@ public class LinuxProcessorStat {
|
|||
long idleTimeDiff = current.getCombinedIdleTime() - previous.getCombinedIdleTime();
|
||||
|
||||
float utilization = (float) (workTimeDiff - idleTimeDiff) / workTimeDiff;
|
||||
utilizationPercentage = (utilization * 100);
|
||||
busy = (utilization * 100);
|
||||
|
||||
// TODO: Calculate user, system, idle and wait diff times into percentage.
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,13 +30,18 @@ public class LinuxProcessorStat {
|
|||
}
|
||||
|
||||
|
||||
public Float getBusy() {
|
||||
return busy;
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<String, Object> getFields() {
|
||||
|
||||
HashMap<String, Object> fieldsMap = new HashMap<>();
|
||||
fieldsMap.put("utilization", utilizationPercentage);
|
||||
|
||||
return fieldsMap;
|
||||
|
||||
Map<String, Object> fields = new HashMap<>();
|
||||
fields.put("busy", busy);
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@ class LinuxProcessorTest extends Specification {
|
|||
|
||||
when:
|
||||
LinuxProcessorExtension extension = new LinuxProcessorExtension()
|
||||
List<LinuxProcessorProcLine> procLines = extension.processFileOutput(lines)
|
||||
LinuxProcessorProcLine procLine = extension.processFileOutput(lines)
|
||||
|
||||
then:
|
||||
procLines[0].getSystemTime() == 4686l
|
||||
procLines[0].getUserTime() == 27477l
|
||||
procLines[0].getIdleTime() == 281276l
|
||||
procLines[0].getIoWaitTime() == 252l
|
||||
procLine.getSystemTime() == 4686l
|
||||
procLine.getUserTime() == 27477l
|
||||
procLine.getIdleTime() == 281276l
|
||||
procLine.getIoWaitTime() == 252l
|
||||
|
||||
}
|
||||
|
||||
|
@ -29,15 +29,14 @@ class LinuxProcessorTest extends Specification {
|
|||
setup:
|
||||
def testFile1 = new File(getClass().getResource('/proc1.txt').toURI())
|
||||
def testFile2 = new File(getClass().getResource('/proc2.txt').toURI())
|
||||
LinuxProcessorProcLine processorProcLine1 = new LinuxProcessorProcLine(testFile1.readLines().get(1))
|
||||
LinuxProcessorProcLine processorProcLine2 = new LinuxProcessorProcLine(testFile2.readLines().get(1))
|
||||
LinuxProcessorProcLine processorProcLine1 = new LinuxProcessorProcLine(testFile1.readLines().get(0))
|
||||
LinuxProcessorProcLine processorProcLine2 = new LinuxProcessorProcLine(testFile2.readLines().get(0))
|
||||
|
||||
when:
|
||||
LinuxProcessorStat processorStat = new LinuxProcessorStat(processorProcLine1, processorProcLine2)
|
||||
|
||||
then:
|
||||
processorStat.getName() == "cpu0"
|
||||
processorStat.getFields().get("utilization") == 42.13362f
|
||||
processorStat.getBusy() == 38.001614f
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ plugins {
|
|||
|
||||
id "com.github.johnrengelman.shadow" version "6.1.0"
|
||||
id "net.nemerosa.versioning" version "2.14.0"
|
||||
id "nebula.ospackage" version "8.4.1"
|
||||
id "nebula.ospackage" version "8.5.6"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -64,10 +64,15 @@ buildRpm {
|
|||
os = "LINUX"
|
||||
}
|
||||
|
||||
|
||||
buildDeb {
|
||||
dependsOn startShadowScripts
|
||||
}
|
||||
|
||||
task aixRpm(type: Rpm) {
|
||||
os "AIX"
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes(
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.sysmon.server;
|
|||
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
import org.influxdb.dto.BatchPoints;
|
||||
import org.influxdb.dto.Point;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -20,37 +21,32 @@ public class MetricResultToPointProcessor implements Processor {
|
|||
public void process(Exchange exchange) throws Exception {
|
||||
|
||||
MetricResult metricResult = exchange.getIn().getBody(MetricResult.class);
|
||||
Measurement measurement = metricResult.getMeasurement();
|
||||
|
||||
Point.Builder builder = Point.measurement(metricResult.getName())
|
||||
.time(metricResult.getTimestamp(), TimeUnit.MILLISECONDS)
|
||||
.tag("hostname", metricResult.getHostname());
|
||||
|
||||
List<Measurement> measurements = metricResult.getMeasurements();
|
||||
for(Measurement measurement : measurements) {
|
||||
|
||||
for (Map.Entry<String,String> entry : measurement.getTags().entrySet()) {
|
||||
log.debug("process() - tag: " + entry.getKey() + "=" + entry.getValue());
|
||||
builder.tag(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
|
||||
for (Map.Entry<String,Object> entry : measurement.getFields().entrySet()) {
|
||||
log.debug("process() - field: " + entry.getKey() + "=" + entry.getValue());
|
||||
if(entry.getValue() instanceof Number) {
|
||||
Number num = (Number) entry.getValue();
|
||||
builder.addField(entry.getKey(), num);
|
||||
} else if(entry.getValue() instanceof Boolean) {
|
||||
Boolean bol = (Boolean) entry.getValue();
|
||||
builder.addField(entry.getKey(), bol);
|
||||
} else {
|
||||
String str = (String) entry.getValue();
|
||||
builder.addField(entry.getKey(), str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (Map.Entry<String,String> entry : measurement.getTags().entrySet()) {
|
||||
log.debug("process() - tag: " + entry.getKey() + "=" + entry.getValue());
|
||||
builder.tag(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
for (Map.Entry<String,Object> entry : measurement.getFields().entrySet()) {
|
||||
log.debug("process() - field: " + entry.getKey() + "=" + entry.getValue());
|
||||
if(entry.getValue() instanceof Number) {
|
||||
Number num = (Number) entry.getValue();
|
||||
builder.addField(entry.getKey(), num);
|
||||
} else if(entry.getValue() instanceof Boolean) {
|
||||
Boolean bol = (Boolean) entry.getValue();
|
||||
builder.addField(entry.getKey(), bol);
|
||||
} else {
|
||||
String str = (String) entry.getValue();
|
||||
builder.addField(entry.getKey(), str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exchange.getIn().setBody(builder.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,9 @@ public class ServerRouteBuilder extends RouteBuilder {
|
|||
//from("seda:inbound").log("Got metric from: ${header.component}").to("mock:sink");
|
||||
|
||||
from("seda:inbound")
|
||||
.log(">>> metric: ${header.hostname} - ${header.metric}")
|
||||
.log(">>> metric: ${header.hostname} - ${body}")
|
||||
.doTry()
|
||||
.process(new MetricResultToPointProcessor())
|
||||
.log("${body}")
|
||||
.to("influxdb://myInfluxConnection?databaseName=sysmon&retentionPolicy=autogen")
|
||||
.doCatch(Exception.class)
|
||||
.log("Error storing metric to InfluxDB: ${exception}")
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.sysmon.shared;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Measurement {
|
||||
|
||||
|
@ -13,8 +14,8 @@ public class Measurement {
|
|||
}
|
||||
|
||||
public Measurement(Map<String, String> tags, Map<String, Object> fields) {
|
||||
this.tags = tags;
|
||||
this.fields = fields;
|
||||
this.tags = Objects.requireNonNull(tags);
|
||||
this.fields = Objects.requireNonNull(fields);
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
|
@ -26,10 +27,12 @@ public class Measurement {
|
|||
}
|
||||
|
||||
public void setTags(Map<String, String> tags) {
|
||||
Objects.requireNonNull(tags);
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public void setFields(Map<String, Object> fields) {
|
||||
Objects.requireNonNull(fields);
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ package org.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 {
|
||||
|
@ -11,9 +9,9 @@ public class MetricResult implements Serializable {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String name;
|
||||
private Long timestamp; // epoch milli
|
||||
private String hostname;
|
||||
private List<Measurement> measurements = new ArrayList<>();
|
||||
private Long timestamp; // epoch milli
|
||||
private Measurement measurement;
|
||||
|
||||
public MetricResult() {
|
||||
}
|
||||
|
@ -23,12 +21,14 @@ public class MetricResult implements Serializable {
|
|||
this.timestamp = Instant.now().toEpochMilli();
|
||||
}
|
||||
|
||||
public void addMeasurements(List<Measurement> measurementList) {
|
||||
this.measurements = measurementList;
|
||||
public MetricResult(String name, Measurement measurement) {
|
||||
this.name = name;
|
||||
this.timestamp = Instant.now().toEpochMilli();
|
||||
this.measurement = measurement;
|
||||
}
|
||||
|
||||
public void addMeasurement(Measurement measurement) {
|
||||
measurements.add(measurement);
|
||||
public void setMeasurement(Measurement measurement) {
|
||||
this.measurement = measurement;
|
||||
}
|
||||
|
||||
public void setHostname(String hostname) {
|
||||
|
@ -55,24 +55,24 @@ public class MetricResult implements Serializable {
|
|||
return hostname;
|
||||
}
|
||||
|
||||
public List<Measurement> getMeasurements() {
|
||||
return measurements;
|
||||
public Measurement getMeasurement() {
|
||||
return measurement;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(String.format("%s - %s\n", timestamp.toString(), name));
|
||||
for(Measurement m : measurements) {
|
||||
StringBuilder sb = new StringBuilder(String.format("%s - %s {", timestamp.toString(), name));
|
||||
|
||||
for (Map.Entry<String,String> entry : m.getTags().entrySet())
|
||||
sb.append(entry.getKey() + " : " + entry.getValue());
|
||||
|
||||
for (Map.Entry<String,Object> entry : m.getFields().entrySet())
|
||||
sb.append(entry.getKey() + " : " + entry.getValue());
|
||||
|
||||
sb.append(m.toString()).append("\n");
|
||||
if(measurement != null && measurement.getTags() != null) {
|
||||
for (Map.Entry<String, String> entry : measurement.getTags().entrySet())
|
||||
sb.append(" [").append(entry.getKey()).append(": ").append(entry.getValue()).append("]");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
if(measurement != null && measurement.getFields() != null) {
|
||||
for (Map.Entry<String,Object> entry : measurement.getFields().entrySet())
|
||||
sb.append(" [").append(entry.getKey()).append(": ").append(entry.getValue()).append("]");
|
||||
}
|
||||
|
||||
return sb.append(" }").toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package org.sysmon.shared;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -9,6 +12,8 @@ import java.util.List;
|
|||
|
||||
public class PluginHelper {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PluginHelper.class);
|
||||
|
||||
final static boolean isWindows = System.getProperty("os.name")
|
||||
.toLowerCase().startsWith("windows");
|
||||
|
||||
|
@ -29,11 +34,9 @@ public class PluginHelper {
|
|||
}
|
||||
|
||||
builder.directory(new File(System.getProperty("user.home")));
|
||||
|
||||
try {
|
||||
|
||||
Process process = builder.start();
|
||||
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
|
@ -43,7 +46,9 @@ public class PluginHelper {
|
|||
}
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
System.out.println("\nExited with error code : " + exitCode);
|
||||
if(exitCode > 0) {
|
||||
log.warn("executeCommand() - exit code: " + exitCode);
|
||||
}
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
|
Loading…
Reference in a new issue