/* * Copyright 1999-2012 Alibaba Group. * * 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 com.alibaba.cobar.manager.web.ajax; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_COMMAND; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_CONNECTION; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_DATABASES; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_DATANODES; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_DATASOURCES; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_PROCESSOR_STATUS; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_SERVER_STATUS; import static com.alibaba.cobar.manager.util.ConstantDefine.TYPE_THREAD_POOL; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.beanutils.PropertyUtilsBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.web.HttpRequestHandler; import com.alibaba.cobar.manager.dao.CobarAdapterDAO; import com.alibaba.cobar.manager.dataobject.cobarnode.CommandStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.ConnectionStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.DataNodesStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.DataSources; import com.alibaba.cobar.manager.dataobject.cobarnode.ProcessorStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.ServerStatus; import com.alibaba.cobar.manager.dataobject.cobarnode.ThreadPoolStatus; import com.alibaba.cobar.manager.service.CobarAccesser; import com.alibaba.cobar.manager.service.XmlAccesser; import com.alibaba.cobar.manager.util.FormatUtil; import com.alibaba.cobar.manager.util.ListSortUtil; import com.alibaba.cobar.manager.util.MathUtil; /** * (created at 2010-8-27) * * @author <a href="mailto:shuo.qius@alibaba-inc.com">QIU Shuo</a> * @author haiqing.zhuhq 2011-9-1 */ public class CobarNodeInstantPerfValueAjax implements HttpRequestHandler, InitializingBean { private XmlAccesser xmlAccesser; private CobarAccesser cobarAccesser; private static final int NET_IN = 1; private static final int NET_OUT = 2; private static final int CONNECTION = 3; private static final int REQUEST_COUNT = 4; public void setCobarAccesser(CobarAccesser cobarAccesser) { this.cobarAccesser = cobarAccesser; } public void setXmlAccesser(XmlAccesser xmlAccesser) { this.xmlAccesser = xmlAccesser; } @Override public void afterPropertiesSet() throws Exception { if (null == xmlAccesser) { throw new IllegalArgumentException("property 'xmlAccesser' is null!"); } if (null == cobarAccesser) { throw new IllegalArgumentException("property 'cobarAccesser' is null!"); } } private long groupBy(List<ProcessorStatus> list, int type) { long result = 0; switch (type) { case NET_IN: for (ProcessorStatus p : list) { result += p.getNetIn(); } break; case NET_OUT: for (ProcessorStatus p : list) { result += p.getNetOut(); } break; case CONNECTION: for (ProcessorStatus p : list) { result += p.getConnections(); } break; case REQUEST_COUNT: for (ProcessorStatus p : list) { result += p.getRequestCount(); } break; default: throw new IllegalArgumentException("invalid parameter"); } return result; } private long groupByCList(List<CommandStatus> list, int type) { long result = 0; switch (type) { case REQUEST_COUNT: for (CommandStatus p : list) { result += p.getQuery(); } break; default: throw new IllegalArgumentException("invalid parameter"); } return result; } /** * Processor Tab * * @param params * @return */ private List<Map<String, Object>> listProcessorStatus(AjaxParams params) { long timestamp = 0; CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); if (!perfAccesser.checkConnection()) { return null; } List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>(); List<ProcessorStatus> list = perfAccesser.listProccessorStatus(); long a[] = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (ProcessorStatus e : list) { a[0] += e.getNetIn(); a[1] += e.getNetOut(); a[2] += e.getRequestCount(); a[3] += e.getrQueue(); a[4] += e.getwQueue(); a[5] += e.getFreeBuffer(); a[6] += e.getTotalBuffer(); a[7] += e.getConnections(); a[8] += e.getBc_count(); timestamp = e.getSampleTimeStamp(); Map<String, Object> map = new HashMap<String, Object>(); map.put("processorId", e.getProcessorId()); map.put("netIn", FormatUtil.formatStore(e.getNetIn())); map.put("netOut", FormatUtil.formatStore(e.getNetOut())); map.put("requestCount", FormatUtil.formatNumber(e.getRequestCount())); map.put("rQueue", e.getrQueue()); map.put("wQueue", e.getwQueue()); map.put("freeBuffer", e.getFreeBuffer()); map.put("totalBuffer", e.getTotalBuffer()); map.put("connections", e.getConnections()); map.put("bc_count", e.getBc_count()); returnList.add(map); } Map<String, Object> total = new HashMap<String, Object>(); total.put("processorId", "TOTAL"); total.put("netIn", FormatUtil.formatStore(a[0])); total.put("netOut", FormatUtil.formatStore(a[1])); total.put("requestCount", FormatUtil.formatNumber(a[2])); total.put("rQueue", a[3]); total.put("wQueue", a[4]); total.put("freeBuffer", a[5]); total.put("totalBuffer", a[6]); total.put("connections", a[7]); total.put("bc_count", a[8]); total.put("sampleTimeStamp", timestamp); total.put("netInC", a[0]); total.put("netOutC", a[1]); total.put("requestCountC", a[2]); returnList.add(total); return returnList; } /** * ThreadPool Tab * * @param params * @return */ private List<Map<String, Object>> listThreadPool(AjaxParams params) { CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); if (!perfAccesser.checkConnection()) { return null; } List<ThreadPoolStatus> pools = perfAccesser.listThreadPoolStatus(); List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>(); for (ThreadPoolStatus t : pools) { Map<String, Object> map = new HashMap<String, Object>(); map.put("threadPoolName", t.getThreadPoolName()); map.put("poolSize", t.getPoolSize()); map.put("activeSize", t.getActiveSize()); map.put("taskQueue", t.getTaskQueue()); map.put("completedTask", FormatUtil.formatNumber(t.getCompletedTask())); map.put("totalTask", FormatUtil.formatNumber(t.getTotalTask())); returnList.add(map); } return returnList; } /** * Command Tab * * @param params * @return */ private List<Map<String, Object>> listCommand(AjaxParams params) { CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); if (!perfAccesser.checkConnection()) { return null; } List<CommandStatus> list = perfAccesser.listCommandStatus(); List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>(); // the last element is total count long a[] = new long[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (CommandStatus l : list) { a[0] += l.getQuery(); a[1] += l.getStmtPrepared(); a[2] += l.getStmtExecute(); a[3] += l.getStmtClose(); a[4] += l.getPing(); a[5] += l.getQuit(); a[6] += l.getOther(); a[7] += l.getInitDB(); a[8] += l.getKill(); Map<String, Object> map = new HashMap<String, Object>(); map.put("processorId", l.getProcessorId()); map.put("stmtPrepared", FormatUtil.formatNumber(l.getStmtPrepared())); map.put("stmtExecute", FormatUtil.formatNumber(l.getStmtExecute())); map.put("query", FormatUtil.formatNumber(l.getQuery())); map.put("stmtClose", FormatUtil.formatNumber(l.getStmtClose())); map.put("ping", FormatUtil.formatNumber(l.getPing())); map.put("quit", FormatUtil.formatNumber(l.getQuit())); map.put("other", FormatUtil.formatNumber(l.getOther())); map.put("kill", FormatUtil.formatNumber(l.getKill())); map.put("initDB", FormatUtil.formatNumber(l.getInitDB())); returnList.add(map); } Map<String, Object> map = new HashMap<String, Object>(); map.put("processorId", "Total"); map.put("stmtPrepared", FormatUtil.formatNumber(a[1])); map.put("stmtExecute", FormatUtil.formatNumber(a[2])); map.put("query", FormatUtil.formatNumber(a[0])); map.put("stmtClose", FormatUtil.formatNumber(a[3])); map.put("ping", FormatUtil.formatNumber(a[4])); map.put("quit", FormatUtil.formatNumber(a[5])); map.put("other", FormatUtil.formatNumber(a[6])); map.put("kill", FormatUtil.formatNumber(a[8])); map.put("initDB", FormatUtil.formatNumber(a[7])); returnList.add(map); return returnList; } /** * Connection Tab * * @param params * @return */ private List<Map<String, Object>> listConnection(AjaxParams params) { CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); if (!perfAccesser.checkConnection()) { return null; } List<ConnectionStatus> list = perfAccesser.listConnectionStatus(); if (null != list) { ListSortUtil.sortConnections(list); } List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>(); for (ConnectionStatus c : list) { Map<String, Object> map = new HashMap<String, Object>(); map.put("processor", c.getProcessor()); map.put("id", c.getId()); map.put("host", c.getHost()); map.put("port", c.getPort()); map.put("local_port", c.getLocal_port()); map.put("schema", c.getSchema()); map.put("charset", c.getCharset()); map.put("netIn", FormatUtil.formatStore(c.getNetIn())); map.put("netOut", FormatUtil.formatStore(c.getNetOut())); map.put("aliveTime", FormatUtil.formatTime(c.getAliveTime() * 1000, 2)); map.put("attempsCount", FormatUtil.formatNumber(c.getAttempsCount())); map.put("recvBuffer", FormatUtil.formatStore(c.getRecvBuffer())); map.put("sendQueue", c.getSendQueue()); map.put("channel", c.getChannel()); returnList.add(map); } return returnList; } @SuppressWarnings({ "unchecked" }) private List<Map<String, Object>> listDatanode(AjaxParams params) { CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); if (!perfAccesser.checkConnection()) { return null; } PropertyUtilsBean util = new PropertyUtilsBean(); List<DataNodesStatus> list = perfAccesser.listDataNodes();; if (null != list) { ListSortUtil.sortDataNodesByPoolName(list); } List<Map<String, Object>> returnList = new ArrayList<Map<String, Object>>(); for (DataNodesStatus c : list) { Map<String, Object> map = null; try { map = util.describe(c); } catch (Exception e1) { throw new RuntimeException(e1); } map.remove("class"); map.remove("executeCount"); map.put("executeCount", FormatUtil.formatNumber(c.getExecuteCount())); map.remove("recoveryTime"); if (-1 != c.getRecoveryTime()) { map.put("recoveryTime", FormatUtil.formatTime(c.getRecoveryTime() * 1000, 2)); } else { map.put("recoveryTime", c.getRecoveryTime()); } returnList.add(map); } return returnList; } private Map<String, Object> getServerStatus(AjaxParams params) { JSONArray array = params.getArray(); JSONObject jobject = array.getJSONObject(0); CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); if (!perfAccesser.checkConnection()) { Map<String, Object> map = new HashMap<String, Object>(); map.put("uptime", 0); map.put("usedMemory", 0); map.put("maxMemory", 0); map.put("totalMemory", 0); map.put("connectionCount", 0); map.put("status", "ERROR"); map.put("version", "UNKNOWN"); map.put("starttime", 0); map.put("netInC", 0); map.put("netOutC", 0); map.put("requestCountC", 0); map.put("sampleTimeStamp", System.currentTimeMillis()); map.put("netIn_deriv", 0); map.put("netOut_deriv", 0); map.put("reCount_deriv", 0); return map; } ServerStatus ss = perfAccesser.getServerStatus(); Map<String, Object> map = new HashMap<String, Object>(); map.put("uptime", ss.getUptime()); map.put("usedMemory", FormatUtil.formatStore(ss.getUsedMemory())); map.put("maxMemory", FormatUtil.formatStore(ss.getMaxMemory())); map.put("totalMemory", FormatUtil.formatStore(ss.getTotalMemory())); List<ProcessorStatus> list = perfAccesser.listProccessorStatus(); List<CommandStatus> cmdList = perfAccesser.listCommandStatus(); long netIn = groupBy(list, NET_IN); long netOut = groupBy(list, NET_OUT); long requestCount = groupByCList(cmdList, REQUEST_COUNT); long connectionCount = groupBy(list, CONNECTION); long timestamp = list.get(list.size() - 1).getSampleTimeStamp(); long o_netIn = jobject.getLong("netIn"); long o_netOut = jobject.getLong("netOut"); long o_requestCount = jobject.getLong("requestCount"); long o_timestamp = jobject.getLong("sampleTimeStamp"); map.put("netInC", netIn); map.put("netOutC", netOut); map.put("requestCountC", requestCount); map.put("sampleTimeStamp", timestamp); map.put("netIn_deriv", FormatUtil.formatNetwork((long) MathUtil.getDerivate(netIn, o_netIn, timestamp, o_timestamp, 1000.0))); map.put("netOut_deriv", FormatUtil.formatNetwork((long) MathUtil.getDerivate(netOut, o_netOut, timestamp, o_timestamp, 1000.0))); map.put("reCount_deriv", FormatUtil.formatNumber((long) MathUtil.getDerivate(requestCount, o_requestCount, timestamp, o_timestamp, 1000.0))); map.put("version", FormatUtil.formatVersion(perfAccesser.getVersion())); map.put("starttime", perfAccesser.getStartUpTime().getFormatTime()); map.put("connectionCount", connectionCount); map.put("status", ss.getStatus()); return map; } @Override public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AjaxParams params = new AjaxParams(request); CobarAdapterDAO perfAccesser = cobarAccesser.getAccesser(params.getCobarNodeId()); JSONArray array = null; String jsonRst = null; String st = params.getValueType(); if (null == st || st.equals("")) { throw new IllegalArgumentException("parameter 'cobarControlValueType' is unknown: " + st); } int type = typeMap.get(st); switch (type) { case TYPE_SERVER_STATUS: jsonRst = JSONObject.fromObject(getServerStatus(params)).toString(2); break; case TYPE_PROCESSOR_STATUS: List<Map<String, Object>> listProcessor = listProcessorStatus(params); array = JSONArray.fromObject(listProcessor); jsonRst = array.toString(2); break; case TYPE_THREAD_POOL: List<Map<String, Object>> listThreadpool = listThreadPool(params); array = JSONArray.fromObject(listThreadpool); jsonRst = array.toString(2); break; case TYPE_COMMAND: List<Map<String, Object>> listCommand = listCommand(params); array = JSONArray.fromObject(listCommand); jsonRst = array.toString(2); break; case TYPE_DATANODES: List<Map<String, Object>> listDatanode = listDatanode(params); array = JSONArray.fromObject(listDatanode); jsonRst = array.toString(2); break; case TYPE_DATABASES: List<String> listDatabase = null; if (perfAccesser.checkConnection()) { listDatabase = perfAccesser.listDataBases(); } array = JSONArray.fromObject(listDatabase); jsonRst = array.toString(2); break; case TYPE_DATASOURCES: List<DataSources> listDatasource = null; if (perfAccesser.checkConnection()) { listDatasource = perfAccesser.listDataSources(); } array = JSONArray.fromObject(listDatasource); jsonRst = array.toString(2); break; case TYPE_CONNECTION: List<Map<String, Object>> listConnection = listConnection(params); array = JSONArray.fromObject(listConnection); jsonRst = array.toString(2); break; default: throw new IllegalArgumentException("parameter 'cobarNodeInstantPerfValueType' is known: " + params.getValueType()); } perfAccesser = null; response.setHeader("Content-Type", "text/json; charset=utf-8"); OutputStream out = response.getOutputStream(); out.write(jsonRst.getBytes("utf-8")); out.flush(); } private static final Map<String, Integer> typeMap = new HashMap<String, Integer>(); static { typeMap.put("serverStatus", TYPE_SERVER_STATUS); typeMap.put("processorStatus", TYPE_PROCESSOR_STATUS); typeMap.put("threadPoolStatus", TYPE_THREAD_POOL); typeMap.put("command", TYPE_COMMAND); typeMap.put("datanodes", TYPE_DATANODES); typeMap.put("connection", TYPE_CONNECTION); typeMap.put("databases", TYPE_DATABASES); typeMap.put("datasources", TYPE_DATASOURCES); } }