/* * Tigase Jabber/XMPP Server * Copyright (C) 2004-2012 "Artur Hefczyc" <artur.hefczyc@tigase.org> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. Look for COPYING file in the top folder. * If not, see http://www.gnu.org/licenses/. * * $Rev$ * Last modified by $Author$ * $Date$ */ package tigase.sys; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryUsage; import java.lang.management.OperatingSystemMXBean; import java.lang.management.ThreadMXBean; import java.util.List; import tigase.server.monitor.MonitorRuntime; import tigase.xmpp.JID; /** * Created: Feb 19, 2009 12:15:02 PM * * @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a> * @version $Rev$ */ public abstract class TigaseRuntime { protected static final long SECOND = 1000; protected static final long MINUTE = 60*SECOND; protected static final long HOUR = 60*MINUTE; private int cpus = Runtime.getRuntime().availableProcessors(); private long prevUptime = 0; private long prevCputime = 0; private float cpuUsage = 0F; private MemoryPoolMXBean oldMemPool = null; public static TigaseRuntime getTigaseRuntime() { return MonitorRuntime.getMonitorRuntime(); } public abstract void addShutdownHook(ShutdownHook hook); public abstract void addMemoryChangeListener(MemoryChangeListener memListener); public abstract void addCPULoadListener(CPULoadListener cpuListener); public abstract void addOnlineJidsReporter(OnlineJidsReporter onlineReporter); public abstract boolean hasCompleteJidsInfo(); public abstract boolean isJidOnline(JID jid); public abstract JID[] getConnectionIdsForJid(JID jid); protected TigaseRuntime() { List<MemoryPoolMXBean> memPools = ManagementFactory.getMemoryPoolMXBeans(); for (MemoryPoolMXBean memoryPoolMXBean : memPools) { if (memoryPoolMXBean.getName().toLowerCase().contains("old")) { oldMemPool = memoryPoolMXBean; break; } } } public ResourceState getMemoryState() { return ResourceState.GREEN; } public ResourceState getCPUState() { return ResourceState.GREEN; } public long getProcessCPUTime() { long result = 0; OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean(); if (osMXBean instanceof com.sun.management.OperatingSystemMXBean) { // The easy way if possible com.sun.management.OperatingSystemMXBean sunOSMXBean = (com.sun.management.OperatingSystemMXBean)osMXBean; result = sunOSMXBean.getProcessCpuTime(); } else { // The hard way... ThreadMXBean thBean = ManagementFactory.getThreadMXBean(); for (long thid : thBean.getAllThreadIds()) { result += thBean.getThreadCpuTime(thid); } } return result; } public long getUptime() { return ManagementFactory.getRuntimeMXBean().getUptime(); } public String getUptimeString() { long uptime = ManagementFactory.getRuntimeMXBean().getUptime(); long days = uptime / (24 * HOUR); long hours = (uptime - (days * 24 * HOUR)) / HOUR; long minutes = (uptime - (days * 24 * HOUR + hours * HOUR)) / MINUTE; long seconds = (uptime - (days * 24 * HOUR + hours * HOUR + minutes * MINUTE)) / SECOND; StringBuilder sb = new StringBuilder(); sb.append(days > 0 ? days + (days == 1 ? " day" : " days") : ""); if (hours > 0) { if (sb.length() > 0) { sb.append(", "); } sb.append(hours + (hours == 1 ? " hour" : " hours")); } if (days == 0 && minutes > 0) { if(sb.length() > 0) { sb.append(", "); } sb.append(minutes + (minutes == 1 ? " min" : " mins")); } if (days == 0 && hours == 0 && seconds > 0) { if (sb.length() > 0) { sb.append(", "); } sb.append(seconds + " sec"); } return sb.toString(); } public int getCPUsNumber() { return cpus; } public float getCPUUsage() { long currCputime = -1; long elapsedCpu = -1; long currUptime = getUptime(); long elapsedTime = currUptime - prevUptime; if (prevUptime > 0L && elapsedTime > 500L) { currCputime = getProcessCPUTime(); elapsedCpu = currCputime - prevCputime; cpuUsage = Math.min(99.99F, elapsedCpu / (elapsedTime * 10000F * cpus)); } if (elapsedTime > 500L) { prevUptime = currUptime; prevCputime = currCputime; } // System.out.println("currUptime: " + currUptime + // "- prevUptime: " + prevUptime + " = elapsedTime: " + elapsedTime + // "\n, currCputime: " + currCputime + // " - prevCputime: " + prevCputime + " = elapsedCpu: " + elapsedCpu); return cpuUsage; } public double getLoadAverage() { return ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(); } public int getThreadsNumber() { return ManagementFactory.getThreadMXBean().getThreadCount(); } /** * We try to return OLD memory pool size as this is what is the most interesting * to us. If this is not possible then we return total Heap size. * @return */ public long getHeapMemMax() { if (oldMemPool != null) { MemoryUsage memUsage = oldMemPool.getUsage(); return memUsage.getMax(); } return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getMax(); } /** * We try to return OLD memory pool size as this is what is the most interesting * to us. If this is not possible then we return total Heap used. * @return */ public long getHeapMemUsed() { if (oldMemPool != null) { MemoryUsage memUsage = oldMemPool.getUsage(); return memUsage.getUsed(); } return ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed(); } public float getHeapMemUsage() { return (getHeapMemUsed() * 100F) / getHeapMemMax(); } public long getNonHeapMemMax() { return ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax(); } public long getNonHeapMemUsed() { return ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getUsed(); } public float getNonHeapMemUsage() { return (getNonHeapMemUsed() * 100F) / getNonHeapMemMax(); } }