unable to fetch process time using sigar

2019-07-20 06:04发布

问题:

import java.io.IOException;
import org.hyperic.sigar.*;

public class SigarDemo {

public static void main(String args[]) throws SigarException, IOException
{

    final Sigar sigar = new Sigar();
    final long[] processes = sigar.getProcList();
    ProcTime pt=new ProcTime();
    for (final long processId : processes)  {
    ProcUtil.getDescription(sigar, processId);
    pt=sigar.getProcTime(processId);       
    System.out.println("---"+pt.getStartTime());
    }
}

I am trying to fetch process time of each process using sigar. I am getting this errors:

Exception in thread "main" java.lang.ExceptionInInitializerError
at taskmanager.SigarDemo.main(SigarDemo.java:22)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "sigar.nativeLogging" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294)
at java.lang.System.getProperty(System.java:714)
at org.hyperic.sigar.Sigar.(Sigar.java:78)

I have tried policy file setting all permission. but still I am getting errors. I am using netbeans 8.0 . and I had already setting

-Djava.security.manager -Djava.security.policy=src/dir1/dir2/important.policy

回答1:

I used this code to get the process times

public static void main(String args[]) {
    try {
        final Sigar sigar = new Sigar();
        final long[] processes = sigar.getProcList();
        ProcTime pt = new ProcTime();
        for (final long processId : processes) {
            try {
                ProcUtil.getDescription(sigar, processId);
                pt = sigar.getProcTime(String.valueOf(processId));
                System.out.println("---" + pt.getStartTime());
            } catch (SigarException e) {
                System.out.println("can't accessible...");
            }

        }

    } catch (SigarException ex) {
        ex.printStackTrace();
    }

}

you don't want to specify the security policy file in VM arguments to get the process times. but the thing is getProcTime() will not return process times for some process ids because of SigarPermissionDeniedException.

but you will get process time for some processes without any problem.

I got this idea from a sample demo file from bindings\java\examples folder. I posted it below with slight modification. you can compile and run it to see the result(it includes the process time also)

import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarProxy;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.ProcCredName;
import org.hyperic.sigar.ProcMem;
import org.hyperic.sigar.ProcTime;
import org.hyperic.sigar.ProcState;
import org.hyperic.sigar.ProcUtil;
import org.hyperic.sigar.cmd.Shell;
import org.hyperic.sigar.cmd.SigarCommandBase;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Show process status.
 */
public class Ps extends SigarCommandBase {

    public Ps(Shell shell) {
        super(shell);
    }

    public Ps() {
        super();
    }

    protected boolean validateArgs(String[] args) {
        return true;
    }

    public String getSyntaxArgs() {
        return "[pid|query]";
    }

    public String getUsageShort() {
        return "Show process status";
    }

    public boolean isPidCompleter() {
        return true;
    }

    public void output(String[] args) throws SigarException {
        long[] pids;
        if (args.length == 0) {
            pids = this.proxy.getProcList();
        }
        else {
            pids = this.shell.findPids(args);
        }

        for (int i=0; i<pids.length; i++) {
            long pid = pids[i];
            try {
                output(pid);
            } catch (SigarException e) {
                this.err.println("Exception getting process info for " +
                                 pid + ": " + e.getMessage());
            }
        }
    }

    public static String join(List info) {
        StringBuffer buf = new StringBuffer();
        Iterator i = info.iterator();
        boolean hasNext = i.hasNext();
        while (hasNext) {
            buf.append((String)i.next());
            hasNext = i.hasNext();
            if (hasNext)
                buf.append("\t");
        }

        return buf.toString();
    }

    public static List getInfo(SigarProxy sigar, long pid)
        throws SigarException {

        ProcState state = sigar.getProcState(pid);
        ProcTime time = null;
        String unknown = "???";

        List info = new ArrayList();
        info.add(String.valueOf(pid));

        try {
            ProcCredName cred = sigar.getProcCredName(pid);
            info.add(cred.getUser());
        } catch (SigarException e) {
            info.add(unknown);
        }

        try {
            time = sigar.getProcTime(pid);
            info.add(getStartTime(time.getStartTime()));
            System.out.println("this line has executed..!!!");
        } catch (SigarException e) {
            info.add(unknown);
        }

        try {
            ProcMem mem = sigar.getProcMem(pid);
            info.add(Sigar.formatSize(mem.getSize()));
            info.add(Sigar.formatSize(mem.getRss()));
            info.add(Sigar.formatSize(mem.getShare()));
        } catch (SigarException e) {
            info.add(unknown);
        }

        info.add(String.valueOf(state.getState()));

        if (time != null) {
            info.add(getCpuTime(time));
        }
        else {
            info.add(unknown);
        }

        String name = ProcUtil.getDescription(sigar, pid);
        info.add(name);

        return info;
    }

    public void output(long pid) throws SigarException {
        println(join(getInfo(this.proxy, pid)));
    }

    public static String getCpuTime(long total) {
        long t = total / 1000;
        return t/60 + ":" + t%60;
    }

    public static String getCpuTime(ProcTime time) {
        return getCpuTime(time.getTotal());
    }

    private static String getStartTime(long time) {
        if (time == 0) {
            return "00:00";
        }
        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 static void main(String[] args) throws Exception {
        new Ps().processCommand(args);
    }
}