blob: 96b8672da928849c53587beb5712388ca857fe23 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.jstorm.ui;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.commons.lang.StringUtils;
import org.yaml.snakeyaml.Yaml;
import backtype.storm.Config;
import backtype.storm.generated.ComponentSummary;
import backtype.storm.generated.ErrorInfo;
import backtype.storm.generated.MetricInfo;
import backtype.storm.generated.MetricWindow;
import backtype.storm.generated.TopologyInfo;
import backtype.storm.generated.TopologySummary;
import backtype.storm.utils.Utils;
import com.alibaba.jstorm.client.ConfigExtension;
import com.alibaba.jstorm.common.metric.MetricRegistry;
import com.alibaba.jstorm.common.metric.window.StatBuckets;
import com.alibaba.jstorm.metric.MetricDef;
import com.alibaba.jstorm.ui.model.ColumnData;
import com.alibaba.jstorm.ui.model.LinkData;
import com.alibaba.jstorm.ui.model.PageGenerator;
import com.alibaba.jstorm.ui.model.PageIndex;
import com.alibaba.jstorm.ui.model.PageGenerator.Output;
import com.alibaba.jstorm.ui.model.TableData;
import com.alibaba.jstorm.utils.JStormUtils;
import com.alibaba.jstorm.utils.NetWorkUtils;
public class UIUtils {
public static ScheduledExecutorService scheduExec = Executors.newScheduledThreadPool(4);
public static Long ONE_TABLE_PAGE_SIZE = null;
public static Map readUiConfig() {
Map ret = Utils.readStormConfig();
String curDir = System.getProperty("user.home");
String confPath =
curDir + File.separator + ".jstorm" + File.separator
+ "storm.yaml";
File file = new File(confPath);
if (file.exists()) {
FileInputStream fileStream;
try {
fileStream = new FileInputStream(file);
Yaml yaml = new Yaml();
Map clientConf = (Map) yaml.load(fileStream);
if (clientConf != null) {
ret.putAll(clientConf);
}
if (ONE_TABLE_PAGE_SIZE == null) {
ONE_TABLE_PAGE_SIZE = ConfigExtension.getUiOneTablePageSize(clientConf);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
}
}
if (ret.containsKey(Config.NIMBUS_HOST) == false) {
ret.put(Config.NIMBUS_HOST, "localhost");
}
return ret;
}
public static String getHostIp(String ipPort) {
if (ipPort.contains(":")) {
String firstPart = ipPort.substring(0, ipPort.indexOf(":"));
String lastPart = ipPort.substring(ipPort.indexOf(":"));
return NetWorkUtils.ip2Host(firstPart) + lastPart;
} else {
return NetWorkUtils.ip2Host(ipPort);
}
}
public static String getHost(String ipPort) {
if (ipPort.contains(":")) {
String firstPart = ipPort.substring(0, ipPort.indexOf(":"));
return NetWorkUtils.ip2Host(firstPart);
} else {
return NetWorkUtils.ip2Host(ipPort);
}
}
public static Set<String> getKeys(Collection<MetricInfo> metrics) {
Set<String> ret = new TreeSet<String>();
for (MetricInfo metric : metrics) {
Set<String> oneKeys = metric.get_baseMetric().keySet();
ret.addAll(oneKeys);
}
return ret;
}
public static String getValue(MetricInfo metric, String key, Integer window) {
MetricWindow metricWindow = metric.get_baseMetric().get(key);
if (metricWindow == null) {
return String.valueOf("000.000");
}
Double value = metricWindow.get_metricWindow().get(window);
if (value == null) {
return String.valueOf("000.000");
}
return JStormUtils.formatSimpleDouble(value);
}
public static void checkKey(List<String> ret, Set<String> temp, String key) {
if (temp.contains(key)) {
ret.add(key);
temp.remove(key);
}
return;
}
public static List<String> getSortedKeys(Set<String> keys) {
List<String> ret = new ArrayList<String>();
Set<String> temp = new TreeSet<String>();
temp.addAll(keys);
checkKey(ret, temp, MetricDef.CPU_USED_RATIO);
checkKey(ret, temp, MetricDef.MEMORY_USED);
checkKey(ret, temp, MetricDef.SEND_TPS);
checkKey(ret, temp, MetricDef.RECV_TPS);
checkKey(ret, temp, MetricDef.EMMITTED_NUM);
checkKey(ret, temp, MetricDef.ACKED_NUM);
checkKey(ret, temp, MetricDef.FAILED_NUM);
checkKey(ret, temp, MetricDef.PROCESS_LATENCY);
ret.addAll(temp);
return ret;
}
public static TableData getMetricTable(MetricInfo metricInfo, Integer window) {
TableData table = new TableData();
List<String> headers = table.getHeaders();
List<Map<String, ColumnData>> lines = table.getLines();
// table.setName(UIDef.TOPOLOGY.toUpperCase());
Map<String, MetricWindow> baseMetric = metricInfo.get_baseMetric();
List<String> keys = getSortedKeys(baseMetric.keySet());
headers.addAll(keys);
Map<String, ColumnData> line =
getMetricLine(metricInfo, headers, window);
lines.add(line);
return table;
}
public static Map<String, ColumnData> getMetricLine(MetricInfo metricInfo,
List<String> headers, Integer window) {
Map<String, ColumnData> line = new HashMap<String, ColumnData>();
for (String key : headers) {
String value = getValue(metricInfo, key, window);
ColumnData columnData = new ColumnData();
columnData.addText(value);
line.put(key, columnData);
}
return line;
}
public static void complementingTable(TableData table) {
List<String> headers = table.getHeaders();
List<Map<String, ColumnData>> lines = table.getLines();
for (Map<String, ColumnData> line : lines) {
for (String header : headers) {
ColumnData item = line.get(header);
if (item == null) {
item = new ColumnData();
item.addText("000.000");
line.put(header, item);
}
}
}
return;
}
public static TableData errorTable(String erro) {
TableData table = new TableData();
List<String> headers = table.getHeaders();
List<Map<String, ColumnData>> lines = table.getLines();
headers.add("Error");
Map<String, ColumnData> line = new HashMap<String, ColumnData>();
lines.add(line);
ColumnData columnData = new ColumnData();
columnData.addText(erro);
line.put("Error", columnData);
return table;
}
public static PageGenerator.Output getErrorInfo(Exception e) {
String errMsg = JStormUtils.getErrorInfo(e);
Output ret = new Output();
ret.tables = new ArrayList<TableData>();
ret.rawData =
"!!!!!!!!!!!!!!!! Occur Exception:" + e.getMessage()
+ " !!!!!!!!!\r\n\r\nPlease refresh once again\r\n" + errMsg;
return ret;
}
public static double getDoubleValue(Double value) {
double ret = (value != null ? value.doubleValue() : 0.0);
return ret;
}
public static void getClusterInfoByName(Map conf, String clusterName) {
List<Map> uiClusters = ConfigExtension.getUiClusters(conf);
Map cluster = ConfigExtension.getUiClusterInfo(uiClusters, clusterName);
conf.put(Config.STORM_ZOOKEEPER_ROOT,
ConfigExtension.getUiClusterZkRoot(cluster));
conf.put(Config.STORM_ZOOKEEPER_SERVERS,
ConfigExtension.getUiClusterZkServers(cluster));
conf.put(Config.STORM_ZOOKEEPER_PORT,
ConfigExtension.getUiClusterZkPort(cluster));
}
public static TableData getTopologyTable(
List<TopologySummary> topologySummaries,
Map<String, String> paramMap) {
TableData table = new TableData();
List<String> headers = table.getHeaders();
List<Map<String, ColumnData>> lines = table.getLines();
table.setName(UIDef.TOPOLOGY.toUpperCase());
headers.add(UIDef.HEADER_TOPOLOGY_NAME);
headers.add(UIDef.HEADER_TOPOLOGY_ID);
headers.add(UIDef.HEADER_STATUS);
headers.add(UIDef.HEADER_UPTIME);
headers.add(UIDef.HEADER_WORKER_NUM);
headers.add(UIDef.HEADER_TASK_NUM);
headers.add(UIDef.HEADER_CONF);
headers.add(UIDef.HEADER_ERROR);
if (topologySummaries == null) {
return table;
}
for (TopologySummary topologySummary : topologySummaries) {
Map<String, ColumnData> line = new HashMap<String, ColumnData>();
lines.add(line);
ColumnData topologyNameColumn = new ColumnData();
LinkData linkData = new LinkData();
topologyNameColumn.addLinkData(linkData);
line.put(UIDef.HEADER_TOPOLOGY_NAME, topologyNameColumn);
linkData.setUrl(UIDef.LINK_WINDOW_TABLE);
linkData.setText(topologySummary.get_name());
linkData.addParam(UIDef.CLUSTER, paramMap.get(UIDef.CLUSTER));
linkData.addParam(UIDef.PAGE_TYPE, UIDef.PAGE_TYPE_TOPOLOGY);
linkData.addParam(UIDef.TOPOLOGY, topologySummary.get_id());
ColumnData topologyIdColumn = new ColumnData();
topologyIdColumn.addText(topologySummary.get_id());
line.put(UIDef.HEADER_TOPOLOGY_ID, topologyIdColumn);
ColumnData statusColumn = new ColumnData();
statusColumn.addText(topologySummary.get_status());
line.put(UIDef.HEADER_STATUS, statusColumn);
ColumnData uptimeColumn = new ColumnData();
int uptime = topologySummary.get_uptime_secs();
uptimeColumn.addText(StatBuckets.prettyUptimeStr(uptime));
line.put(UIDef.HEADER_UPTIME, uptimeColumn);
ColumnData workerNumColumn = new ColumnData();
workerNumColumn.addText(String.valueOf(topologySummary
.get_num_workers()));
line.put(UIDef.HEADER_WORKER_NUM, workerNumColumn);
ColumnData taskNumColumn = new ColumnData();
taskNumColumn.addText(String.valueOf(topologySummary
.get_num_tasks()));
line.put(UIDef.HEADER_TASK_NUM, taskNumColumn);
ColumnData confColumn = new ColumnData();
LinkData confLink = new LinkData();
confColumn.addLinkData(confLink);
line.put(UIDef.HEADER_CONF, confColumn);
confLink.setUrl(UIDef.LINK_TABLE_PAGE);
confLink.setText(UIDef.HEADER_CONF.toLowerCase());
confLink.addParam(UIDef.CLUSTER, paramMap.get(UIDef.CLUSTER));
confLink.addParam(UIDef.PAGE_TYPE, UIDef.PAGE_TYPE_CONF);
confLink.addParam(UIDef.CONF_TYPE, UIDef.CONF_TYPE_TOPOLOGY);
confLink.addParam(UIDef.TOPOLOGY, topologySummary.get_id());
ColumnData errorColumn = new ColumnData();
String errorInfo = String.valueOf(topologySummary.get_error_info());
errorColumn.addText(errorInfo);
line.put(UIDef.HEADER_ERROR, errorColumn);
}
return table;
}
public static TableData getComponentTable(TopologyInfo topologyInfo,
List<ComponentSummary> componentSummaries,
Map<String, MetricInfo> componentMetrics,
Map<String, String> paramMap, Integer window) {
TableData table = new TableData();
List<String> headers = table.getHeaders();
List<Map<String, ColumnData>> lines = table.getLines();
List<String> keys =
UIUtils.getSortedKeys(UIUtils.getKeys(componentMetrics.values()));
headers.add(UIDef.HEADER_COMPONENT_NAME);
headers.add(UIDef.HEADER_TASK_NUM);
headers.addAll(keys);
headers.add(UIDef.HEADER_ERROR);
for (ComponentSummary componentSummary : componentSummaries) {
Map<String, ColumnData> line = new HashMap<String, ColumnData>();
lines.add(line);
String name = componentSummary.get_name();
ColumnData nameColumnData = new ColumnData();
LinkData linkData = new LinkData();
nameColumnData.addLinkData(linkData);
line.put(UIDef.HEADER_COMPONENT_NAME, nameColumnData);
linkData.setUrl(UIDef.LINK_WINDOW_TABLE);
linkData.setText(name);
linkData.addParam(UIDef.CLUSTER, paramMap.get(UIDef.CLUSTER));
linkData.addParam(UIDef.PAGE_TYPE, UIDef.PAGE_TYPE_COMPONENT);
linkData.addParam(UIDef.TOPOLOGY, topologyInfo.get_topology()
.get_id());
linkData.addParam(UIDef.COMPONENT, name);
ColumnData taskNumColumn = new ColumnData();
taskNumColumn.addText(String.valueOf(componentSummary
.get_parallel()));
line.put(UIDef.HEADER_TASK_NUM, taskNumColumn);
ColumnData errColumn = new ColumnData();
line.put(UIDef.HEADER_ERROR, errColumn);
List<ErrorInfo> errs = componentSummary.get_errors();
if (errs == null) {
errColumn.addText("");
} else {
for (ErrorInfo err : errs) {
errColumn.addText(err.get_error() + "\r\n");
}
}
MetricInfo metric = componentMetrics.get(name);
if (metric == null) {
continue;
}
for (String key : keys) {
String value = UIUtils.getValue(metric, key, window);
ColumnData columnData = new ColumnData();
columnData.addText(value);
line.put(key, columnData);
}
}
return table;
}
public static ColumnData getConnectionColumnData(Map<String, String> paramMap, String connectionName) {
ColumnData columnData = new ColumnData();
LinkData linkData = new LinkData();
columnData.addLinkData(linkData);
linkData.setUrl(UIDef.LINK_WINDOW_TABLE);
linkData.setText(connectionName);
Map<String, String> linkDataParam = new HashMap<String, String>();
linkData.setParamMap(linkDataParam);
linkDataParam.putAll(paramMap);
linkDataParam.remove(UIDef.POS);
try {
int pos = connectionName.indexOf(":");
if (pos > 0) {
String source = connectionName.substring(0, pos);
linkDataParam.put(UIDef.HOST, source);
}
} catch (Exception e) {
}
return columnData;
}
public static TableData getNettyMetricsTable(Map<String, MetricInfo> metrics,
Integer window, Map<String, String> paramMap) {
TableData nettyTable = new TableData();
nettyTable.setName(MetricDef.NETTY + " Metrics " + StatBuckets.getShowTimeStr(window));
List<String> nettyHeaders = nettyTable.getHeaders();
nettyHeaders.add(UIDef.HEADER_NETWORKER_CONNECTION);
nettyHeaders.addAll(getKeys(metrics.values()));
List<Map<String, ColumnData>> nettyLines = nettyTable.getLines();
for (Entry<String, MetricInfo> entry : metrics.entrySet()) {
String connectionName = entry.getKey();
MetricInfo metricInfo = entry.getValue();
Map<String, ColumnData> line = getMetricLine(metricInfo, nettyHeaders, window);
ColumnData columnData = getConnectionColumnData(paramMap, connectionName);
line.put(UIDef.HEADER_NETWORKER_CONNECTION, columnData);
nettyLines.add(line);
}
return nettyTable;
}
public static List<TableData> getWorkerMetricsTable(Map<String, MetricInfo> metrics,
Integer window, Map<String, String> paramMap) {
List<TableData> ret = new ArrayList<TableData>();
TableData table = new TableData();
ret.add(table);
List<String> headers = table.getHeaders();
List<Map<String, ColumnData>> lines = table.getLines();
table.setName("Worker " + UIDef.METRICS);
List<String> keys = getSortedKeys(UIUtils.getKeys(metrics.values()));
headers.add(UIDef.PORT);
headers.add(MetricDef.NETTY);
headers.addAll(keys);
TreeMap<String, MetricInfo> tmpMap = new TreeMap<String, MetricInfo>();
tmpMap.putAll(metrics);
Map<String, MetricInfo> showMap = new TreeMap<String, MetricInfo>();
long pos = JStormUtils.parseLong(paramMap.get(UIDef.POS), 0);
long index = 0;
for (Entry<String, MetricInfo> entry : tmpMap.entrySet()) {
if (index < pos) {
index ++;
}else if (pos <= index && index < pos + UIUtils.ONE_TABLE_PAGE_SIZE) {
showMap.put(entry.getKey(), entry.getValue());
index++;
}else {
break;
}
}
for (Entry<String, MetricInfo> entry : showMap.entrySet()) {
Map<String, ColumnData> line = new HashMap<String, ColumnData>();
lines.add(line);
String slot = entry.getKey();
MetricInfo metric = entry.getValue();
ColumnData slotColumn = new ColumnData();
slotColumn.addText(slot);
line.put(UIDef.PORT, slotColumn);
ColumnData nettyColumn = new ColumnData();
line.put(MetricDef.NETTY, nettyColumn);
if (StringUtils.isBlank(paramMap.get(UIDef.TOPOLOGY) ) ) {
nettyColumn.addText(MetricDef.NETTY);
}else {
LinkData linkData = new LinkData();
nettyColumn.addLinkData(linkData);
linkData.setUrl(UIDef.LINK_WINDOW_TABLE);
linkData.setText(MetricDef.NETTY);
linkData.addParam(UIDef.CLUSTER, paramMap.get(UIDef.CLUSTER));
linkData.addParam(UIDef.PAGE_TYPE, UIDef.PAGE_TYPE_NETTY);
linkData.addParam(UIDef.TOPOLOGY, paramMap.get(UIDef.TOPOLOGY));
}
for (String key : keys) {
String value = UIUtils.getValue(metric, key, window);
ColumnData valueColumn = new ColumnData();
valueColumn.addText(value);
line.put(key, valueColumn);
}
}
return ret;
}
public static void main(String[] args) {
}
}