无法使用 sigar 获取处理时间

Posted

技术标签:

【中文标题】无法使用 sigar 获取处理时间【英文标题】:unable to fetch process time using sigar 【发布时间】:2014-06-04 10:29:47 【问题描述】:
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());
    

我正在尝试使用 sigar 获取每个进程的进程时间。我收到此错误:

线程“主”java.lang.ExceptionInInitializerError 中的异常 在 taskmanager.SigarDemo.main(SigarDemo.java:22) 引起:java.security.AccessControlException:访问被拒绝(“java.util.PropertyPermission”“sigar.nativeLogging”“read”) 在 java.security.AccessControlContext.checkPermission(AccessControlContext.java:457) 在 java.security.AccessController.checkPermission(AccessController.java:884) 在 java.lang.SecurityManager.checkPermission(SecurityManager.java:549) 在 java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294) 在 java.lang.System.getProperty(System.java:714) 在 org.hyperic.sigar.Sigar.(Sigar.java:78)

我已尝试设置所有权限的策略文件。但我仍然遇到错误。我正在使用 netbeans 8.0 。我已经设置了

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

【问题讨论】:

【参考方案1】:

我使用此代码来获取处理时间

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();
    


您不想在 VM 参数中指定安全策略文件来获取处理时间。但问题是getProcTime() 不会返回某些进程 id 的进程时间,因为SigarPermissionDeniedException

但您将获得某些进程的处理时间,没有任何问题。

我从bindings\java\examples 文件夹中的示例演示文件中得到了这个想法。我把它贴在下面,稍作修改。您可以编译并运行它以查看结果(它还包括处理时间)

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);
    

【讨论】:

但我的实际问题是如何避免“SigarExceptionPermissionDenied”?我知道..我应该写策略文件以获得许可。但是如何写以及在哪里发布?

以上是关于无法使用 sigar 获取处理时间的主要内容,如果未能解决你的问题,请参考以下文章

Sigar介绍与使用

利用Sigar获取系统信息

java获取cpu内存硬盘信息

在 Maven 中使用 SIGAR

JAVA获取计算机CPU硬盘主板网络等信息

Tomcat 8 无法使用“|”处理获取请求在查询参数中?