/*
* NOTE: This copyright does *not* cover user programs that use HQ
* program services by normal system calls through the application
* program interfaces provided as part of the Hyperic Plug-in Development
* Kit or the Hyperic Client Development Kit - this is merely considered
* normal use of the program, and does *not* fall under the heading of
* "derived work".
*
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
* This file is part of HQ.
*
* HQ is free software; you can redistribute it and/or modify
* it under the terms version 2 of the GNU General Public License as
* published by the Free Software Foundation. This program 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
//XXX move this class to sigar
package org.hyperic.hq.plugin.system;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.ProcCpu;
import org.hyperic.sigar.ProcCredName;
import org.hyperic.sigar.ProcDiskIO;
import org.hyperic.sigar.ProcMem;
import org.hyperic.sigar.ProcState;
import org.hyperic.sigar.ProcUtil;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarProxy;
public class ProcessData {
public static final String NA = "-";
public static final String LABEL_PID = "PID";
public static final String LABEL_USER = "USER";
public static final String LABEL_STIME = "STIME";
public static final String LABEL_SIZE = "SIZE";
public static final String LABEL_RSS = "RSS";
public static final String LABEL_SHARE = "SHARE";
public static final String LABEL_STATE = "STATE";
public static final String LABEL_TIME = "TIME";
public static final String LABEL_CPU = "%CPU";
public static final String LABEL_MEM = "%MEM";
public static final String LABEL_NAME = "COMMAND";
public static Pattern baseNamePattern = Pattern.compile("\\d+|\\d+:\\d+|u:\\d+");
public static final String PS_HEADER = LABEL_PID + "\t" + LABEL_USER + "\t" + LABEL_STIME + "\t" + LABEL_SIZE
+ "\t" + LABEL_RSS + "\t" + LABEL_SHARE + "\t" + LABEL_STATE + "\t" + LABEL_TIME + "\t" + LABEL_CPU + "\t"
+ LABEL_MEM + "\t" + LABEL_NAME;
private long _pid;
private String _owner;
private long _startTime;
private long _size;
private long _resident;
private long _share;
private char _state;
private long _cpuTotal;
private double _cpuPerc;
private double _memPerc;
private long _totalDiskBytes;
private long _diskBytesRead;
private long _diskBytesWritten;
private String _name;
private String[] _args;
private Map _env;
private ProcState _procState;
private ProcCredName _procCredName;
private ProcCpu _procCpu;
private ProcMem _procMem;
private ProcDiskIO _procDiskIO;
public ProcessData() {
}
public void populate(SigarProxy sigar, long pid) throws SigarException {
try {
_args = sigar.getProcArgs(pid);
} catch (SigarException e) {
_args = new String[] {};
}
try {
_env = sigar.getProcEnv(pid);
} catch (SigarException e) {
_env = new HashMap();
}
_procState = sigar.getProcState(pid);
final String unknown = "???";
_pid = pid;
try {
_procCredName = sigar.getProcCredName(pid);
_owner = _procCredName.getUser();
} catch (SigarException e) {
_owner = unknown;
}
try {
_procDiskIO = sigar.getProcDiskIO(pid);
_totalDiskBytes = _procDiskIO.getBytesTotal();
_diskBytesRead = _procDiskIO.getBytesRead();
_diskBytesWritten = _procDiskIO.getBytesWritten();
} catch (SigarException e) {
_totalDiskBytes = _diskBytesRead = _diskBytesWritten = Sigar.FIELD_NOTIMPL;
}
try {
_procCpu = sigar.getProcCpu(pid);
_startTime = _procCpu.getStartTime();
} catch (SigarException e) {
_startTime = Sigar.FIELD_NOTIMPL;
}
try {
_procMem = sigar.getProcMem(pid);
_size = _procMem.getSize();
_resident = _procMem.getResident();
_share = _procMem.getShare();
_memPerc = (double) _resident / sigar.getMem().getTotal();
} catch (SigarException e) {
_memPerc = _size = _resident = _share = Sigar.FIELD_NOTIMPL;
}
_state = _procState.getState();
if (_procCpu != null) {
_cpuTotal = _procCpu.getTotal();
_cpuPerc = _procCpu.getPercent();
} else {
_cpuPerc = _cpuTotal = Sigar.FIELD_NOTIMPL;
}
_name = ProcUtil.getDescription(sigar, pid);
}
public static ProcessData gather(SigarProxy sigar, long pid) throws SigarException {
ProcessData data = new ProcessData();
data.populate(sigar, pid);
return data;
}
public String[] getProcArgs() {
return _args;
}
public Map getProcEnv() {
return Collections.unmodifiableMap(_env);
}
public ProcState getProcState() {
return _procState;
}
public ProcCredName getProcCredName() {
return _procCredName;
}
public ProcCpu getProcCpu() {
return _procCpu;
}
public ProcMem getProcMem() {
return _procMem;
}
public long getPid() {
return _pid;
}
public String getOwner() {
return _owner;
}
public long getStartTime() {
return _startTime;
}
public long getSize() {
return _size;
}
public long getShare() {
return _share;
}
public long getResident() {
return _resident;
}
public char getState() {
return _state;
}
public long getCpuTotal() {
return _cpuTotal;
}
public double getCpuPerc() {
return _cpuPerc;
}
public double getMemPerc() {
return _memPerc;
}
public String getName() {
return _name;
}
public String getBaseName() {
int ix = _name.lastIndexOf("/");
if (ix == -1) {
ix = _name.lastIndexOf("\\");
}
if (ix == -1) {
return _name;
} else {
String afterLastSlash = _name.substring(ix + 1).trim();
if (StringUtils.isEmpty(afterLastSlash) || baseNamePattern.matcher(afterLastSlash).matches()) {
// afterLastSlash is empty or of the form: digits, digits:digits, u:digits - return the whole _name
return _name;
}
else {
return afterLastSlash;
}
}
}
public String getFormattedStartTime() {
return getFormattedStartTime(_startTime);
}
public static String getFormattedStartTime(long time) {
if (time == 0) {
return "00:00";
} else if (time == Sigar.FIELD_NOTIMPL) {
return NA;
}
long timeNow = System.currentTimeMillis();
String fmt = "MMMd";
if ((timeNow - time) < ((60 * 60 * 24) * 1000)) {
fmt = "HH:mm";
}
return new SimpleDateFormat(fmt).format(new Date(time));
}
public String getFormattedSize() {
return Sigar.formatSize(_size);
}
public String getFormattedShare() {
return Sigar.formatSize(_share);
}
public String getFormattedResident() {
return Sigar.formatSize(_resident);
}
public String getFormattedTotalDiskBytes() {
return Sigar.formatSize(_totalDiskBytes);
}
public String getFormattedDiskReadBytes() {
return Sigar.formatSize(_diskBytesRead);
}
public String getFormattedDiskWrittenBytes() {
return Sigar.formatSize(_diskBytesWritten);
}
public long getTotalDiskBytes() {
return _totalDiskBytes;
}
public long getdDiskReadBytes() {
return _diskBytesRead;
}
public long getDiskWrittenBytes() {
return _diskBytesWritten;
}
public String getFormattedCpuTotal() {
return getFormattedCpuTotal(_cpuTotal);
}
public static String getFormattedCpuTotal(long total) {
if (total == Sigar.FIELD_NOTIMPL) {
return NA;
}
long t = total / 1000;
String sec = String.valueOf(t % 60);
if (sec.length() == 1) {
sec = "0" + sec;
}
return (t / 60) + ":" + sec;
}
public String getFormattedCpuPerc() {
if (_cpuPerc == Sigar.FIELD_NOTIMPL) {
return NA;
}
return CpuPerc.format(_cpuPerc);
}
public String getFormattedMemPerc() {
if (_memPerc == Sigar.FIELD_NOTIMPL) {
return NA;
}
NumberFormat percentFormat = NumberFormat.getPercentInstance();
percentFormat.setMaximumFractionDigits(1);
percentFormat.setMinimumFractionDigits(1);
return percentFormat.format(_memPerc);
}
public String toString(String delim) {
return _pid + delim + _owner + delim + getFormattedStartTime() + delim + getFormattedSize() + delim
+ getFormattedResident() + delim + getFormattedShare() + delim + _state + delim
+ getFormattedCpuTotal() + delim + getFormattedCpuPerc() + delim + getFormattedMemPerc() + delim
+ getBaseName();
}
@Override
public String toString() {
return toString(",");
}
}