/*
* Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved
* http://www.griddynamics.com
*
* This library is free software; you can redistribute it and/or modify it under the terms of
* the Apache License; either
* version 2.0 of the License, or any later version.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.griddynamics.jagger.agent.impl;
import com.google.common.collect.Maps;
import com.griddynamics.jagger.agent.model.CpuData;
import com.griddynamics.jagger.agent.model.DisksData;
import com.griddynamics.jagger.agent.model.SystemInfoCollector;
import com.griddynamics.jagger.agent.model.TcpData;
import org.apache.commons.lang.StringUtils;
import org.hyperic.sigar.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* User: vshulga
* Date: 7/5/11
* Time: 12:41 PM
* <p/>
* Implementation of general info gathering with hyperic Sigar.
* Collector could be used for getting cpu info, cpu load, memory info, network info, tcp info.
*/
public class SigarSystemInfoCollector implements SystemInfoCollector {
private final static Logger logger = LoggerFactory.getLogger(SigarSystemInfoCollector.class);
private Set<String> interfaceNames;
private static String cpuTemplate = "CPU model %s with %d mhz frequency; with %d cores";
private Sigar sigar;
public SigarSystemInfoCollector() {
}
public void setInterfaceNames(String commaSeparatedInterfaceNames) {
this.interfaceNames = new HashSet<String>(Arrays.asList(StringUtils.split(commaSeparatedInterfaceNames, ", ")));
}
public void setSigar(Sigar sigar) {
this.sigar = sigar;
}
public List<String> getCPUInfo() {
ArrayList<String> result = new ArrayList<String>();
try {
CpuInfo[] cpuInfoList = sigar.getCpuInfoList();
for (CpuInfo cpuInfo : cpuInfoList) {
String cpu = String.format(cpuTemplate, cpuInfo.getModel(), cpuInfo.getMhz(), cpuInfo.getTotalCores());
result.add(cpu);
}
} catch (Exception e) {
logger.warn("exception during getCPUInfo", e);
}
logger.trace("getCPUInfo: {}", result);
return result;
}
public Map<String, String> getCPULoadInfo() {
Map<String, String> result = Maps.newHashMap();
try {
result = sigar.getCpu().toMap();
} catch (Exception e) {
logger.warn("exception during getCPULoadInfo", e);
}
logger.trace("getCPULoadInfo: {}", result);
return result;
}
public Map<String, String> getMemInfo() {
Map<String, String> result = Maps.newHashMap();
try {
result = sigar.getMem().toMap();
} catch (Exception e) {
logger.warn("exception during getMemInfo", e);
}
logger.trace("getMemInfo: {}", result);
return result;
}
public Map<String, String> getNetworkInfo() {
Map<String, String> result = Maps.newHashMap();
try {
result = toMap(sigar.getNetStat());
} catch (Exception e) {
logger.warn("exception during getNetworkInfo", e);
}
logger.trace("getNetworkInfo: {}", result);
return result;
}
private static Map<String, String> toMap(NetStat netStat) {
Map<String, String> result = Maps.newHashMap();
result.put("allInboundTotal", "" + netStat.getAllInboundTotal());
result.put("allOutboundTotal", "" + netStat.getAllOutboundTotal());
result.put("tcpBound", "" + netStat.getTcpBound());
result.put("tcpClose", "" + netStat.getTcpClose());
result.put("tcpCloseWait", "" + netStat.getTcpCloseWait());
result.put("tcpClosing", "" + netStat.getTcpClosing());
result.put("tcpEstablished", "" + netStat.getTcpEstablished());
result.put("tcpFinWait1", "" + netStat.getTcpFinWait1());
result.put("tcpFinWait2", "" + netStat.getTcpFinWait2());
result.put("tcpIdle", "" + netStat.getTcpIdle());
result.put("tcpInboundTotal", "" + netStat.getTcpInboundTotal());
result.put("tcpLastAck", "" + netStat.getTcpLastAck());
result.put("tcpListen", "" + netStat.getTcpListen());
result.put("tcpOutboundTotal", "" + netStat.getTcpOutboundTotal());
result.put("tcpStates", "" + netStat.getTcpStates());
result.put("tcpSynRecv", "" + netStat.getTcpSynRecv());
result.put("tcpSynSent", "" + netStat.getTcpSynSent());
result.put("tcpTimeWait", "" + netStat.getTcpTimeWait());
return result;
}
@Override
public double[] getLoadAverage() {
try {
return sigar.getLoadAverage();
} catch (SigarException e) {
logger.warn("Exception during load average polling", e);
}
return new double[] {0, 0, 0};
}
@Override
public TcpData getTcpData() {
TcpData data = new TcpData();
try {
NetStat stat = sigar.getNetStat();
data.setTcpBound(stat.getTcpBound());
data.setTcpEstablished(stat.getTcpEstablished());
data.setTcpIdle(stat.getTcpIdle());
data.setTcpListen(stat.getTcpListen());
data.setTcpSynchronizedReceived(stat.getTcpSynRecv());
long inboundBytes = 0;
long outboundBytes = 0;
for(String netInterface : sigar.getNetInterfaceList()) {
for(String mask : interfaceNames) {
if(netInterface.matches(mask)) {
inboundBytes += sigar.getNetInterfaceStat(netInterface).getRxBytes();
outboundBytes += sigar.getNetInterfaceStat(netInterface).getTxBytes();
}
}
}
data.setTcpInboundTotal(inboundBytes);
data.setTcpOutboundTotal(outboundBytes);
logger.debug("getTcpData: {}", data);
} catch (SigarException e) {
logger.warn("Exception during getTcpData", e);
}
return data;
}
@Override
public CpuData getCpuData() {
CpuData data = new CpuData();
try {
CpuPerc cpuPerc = sigar.getCpuPerc();
double value = cpuPerc.getIdle();
data.setCpuStateIdle(Double.isNaN(value) ? 0 : value);
value = cpuPerc.getSys();
data.setCpuStateSys(Double.isNaN(value) ? 0 : value);
value = cpuPerc.getUser();
data.setCpuStateUser(Double.isNaN(value) ? 0 : value);
value = cpuPerc.getWait();
data.setCpuStateWait(Double.isNaN(value) ? 0 : value);
value = cpuPerc.getCombined();
data.setCpuStateCombined(Double.isNaN(value) ? 0 : value);
logger.debug("getCpuData: {}", data);
} catch (SigarException e) {
logger.warn("Exception during getCpuData", e);
}
return data;
}
@Override
public DisksData getDisksData() {
DisksData data = new DisksData();
try {
long disksReadBytesTotal = 0;
long disksQueueTotal = 0;
long disksSvcTimeTotal = 0;
long disksWriteBytesTotal = 0;
FileSystem[] devices = sigar.getFileSystemList();
for (FileSystem dev : devices) {
if(FileSystem.TYPE_LOCAL_DISK == dev.getType()) {
DiskUsage disk = sigar.getDiskUsage(dev.getDirName());
disksReadBytesTotal += disk.getReadBytes();
disksWriteBytesTotal += disk.getWriteBytes();
double value = disk.getQueue();
disksQueueTotal += Double.isNaN(value) ? 0 : value;
value = disk.getServiceTime();
disksSvcTimeTotal += Double.isNaN(value) ? 0 : value;
}
}
data.setDisksQueueTotal(disksQueueTotal);
data.setDisksReadBytesTotal(disksReadBytesTotal);
data.setDisksSvcTimeTotal(disksSvcTimeTotal);
data.setDisksWriteBytesTotal(disksWriteBytesTotal);
logger.debug("getDisksData: {}", data);
} catch (SigarException e) {
logger.warn("Exception during getDisksData", e);
}
return data;
}
}