/*
* Tigase Jabber/XMPP Server
* Copyright (C) 2004-2008 "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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://www.gnu.org/licenses/.
*
* $Rev: 1300 $
* Last modified by $Author: kobit $
* $Date: 2008-12-13 10:29:13 +0000 (Sat, 13 Dec 2008) $
*/
package tigase.server.sreceiver.sysmon;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryNotificationInfo;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import java.util.logging.Logger;
import javax.management.Notification;
import javax.management.NotificationEmitter;
import javax.management.NotificationListener;
/**
* Created: Dec 10, 2008 1:23:17 PM
*
* @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a>
* @version $Rev: 1300 $
*/
public class MemMonitor extends AbstractMonitor
implements NotificationListener {
private static Logger log =
Logger.getLogger("tigase.server.sreceiver.sysmon.MemMonitor");
private MemoryMXBean memoryMXBean = null;
@Override
public void init(String jid, double treshold, SystemMonitorTask smTask) {
super.init(jid, treshold, smTask);
memoryMXBean = ManagementFactory.getMemoryMXBean();
NotificationEmitter emitter = (NotificationEmitter)memoryMXBean;
List<MemoryPoolMXBean> memPools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean memoryPoolMXBean : memPools) {
try {
emitter.removeNotificationListener(this, null, memoryPoolMXBean);
} catch (Exception e) { }
MemoryUsage memUsage = memoryPoolMXBean.getUsage();
if (memUsage != null) {
if (memoryPoolMXBean.isUsageThresholdSupported()) {
emitter.addNotificationListener(this, null, memoryPoolMXBean);
long memUsageTreshold =
new Double(new Long(memUsage.getMax()).doubleValue() *
treshold).longValue();
memoryPoolMXBean.setUsageThreshold(memUsageTreshold);
log.config("Setting treshold: " + memUsageTreshold +
" for memory pool: " + memoryPoolMXBean.getName() +
", type: " + memoryPoolMXBean.getType().toString() +
", memMax: " + memUsage.getMax() +
", memUsed: " + memUsage.getUsed() +
", config treeshold: " + treshold);
if (memUsage.getUsed() > memUsageTreshold) {
Notification not = new Notification(
MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
this, 1);
handleNotification(not, memoryPoolMXBean);
}
} else {
log.config("Memory pool name: " + memoryPoolMXBean.getName() +
", type: " + memoryPoolMXBean.getType().toString() +
" usage threshold is not supported.");
}
} else {
log.config("Memory pool name: " + memoryPoolMXBean.getName() +
", type: " + memoryPoolMXBean.getType().toString() +
" is invalid.");
}
}
}
public void handleNotification(Notification note, Object handback) {
if (note.getType().equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
log.info("Usage threshold exceeded, sending notification.");
NumberFormat format = NumberFormat.getIntegerInstance();
if (format instanceof DecimalFormat) {
DecimalFormat decf = (DecimalFormat) format;
decf.applyPattern(decf.toPattern() + " KB");
}
MemoryPoolMXBean memoryPoolMXBean = (MemoryPoolMXBean) handback;
String message = "Threshold " +
format.format(memoryPoolMXBean.getUsageThreshold() / 1024) +
" for memory pool: " + memoryPoolMXBean.getName() +
", type: " + memoryPoolMXBean.getType().toString() +
" exceeded.";
sendWarningOut(message, handback);
}
}
public String getState() {
NumberFormat format = NumberFormat.getIntegerInstance();
if (format instanceof DecimalFormat) {
DecimalFormat decf = (DecimalFormat) format;
decf.applyPattern(decf.toPattern() + " KB");
}
NumberFormat formp = NumberFormat.getPercentInstance();
formp.setMaximumFractionDigits(2);
StringBuilder sb = new StringBuilder();
List<MemoryPoolMXBean> memPools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean memoryPoolMXBean : memPools) {
MemoryUsage memUsage = memoryPoolMXBean.getUsage();
if (memUsage != null && memoryPoolMXBean.isUsageThresholdSupported()) {
sb.append("Memory pool: " + memoryPoolMXBean.getName() +
", type: " + memoryPoolMXBean.getType().toString() +
", usage: " + format.format(memUsage.getUsed()/1024) +
" of " + format.format(memUsage.getMax()/1024) +
" - " +
formp.format(new Long(memUsage.getUsed()).doubleValue()/
new Long(memUsage.getMax()).doubleValue()) +
", treshold: " +
format.format(memoryPoolMXBean.getUsageThreshold() / 1024) +
"\n");
}
}
return sb.toString();
}
}