Work on base/common metrics.

This commit is contained in:
Mark Nellemann 2021-05-28 15:52:33 +02:00
parent f07f399b94
commit 0973c974ac
48 changed files with 451 additions and 1299 deletions

View file

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

View file

@ -19,6 +19,10 @@ dependencies {
implementation "info.picocli:picocli:${picocliVersion}"
implementation 'org.tomlj:tomlj:1.0.0'
implementation(group: 'com.github.oshi', name: 'oshi-core', version: "5.7.3") {
exclude(group: "org.slf4j")
}
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

View file

@ -20,6 +20,11 @@ subprojects {
exclude(group: "org.slf4j")
}
annotationProcessor(group: 'org.pf4j', name: 'pf4j', version: "${pf4jVersion}")
implementation(group: 'com.github.oshi', name: 'oshi-core', version: "5.7.3") {
exclude(group: "org.slf4j")
}
}
/*

View file

@ -1,6 +1,3 @@
dependencies {
implementation(group: 'com.github.oshi', name: 'oshi-core', version: "5.7.3") {
exclude(group: "org.slf4j")
}
}

View file

@ -1,91 +0,0 @@
package sysmon.plugins.os_aix;
import org.pf4j.Extension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import sysmon.shared.Measurement;
import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import sysmon.shared.PluginHelper;
import java.util.List;
import java.util.Map;
@Extension
public class AixDiskExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(AixProcessorExtension.class);
private final SystemInfo systemInfo;
private final HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isSupported() {
if(!System.getProperty("os.name").toLowerCase().contains("aix")) {
log.warn("Requires AIX.");
return false;
}
if(!PluginHelper.canExecute("iostat")) {
log.warn("Requires the 'iostat' command.");
return false;
}
return true;
}
public AixDiskExtension() {
systemInfo = new SystemInfo();
hardwareAbstractionLayer = systemInfo.getHardware();
log.warn(systemInfo.getOperatingSystem().toString());
}
@Override
public String getName() {
return "aix-disk";
}
@Override
public String getProvides() {
return "disk";
}
@Override
public String getDescription() {
return "AIX Disk Metrics";
}
@Override
public MetricResult getMetrics() {
long writeBytes = hardwareAbstractionLayer.getDiskStores().get(0).getWriteBytes();
log.warn(String.format("Disk 0 - Write Bytes: %d", writeBytes));
long readBytes = hardwareAbstractionLayer.getDiskStores().get(0).getReadBytes();
log.warn(String.format("Disk 0 - Read Bytes: %d", readBytes));
long memAvailable = hardwareAbstractionLayer.getMemory().getAvailable();
log.warn(String.format("Memory - Available: %d", memAvailable));
List<String> iostat = PluginHelper.executeCommand("iostat -d 1 1");
AixDiskStat diskStat = processCommandOutput(iostat);
Map<String, String> tagsMap = diskStat.getTags();
Map<String, Object> fieldsMap = diskStat.getFields();
return new MetricResult("disk", new Measurement(tagsMap, fieldsMap));
}
protected AixDiskStat processCommandOutput(List<String> inputLines) {
return new AixDiskStat(inputLines);
}
}

View file

@ -1,53 +0,0 @@
package sysmon.plugins.os_aix;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AixDiskStat {
// Disks: % tm_act Kbps tps Kb_read Kb_wrtn
// hdisk0 1.0 752.0 81.0 740 12
private final Pattern pattern = Pattern.compile("^(hdisk\\d+)\\s+(\\d+\\.?\\d*)\\s+\\s+(\\d+\\.?\\d*)\\s+\\s+(\\d+\\.?\\d*)\\s+(\\d+)\\s+(\\d+)");
//private String device;
//private Float tmAct = 0.0f; // Indicates the percentage of time the physical disk/tape was active (bandwidth utilization for the drive).
private float kbps = 0.0f; // Indicates the amount of data transferred (read or written) to the drive in KB per second.
private float tps = 0.0f; // Indicates the number of transfers per second that were issued to the physical disk/tape. A transfer is an I/O request to the physical disk/tape. Multiple logical requests can be combined into a single I/O request to the disk. A transfer is of indeterminate size.
private long kbRead = 0L; // The total number of KB read.
private long kbWritten = 0L; // The total number of KB written.
AixDiskStat(List<String> lines) {
for (String line : lines) {
if (line.startsWith("hdisk")) {
Matcher matcher = pattern.matcher(line);
if (matcher.find() && matcher.groupCount() == 6) {
//device = matcher.group(1);
//tmAct = Float.parseFloat(matcher.group(2));
kbps += Float.parseFloat(matcher.group(3));
tps += Float.parseFloat(matcher.group(4));
kbRead += Long.parseLong(matcher.group(5));
kbWritten += Long.parseLong(matcher.group(6));
}
}
}
}
public Map<String, String> getTags() {
return new HashMap<>();
}
public Map<String, Object> getFields() {
Map<String, Object> fields = new HashMap<>();
fields.put("reads", kbRead * 1024); // from Kb to bytes
fields.put("writes", kbWritten * 1024); // from Kb to bytes
fields.put("kbps", (int) kbps);
fields.put("tps", (int) tps);
return fields;
}
}

View file

@ -1,68 +0,0 @@
package sysmon.plugins.os_aix;
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.List;
import java.util.Map;
@Extension
public class AixMemoryExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(AixMemoryExtension.class);
@Override
public boolean isSupported() {
if(!System.getProperty("os.name").toLowerCase().contains("aix")) {
log.warn("Requires AIX.");
return false;
}
if(!PluginHelper.canExecute("svmon")) {
log.warn("Requires the 'svmon' command.");
return false;
}
return true;
}
@Override
public String getName() {
return "aix-memory";
}
@Override
public String getProvides() {
return "memory";
}
@Override
public String getDescription() {
return "AIX Memory Metrics";
}
@Override
public MetricResult getMetrics() {
//List<String> svmon = PluginHelper.executeCommand("svmon -G -O unit=KB");
List<String> svmon = PluginHelper.executeCommand("svmon -G -O summary=longreal,unit=KB");
AixMemoryStat memoryStat = processCommandOutput(svmon);
Map<String, String> tagsMap = memoryStat.getTags();
Map<String, Object> fieldsMap = memoryStat.getFields();
return new MetricResult("memory", new Measurement(tagsMap, fieldsMap));
}
protected AixMemoryStat processCommandOutput(List<String> inputLines) {
return new AixMemoryStat(inputLines);
}
}

View file

@ -1,60 +0,0 @@
package sysmon.plugins.os_aix;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AixMemoryStat {
private final Pattern pattern = Pattern.compile("^\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
private long total;
private long used;
private long free;
private long pin;
private long virtual;
private long available;
private long paged;
AixMemoryStat(List<String> lines) {
for (String line : lines) {
Matcher matcher = pattern.matcher(line);
if (matcher.find() && matcher.groupCount() == 7) {
total = Long.parseLong(matcher.group(1));
used = Long.parseLong(matcher.group(2));
free = Long.parseLong(matcher.group(3));
pin = Long.parseLong(matcher.group(4));
virtual = Long.parseLong(matcher.group(5));
available = Long.parseLong(matcher.group(6));
paged = Long.parseLong(matcher.group(7));
break;
}
}
}
public Map<String, String> getTags() {
return new HashMap<>();
}
public Map<String, Object> getFields() {
float usage = ((float) (total - available) / total ) * 100;
//BigDecimal usage = new BigDecimal(tmp).setScale(2, RoundingMode.HALF_UP);
Map<String, Object> fields = new HashMap<>();
fields.put("total", total);
fields.put("used", used);
fields.put("free", free);
fields.put("pin", pin);
fields.put("virtual", virtual);
fields.put("available", available);
fields.put("paged", paged);
fields.put("usage", usage);
return fields;
}
}

View file

@ -40,7 +40,7 @@ public class AixProcessorExtension implements MetricExtension {
@Override
public String getProvides() {
return "processor";
return "processor-lpar";
}
@Override
@ -57,7 +57,7 @@ public class AixProcessorExtension implements MetricExtension {
Map<String, String> tagsMap = processorStat.getTags();
Map<String, Object> fieldsMap = processorStat.getFields();
return new MetricResult("processor", new Measurement(tagsMap, fieldsMap));
return new MetricResult("processor_lpar", new Measurement(tagsMap, fieldsMap));
}

View file

@ -1,26 +0,0 @@
import sysmon.plugins.os_aix.AixDiskExtension
import sysmon.plugins.os_aix.AixDiskStat
import spock.lang.Specification
class AixDiskTest extends Specification {
void "test AIX iostat output processing"() {
setup:
def testFile = new File(getClass().getResource('/iostat.txt').toURI())
List<String> lines = testFile.readLines("UTF-8")
when:
AixDiskExtension extension = new AixDiskExtension()
AixDiskStat stats = extension.processCommandOutput(lines)
then:
//stats.getTags().get("device") == "hdisk0"
stats.getFields().get("reads") == 757760L
stats.getFields().get("writes") == 12288L
stats.getFields().get("kbps") == 752L
stats.getFields().get("tps") == 81L
}
}

View file

@ -1,29 +0,0 @@
import sysmon.plugins.os_aix.AixMemoryExtension
import sysmon.plugins.os_aix.AixMemoryStat
import spock.lang.Specification
class AixMemoryTest extends Specification {
void "test AIX svmon output processing"() {
setup:
def testFile = new File(getClass().getResource('/svmon.txt').toURI())
List<String> lines = testFile.readLines("UTF-8")
when:
AixMemoryExtension extension = new AixMemoryExtension()
AixMemoryStat stats = extension.processCommandOutput(lines)
then:
stats.getFields().get("total") == 4194304L
stats.getFields().get("used") == 4065060L
stats.getFields().get("free") == 129244L
stats.getFields().get("pin") == 1878240L
stats.getFields().get("virtual") == 2784988L
stats.getFields().get("available") == 1058012L
stats.getFields().get("paged") == 524288L
stats.getFields().get("usage") == 74.775024f
}
}

View file

@ -1,3 +0,0 @@
Disks: % tm_act Kbps tps Kb_read Kb_wrtn
cd0 0.0 0.0 0.0 0 0
hdisk0 1.0 752.0 81.0 740 12

View file

@ -1,15 +0,0 @@
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%] -

View file

@ -1,6 +0,0 @@
Unit: KB
------------------------------------------------------------------------
Memory
------------------------------------------------------------------------
Size Inuse Free Pin Virtual Available Pgsp
4194304 4065060 129244 1878240 2784988 1058012 524288

View file

@ -1,7 +0,0 @@
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

36
plugins/os-base/README.md Normal file
View file

@ -0,0 +1,36 @@
# Base Plugin
## Processor Extension
Reports the following metrics seen:
- **user** - CPU time spend on user processes.
- **system** -CPU time spend on system processes.
- **iowait** - CPU time spend on waiting (for i/o).
- **idle** - CPU time spend on idle (doing nothing).
- **busy** - CPU time not spend on idle (working).
## Memory Extension
Reports the following metrics, from the *free* command:
- **total** - The total amount of (installed) memory (in KB).
- **used** - Used memory (calculated as total - free - buffers - cache) (in KB).
- **free** - Unused memory (MemFree and SwapFree in /proc/meminfo) (in KB).
- **shared** - Memory used (mostly) by tmpfs (Shmem in /proc/meminfo) (in KB).
- **buffers** - Sum of buffers and cache (in KB).
- **available** - Estimation of how much memory is available for starting new applications, without swapping (in KB).
- **usage** - Percentage of memory used out of the total amount of memory.
## Disk Extension
Only reports first device found. Improvements on the TODO.
Metrics reported are:
- **device** - Name of device.
- **reads** - The total number of KB read.
- **writes** - The total number of KB written.

View file

@ -0,0 +1,2 @@
plugins {
}

View file

@ -0,0 +1,7 @@
pluginId=sysmon-base
pluginClass=sysmon.plugins.os_base.BasePlugin
pluginVersion=0.0.1
pluginProvider=System Monitor
pluginDependencies=
pluginDescription=Base OS metrics where supported.

View file

@ -0,0 +1,87 @@
package sysmon.plugins.os_base;
import org.pf4j.Extension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.HWDiskStore;
import oshi.hardware.HardwareAbstractionLayer;
import sysmon.shared.Measurement;
import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Extension
public class BaseDiskExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseDiskExtension.class);
private SystemInfo systemInfo;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isSupported() {
try {
systemInfo = new SystemInfo();
hardwareAbstractionLayer = systemInfo.getHardware();
return true;
} catch (UnsupportedOperationException e) {
log.warn(e.getMessage());
}
return false;
}
@Override
public String getName() {
return "base-disk";
}
@Override
public String getProvides() {
return "disk";
}
@Override
public String getDescription() {
return "Base Disk Metrics";
}
@Override
public MetricResult getMetrics() {
long writeBytes = 0L;
long readBytes = 0L;
long transferTime = 0L;
long queueLength = 0L;
Map<String, String> tagsMap = new HashMap<>();
Map<String, Object> fieldsMap = new HashMap<>();
List<HWDiskStore> diskStores = hardwareAbstractionLayer.getDiskStores();
for(HWDiskStore store : diskStores) {
String name = store.getName();
if (name.matches("hdisk[0-9]+") || name.matches("/dev/[sv]d[a-z]{1}") || name.matches("/dev/nvme[0-9]n[0-9]")) {
log.debug("Using device: " + name);
writeBytes += store.getWriteBytes();
readBytes += store.getReadBytes();
transferTime += store.getTransferTime();
queueLength = store.getCurrentQueueLength();
}
}
fieldsMap.put("reads", readBytes);
fieldsMap.put("writes", writeBytes);
fieldsMap.put("iotime", transferTime);
fieldsMap.put("queue", queueLength);
return new MetricResult("disk", new Measurement(tagsMap, fieldsMap));
}
}

View file

@ -0,0 +1,72 @@
package sysmon.plugins.os_base;
import org.pf4j.Extension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import sysmon.shared.Measurement;
import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import java.util.HashMap;
import java.util.Map;
@Extension
public class BaseMemoryExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseMemoryExtension.class);
private SystemInfo systemInfo;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isSupported() {
try {
systemInfo = new SystemInfo();
hardwareAbstractionLayer = systemInfo.getHardware();
return true;
} catch (UnsupportedOperationException e) {
log.warn(e.getMessage());
}
return false;
}
@Override
public String getName() {
return "base-memory";
}
@Override
public String getProvides() {
return "memory";
}
@Override
public String getDescription() {
return "Base Memory Metrics";
}
@Override
public MetricResult getMetrics() {
Map<String, String> tagsMap = new HashMap<>();
Map<String, Object> fieldsMap = new HashMap<>();
long total = hardwareAbstractionLayer.getMemory().getTotal();
long available = hardwareAbstractionLayer.getMemory().getAvailable();
float usage = ((float) (total - available) / total ) * 100;
fieldsMap.put("available", available);
fieldsMap.put("total", total);
fieldsMap.put("usage", usage);
fieldsMap.put("paged", hardwareAbstractionLayer.getMemory().getPageSize());
fieldsMap.put("virtual", hardwareAbstractionLayer.getMemory().getVirtualMemory().getVirtualInUse());
return new MetricResult("memory", new Measurement(tagsMap, fieldsMap));
}
}

View file

@ -0,0 +1,89 @@
package sysmon.plugins.os_base;
import org.pf4j.Extension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import sysmon.shared.Measurement;
import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Extension
public class BaseNetworkExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseNetworkExtension.class);
private SystemInfo systemInfo;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isSupported() {
try {
systemInfo = new SystemInfo();
hardwareAbstractionLayer = systemInfo.getHardware();
return true;
} catch (UnsupportedOperationException e) {
log.warn(e.getMessage());
}
return false;
}
@Override
public String getName() {
return "base-network";
}
@Override
public String getProvides() {
return "network";
}
@Override
public String getDescription() {
return "Base Network Metrics";
}
@Override
public MetricResult getMetrics() {
long rxBytes = 0L;
long rxPackets = 0L;
long rxErrs = 0L;
long txBytes = 0L;
long txPackets = 0L;
long txErrs = 0L;
Map<String, String> tagsMap = new HashMap<>();
Map<String, Object> fieldsMap = new HashMap<>();
List<NetworkIF> interfaces = hardwareAbstractionLayer.getNetworkIFs();
for(NetworkIF netif : interfaces) {
//String name = netif.getName();
//log.warn("Device: " + name);
rxPackets += netif.getPacketsRecv();
txPackets += netif.getPacketsSent();
rxBytes += netif.getBytesRecv();
txBytes += netif.getBytesSent();
rxErrs += netif.getInErrors();
txErrs += netif.getOutErrors();
}
fieldsMap.put("rxPackets", rxPackets);
fieldsMap.put("txPackets", txPackets);
fieldsMap.put("rxBytes", rxBytes);
fieldsMap.put("txBytes", txBytes);
fieldsMap.put("rxErrors", rxErrs);
fieldsMap.put("txErrors", txErrs);
return new MetricResult("network", new Measurement(tagsMap, fieldsMap));
}
}

View file

@ -0,0 +1,17 @@
package sysmon.plugins.os_base;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.pf4j.Plugin;
import org.pf4j.PluginWrapper;
public class BasePlugin extends Plugin {
private static final Logger log = LoggerFactory.getLogger(BasePlugin.class);
public BasePlugin(PluginWrapper wrapper) {
super(wrapper);
}
}

View file

@ -0,0 +1,111 @@
package sysmon.plugins.os_base;
import org.pf4j.Extension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
import sysmon.shared.Measurement;
import sysmon.shared.MetricExtension;
import sysmon.shared.MetricResult;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Extension
public class BaseProcessorExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(BaseProcessorExtension.class);
private SystemInfo systemInfo;
private HardwareAbstractionLayer hardwareAbstractionLayer;
@Override
public boolean isSupported() {
try {
systemInfo = new SystemInfo();
hardwareAbstractionLayer = systemInfo.getHardware();
return true;
} catch (UnsupportedOperationException e) {
log.warn(e.getMessage());
}
return false;
}
@Override
public String getName() {
return "base-processor";
}
@Override
public String getProvides() {
return "processor";
}
@Override
public String getDescription() {
return "Base Processor Metrics";
}
@Override
public MetricResult getMetrics() {
Map<String, String> tagsMap = new HashMap<>();
Map<String, Object> fieldsMap = new HashMap<>();
long user = 0L;
long system = 0L;
long steal = 0L;
long irq = 0L;
long softirq = 0L;
long nice = 0L;
long idle = 0L;
long iowait = 0L;
long[][] ticks = hardwareAbstractionLayer.getProcessor().getProcessorCpuLoadTicks();
int cores = ticks.length;
//log.warn("Cores: " + cores);
for (long[] tick : ticks) {
nice += tick[CentralProcessor.TickType.NICE.getIndex()];
user += tick[CentralProcessor.TickType.USER.getIndex()];
system += tick[CentralProcessor.TickType.SYSTEM.getIndex()];
steal += tick[CentralProcessor.TickType.STEAL.getIndex()];
irq += tick[CentralProcessor.TickType.IRQ.getIndex()];
softirq += tick[CentralProcessor.TickType.SOFTIRQ.getIndex()];
idle += tick[CentralProcessor.TickType.IDLE.getIndex()];
iowait += tick[CentralProcessor.TickType.IOWAIT.getIndex()];
}
long busy = nice + user + system + steal + irq + softirq;
long nonBusy = idle + iowait;
long total = busy + nonBusy;
log.info("idle: " + idle);
log.info("iowait: " + iowait);
log.info("busy: " + busy);
log.info("nonBusy: " + nonBusy);
log.info("total: " + total);
fieldsMap.put("user", (float) user / (float) total);
fieldsMap.put("iowait", (float) iowait / (float) total);
fieldsMap.put("idle", (float) nonBusy / (float) total);
fieldsMap.put("busy", (float) busy / (float) total);
fieldsMap.put("system", (float) system / (float) total);
log.info(fieldsMap.toString());
return new MetricResult("processor", new Measurement(tagsMap, fieldsMap));
}
}

View file

@ -0,0 +1,6 @@
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

View file

@ -1,14 +1,14 @@
# Linux Plugin
# Base Plugin
## Processor Extension
Reports the following metrics seen:
- **user** - Percentage of CPU time spend on user processes.
- **sys** - Percentage of CPU time spend on system processes.
- **wait** - Percentage of CPU time spend on waiting (for i/o).
- **idle** - Percentage of CPU time spend on idle (doing nothing).
- **busy** - Percentage of CPU time not spend on idle (working).
- **user** - CPU time spend on user processes.
- **system** -CPU time spend on system processes.
- **iowait** - CPU time spend on waiting (for i/o).
- **idle** - CPU time spend on idle (doing nothing).
- **busy** - CPU time not spend on idle (working).
## Memory Extension

View file

@ -3,5 +3,5 @@ pluginClass=sysmon.plugins.os_linux.LinuxPlugin
pluginVersion=0.0.1
pluginProvider=System Monitor
pluginDependencies=
pluginDescription=Collects Linux OS metrics.
pluginDescription=Linux OS Metrics.

View file

@ -1,88 +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 java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@Extension
public class LinuxDiskExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(LinuxDiskExtension.class);
@Override
public boolean isSupported() {
return System.getProperty("os.name").toLowerCase().contains("linux");
}
@Override
public String getName() {
return "linux-disk";
}
@Override
public String getProvides() {
return "disk";
}
@Override
public String getDescription() {
return "Linux Disk Metrics";
}
@Override
public MetricResult getMetrics() {
LinuxDiskProcLine proc1 = processFileOutput(readProcFile());
try {
Thread.sleep(1 * 1000); // TODO: Configure sample collect time
} catch (InterruptedException e) {
log.warn("getMetrics() - sleep interrupted");
return null;
}
LinuxDiskProcLine proc2 = processFileOutput(readProcFile());
LinuxDiskStat stat = new LinuxDiskStat(proc1, proc2);
return new MetricResult("disk", new Measurement(stat.getTags(), stat.getFields()));
}
protected List<String> readProcFile() {
List<String> allLines = new ArrayList<>();
try {
allLines = Files.readAllLines(Paths.get("/proc/diskstats"), StandardCharsets.UTF_8);
} catch (IOException e) {
log.error(e.getMessage());
}
return allLines;
}
protected LinuxDiskProcLine processFileOutput(List<String> inputLines) {
List<String> lines = new ArrayList<>(inputLines.size());
for(String line : inputLines) {
String[] splitStr = line.trim().split("\\s+");
String device = splitStr[2];
if (device.matches("[sv]d[a-z]{1}") || device.matches("nvme[0-9]n[0-9]")) {
//log.warn("Going for: " + line);
lines.add(line);
}
}
return new LinuxDiskProcLine(lines);
}
}

View file

@ -1,146 +0,0 @@
package sysmon.plugins.os_linux;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
public class LinuxDiskProcLine {
// Sectors to bytes - each sector is 512 bytes - https://lkml.org/lkml/2015/8/17/269
private static final int SECTOR_BYTE_SIZE = 512;
private static final Logger log = LoggerFactory.getLogger(LinuxDiskProcLine.class);
/*
== ===================================
1 major number
2 minor mumber
3 device name
4 reads completed successfully
5 reads merged
6 sectors read
7 time spent reading (ms)
8 writes completed
9 writes merged
10 sectors written
11 time spent writing (ms)
12 I/Os currently in progress
13 time spent doing I/Os (ms)
14 weighted time spent doing I/Os (ms)
== ===================================
Kernel 4.18+ appends four more fields for discard
tracking putting the total at 18:
== ===================================
15 discards completed successfully
16 discards merged
17 sectors discarded
18 time spent discarding
== ===================================
Kernel 5.5+ appends two more fields for flush requests:
== =====================================
19 flush requests completed successfully
20 time spent flushing
== =====================================
*/
private long readsCompleted; // successfully
//private long readsMerged;
private long sectorsRead; // 512 bytes pr. sector
private long timeSpentReading; // ms
private long writesCompleted; // successfully
//private long writesMerged;
private long sectorsWritten; // 512 bytes pr. sector
private long timeSpentWriting; // ms
//private long ioInProgress;
private long timeSpentOnIo; // ms
//private long timeSpentOnIoWeighted;
//private long discardsCompleted; // successfully
//private long discardsMerged;
//private long sectorsDiscarded; // 512 bytes pr. sector
//private long timeSpentDiscarding; // ms
//private long flushRequestsCompleted;
//private long timeSpentFlushing; // ms
public LinuxDiskProcLine(List<String> procLines) {
for(String procLine : procLines) {
String[] splitStr = procLine.trim().split("\\s+");
if (splitStr.length < 14) {
throw new UnsupportedOperationException("Linux proc DISK string error: " + procLine);
}
//this.major = Integer.parseInt(splitStr[0]);
//this.minor = Integer.parseInt(splitStr[1]);
//this.device = splitStr[2];
this.readsCompleted += Long.parseLong(splitStr[3]);
//this.readsMerged += Long.parseLong(splitStr[4]);
this.sectorsRead += Long.parseLong(splitStr[5]);
this.timeSpentReading += Long.parseLong(splitStr[6]);
this.writesCompleted += Long.parseLong(splitStr[7]);
//this.writesMerged += Long.parseLong(splitStr[8]);
this.sectorsWritten += Long.parseLong(splitStr[9]);
this.timeSpentWriting += Long.parseLong(splitStr[10]);
//this.ioInProgress += Long.parseLong(splitStr[11]);
this.timeSpentOnIo += Long.parseLong(splitStr[12]);
//this.timeSpentOnIoWeighted += Long.parseLong(splitStr[13]);
/*
if (splitStr.length >= 18) {
this.discardsCompleted += Long.parseLong(splitStr[10]);
this.discardsMerged += Long.parseLong(splitStr[11]);
this.sectorsDiscarded += Long.parseLong(splitStr[12]);
this.timeSpentDiscarding += Long.parseLong(splitStr[13]);
} else {
this.discardsCompleted = null;
this.discardsMerged = null;
this.sectorsDiscarded = null;
this.timeSpentDiscarding = null;
}
if (splitStr.length == 20) {
this.flushRequestsCompleted += Long.parseLong(splitStr[14]);
this.timeSpentFlushing += Long.parseLong(splitStr[15]);
} else {
this.flushRequestsCompleted = null;
this.timeSpentFlushing = null;
}
*/
}
}
public Long getTimeSpentOnIo() {
return timeSpentOnIo;
}
public Long getBytesRead() {
return sectorsRead * SECTOR_BYTE_SIZE;
}
public Long getBytesWritten() {
return sectorsWritten * SECTOR_BYTE_SIZE;
}
public Long getTimeSpentReading() {
return timeSpentReading;
}
public Long getTimeSpentWriting() {
return timeSpentWriting;
}
public Long getTransactions() {
return readsCompleted + writesCompleted;
}
}

View file

@ -1,39 +0,0 @@
package sysmon.plugins.os_linux;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
public class LinuxDiskStat {
private String device;
private final long iotime;
private final long reads;
private final long writes;
private final long kbps;
private final long tps;
LinuxDiskStat(LinuxDiskProcLine proc1, LinuxDiskProcLine proc2) {
iotime = proc2.getTimeSpentOnIo() - proc1.getTimeSpentOnIo();
writes = proc2.getBytesWritten() - proc1.getBytesWritten();
reads = proc2.getBytesRead() - proc1.getBytesRead();
kbps = (writes + reads) / 1024;
tps = proc2.getTransactions() - proc1.getTransactions();
}
public Map<String, String> getTags() {
return new HashMap<>();
}
public Map<String, Object> getFields() {
Map<String, Object> fields = new HashMap<>();
fields.put("iotime", iotime);
fields.put("writes", writes);
fields.put("reads", reads);
fields.put("kbps", kbps);
fields.put("tps", tps);
return fields;
}
}

View file

@ -1,67 +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.List;
import java.util.Map;
@Extension
public class LinuxMemoryExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(LinuxMemoryExtension.class);
@Override
public boolean isSupported() {
if(!System.getProperty("os.name").toLowerCase().contains("linux")) {
log.warn("Requires Linux.");
return false;
}
if(!PluginHelper.canExecute("free")) {
log.warn("Requires the 'free' command.");
return false;
}
return true;
}
@Override
public String getName() {
return "linux-memory";
}
@Override
public String getProvides() {
return "memory";
}
@Override
public String getDescription() {
return "Linux Memory Metrics";
}
@Override
public MetricResult getMetrics() {
List<String> svmon = PluginHelper.executeCommand("free -k");
LinuxMemoryStat memoryStat = processCommandOutput(svmon);
Map<String, String> tagsMap = memoryStat.getTags();
Map<String, Object> fieldsMap = memoryStat.getFields();
return new MetricResult("memory", new Measurement(tagsMap, fieldsMap));
}
protected LinuxMemoryStat processCommandOutput(List<String> inputLines) {
return new LinuxMemoryStat(inputLines);
}
}

View file

@ -1,63 +0,0 @@
package sysmon.plugins.os_linux;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LinuxMemoryStat {
/*
total used free shared buff/cache available
Mem: 16069172 5896832 4597860 639780 5574480 9192992
Swap: 3985404 0 3985404
*/
private static final Pattern pattern = Pattern.compile("^Mem:\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
private long total;
private long used;
private long free;
private long shared;
private long buffers;
private long available;
//private String mode;
LinuxMemoryStat(List<String> lines) {
for (String line : lines) {
Matcher matcher = pattern.matcher(line);
if (matcher.find() && matcher.groupCount() == 6) {
total = Long.parseLong(matcher.group(1));
used = Long.parseLong(matcher.group(2));
free = Long.parseLong(matcher.group(3));
shared = Long.parseLong(matcher.group(4));
buffers = Long.parseLong(matcher.group(5));
available = Long.parseLong(matcher.group(6));
break;
}
}
}
public Map<String, String> getTags() {
return new HashMap<>();
}
public Map<String, Object> getFields() {
float usage = ((float) (total - available) / total ) * 100;
//BigDecimal usage = new BigDecimal(tmp).setScale(2, RoundingMode.HALF_UP);
Map<String, Object> fields = new HashMap<>();
fields.put("total", total);
fields.put("used", used);
fields.put("free", free);
fields.put("shared", shared);
fields.put("buffers", buffers);
fields.put("available", available);
fields.put("usage", usage);
return fields;
}
}

View file

@ -1,105 +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.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LinuxNetworkDevStat {
private static final Logger log = LoggerFactory.getLogger(LinuxNetworkDevStat.class);
private static final Pattern pattern1 = Pattern.compile("^\\s+([a-z]{2,}[0-9]+):.*");
private static final Pattern pattern2 = Pattern.compile("^\\s+([a-z]{2,}[0-9]+):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
private long rxBytes;
private long rxPackets;
private long rxErrs;
private long txBytes;
private long txPackets;
private long txErrs;
/*
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
env2: 657010764 483686 0 0 0 0 0 0 55416850 431020 0 0 0 0 0 0
env3: 6900272 41836 0 0 0 0 0 0 7667444 41849 0 0 0 0 0 0
lo: 3098805 14393 0 0 0 0 0 0 3098805 14393 0 0 0 0 0 0
*/
public LinuxNetworkDevStat(List<String> procLines) {
Matcher matcher1;
Matcher matcher2;
for(String procLine : procLines) {
matcher1 = pattern1.matcher(procLine);
if(matcher1.matches()) {
if(matcher1.group(1).equals("lo")) {
continue;
}
matcher2 = pattern2.matcher(procLine);
if(matcher2.matches() && matcher2.groupCount() == 17) {
rxBytes += Long.parseLong(matcher2.group(2));
rxPackets += Long.parseLong(matcher2.group(3));
rxErrs += Long.parseLong(matcher2.group(4));
txBytes += Long.parseLong(matcher2.group(10));
txPackets += Long.parseLong(matcher2.group(11));
txErrs += Long.parseLong(matcher2.group(12));
}
}
}
}
public long getRxBytes() {
return rxBytes;
}
public long getRxPackets() {
return rxPackets;
}
public long getRxErrs() {
return rxErrs;
}
public long getTxBytes() {
return txBytes;
}
public long getTxPackets() {
return txPackets;
}
public long getTxErrs() {
return txErrs;
}
public Map<String, String> getTags() {
return new HashMap<>();
}
public Map<String, Object> getFields() {
Map<String, Object> fields = new HashMap<>();
fields.put("rxBytes", rxBytes);
fields.put("rxPackets", rxPackets);
fields.put("txBytes", txBytes);
fields.put("txPackets", txPackets);
return fields;
}
}

View file

@ -29,39 +29,33 @@ public class LinuxNetworkExtension implements MetricExtension {
@Override
public String getName() {
return "linux-network";
return "linux-network-sockets";
}
@Override
public String getProvides() {
return "network";
return "network-sockets";
}
@Override
public String getDescription() {
return "Linux Network Metrics";
return "Linux Network Socket Metrics";
}
@Override
public MetricResult getMetrics() {
LinuxNetworkSockStat sockStat = processSockOutput(PluginHelper.readFile("/proc/net/sockstat"));
LinuxNetworkDevStat devStat = processDevOutput(PluginHelper.readFile("/proc/net/dev"));
Map<String, String> tagsMap = sockStat.getTags();
Map<String, Object> fieldsMap = sockStat.getFields();
fieldsMap.putAll(devStat.getFields());
return new MetricResult("network", new Measurement(tagsMap, fieldsMap));
return new MetricResult("network_sockets", new Measurement(tagsMap, fieldsMap));
}
protected LinuxNetworkSockStat processSockOutput(List<String> inputLines) {
return new LinuxNetworkSockStat(inputLines);
}
protected LinuxNetworkDevStat processDevOutput(List<String> inputLines) {
return new LinuxNetworkDevStat(inputLines);
}
}

View file

@ -1,95 +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 java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@Extension
public class LinuxProcessorExtension implements MetricExtension {
private static final Logger log = LoggerFactory.getLogger(LinuxProcessorExtension.class);
private List<LinuxProcessorProcLine> currentProcessorProc;
private List<LinuxProcessorProcLine> previousProcessorProc;
@Override
public boolean isSupported() {
return System.getProperty("os.name").toLowerCase().contains("linux");
}
@Override
public String getName() {
return "linux-processor";
}
@Override
public String getProvides() {
return "processor";
}
@Override
public String getDescription() {
return "Linux Processor Metrics";
}
@Override
public MetricResult getMetrics() {
LinuxProcessorProcLine proc1 = processFileOutput(readProcFile());
try {
Thread.sleep(1 * 1000); // TODO: Configure sample collect time
} catch (InterruptedException e) {
log.warn("getMetrics() - sleep interrupted");
return null;
}
LinuxProcessorProcLine proc2 = processFileOutput(readProcFile());
LinuxProcessorStat stat = new LinuxProcessorStat(proc1, proc2);
return new MetricResult("processor", new Measurement(stat.getTags(), stat.getFields()));
}
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 LinuxProcessorProcLine processFileOutput(List<String> inputLines) {
for(String line : inputLines) {
if(line.matches("^cpu\\S+.*")) {
return new LinuxProcessorProcLine(line);
}
}
return null;
}
}

View file

@ -1,95 +0,0 @@
package sysmon.plugins.os_linux;
public class LinuxProcessorProcLine {
private final String cpuName;
private final long userTime;
private final long niceTime;
private final long systemTime;
private final long idleTime;
private final long ioWaitTime;
private final long irqTime;
private final long softIrqTime;
private final long stealTime;
private final long guestTime;
private final long guestNiceTime;
public LinuxProcessorProcLine(String procString) {
String[] splitStr = procString.trim().split("\\s+");
if(splitStr.length != 11) {
throw new UnsupportedOperationException("Linux proc CPU string error: " + procString);
}
this.cpuName = splitStr[0];
this.userTime = Long.parseLong(splitStr[1]);
this.niceTime = Long.parseLong(splitStr[2]);
this.systemTime = Long.parseLong(splitStr[3]);
this.idleTime = Long.parseLong(splitStr[4]);
this.ioWaitTime = Long.parseLong(splitStr[5]);
this.irqTime = Long.parseLong(splitStr[6]);
this.softIrqTime = Long.parseLong(splitStr[7]);
this.stealTime = Long.parseLong(splitStr[8]);
this.guestTime = Long.parseLong(splitStr[9]);
this.guestNiceTime = Long.parseLong(splitStr[10]);
}
public String getCpuName() {
return cpuName;
}
public long getUserTime() {
return userTime;
}
public long getNiceTime() {
return niceTime;
}
public long getSystemTime() {
return systemTime;
}
public long getIdleTime() {
return idleTime;
}
public long getIoWaitTime() {
return ioWaitTime;
}
public long getIrqTime() {
return irqTime;
}
public long getSoftIrqTime() {
return softIrqTime;
}
public long getStealTime() {
return stealTime;
}
public long getGuestTime() {
return guestTime;
}
public long getGuestNiceTime() {
return guestNiceTime;
}
public long getCombinedIdleTime() {
return idleTime + ioWaitTime;
}
public long getCombinedWorkTime() {
return userTime + niceTime + systemTime + irqTime + softIrqTime + stealTime + guestTime + guestNiceTime;
}
public long getCombinedTime() {
return getCombinedIdleTime() + getCombinedWorkTime();
}
}

View file

@ -1,60 +0,0 @@
package sysmon.plugins.os_linux;
import java.util.HashMap;
import java.util.Map;
public class LinuxProcessorStat {
private final float user;
private final float sys;
private final float wait;
private final float idle;
private final float busy;
public LinuxProcessorStat(LinuxProcessorProcLine previous, LinuxProcessorProcLine current) {
long workTime = current.getCombinedTime() - previous.getCombinedTime();
long busyTime = current.getCombinedIdleTime() - previous.getCombinedIdleTime();
float busyDiff = (float) (workTime - busyTime) / workTime;
busy = (busyDiff * 100);
long userTime = current.getUserTime() - previous.getUserTime();
float userDiff = (float) (workTime - userTime) / workTime;
user = 100 - (userDiff * 100);
long sysTime = current.getSystemTime() - previous.getSystemTime();
float sysDiff = (float) (workTime - sysTime) / workTime;
sys = 100 - (sysDiff * 100);
long waitTime = current.getIoWaitTime() - previous.getIoWaitTime();
float waitDiff = (float) (workTime - waitTime) / workTime;
wait = 100 - (waitDiff * 100);
long idleTime = current.getIdleTime() - previous.getIdleTime();
float idleDiff = (float) (workTime - idleTime) / workTime;
idle = 100 - (idleDiff * 100);
}
public Float getBusy() {
return busy;
}
public Map<String, String> getTags() {
return new HashMap<>();
}
public Map<String, Object> getFields() {
Map<String, Object> fields = new HashMap<>();
fields.put("user", user);
fields.put("sys", sys);
fields.put("wait", wait);
fields.put("idle", idle);
fields.put("busy", busy);
return fields;
}
}

View file

@ -1,43 +0,0 @@
import sysmon.plugins.os_linux.LinuxDiskExtension
import sysmon.plugins.os_linux.LinuxDiskProcLine
import sysmon.plugins.os_linux.LinuxDiskStat
import spock.lang.Specification
class LinuxDiskTest extends Specification {
void "test proc file processing"() {
setup:
def testFile = new File(getClass().getResource('/proc_diskstats1.txt').toURI())
List<String> lines = testFile.readLines("UTF-8")
when:
LinuxDiskExtension extension = new LinuxDiskExtension()
LinuxDiskProcLine procLine = extension.processFileOutput(lines)
then:
procLine.getTimeSpentOnIo() == 11145860l
}
void "test disk utilization"() {
setup:
def testFile1 = new File(getClass().getResource('/proc_diskstats1.txt').toURI())
def testFile2 = new File(getClass().getResource('/proc_diskstats2.txt').toURI())
LinuxDiskExtension extension = new LinuxDiskExtension()
LinuxDiskProcLine procLine1 = extension.processFileOutput(testFile1.readLines())
LinuxDiskProcLine procLine2 = extension.processFileOutput(testFile2.readLines())
when:
LinuxDiskStat diskStat = new LinuxDiskStat(procLine1, procLine2)
then:
diskStat.getFields().get("iotime") == 180L
diskStat.getFields().get("writes") == 108371968L
diskStat.getFields().get("reads") == 69632L
diskStat.getFields().get("kbps") == 105900.0f
diskStat.getFields().get("tps") == 97.0f
}
}

View file

@ -1,28 +0,0 @@
import sysmon.plugins.os_linux.LinuxMemoryExtension
import sysmon.plugins.os_linux.LinuxMemoryStat
import spock.lang.Specification
class LinuxMemoryTest extends Specification {
void "test Linux free output processing"() {
setup:
def testFile = new File(getClass().getResource('/free.txt').toURI())
List<String> lines = testFile.readLines("UTF-8")
when:
LinuxMemoryExtension extension = new LinuxMemoryExtension()
LinuxMemoryStat stats = extension.processCommandOutput(lines)
then:
stats.getFields().get("total") == 16069172l
stats.getFields().get("used") == 5896832l
stats.getFields().get("free") == 4597860l
stats.getFields().get("shared") == 639780l
stats.getFields().get("buffers") == 5574480l
stats.getFields().get("available") == 9192992l
stats.getFields().get("usage") == 42.79113f
}
}

View file

@ -1,5 +1,4 @@
import spock.lang.Specification
import sysmon.plugins.os_linux.LinuxNetworkDevStat
import sysmon.plugins.os_linux.LinuxNetworkExtension
import sysmon.plugins.os_linux.LinuxNetworkSockStat
@ -27,44 +26,4 @@ class LinuxNetworkTest extends Specification {
}
void "test /proc/net/dev parsing"() {
setup:
def testFile = new File(getClass().getResource('/proc_net_dev1.txt').toURI())
List<String> lines = testFile.readLines("UTF-8")
when:
LinuxNetworkExtension extension = new LinuxNetworkExtension()
LinuxNetworkDevStat procLine = extension.processDevOutput(lines)
then:
procLine.getRxBytes() == 663911036L
procLine.getRxPackets() == 525522L
procLine.getRxErrs() == 0L
procLine.getTxBytes() == 63084294L
procLine.getTxPackets() == 472869L
procLine.getTxErrs() == 0L
}
/*
void "test dev utilization"() {
setup:
def testFile1 = new File(getClass().getResource('/proc_net_dev1.txt').toURI())
def testFile2 = new File(getClass().getResource('/proc_net_dev2.txt').toURI())
LinuxNetworkExtension extension = new LinuxNetworkExtension()
LinuxNetworkDevStat procLine1 = extension.processDevOutput(testFile1.readLines())
LinuxNetworkDevStat procLine2 = extension.processDevOutput(testFile2.readLines())
when:
LinuxNetworkDevStat networkDevStat = new LinuxNetworkDevStat(procLine1, procLine2)
then:
networkDevStat.getFields().get("rxPackets") == 223L
networkDevStat.getFields().get("rxBytes") == 31501L
networkDevStat.getFields().get("txBytes") == 46460L
networkDevStat.getFields().get("txPackets") == 341L
}*/
}

View file

@ -1,48 +0,0 @@
import sysmon.plugins.os_linux.LinuxProcessorExtension
import sysmon.plugins.os_linux.LinuxProcessorProcLine
import sysmon.plugins.os_linux.LinuxProcessorStat
import spock.lang.Specification
class LinuxProcessorTest extends Specification {
void "test proc file processing"() {
setup:
def testFile = new File(getClass().getResource('/proc_stats1.txt').toURI())
List<String> lines = testFile.readLines("UTF-8")
when:
LinuxProcessorExtension extension = new LinuxProcessorExtension()
LinuxProcessorProcLine procLine = extension.processFileOutput(lines)
then:
procLine.getSystemTime() == 4686l
procLine.getUserTime() == 27477l
procLine.getIdleTime() == 281276l
procLine.getIoWaitTime() == 252l
}
void "test processor utilization"() {
setup:
def testFile1 = new File(getClass().getResource('/proc_stats1.txt').toURI())
def testFile2 = new File(getClass().getResource('/proc_stats2.txt').toURI())
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.getBusy() == 38.001614f
processorStat.getFields().get("user") == 35.6989f
processorStat.getFields().get("sys") == 2.2623215f
processorStat.getFields().get("idle") == 61.823322f
processorStat.getFields().get("wait") == 0.17505646f
}
}