/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2007, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.apmrouter.monitor.nativex;
import org.helios.apmrouter.jmx.ConfigurationHelper;
import org.helios.apmrouter.monitor.AbstractMonitor;
import org.helios.apmrouter.nativex.APMSigar;
import org.helios.apmrouter.util.SystemClock;
import org.hyperic.sigar.*;
import java.net.NetworkInterface;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* <p>Title: NativeMonitor</p>
* <p>Description: Monitor implementation to monitor native OS resources and performance</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.monitor.nativex.NativeMonitor</code></p>
*/
public class NativeMonitor extends AbstractMonitor {
/** The wrapped sigar instance */
protected final APMSigar hsigar = APMSigar.getInstance();
/** The native sigar instance */
protected final Sigar sigar = hsigar.getSigar();
/** A map maintaining the last usage and timestamp for each file system */
protected final Map<String, long[]> fileSystemState = new HashMap<String, long[]>();
/** The number of collection sweeps before the file systems are rescanned */
protected int fsRescanCollectionSweep = 10;
/** The number of collection sweeps before a file system time-to-full is computed */
protected int fsTimeToFullCollectionSweep = 10;
/** Indicates if static os meta-data should be traced during rescans */
protected boolean traceMeta = false;
/** Indicates if detailed localStats for all cpus should be traced */
protected boolean traceAllCpus = false;
/** Indicates if this is windows */
public static final boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows") ;
/** The NIC name tag foramat */
public static final String NIC_NAME = "if=%s";
/** The CPU resource tag */
public static final String NIC_RESOURCE = "resource=if";
/** The swap resource tag */
public static final String SWAP_RESOURCE = "resource=swap";
/** The TCP resource tag */
public static final String TCP_RESOURCE = "resource=tcp";
/** The Net stat resource tag */
public static final String NET_RESOURCE = "resource=netstat";
/** The process stat resource tag */
public static final String PS_RESOURCE = "resource=ps";
/** The JVM process resource tag */
public static final String JVM_PROCESS_RESOURCE = "resource=jvm";
/** The CPU name tag foramat */
public static final String CPU_NAME = "cpu=%s";
/** The CPU resource tag */
public static final String CPU_RESOURCE = "resource=cpu";
/** The System memory resource tag */
public static final String SYSMEM_RESOURCE = "resource=sysmem";
/** The Filesystem resource tag */
public static final String FS_RESOURCE = "resource=filesystem";
/** The Filesystem name tag foramat */
public static final String FS_NAME = "fsname=%s";
/** The OS patform tag */
public static final String PLAT = "platform=os";
/** The tracing tag for OS static meta-data */
public static final String META_TAG = "info=meta";
/** The size of the long array in fs-state */
public static final int FS_STATE_SIZE = 6;
/** The fs-state long arr index for the monitor flag */
public static final int FS_STATE_FLAG = 0;
/** The fs-state long arr index for the last timestamp collected */
public static final int FS_STATE_TS = 1;
/** The fs-state long arr index for the kb-used collected in the last period */
public static final int FS_STATE_USED = 2;
/** The fs-state long arr index for the kb-total collected in the last period */
public static final int FS_STATE_TOTAL = 3;
/** The fs-state long arr index for the time until full for the last period */
public static final int FS_STATE_TTF = 4;
/** The fs-state long arr index for the number of consecutive times there has been no increment in fs usage */
public static final int FS_STATE_NOINCR = 5;
/** The property name for configuring the number of collection sweeps before the file systems are rescanned */
public static final String RESCAN_PROP = "monitor.nativex.fs.rescan";
/** The default count of collection sweeps before the file systems are rescanned */
public static final int DEFAULT_RESCAN = 10;
/** The property name for configuring the number of collection sweeps before a file system time-to-full is computed */
public static final String TTF_PROP = "monitor.nativex.fs.ttf";
/** The default count of collection sweeps before a file system time-to-full is computed */
public static final int DEFAULT_TTF = 10;
/** The property name for configuring if static os data (e.g. file-system meta etc.) should be traced when systems are rescanned */
public static final String OS_META_PROP = "monitor.nativex.tracemeta";
/** The default configuration that specifies if static os data should be traced when systems are rescanned */
public static final boolean DEFAULT_OS_META = false;
/** The property name for configuring if detailed localStats on each cpu should be traced, or just the combined */
public static final String CPU_ALL_PROP = "monitor.nativex.cpu.traceall";
/** The default configuration for detailed localStats on each cpu should be traced */
public static final boolean DEFAULT_CPU_ALL = false;
/**
* Creates a new NativeMonitor
*/
public NativeMonitor() {
// TODO Auto-generated constructor stub
}
/**
* {@inheritDoc}
* @see org.helios.apmrouter.monitor.AbstractMonitor#setProperties(java.util.Properties)
*/
@Override
public void setProperties(Properties p) {
super.setProperties(p);
fsRescanCollectionSweep = ConfigurationHelper.getIntSystemThenEnvProperty(RESCAN_PROP, DEFAULT_RESCAN, p);
fsTimeToFullCollectionSweep = ConfigurationHelper.getIntSystemThenEnvProperty(TTF_PROP, DEFAULT_TTF, p);
traceMeta = ConfigurationHelper.getBooleanSystemThenEnvProperty(OS_META_PROP, DEFAULT_OS_META, p);
traceAllCpus = ConfigurationHelper.getBooleanSystemThenEnvProperty(CPU_ALL_PROP, DEFAULT_CPU_ALL, p);
}
/**
* {@inheritDoc}
* @see org.helios.apmrouter.monitor.AbstractMonitor#doCollect(long)
*/
@Override
protected void doCollect(long collectionSweep) {
traceCpus();
traceFileSystemUsage();
traceNics();
traceSystemMem();
traceSwap();
traceTCP();
traceNetstat();
traceMe();
traceProcessStats();
}
/**
* Traces the states of system processes
*/
protected void traceProcessStats() {
ProcStat ps = hsigar.getProcStat();
tracer.traceGauge(ps.getIdle(), "Idle", PLAT, PS_RESOURCE);
tracer.traceGauge(ps.getRunning(), "Running", PLAT, PS_RESOURCE);
tracer.traceGauge(ps.getSleeping(), "Sleeping", PLAT, PS_RESOURCE);
tracer.traceGauge(ps.getStopped(), "Stopped", PLAT, PS_RESOURCE);
tracer.traceGauge(ps.getThreads(), "Threads", PLAT, PS_RESOURCE);
tracer.traceGauge(ps.getTotal(), "Total", PLAT, PS_RESOURCE);
tracer.traceGauge(ps.getZombie(), "Zombie", PLAT, PS_RESOURCE);
}
/**
* Traces network localStats
*/
protected void traceNetstat() {
NetStat net = hsigar.getNetStat();
tracer.traceDeltaGauge(net.getAllInboundTotal(), "Inbound", PLAT, NET_RESOURCE);
tracer.traceDeltaGauge(net.getAllOutboundTotal(), "Outbound", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpBound(), "TcpBound", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpClose(), "TcpClose", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpCloseWait(), "TcpCloseWait", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpClosing(), "TcpClosing", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpEstablished(), "TcpEstablished", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpFinWait1(), "TcpFinWait1", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpFinWait2(), "TcpFinWait2", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpIdle(), "TcpIdle", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpInboundTotal(), "TcpInbound", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpOutboundTotal(), "TcpOutbound", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpLastAck(), "TcpLastAck", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpListen(), "TcpListen", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpSynRecv(), "TcpSynRecv", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpSynSent(), "TcpSynSent", PLAT, NET_RESOURCE);
tracer.traceCounter(net.getTcpTimeWait(), "TcpTimeWait", PLAT, NET_RESOURCE);
}
/**
* Traces metrics about this process.
*/
protected void traceMe() {
ProcCpu procCpu = hsigar.getProcCpu(hsigar.pid);
tracer.traceGauge(procCpu.getSys(), "System", "platform=JVM", "category=cpu");
tracer.traceGauge(procCpu.getTotal(), "Total", "platform=JVM", "category=cpu");
tracer.traceGauge(procCpu.getUser(), "User", "platform=JVM", "category=cpu");
tracer.traceGauge( dbl2longPerc(procCpu.getPercent()), "PercentUsage", "platform=JVM", "category=cpu");
ProcMem pmem = hsigar.getProcMem(hsigar.pid);
tracer.traceGauge(pmem.getMajorFaults(), "MajorFaults", "platform=JVM", "category=processMemory");
tracer.traceGauge(pmem.getMinorFaults(), "MinorFaults", "platform=JVM", "category=processMemory");
tracer.traceGauge(pmem.getPageFaults(), "PageFaults", "platform=JVM", "category=processMemory");
tracer.traceGauge(pmem.getResident(), "Resident", "platform=JVM", "category=processMemory");
if(!isWindows) tracer.traceGauge(pmem.getShare(), "Shared", "platform=JVM", "category=processMemory");
tracer.traceGauge(pmem.getSize(), "Size", "platform=JVM", "category=processMemory");
tracer.traceGauge(hsigar.getProcFd(hsigar.pid).getTotal(), "OpenFileDescriptors", "platform=JVM", "category=fd");
}
/**
* Traces tcp metris
*/
protected void traceTCP() {
Tcp tcp = hsigar.getTcp();
tracer.traceDeltaGauge(tcp.getActiveOpens(), "Opens", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getAttemptFails(), "Fails", PLAT, TCP_RESOURCE);
tracer.traceGauge(tcp.getCurrEstab(), "Established", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getEstabResets(), "Resets", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getInErrs(), "InErrors", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getInSegs(), "InSegs", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getOutRsts(), "OutResets", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getOutSegs(), "OutSegs", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getPassiveOpens(), "PassiveOpens", PLAT, TCP_RESOURCE);
tracer.traceDeltaGauge(tcp.getRetransSegs(), "RetransSegs", PLAT, TCP_RESOURCE);
}
/**
* Traces metrics on swap space usage
*/
protected void traceSwap() {
Swap swap = hsigar.getSwap();
long total = swap.getTotal();
if((collectionSweep==0 || collectionSweep%fsRescanCollectionSweep==0)) {
tracer.traceCounter(total, "Total", PLAT, SWAP_RESOURCE);
}
long free = swap.getFree();
long used = swap.getUsed();
tracer.traceCounter(free, "Free", PLAT, SWAP_RESOURCE);
tracer.traceCounter(used, "Used", PLAT, SWAP_RESOURCE);
tracer.traceCounter(percent(total,free), "FreePercent", PLAT, SWAP_RESOURCE);
tracer.traceCounter(percent(total,used), "UsedPercent", PLAT, SWAP_RESOURCE);
tracer.traceCounter(swap.getPageIn(), "PageIn", PLAT, SWAP_RESOURCE);
tracer.traceCounter(swap.getPageOut(), "PageOut", PLAT, SWAP_RESOURCE);
}
private static long percent(double total, double part) {
if(total==0 || part==0) return 0;
double d = part/total*100;
return (long)d;
}
/**
* Traces metrics on system memory
*/
protected void traceSystemMem() {
Mem mem = hsigar.getMem();
if((collectionSweep==0 || collectionSweep%fsRescanCollectionSweep==0)) {
tracer.traceCounter(mem.getRam(), "TotalMemMB", PLAT, SYSMEM_RESOURCE);
}
tracer.traceCounter(mem.getActualFree(), "ActualFree", PLAT, SYSMEM_RESOURCE);
tracer.traceCounter(mem.getActualUsed(), "ActualUsed", PLAT, SYSMEM_RESOURCE);
tracer.traceCounter(mem.getFree(), "Free", PLAT, SYSMEM_RESOURCE);
tracer.traceCounter(mem.getUsed(), "Used", PLAT, SYSMEM_RESOURCE);
tracer.traceCounter(dbl2longPerc(mem.getFreePercent()), "FreePercent", PLAT, SYSMEM_RESOURCE);
tracer.traceCounter(dbl2longPerc(mem.getUsedPercent()), "UsedPercent", PLAT, SYSMEM_RESOURCE);
}
/**
* Traces metrics on NIC trafic and meta
*/
protected void traceNics() {
StringBuilder b = new StringBuilder("\n\t=================================\n\tDiscovered NICs\n\t=================================");
for(String nic: hsigar.getNetInterfaceList()) {
NetworkInterface jnic = null;
try {
jnic = NetworkInterface.getByName(("lo0".equals(nic) ? "lo" : nic)); // Windows reports "lo" where sigar sees "lo0"
if(jnic==null || !jnic.isUp()) {
continue;
}
} catch (Exception e) { continue; }
if(collectionSweep==0) {
NetInterfaceConfig config = hsigar.getNetInterfaceConfig(nic);
b.append("\n\t").append(nic).append("/").append(config.getName()).append("\t(").append(config.getDescription()).append(")");
}
NetInterfaceStat nicStat = hsigar.getNetInterfaceStat(nic);
tracer.traceDeltaGauge(nicStat.getRxBytes(), "RXBytes", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxBytes(), "TXBytes", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getRxDropped(), "RXDropped", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxDropped(), "TXDropped", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getRxErrors(), "RXErrors", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxErrors(), "TXErrors", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getRxPackets(), "RXPackets", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxPackets(), "TXPackets", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getRxOverruns(), "RXOverruns", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxOverruns(), "TXOverruns", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxCollisions(), "TXCollisions", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getTxCarrier(), "TxCarrier", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
tracer.traceDeltaGauge(nicStat.getSpeed(), "Speed", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic));
if((collectionSweep==0 || collectionSweep%fsRescanCollectionSweep==0) && traceMeta) {
NetInterfaceConfig config = hsigar.getNetInterfaceConfig(nic);
tracer.traceString(config.getAddress(), "Address", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getBroadcast(), "Broadcast", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(jnic.getDisplayName(), "DisplayName", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getDescription(), "Description", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getDestination(), "Destination", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getHwaddr(), "MAC", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getName(), "Name", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getNetmask(), "Netmask", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceString(config.getType(), "Type", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceCounter(config.getMetric(), "Metric", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceCounter(config.getMtu(), "Mtu", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
tracer.traceCounter(config.getFlags(), "Flags", PLAT, NIC_RESOURCE, String.format(NIC_NAME, nic), META_TAG);
}
}
if(collectionSweep==0) {
b.append("\n");
log(b);
}
}
/**
* Collects individual and aggregate CPU percentage utilization localStats.
*/
protected void traceCpus() {
int cid = 0;
if(traceAllCpus) {
for(CpuPerc c : hsigar.getCpuPercList()) {
traceCpuPerc(c, String.format(CPU_NAME, cid));
cid++;
}
}
traceCpuPerc(hsigar.getCpuPerc(), String.format(CPU_NAME, "all"));
if((collectionSweep==0 || collectionSweep%fsRescanCollectionSweep==0) && traceMeta && traceAllCpus) {
CpuInfo[] infos = hsigar.getCpuInfoList();
tracer.traceCounter(infos[0].getTotalCores(),"TotalCores", PLAT, CPU_RESOURCE, META_TAG);
tracer.traceCounter(infos[0].getTotalCores(),"TotalSockets", PLAT, CPU_RESOURCE, META_TAG);
for(int i = 0; i < infos.length; i++) {
tracer.traceString(infos[i].getModel(),"Model", PLAT, CPU_RESOURCE, META_TAG, String.format(CPU_NAME, i));
tracer.traceString(infos[i].getVendor(),"Vendor", PLAT, CPU_RESOURCE, META_TAG, String.format(CPU_NAME, i));
tracer.traceCounter(infos[i].getCacheSize(),"CacheSize", PLAT, CPU_RESOURCE, META_TAG, String.format(CPU_NAME, i));
tracer.traceCounter(infos[i].getCoresPerSocket(),"CoresPerSocket", PLAT, CPU_RESOURCE, META_TAG, String.format(CPU_NAME, i));
tracer.traceCounter(infos[i].getMhz(),"Mhz", PLAT, CPU_RESOURCE, META_TAG, String.format(CPU_NAME, i));
tracer.traceCounter(infos[i].getCoresPerSocket(),"CoresPerSocket", PLAT, CPU_RESOURCE, META_TAG, String.format(CPU_NAME, i));
}
}
}
/**
* Traces the passed PCU percentage localStats
* @param c The CPU percentage localStats
* @param cpuName The cpu name
*/
private void traceCpuPerc(CpuPerc c, String cpuName) {
tracer.traceGauge(dbl2longPerc(c.getCombined()), "Combined", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getIdle()), "Idle", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getIrq()), "Irq", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getNice()), "Nice", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getSoftIrq()), "SoftIrq", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getStolen()), "Stolen", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getSys()), "Sys", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getUser()), "User", PLAT, CPU_RESOURCE, cpuName);
tracer.traceGauge(dbl2longPerc(c.getWait()), "Wait", PLAT, CPU_RESOURCE, cpuName);
}
/**
* Traces usage localStats about the local file systems
*/
protected void traceFileSystemUsage() {
StringBuilder b = new StringBuilder("\n\t=================================\n\tDiscovered File Systems\n\t=================================");
if(collectionSweep==0 || collectionSweep%fsRescanCollectionSweep==0) {
refreshCollectedFileSystems();
}
if(collectionSweep==0) {
for(String fsName:fileSystemState.keySet()) {
b.append("\n\t").append(fsName);
}
b.append("\n");
log(b);
}
for(Map.Entry<String, long[]> entry: fileSystemState.entrySet()) {
final String dirName = entry.getKey();
final long[] fsState = entry.getValue();
final FileSystemUsage fsu = hsigar.getFileSystemUsageOrNull(dirName);
if(fsu==null) {
String msg = "Detected unmounted filesystem [" + dirName + "]";
log(msg);
tracer.traceString(msg, "FileSystemEvents", PLAT, FS_RESOURCE);
continue;
}
long used = fsu.getUsed();
long total = fsu.getTotal();
long now = SystemClock.time();
if(collectionSweep==0 || collectionSweep%fsTimeToFullCollectionSweep==0) {
if(fsState[FS_STATE_TS]!=0L) {
long secondsUntilFull = timeUntilFull(total, used, now, fsState);
tracer.traceGauge(secondsUntilFull, "SecondsToFull", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
}
fsState[FS_STATE_USED] = used;
fsState[FS_STATE_TOTAL] = total;
fsState[FS_STATE_TS] = now;
}
tracer.traceGauge(fsu.getAvail(), "AvailableKb", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceDeltaGauge(fsu.getDiskReadBytes(), "DiskReadBytes", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceDeltaGauge(fsu.getDiskWriteBytes(), "DiskWriteBytes", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceDeltaGauge(fsu.getDiskReads(), "DiskReads", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceDeltaGauge(fsu.getDiskWrites(), "DiskWrites", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceGauge(fsu.getFree(), "FreeKb", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceGauge(fsu.getTotal(), "TotalKb", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceGauge(fsu.getUsed(), "UsedKb", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
tracer.traceGauge((long)fsu.getDiskQueue(), "DiskQueue", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
// No impl. for Win
tracer.traceGauge((long)fsu.getDiskServiceTime(), "DiskServiceTime", PLAT, FS_RESOURCE, String.format(FS_NAME, dirName.replace(":\\", "")));
}
// for(FileSystem fs: hsigar.getFileSystemList()) {
// log("[FS]:DevName:" + fs.getDevName()
// + "\n\tDirName:" + fs.getDirName()
// + "\n\tOptions:" + fs.getOptions()
// + "\n\tSysTypeName:" + fs.getSysTypeName()
// + "\n\tTypeName:" + fs.getTypeName()
// );
// FileSystemUsage fsu = hsigar.getFileSystemUsageOrNull(fs.getDirName());
// if(fsu==null) log("No FSU for [" + fs.getDirName() + "]");
// else {
// log("[FSU]:DirName:" + fs.getDirName()
// + "\n\tAvail KB:" + fsu.getAvail()
// + "\n\tFree KB:" + fsu.getFree()
// + "\n\tTotal KB:" + fsu.getTotal()
// + "\n\tUsed KB:" + fsu.getUsed()
// + "\n\t%Used KB:" + dbl2longPerc(fsu.getUsePercent())
// + "\n\tDiskQueue:" + fsu.getDiskQueue()
// + "\n\tDiskServiceTime:" + fsu.getDiskServiceTime()
// + "\n\tDiskReadBytes:" + fsu.getDiskReadBytes()
// + "\n\tDiskReads:" + fsu.getDiskReads()
// + "\n\tDiskWriteBytes:" + fsu.getDiskWriteBytes()
// + "\n\tDiskWrites:" + fsu.getDiskWrites()
//
//
// );
// }
// }
}
/**
* Calculates the approximate number of seconds until a file system is full based on the incremental usage in the last period.
* If the file system is already full, returns zero. If there has been no usage, returns {@link Long#MAX_VALUE} (Infinity)
* @param total The file system's total capacity
* @param used The file system usage in this collection period
* @param now The current timestamp
* @param fsState The collected localStats from the prior period
* @return the approximate number of seconds until a file system is full
*/
protected long timeUntilFull(long total, long used, long now, long[] fsState) {
long increment = used - fsState[FS_STATE_USED];
if(increment<1) {
fsState[FS_STATE_NOINCR]++;
if(fsState[FS_STATE_TTF]==Long.MIN_VALUE) {
return Long.MAX_VALUE;
}
return fsState[FS_STATE_TTF];
}
fsState[FS_STATE_NOINCR]=0;
long elapsed = now - fsState[FS_STATE_TS];
long free = total-used;
if(free==0) return 0;
long periodsUntilFull = free/increment;
return TimeUnit.SECONDS.convert(periodsUntilFull * elapsed, TimeUnit.MILLISECONDS);
}
/**
* Updates the file system state, adding any new file systems and removing any unmounted file systems.
*/
protected void refreshCollectedFileSystems() {
// mark long[0] to 0 before refresh
// during collection, set long[0] to 1
// when done, any dir left with long[0]==0 has been unmounted.
for(Map.Entry<String, long[]> entry: fileSystemState.entrySet()) {
entry.getValue()[FS_STATE_FLAG] = 0;
}
for(FileSystem fs: hsigar.getFileSystemList()) {
String dirName = fs.getDirName();
FileSystemUsage fsu = hsigar.getFileSystemUsageOrNull(dirName);
if(fsu==null) continue;
if(fsu.getDiskReadBytes()==-1 && fsu.getDiskWriteBytes()==-1) continue;
long[] fsState = fileSystemState.get(dirName);
if(fsState==null) {
fsState = new long[]{1L,0L,0L,0L,Long.MIN_VALUE,0L};
fileSystemState.put(dirName, fsState);
} else {
fsState[FS_STATE_FLAG] = 1;
}
}
Set<String> removed = new HashSet<String>(fileSystemState.size());
for(Map.Entry<String, long[]> entry: fileSystemState.entrySet()) {
if(entry.getValue()[FS_STATE_FLAG] == 0) {
removed.add(entry.getKey());
}
}
if(!removed.isEmpty()) {
for(String removedFs : removed) {
fileSystemState.remove(removedFs);
String msg = "Detected unmounted filesystem [" + removedFs + "]";
log(msg);
tracer.traceString(msg, "FileSystemEvents", PLAT, FS_RESOURCE);
}
}
if(traceMeta) {
for(FileSystem fs: hsigar.getFileSystemList()) {
String dirName = fs.getDirName();
if(fileSystemState.containsKey(dirName)) continue;
tracer.traceString(fs.getDevName(), "DeviceName", PLAT, FS_RESOURCE, META_TAG, "dirname=" + dirName.replace(":\\", "").replace("/", "~"));
tracer.traceString(fs.getOptions(), "Options", PLAT, FS_RESOURCE, META_TAG, "dirname=" + dirName.replace(":\\", "").replace("/", "~"));
tracer.traceString(fs.getSysTypeName(), "SysType", PLAT, FS_RESOURCE, META_TAG, "dirname=" + dirName.replace(":\\", "").replace("/", "~"));
tracer.traceString(fs.getTypeName(), "Type", PLAT, FS_RESOURCE, META_TAG, "dirname=" + dirName.replace(":\\", "").replace("/", "~"));
}
}
}
private static void l(Object msg) {
System.out.println(msg);
}
private static long dbl2longPerc(double value) {
double d = value*100;
return (long)d;
}
public static void main(String[] args) {
NativeMonitor nm = new NativeMonitor();
for(String s: nm.hsigar.getNetInterfaceList()) {
l("NIC:" + s);
}
}
}