策划和开发需求openfire数据
(1)使用jvm暴露接口进行监控:
jvm接口介绍:http://blog.csdn.net/linghunhong/article/details/6438409
在ServerStarter.java中start方法最后添加mbean注册:
[java] view plaincopy
<span style="white-space:pre"> </span>/**
* 注册jmx
*
*/
MBeanServer ms = ManagementFactory.getPlatformMBeanServer();
ObjectName ofJmxName = new ObjectName("******:type=***");
Class jmxClass = loader.loadClass(
"org.jmx.你的mbean实现");
ms.registerMBean(jmxClass.newInstance(),ofJmxName);
//注册结束
你的mbean注册中可以实现对已有统计的接口,openfire统计相关都在StatisticsManager.java中
然后可以使用jdk提供的jconsole.exe监控查看
(2)数据库连接监控:
安装Load Statistic插件
(3)数据包聊天、登陆用户监控:
安装Monitoring Service插件
(4)
要求:统计消息转发的最长时长、最短时长、平均时长
统计IQ最长时长、最短时长、平均时长
方案:
1、利用openfire提供的PacketInterceptor,在interceptPacket方法中实现对IQ和Message的日志打印(具体打印内容自定义)。可以每个一段时间对日志内容进行分析
2、利用Monitoring Service提供的接口进行仿照开发
制作插件,主体部分逻辑如下:
[java] view plaincopy
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.jivesoftware.openfire.interceptor.InterceptorManager;
import org.jivesoftware.openfire.interceptor.PacketInterceptor;
import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.openfire.stats.Statistic;
import org.jivesoftware.openfire.stats.StatisticsManager;
import org.jivesoftware.openfire.stats.i18nStatistic;
import org.picocontainer.Startable;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
/**
* Creates and manages Enteprise-specific statistics, specifically: <ul>
* message 转发最长时间、最短时间、平均时间、所有时间、数目
*
* </ul>
*
* @author
*/
public class StatisticsModule implements Startable {
//message 统计相关key
public static final String MESSAGE_COUNT_KEY = "m_count";
public static final String MESSAGE_LONGEST_TIME_KEY = "m_longest_time";
public static final String MESSAGE_SHORTEST_TIME_KEY = "m_shortest_time";
public static final String MESSAGE_ALL_TIME_KEY = "m_all_time";
public static final String MESSAGE_AVG_TIME_KEY = "m_avg_time";
//message统计存储
private ConcurrentHashMap<String,AtomicLong> m_timeHash = new ConcurrentHashMap<String,AtomicLong>() ;
private AtomicInteger message_Count = new AtomicInteger();
private AtomicLong messgae_longestTime = new AtomicLong();
private AtomicLong message_shortestTime = new AtomicLong(100000l);
private AtomicLong message_allTime = new AtomicLong();
private StatisticsManager statisticsManager;
private PacketInterceptor packetInterceptor;
// private long
public void start() {
// Retrieve instance of StatisticsManager
statisticsManager = StatisticsManager.getInstance();
// Register a packet listener so that we can track packet traffic.
packetInterceptor = new PacketInterceptor() {
public void interceptPacket(Packet packet, Session session, boolean incoming,
boolean processed)
{
if(null==packet.getID()){
//没有id的不能统计
return;
}
// Only track processed packets so that we don't count them twice.
if (incoming&&!processed) {
if (packet instanceof Message) {
m_timeHash.put(packet.getID(),new AtomicLong(System.currentTimeMillis()));
}else if(packet instanceof IQ){
iq_timeHash.put(packet.getID(), new AtomicLong(System.currentTimeMillis()));
}
}else if(incoming&&processed){
if (packet instanceof Message) {
AtomicLong time = m_timeHash.get(packet.getID());
if(time!=null){
//end-start
//获取longest时间和shortest时间,比较,如果需要的话保存
//获取all,进行加法操作
//获取count进行自增1操作
//删除这个map
long t = System.currentTimeMillis()-time.longValue();
if(messgae_longestTime.longValue()<t){
messgae_longestTime.set(t);
}
if(message_shortestTime.longValue()>t){
message_shortestTime.set(t);
}
message_allTime.getAndAdd(t);
message_Count.incrementAndGet();
m_timeHash.remove(packet.getID());
}
}
}
}
};
InterceptorManager.getInstance().addInterceptor(packetInterceptor);
// Register all statistics.
addPacketNumberStatistic();
addPacketAllTimeStatistic();
addPacketLongestTimeStatistic();
addPacketShortestTimeStatistic();
addPacketAvgTimeStatistic();
}
/**
* Remove all registered statistics.
*/
public void stop() {
// Remove Statistic
statisticsManager.removeStatistic(MESSAGE_COUNT_KEY);
statisticsManager.removeStatistic(MESSAGE_LONGEST_TIME_KEY);
statisticsManager.removeStatistic(MESSAGE_SHORTEST_TIME_KEY);
statisticsManager.removeStatistic(MESSAGE_ALL_TIME_KEY);
statisticsManager.removeStatistic(MESSAGE_AVG_TIME_KEY);
statisticsManager = null;
// Remove the packet listener.
InterceptorManager.getInstance().removeInterceptor(packetInterceptor);
packetInterceptor = null;
message_Count = null;
messgae_longestTime = null;
message_shortestTime = null;
message_allTime = null;
m_timeHash = null;
}
/**
* Tracks the total number of message
*/
private void addPacketAvgTimeStatistic() {
// Register a statistic.
Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_AVG_TIME_KEY, null, Statistic.Type.count) {
public double sample() {
if(message_Count.longValue()==0){
return 0;
}
return message_allTime.longValue()/message_Count.longValue();
}
public boolean isPartialSample() {
return true;
}
};
statisticsManager.addStatistic(MESSAGE_AVG_TIME_KEY, packetTrafficStatistic);
}
/**
* Tracks the total number of message
*/
private void addPacketNumberStatistic() {
// Register a statistic.
Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_COUNT_KEY, null, Statistic.Type.count) {
public double sample() {
return message_Count.get();
}
public boolean isPartialSample() {
return true;
}
};
statisticsManager.addStatistic(MESSAGE_COUNT_KEY, packetTrafficStatistic);
}
/**
* Tracks the total time of message
*/
private void addPacketAllTimeStatistic() {
// Register a statistic.
Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_ALL_TIME_KEY, null, Statistic.Type.count) {
public double sample() {
return message_allTime.get();
}
public boolean isPartialSample() {
return true;
}
};
statisticsManager.addStatistic(MESSAGE_ALL_TIME_KEY, packetTrafficStatistic);
}
/**
* Tracks the longestTime of message
*/
private void addPacketLongestTimeStatistic() {
// Register a statistic.
Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_LONGEST_TIME_KEY, null, Statistic.Type.count) {
public double sample() {
return messgae_longestTime.get();
}
public boolean isPartialSample() {
return true;
}
};
statisticsManager.addStatistic(MESSAGE_LONGEST_TIME_KEY, packetTrafficStatistic);
}
/**
* Tracks the shortestTime of message
*/
private void addPacketShortestTimeStatistic() {
// Register a statistic.
Statistic packetTrafficStatistic = new i18nStatistic(MESSAGE_SHORTEST_TIME_KEY, null, Statistic.Type.count) {
public double sample() {
return message_shortestTime.get();
}
public boolean isPartialSample() {
return true;
}
};
statisticsManager.addStatistic(MESSAGE_SHORTEST_TIME_KEY, packetTrafficStatistic);
}
}
这样,以上信息就能在jmx接口中暴露出来了