More work on plugins and added some tests.
This commit is contained in:
parent
afbf506749
commit
15cf1963b7
9
agent/src/test/groovy/org/sysmon/agent/AppTest.groovy
Normal file
9
agent/src/test/groovy/org/sysmon/agent/AppTest.groovy
Normal file
|
@ -0,0 +1,9 @@
|
|||
package org.sysmon.agent
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class AppTest extends Specification {
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
/*
|
||||
* This Spock specification was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package org.sysmon.test
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class AppTest extends Specification {
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,5 +1,21 @@
|
|||
subprojects {
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'groovy'
|
||||
|
||||
dependencies {
|
||||
|
||||
testImplementation 'org.spockframework:spock-core:2.0-M4-groovy-3.0'
|
||||
testImplementation "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||
testImplementation project(':shared')
|
||||
|
||||
implementation project(':shared')
|
||||
implementation(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
|
||||
exclude(group: "org.slf4j")
|
||||
}
|
||||
annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
|
||||
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
|
@ -22,6 +38,13 @@ subprojects {
|
|||
copyJar
|
||||
}
|
||||
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
task customCleanUp(type:Delete) {
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
dependencies {
|
||||
// compileOnly important!!! We do not want to put the api into the zip file since the main program has it already!
|
||||
implementation project(':shared')
|
||||
implementation(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
|
||||
exclude(group: "org.slf4j")
|
||||
}
|
||||
annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
|
||||
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||
|
||||
}
|
|
@ -1,12 +1,21 @@
|
|||
package org.sysmon.plugins.sysmon_aix;
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sysmon.shared.MetricExtension;
|
||||
import org.sysmon.shared.MetricMeasurement;
|
||||
import org.sysmon.shared.MetricResult;
|
||||
import org.sysmon.shared.PluginHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Extension
|
||||
public class AixProcessorExtension implements MetricExtension {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AixProcessorExtension.class);
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return System.getProperty("os.name").toLowerCase().contains("aix");
|
||||
|
@ -19,59 +28,30 @@ public class AixProcessorExtension implements MetricExtension {
|
|||
|
||||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
return null;
|
||||
|
||||
MetricResult result = new MetricResult("processor");
|
||||
|
||||
List<String> mpstat = PluginHelper.executeCommand("mpstat", "-a");
|
||||
List<AixProcessorStat> processorStats = processCommandOutput(mpstat);
|
||||
for(AixProcessorStat stat : processorStats) {
|
||||
result.addMetricMeasurement(new MetricMeasurement(String.format("cpu%d", stat.getCpuNum()), stat.getUtilizationPercentage()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
# mpstat -v
|
||||
|
||||
System configuration: lcpu=8 ent=0.5 mode=Uncapped
|
||||
|
||||
|
||||
vcpu lcpu us sy wa id pbusy pc VTB(ms)
|
||||
---- ---- ---- ---- ----- ----- ----- ----- -------
|
||||
0 12.26 10.89 0.11 76.74 0.00[ 23.1%] 0.00[ 0.0%] 121967
|
||||
0 10.58 8.53 0.04 5.71 0.00[ 19.1%] 0.00[ 24.9%] -
|
||||
1 1.32 1.21 0.05 11.16 0.00[ 2.5%] 0.00[ 13.7%] -
|
||||
2 0.22 0.28 0.01 8.24 0.00[ 0.5%] 0.00[ 8.8%] -
|
||||
3 0.11 0.19 0.01 11.63 0.00[ 0.3%] 0.00[ 11.9%] -
|
||||
4 0.01 0.10 0.00 8.34 0.00[ 0.1%] 0.00[ 8.5%] -
|
||||
5 0.00 0.07 0.00 11.69 0.00[ 0.1%] 0.00[ 11.8%] -
|
||||
6 0.00 0.13 0.00 8.33 0.00[ 0.1%] 0.00[ 8.5%] -
|
||||
7 0.01 0.37 0.00 11.63 0.00[ 0.4%] 0.00[ 12.0%] -
|
||||
|
||||
|
||||
|
||||
|
||||
# mpstat
|
||||
|
||||
System configuration: lcpu=8 ent=0.5 mode=Uncapped
|
||||
|
||||
cpu min maj mpc int cs ics rq mig lpa sysc us sy wa id pc %ec lcs
|
||||
0 1489677 9337 2633 2146943 1160666 30547 3 2951 100 8361624 43 35 0 23 0.00 0.0 1646908
|
||||
1 336156 2711 383 266244 25376 5494 0 3401 100 1042507 10 9 0 80 0.00 0.0 230605
|
||||
2 45820 829 377 116004 5984 2326 0 1889 100 474631 3 3 0 94 0.00 0.0 117923
|
||||
3 46812 699 377 115297 6217 2306 0 1746 100 58549 1 2 0 97 0.00 0.0 117011
|
||||
4 2786 39 377 112634 1485 1124 0 1143 100 7432 0 1 0 99 0.00 0.0 114271
|
||||
5 1233 45 377 112032 1369 1111 0 1147 100 7591 0 1 0 99 0.00 0.0 113674
|
||||
6 25415 238 377 112763 1519 1235 0 1126 100 2403 0 2 0 98 0.00 0.0 114479
|
||||
7 3596 124 377 193193 1615 1181 0 1123 100 2572 0 3 0 97 0.00 0.0 195104
|
||||
U - - - - - - - - - - - - 0 100 0.50 100.0 -
|
||||
ALL 1951495 14022 5278 3175110 1204231 45324 3 14526 100 9957309 0 0 0 100 0.00 0.0 2649975
|
||||
|
||||
|
||||
%ec
|
||||
(Default, -a flag) The percentage of entitled capacity consumed by the logical processor.
|
||||
The %ec of the ALL CPU row represents the percentage of entitled capacity consumed.
|
||||
Because the time base over which this data is computed can vary, the entitled capacity
|
||||
percentage can sometimes exceed 100%. This excess is noticeable only with small sampling intervals.
|
||||
The attribute is displayed only in a shared partition.
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package org.sysmon.plugins.sysmon_aix;
|
||||
|
||||
public class AixProcessorStat {
|
||||
|
||||
private final Integer cpuNum;
|
||||
private final Float userTime;
|
||||
private final Float systemTime;
|
||||
private final Float waitTime;
|
||||
private final Float idleTime;
|
||||
|
||||
AixProcessorStat(String procString) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
this.cpuNum = Integer.parseInt(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]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Integer getCpuNum() {
|
||||
return cpuNum;
|
||||
}
|
||||
|
||||
public Float getUserTime() {
|
||||
return userTime;
|
||||
}
|
||||
|
||||
public Float getSystemTime() {
|
||||
return systemTime;
|
||||
}
|
||||
|
||||
public Float getIdleTime() {
|
||||
return idleTime;
|
||||
}
|
||||
|
||||
public Float getWaitTime() {
|
||||
return waitTime;
|
||||
}
|
||||
|
||||
|
||||
public Float getCombinedWorkTime() {
|
||||
return userTime + systemTime;
|
||||
}
|
||||
|
||||
public Float getCombinedTime() {
|
||||
return getIdleTime() + getCombinedWorkTime();
|
||||
}
|
||||
|
||||
public float getUtilizationPercentage() {
|
||||
return 100 - idleTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
dependencies {
|
||||
// compileOnly important!!! We do not want to put the api into the zip file since the main program has it already!
|
||||
implementation project(':shared')
|
||||
implementation(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}") {
|
||||
exclude(group: "org.slf4j")
|
||||
}
|
||||
annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
|
||||
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||
|
||||
}
|
|
@ -35,7 +35,7 @@ public class LinuxDiskExtension implements MetricExtension {
|
|||
try {
|
||||
copyCurrentValues();
|
||||
readProcFile();
|
||||
result.setMeasurementList(calculate());
|
||||
result.setMetricMeasurementList(calculate());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class LinuxMemoryExtension implements MetricExtension {
|
|||
|
||||
MetricResult result = new MetricResult("memory");
|
||||
try {
|
||||
result.setMeasurementList(readProcFile());
|
||||
result.setMetricMeasurementList(readProcFile());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package org.sysmon.plugins.sysmon_linux;
|
|||
|
||||
|
||||
import org.pf4j.Extension;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sysmon.shared.MetricExtension;
|
||||
import org.sysmon.shared.MetricMeasurement;
|
||||
import org.sysmon.shared.MetricResult;
|
||||
|
@ -16,58 +18,40 @@ import java.util.List;
|
|||
@Extension
|
||||
public class LinuxProcessorExtension implements MetricExtension {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LinuxProcessorExtension.class);
|
||||
|
||||
private List<LinuxProcessorStat> currentProcessorStats;
|
||||
private List<LinuxProcessorStat> previousProcessorStats;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return System.getProperty("os.name").toLowerCase().contains("linux");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getGreeting() {
|
||||
return "Welcome from Linux ProcessorMetric";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MetricResult getMetrics() {
|
||||
|
||||
MetricResult result = new MetricResult("processor");
|
||||
try {
|
||||
copyCurrentValues();
|
||||
readProcFile();
|
||||
result.setMeasurementList(calculate());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private void readProcFile() throws IOException {
|
||||
|
||||
currentProcessorStats = new ArrayList<>();
|
||||
List<String> allLines = Files.readAllLines(Paths.get("/proc/stat"), StandardCharsets.UTF_8);
|
||||
for(String line : allLines) {
|
||||
if(line.startsWith("cpu")) {
|
||||
currentProcessorStats.add(new LinuxProcessorStat(line));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void copyCurrentValues() {
|
||||
|
||||
if(currentProcessorStats != null && currentProcessorStats.size() > 0) {
|
||||
previousProcessorStats = new ArrayList<>(currentProcessorStats);
|
||||
}
|
||||
|
||||
MetricResult result = new MetricResult("processor");
|
||||
currentProcessorStats = processFileOutput(readProcFile());
|
||||
result.setMetricMeasurementList(calculateDifference());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<MetricMeasurement> calculate() {
|
||||
private List<MetricMeasurement> calculateDifference() {
|
||||
|
||||
List<MetricMeasurement> measurementList = new ArrayList<>();
|
||||
|
||||
|
@ -92,6 +76,34 @@ public class LinuxProcessorExtension implements MetricExtension {
|
|||
return measurementList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected List<String> readProcFile() {
|
||||
|
||||
List<String> allLines = new ArrayList<>();
|
||||
try {
|
||||
allLines = Files.readAllLines(Paths.get("/proc/stat"), StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return allLines;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected List<LinuxProcessorStat> processFileOutput(List<String> inputLines) {
|
||||
|
||||
List<LinuxProcessorStat> processorStats = new ArrayList<>();
|
||||
for(String line : inputLines) {
|
||||
if(line.matches("^cpu\\d+.*")) {
|
||||
processorStats.add(new LinuxProcessorStat(line));
|
||||
}
|
||||
}
|
||||
|
||||
return processorStats;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package org.sysmon.shared;
|
||||
|
||||
public interface AixPlugin {
|
||||
|
||||
}
|
|
@ -14,10 +14,13 @@ public class MetricResult {
|
|||
this.timestamp = Instant.now();
|
||||
}
|
||||
|
||||
public void setMeasurementList(List<MetricMeasurement> measurementList) {
|
||||
public void setMetricMeasurementList(List<MetricMeasurement> measurementList) {
|
||||
this.measurementList = measurementList;
|
||||
}
|
||||
|
||||
public void addMetricMeasurement(MetricMeasurement measurement) {
|
||||
measurementList.add(measurement);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(String.format("%s - %s\n", timestamp.toString(), name));
|
||||
|
|
57
shared/src/main/java/org/sysmon/shared/PluginHelper.java
Normal file
57
shared/src/main/java/org/sysmon/shared/PluginHelper.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package org.sysmon.shared;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PluginHelper {
|
||||
|
||||
final static boolean isWindows = System.getProperty("os.name")
|
||||
.toLowerCase().startsWith("windows");
|
||||
|
||||
|
||||
public static List<String> executeCommand(String... cmd) {
|
||||
|
||||
List<String> outputLines = new ArrayList<>();
|
||||
|
||||
ProcessBuilder builder = new ProcessBuilder();
|
||||
if (isWindows) {
|
||||
builder.command("cmd.exe", "/c");
|
||||
} else {
|
||||
builder.command("sh", "-c");
|
||||
}
|
||||
|
||||
for(String c : cmd) {
|
||||
builder.command().add(c);
|
||||
}
|
||||
|
||||
builder.directory(new File(System.getProperty("user.home")));
|
||||
|
||||
try {
|
||||
|
||||
Process process = builder.start();
|
||||
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
outputLines.add(line);
|
||||
}
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
System.out.println("\nExited with error code : " + exitCode);
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in a new issue