package jane.tool; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Map.Entry; import java.util.concurrent.ThreadPoolExecutor; import org.apache.mina.core.session.IoSession; import jane.core.Const; import jane.core.DBManager; import jane.core.HttpCodec; import jane.core.NetManager; import jane.core.OctetsStream; import jane.core.ProcThread; import jane.core.StorageLevelDB; import jane.core.TableBase; public class StatusServer extends NetManager { public StatusServer() { setCodec(HttpCodec.class); } public static ArrayList<Object> genStatusList() { ArrayList<Object> list = new ArrayList<>(); long v1 = 0, v2 = 0, v3 = 0, v4 = 0; for(TableBase<?> table : TableBase.getTables()) { ArrayList<Object> strs = new ArrayList<>(); strs.add(table.getTableName()); int v = table.getCacheSize(); v1 += v; strs.add(v); v = table.getCacheModSize(); v2 += v; strs.add(v); long rc = table.getReadCount(); long rtc = table.getReadStoCount(); v3 += rc; v4 += rtc; strs.add(rc); strs.add(rtc); strs.add(rc > 0 ? String.format("%.2f%%", (double)(rc - rtc) * 100 / rc) : "-.--%"); list.add(strs); } ArrayList<Object> strs = new ArrayList<>(); strs.add("<b>ALL</b>"); strs.add(v1); strs.add(v2); strs.add(v3); strs.add(v4); strs.add(v3 > 0 ? String.format("%.2f%%", (double)(v3 - v4) * 100 / v3) : "-.--%"); list.add(strs); DBManager dbMgr = DBManager.instance(); ThreadPoolExecutor tpe = dbMgr.getProcThreads(); list.add(new SimpleEntry<String, Object>("jane.RpcWaitingCount", NetManager.getRpcCount())); list.add(new SimpleEntry<String, Object>("jane.ProcSessionCount", dbMgr.getSessionCount())); list.add(new SimpleEntry<String, Object>("jane.ProcWaitingCount", dbMgr.getProcQueuedCount())); list.add(new SimpleEntry<String, Object>("jane.ProcQueueCount", tpe.getQueue().size())); list.add(new SimpleEntry<String, Object>("jane.ProcThreadCount", tpe.getActiveCount() + "/" + tpe.getPoolSize() + "/" + tpe.getLargestPoolSize())); list.add(new SimpleEntry<String, Object>("jane.ProcCompletedCount", tpe.getCompletedTaskCount())); list.add(new SimpleEntry<String, Object>("jane.ProcInterruptCount", ProcThread.getInterruptCount())); return list; } @SuppressWarnings("unchecked") public static void genStatus(StringBuilder sb) { ArrayList<Object> list = genStatusList(); sb.append("<table border=1 style=border-collapse:collapse><tr bgcolor=silver><td><b>Table</b><td><b>RCacheSize</b><td><b>WCacheSize</b><td><b>RCount</b><td><b>RCacheMissCount</b><td><b>RCacheRatio</b>\n"); for(Object obj : list) { if(obj instanceof ArrayList) { ArrayList<Object> objs = (ArrayList<Object>)obj; int n = objs.size(); if(n > 0) { sb.append("<tr><td bgcolor=silver>").append(objs.get(0)); for(int i = 1; i < n; ++i) sb.append("<td align=right>").append(objs.get(i)); sb.append('\n'); } } } sb.append("</table>\n<p>\n<table border=1 style=border-collapse:collapse>\n"); for(Object obj : list) { if(obj instanceof Entry) { Entry<String, Object> e = (Entry<String, Object>)obj; sb.append("<tr><td bgcolor=silver>").append(e.getKey()).append("<td align=right>").append(e.getValue()).append('\n'); } } sb.append("</table>\n"); } public static void genLevelDBInfo(StringBuilder sb) { sb.append("<table border=1 style=border-collapse:collapse><tr bgcolor=silver><td><b>property</b><td><b>value</b>\n"); for(int i = 0; i < 7; ++i) { sb.append("<tr><td bgcolor=silver>").append("num-files-at-level" + i); sb.append("<td align=right>").append(StorageLevelDB.instance().getProperty("leveldb.num-files-at-level" + i)).append('\n'); } sb.append("<tr><td bgcolor=silver>").append("approximate-memory-usage"); sb.append("<td align=right>").append(StorageLevelDB.instance().getProperty("leveldb.approximate-memory-usage")).append('\n'); sb.append("</table>\n"); sb.append("<b>stats</b><br><pre>"); sb.append(StorageLevelDB.instance().getProperty("leveldb.stats")).append("</pre>\n"); // sb.append("<b>sstables</b><br><pre>"); // sb.append(StorageLevelDB.instance().getProperty("leveldb.sstables")).append("</pre>\n"); } @Override public void messageReceived(IoSession session, Object message) { ArrayList<String> param = new ArrayList<>(); param.add("Server: jane"); if(HttpCodec.getHeadPath((OctetsStream)message).endsWith("/favicon.ico")) HttpCodec.sendHead(session, "404 Not Found", 0, param); else { param.add("Content-Type: text/html; charset=utf-8"); param.add("Cache-Control: no-cache"); param.add("Pragma: no-cache"); StringBuilder sb = new StringBuilder(4000); sb.append("<html><head><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"/><title>Jane Status</title></head><body>\n"); genStatus(sb); sb.append("<p>\n"); genLevelDBInfo(sb); sb.append("</body></html>\n"); byte[] data = sb.toString().getBytes(Const.stringCharsetUTF8); HttpCodec.sendHead(session, "200 OK", data.length, param); HttpCodec.send(session, data); } } }