/* * Copyright 2008 to the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.impl.system.measurable.cpu; import org.rioproject.impl.system.measurable.MXBeanMonitor; import org.rioproject.impl.system.measurable.SigarHelper; import org.rioproject.system.MeasuredResource; import org.rioproject.system.measurable.cpu.ProcessCpuUtilization; import org.rioproject.watch.ThresholdValues; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; /** * CPU monitor that obtains process CPU utilization. This utility uses either * Hyperic SIGAR, or {@link com.sun.management.OperatingSystemMXBean} to obtain * process CPU time. Hyperic SIGAR is preferred. If not available * the <tt>com.sun.management.OperatingSystemMXBean</tt> will be used. * * @author Dennis Reedy */ public class ProcessCPUHandler implements MXBeanMonitor<OperatingSystemMXBean> { private com.sun.management.OperatingSystemMXBean osMBean; private double startTime; private double cpuBefore; private String id; private ThresholdValues tVals; private long pid; private SigarHelper sigar; static Logger logger = LoggerFactory.getLogger(ProcessCPUHandler.class.getPackage().getName()); public ProcessCPUHandler() { sigar = SigarHelper.getInstance(); if(sigar!=null) { pid = sigar.getPid(); } } public ProcessCPUHandler(long pid) { sigar = SigarHelper.getInstance(); if (sigar!=null) { this.pid = pid; } } public void setMXBean(OperatingSystemMXBean mxBean) { if(mxBean instanceof com.sun.management.OperatingSystemMXBean) { osMBean = (com.sun.management.OperatingSystemMXBean)mxBean; } } public void setPID(long pid) { this.pid = pid; } public void setStartTime(long startTime) { this.startTime = startTime; } public void setID(String id) { this.id = id; } public void setThresholdValues(ThresholdValues tVals) { this.tVals = tVals; } public MeasuredResource getMeasuredResource() { return getUtilization(); } public void terminate() { } private synchronized ProcessCpuUtilization getUtilization() { ProcessCpuUtilization pCpu; if (sigar!=null) { try { /* On rare occasions the percentage has been a negative value, * always make sure its a postive value */ double percent = Math.abs(sigar.getProcessCpuPercentage(pid)); long sys = sigar.getProcessCpuSys(pid); long user = sigar.getProcessCpuUser(pid); //System.out.println("User time....." + user); //System.out.println("Sys time......" + sys); //System.out.println("Percent......." + percent); //System.out.println("------------") pCpu = new ProcessCpuUtilization(id, percent, sys, user, tVals); } catch(Exception e) { logger.warn("SIGAR exception getting ProcessCpu, get CPU process utilization using JMX", e); double percent = getUtilizationUsingJMX(); pCpu = new ProcessCpuUtilization(id, percent, tVals); } } else { double percent = getUtilizationUsingJMX(); pCpu = new ProcessCpuUtilization(id, percent, tVals); } return pCpu; } private double getUtilizationUsingJMX() { double utilization = 0; checkMXBean(); if(osMBean==null) return 0; double cpuAfter = osMBean.getProcessCpuTime(); double endTime = System.nanoTime(); if(endTime>startTime) { utilization = (cpuAfter-cpuBefore)/(endTime-startTime); } startTime = endTime; cpuBefore = cpuAfter; return utilization; } private void checkMXBean() { if(osMBean==null) { OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean(); setMXBean(mxBean); } } }