From 855511232fc0cd3b78e16501385d615f9596ebc7 Mon Sep 17 00:00:00 2001 From: "Hulva Luva.H" Date: Wed, 2 Aug 2017 17:55:31 +0800 Subject: [PATCH 1/7] jmx metrics line chart --- .../controller/JMXMetricController.java | 1 - .../core/db/ElasticsearchOffsetDB.java | 200 +++++------ .../chickling/kmonitor/core/db/OffsetDB.java | 20 +- .../kmonitor/initialize/SystemManager.java | 331 +++++++++++------- .../chickling/kmonitor/utils/MetricUtils.java | 2 +- .../resources/static/scripts/cluster-viz.js | 105 ++++++ .../resources/static/views/cluster-viz.html | 3 + .../chickling/kmonitor/test/EsSearchTest.java | 20 +- 8 files changed, 432 insertions(+), 250 deletions(-) diff --git a/src/main/java/com/chickling/kmonitor/controller/JMXMetricController.java b/src/main/java/com/chickling/kmonitor/controller/JMXMetricController.java index b4f2813..438c876 100644 --- a/src/main/java/com/chickling/kmonitor/controller/JMXMetricController.java +++ b/src/main/java/com/chickling/kmonitor/controller/JMXMetricController.java @@ -151,7 +151,6 @@ public void doWithConnection(MBeanServerConnection mBeanServerConnection) { } } catch (Exception e) { LOG.error("Get jmxHosts error!" + e.getMessage()); - } return response.toString(); } diff --git a/src/main/java/com/chickling/kmonitor/core/db/ElasticsearchOffsetDB.java b/src/main/java/com/chickling/kmonitor/core/db/ElasticsearchOffsetDB.java index 2d0f1fd..e16fa7a 100644 --- a/src/main/java/com/chickling/kmonitor/core/db/ElasticsearchOffsetDB.java +++ b/src/main/java/com/chickling/kmonitor/core/db/ElasticsearchOffsetDB.java @@ -21,103 +21,107 @@ * @author Hulva Luva.H * */ -public class ElasticsearchOffsetDB implements OffsetDB { - - private Ielasticsearch esUtil; - private String indexPrefix; - private String docType; - - private static final SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - - public ElasticsearchOffsetDB(AppConfig config) { - if (config.getApiType().equalsIgnoreCase("Java API")) { - esUtil = new ElasticsearchJavaUtil(config.getEsHosts()); - } else { - esUtil = new ElasticsearchRESTUtil(config.getEsHosts()); - } - - setIndexAndType(config.getEsIndex(), config.getDocTypeForOffset()); - } - - public void setIndexAndType(String index, String docType) { - this.indexPrefix = index + "-"; - this.docType = docType; - } - - /* - * (non-Javadoc) - * - * @see com.chickling.kmonitor.core.db.OffsetDb#insert(long, - * com.chickling.kmonitor.model.OffsetInfo) - */ - @Override - public void insert(long timestamp, OffsetInfo offsetInfo) { - // TODO Auto-generated method stub - } - - /* - * (non-Javadoc) - * - * @see com.chickling.kmonitor.core.db.OffsetDb#batchInsert(java. util.List) - */ - @Override - public void batchInsert(List offsetInfoList) { - long now = System.currentTimeMillis(); - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(now); - cal.set(Calendar.MILLISECOND, 0); - cal.set(Calendar.SECOND, 0); - - JSONObject data = new JSONObject(); - for (int i = 0; i < offsetInfoList.size(); i++) { - data.put(i + "", generateRecord(cal.getTimeInMillis(), offsetInfoList.get(i))); - } - esUtil.bulkIndex(data, docType, indexPrefix); - } - - private JSONObject generateRecord(long timestamp, OffsetInfo offsetInfo) { - JSONObject data = new JSONObject(); - data.put("group", offsetInfo.getGroup()); - data.put("topic", offsetInfo.getTopic()); - data.put("partition", offsetInfo.getPartition()); - data.put("offset", offsetInfo.getOffset()); - data.put("logSize", offsetInfo.getLogSize()); - data.put("owner", offsetInfo.getOwner()/* owner.getOrElse("NA") */); - data.put("date", sFormat.format(new Date(timestamp))); - data.put("timestamp", timestamp); - data.put("creation", offsetInfo.getCreation()); - data.put("modified", offsetInfo.getModified()); - data.put("lag", offsetInfo.getLag()); - return data; - } - - /* - * (non-Javadoc) - * - * @see com.chickling.kmonitor.core.db.OffsetDb#offsetHistory() - */ - @Override - public OffsetHistory offsetHistory(String group, String topic) { - List offsetPointsList = esUtil.offsetHistory(indexPrefix, docType, group, topic); - CommonUtils.sortByTimestampThenPartition(offsetPointsList); - return new OffsetHistory(group, topic, offsetPointsList); - } - - @Override - public OffsetHistory offsetHistory(OffsetHistoryQueryParams params) { - List offsetPointsList = esUtil.scrollsSearcher(params, docType, indexPrefix); - CommonUtils.sortByTimestampThenPartition(offsetPointsList); - return new OffsetHistory(params.getGroup(), params.getTopic(), offsetPointsList); - } - - @Override - public boolean check() { - return esUtil.check(); - } - - @Override - public void close() { - esUtil.close(); - } +public class ElasticsearchOffsetDB implements OffsetDB { + + private Ielasticsearch esUtil; + private String indexPrefix; + private String docType; + + private static final SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + + public ElasticsearchOffsetDB(AppConfig config) { + if (config.getApiType().equalsIgnoreCase("Java API")) { + esUtil = new ElasticsearchJavaUtil(config.getEsHosts()); + } else { + esUtil = new ElasticsearchRESTUtil(config.getEsHosts()); + } + setIndexAndType(config.getEsIndex(), config.getDocTypeForOffset()); + } + + public void setIndexAndType(String index, String docType) { + this.indexPrefix = index + "-"; + this.docType = docType; + } + + /* + * (non-Javadoc) + * + * @see com.chickling.kmonitor.core.db.OffsetDb#insert(long, + * com.chickling.kmonitor.model.OffsetInfo) + */ + @Override + public void insert(long timestamp, OffsetInfo offsetInfo) { + // TODO Auto-generated method stub + } + + /* + * (non-Javadoc) + * + * @see com.chickling.kmonitor.core.db.OffsetDb#batchInsert(java. util.List) + */ + @Override + public void batchInsert(List offsetInfoList) { + long now = System.currentTimeMillis(); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(now); + cal.set(Calendar.MILLISECOND, 0); + cal.set(Calendar.SECOND, 0); + + JSONObject data = new JSONObject(); + for (int i = 0; i < offsetInfoList.size(); i++) { + data.put(i + "", generateRecord(cal.getTimeInMillis(), offsetInfoList.get(i))); + } + esUtil.bulkIndex(data, docType, indexPrefix); + } + + private JSONObject generateRecord(long timestamp, OffsetInfo offsetInfo) { + JSONObject data = new JSONObject(); + data.put("group", offsetInfo.getGroup()); + data.put("topic", offsetInfo.getTopic()); + data.put("partition", offsetInfo.getPartition()); + data.put("offset", offsetInfo.getOffset()); + data.put("logSize", offsetInfo.getLogSize()); + data.put("owner", offsetInfo.getOwner()/* owner.getOrElse("NA") */); + data.put("date", sFormat.format(new Date(timestamp))); + data.put("timestamp", timestamp); + data.put("creation", offsetInfo.getCreation()); + data.put("modified", offsetInfo.getModified()); + data.put("lag", offsetInfo.getLag()); + return data; + } + + /* + * (non-Javadoc) + * + * @see com.chickling.kmonitor.core.db.OffsetDb#offsetHistory() + */ + @Override + public OffsetHistory offsetHistory(String group, String topic) { + List offsetPointsList = esUtil.offsetHistory(indexPrefix, docType, group, topic); + CommonUtils.sortByTimestampThenPartition(offsetPointsList); + return new OffsetHistory(group, topic, offsetPointsList); + } + + @Override + public OffsetHistory offsetHistory(OffsetHistoryQueryParams params) { + List offsetPointsList = esUtil.scrollsSearcher(params, docType, indexPrefix); + CommonUtils.sortByTimestampThenPartition(offsetPointsList); + return new OffsetHistory(params.getGroup(), params.getTopic(), offsetPointsList); + } + + @Override + public boolean check() { + return esUtil.check(); + } + + @Override + public void close() { + esUtil.close(); + } + + @Override + public Ielasticsearch getDB() { + return esUtil; + } } diff --git a/src/main/java/com/chickling/kmonitor/core/db/OffsetDB.java b/src/main/java/com/chickling/kmonitor/core/db/OffsetDB.java index 1be1a91..40d0ffb 100644 --- a/src/main/java/com/chickling/kmonitor/core/db/OffsetDB.java +++ b/src/main/java/com/chickling/kmonitor/core/db/OffsetDB.java @@ -11,16 +11,18 @@ * @author Hulva Luva.H * */ -public interface OffsetDB { - void insert(long timestamp, OffsetInfo offsetInfo); +public interface OffsetDB { + T getDB(); - void batchInsert(List offsetInfoList); + void insert(long timestamp, OffsetInfo offsetInfo); - OffsetHistory offsetHistory(String group, String topic); + void batchInsert(List offsetInfoList); - OffsetHistory offsetHistory(OffsetHistoryQueryParams params); - - void close(); - - boolean check(); + OffsetHistory offsetHistory(String group, String topic); + + OffsetHistory offsetHistory(OffsetHistoryQueryParams params); + + void close(); + + boolean check(); } diff --git a/src/main/java/com/chickling/kmonitor/initialize/SystemManager.java b/src/main/java/com/chickling/kmonitor/initialize/SystemManager.java index 98e53b7..5534f8c 100644 --- a/src/main/java/com/chickling/kmonitor/initialize/SystemManager.java +++ b/src/main/java/com/chickling/kmonitor/initialize/SystemManager.java @@ -3,8 +3,11 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Optional; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -13,6 +16,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import javax.management.MBeanServerConnection; + +import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,8 +32,14 @@ import com.chickling.kmonitor.core.db.ElasticsearchOffsetDB; import com.chickling.kmonitor.core.db.OffsetDB; import com.chickling.kmonitor.email.EmailSender; +import com.chickling.kmonitor.jmx.FormatedMeterMetric; +import com.chickling.kmonitor.jmx.JMXExecutor; +import com.chickling.kmonitor.jmx.KafkaJMX; +import com.chickling.kmonitor.jmx.KafkaMetrics; import com.chickling.kmonitor.model.KafkaInfo; import com.chickling.kmonitor.utils.CommonUtils; +import com.chickling.kmonitor.utils.ZKUtils; +import com.chickling.kmonitor.utils.elasticsearch.Ielasticsearch; import com.google.gson.Gson; /** @@ -36,137 +48,190 @@ * */ public class SystemManager { - private static Logger LOG = LoggerFactory.getLogger(SystemManager.class); - - // TODO schedule pool size? any other schedule? - private static ScheduledExecutorService scheduler = null; - - private static ExecutorService worker; - - public static final int DEFAULT_THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors(); - - private static final ExecutorService kafkaInfoCollectAndSavePool = Executors - .newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE, new WorkerThreadFactory("KafkaInfo Collector")); - - public static BlockingQueue offsetInfoCacheQueue; - - public static OffsetDB db = null; - - public static OffsetGetter og = null; - - public static AtomicBoolean IS_SYSTEM_READY = new AtomicBoolean(false); - - public static List excludePath = new ArrayList(); - - private static AppConfig config; - - static { - excludePath.add("/"); - excludePath.add("/views/setting.html"); - excludePath.add("/setting"); - excludePath.add("/favicon.svg"); - excludePath.add("/style.css"); - excludePath.add("/index.html"); - } - - public static AppConfig getConfig() { - return config == null ? new AppConfig() : config; - } - - public static synchronized void setConfig(AppConfig _config) throws Exception { - config = _config; - initSystem(); - // TODO - IS_SYSTEM_READY.set(true); - ; - saveToFile(); - } - - private static void saveToFile() { - try { - PrintWriter writer = new PrintWriter("system.json", "UTF-8"); - writer.println(new Gson().toJson(config)); - writer.close(); - } catch (IOException e) { - LOG.error("Save system config to file failed!", e); - } - } - - private static void initSystem() { - try { - if (db != null) - db.close(); - db = new ElasticsearchOffsetDB(config); - if (!db.check()) { - throw new RuntimeException("No elasticsearch node avialable!"); - } - if (og != null) - og.close(); - og = new ZKOffsetGetter(config); - // TODO how cheack og is avialable? - - if (scheduler != null) - scheduler.shutdownNow(); - scheduler = Executors.newScheduledThreadPool(2, new WorkerThreadFactory("FixedRateSchedule")); - - if (config.getIsAlertEnabled()) { - initAlert(config); - } - - scheduler.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - try { - List groups = og.getGroups(); - groups.forEach(group -> { - kafkaInfoCollectAndSavePool.submit(new GenerateKafkaInfoTask(group)); - }); - } catch (Exception e) { - LOG.warn("Ops..." + e.getMessage()); - } - } - }, 0, config.getDataCollectFrequency() * 60 * 1000, TimeUnit.MILLISECONDS); - - } catch (Exception e) { - // TODO - IS_SYSTEM_READY.set(false); - throw new RuntimeException("Init system failed! " + e.getMessage()); - } - } - - private static void initAlert(AppConfig config) { - EmailSender.setConfig(config); - TaskManager.init(config); - if (offsetInfoCacheQueue != null) { - offsetInfoCacheQueue.clear(); - } else { - offsetInfoCacheQueue = new LinkedBlockingQueue(config.getOffsetInfoCacheQueue()); - } - if (worker != null) - worker.shutdownNow(); - int corePoolSize = config.getOffsetInfoHandler() != null ? config.getOffsetInfoHandler() - : DEFAULT_THREAD_POOL_SIZE; - if (worker != null) { - worker.shutdownNow(); - } - worker = Executors.newFixedThreadPool(corePoolSize, new WorkerThreadFactory("AlertTaskChecker")); - - for (int i = 0; i < corePoolSize; i++) { - worker.submit(new TaskHandler()); - } - - File dir = new File(config.getTaskFolder()); - if (!dir.exists()) { - dir.mkdir(); - } - // Scan task folder load tasks to memory - File[] listOfFiles = dir.listFiles(); - for (File file : listOfFiles) { - if (file.isFile() && (file.getName().substring(file.getName().lastIndexOf('.') + 1).equals("task"))) { - String strTaskContent = CommonUtils.loadFileContent(file.getAbsolutePath()); - TaskManager.addTask(new Gson().fromJson(strTaskContent, TaskContent.class)); - } - } - } + private static Logger LOG = LoggerFactory.getLogger(SystemManager.class); + + // TODO schedule pool size? any other schedule? + private static ScheduledExecutorService scheduler = null; + + private static ExecutorService worker; + + public static final int DEFAULT_THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors(); + + private static final ExecutorService kafkaInfoCollectAndSavePool = + Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE, new WorkerThreadFactory("KafkaInfo Collector")); + + public static BlockingQueue offsetInfoCacheQueue; + + public static OffsetDB db = null; + + public static OffsetGetter og = null; + + public static AtomicBoolean IS_SYSTEM_READY = new AtomicBoolean(false); + + public static List excludePath = new ArrayList(); + + private static AppConfig config; + + static { + excludePath.add("/"); + excludePath.add("/views/setting.html"); + excludePath.add("/setting"); + excludePath.add("/favicon.svg"); + excludePath.add("/style.css"); + excludePath.add("/index.html"); + } + + public static AppConfig getConfig() { + return config == null ? new AppConfig() : config; + } + + public static synchronized void setConfig(AppConfig _config) throws Exception { + config = _config; + initSystem(); + // TODO + IS_SYSTEM_READY.set(true);; + saveToFile(); + } + + private static void saveToFile() { + try { + PrintWriter writer = new PrintWriter("system.json", "UTF-8"); + writer.println(new Gson().toJson(config)); + writer.close(); + } catch (IOException e) { + LOG.error("Save system config to file failed!", e); + } + } + + private static void initSystem() { + try { + if (db != null) + db.close(); + db = new ElasticsearchOffsetDB(config); + if (!db.check()) { + throw new RuntimeException("No elasticsearch node avialable!"); + } + if (og != null) + og.close(); + og = new ZKOffsetGetter(config); + // TODO how cheack og is avialable? + + if (scheduler != null) + scheduler.shutdownNow(); + scheduler = Executors.newScheduledThreadPool(2, new WorkerThreadFactory("FixedRateSchedule")); + + if (config.getIsAlertEnabled()) { + initAlert(config); + } + + // Offset info data + scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + try { + List groups = og.getGroups(); + groups.forEach(group -> { + kafkaInfoCollectAndSavePool.submit(new GenerateKafkaInfoTask(group)); + }); + } catch (Exception e) { + LOG.warn("Ops..." + e.getMessage()); + } + } + }, 0, config.getDataCollectFrequency() * 60 * 1000, TimeUnit.MILLISECONDS); + + + // JMX metrics data + scheduler.scheduleAtFixedRate(new Runnable() { + private final SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + + @Override + public void run() { + Date now = new Date(); + JSONObject data = new JSONObject(); + try { + List jmxHosts = ZKUtils.getKafkaJMXHostsFromZookeeper(); + for (String jmxHost : jmxHosts) { + String[] jmxArr = jmxHost.split(":"); + if ("-1".equals(jmxArr[2])) { + LOG.warn("JMX disabled in " + jmxHost); + continue; + } + KafkaJMX kafkaJMX = new KafkaJMX(); + kafkaJMX.doWithConnection(jmxArr[1], Integer.parseInt(jmxArr[2]), Optional.of(""), Optional.of(""), false, new JMXExecutor() { + + @Override + public void doWithConnection(MBeanServerConnection mBeanServerConnection) { + KafkaMetrics metrics = new KafkaMetrics(); + JSONObject metric = null; + metric = new JSONObject(new FormatedMeterMetric(metrics.getMessagesInPerSec(mBeanServerConnection, Optional.empty()), 0)); + metric.put("broker", jmxArr[1]); + metric.put("date", sFormat.format(now)); + metric.put("timestamp", now.getTime()); + metric.put("metric", "MessagesInPerSec"); + data.put("MessagesInPerSec" + jmxArr[0], metric); + + metric = new JSONObject(new FormatedMeterMetric(metrics.getBytesInPerSec(mBeanServerConnection, Optional.empty()))); + metric.put("broker", jmxArr[1]); + metric.put("date", sFormat.format(now)); + metric.put("timestamp", now.getTime()); + metric.put("metric", "BytesInPerSec"); + data.put("BytesInPerSec" + jmxArr[0], metric); + + metric = new JSONObject(new FormatedMeterMetric(metrics.getBytesOutPerSec(mBeanServerConnection, Optional.empty()))); + metric.put("broker", jmxArr[1]); + metric.put("date", sFormat.format(now)); + metric.put("timestamp", now.getTime()); + metric.put("metric", "BytesOutPerSec"); + data.put("BytesOutPerSec" + jmxArr[0], metric); + } + }); + } + db.getDB().bulkIndex(data, "jmxMetrics", config.getEsIndex() + "-"); + } catch (Exception e) { + LOG.warn("Ops..." + e.getMessage()); + } + } + }, 0, config.getDataCollectFrequency() * 60 * 1000, TimeUnit.MILLISECONDS); + + } catch (Exception e) { + // TODO + IS_SYSTEM_READY.set(false); + throw new RuntimeException("Init system failed! " + e.getMessage()); + } + } + + private static void initAlert(AppConfig config) { + EmailSender.setConfig(config); + TaskManager.init(config); + if (offsetInfoCacheQueue != null) { + offsetInfoCacheQueue.clear(); + } else { + offsetInfoCacheQueue = new LinkedBlockingQueue(config.getOffsetInfoCacheQueue()); + } + if (worker != null) + worker.shutdownNow(); + int corePoolSize = config.getOffsetInfoHandler() != null ? config.getOffsetInfoHandler() : DEFAULT_THREAD_POOL_SIZE; + if (worker != null) { + worker.shutdownNow(); + } + worker = Executors.newFixedThreadPool(corePoolSize, new WorkerThreadFactory("AlertTaskChecker")); + + for (int i = 0; i < corePoolSize; i++) { + worker.submit(new TaskHandler()); + } + + File dir = new File(config.getTaskFolder()); + if (!dir.exists()) { + dir.mkdir(); + } + // Scan task folder load tasks to memory + File[] listOfFiles = dir.listFiles(); + for (File file : listOfFiles) { + if (file.isFile() && (file.getName().substring(file.getName().lastIndexOf('.') + 1).equals("task"))) { + String strTaskContent = CommonUtils.loadFileContent(file.getAbsolutePath()); + TaskManager.addTask(new Gson().fromJson(strTaskContent, TaskContent.class)); + } + } + } } diff --git a/src/main/java/com/chickling/kmonitor/utils/MetricUtils.java b/src/main/java/com/chickling/kmonitor/utils/MetricUtils.java index 0d19450..e772445 100644 --- a/src/main/java/com/chickling/kmonitor/utils/MetricUtils.java +++ b/src/main/java/com/chickling/kmonitor/utils/MetricUtils.java @@ -34,7 +34,7 @@ public static String sizeFormat(Double bytes) { return new BigDecimal(bytes).setScale(2, BigDecimal.ROUND_HALF_UP).toString() + " B"; } else { int exp = new Double((Math.log(bytes) / Math.log(unit))).intValue(); - char pre = "kMGTPE".charAt(exp - 1); + char pre = "KMGTPE".charAt(exp - 1); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } } diff --git a/src/main/resources/static/scripts/cluster-viz.js b/src/main/resources/static/scripts/cluster-viz.js index 9bbab3d..c48c0f1 100644 --- a/src/main/resources/static/scripts/cluster-viz.js +++ b/src/main/resources/static/scripts/cluster-viz.js @@ -16,6 +16,9 @@ var diagonal = d3.svg.diagonal().projection(function(d) { var svg; +var seriesOptions = [], +seriesCounter = 0; + function loadViz(load_to_id, data_path) { svg = d3.select(load_to_id).append("svg").attr("width", width + margin.right + margin.left).attr("height", @@ -41,6 +44,108 @@ function loadViz(load_to_id, data_path) { $(".alert-info").hide("slow"); }); d3.select(self.frameElement).style("height", "800px"); + + /** + * Create the chart when all data is loaded + * + * @returns {undefined} + */ + function createChart() { + + Highcharts.stockChart('metrics', { + + rangeSelector: { + selected: 4 + }, + + yAxis: { + labels: { + formatter: function () { + return (this.value > 0 ? ' + ' : '') + this.value + '%'; + } + }, + plotLines: [{ + value: 0, + width: 2, + color: 'silver' + }] + }, + + plotOptions: { + series: { + compare: 'value', // 'value', 'percent' + showInNavigator: true + } + }, + + tooltip: { + pointFormat: '{series.name}: {point.y} ({point.change})
' + }, + + series: seriesOptions + }); + } + +// broker +// : +// "10.16.238.104" +// count +// : +// 17284985 +// date +// : +// "2017-08-02T15:16:41.978+0800" +// fifteenMinuteRate +// : +// "0.00 B" +// fiveMinuteRate +// : +// "0.00 B" +// meanRate +// : +// "29.38 B" +// metric +// : +// "BytesOutPerSec" +// oneMinuteRate +// : +// "0.00 B" +// timestamp +// : +// 1501658201978 + + + $.getJSON('http://10.16.238.82:9200/logx_healthcheck_test-*/jmxMetrics/_search?q=metric:BytesOutPerSec', function (data) { + var hits = data.hits.hits; + let brokerHitsMap = new Map(); + $.each(hits, function (i, hit){ + var source = hit._source; + var brokerHits = brokerHitsMap.get(source.broker); + if(brokerHits == undefined){ + brokerHitsMap.set(source.broker, [[source.timestamp, source.count]]); + }else{ + brokerHits.push([source.timestamp, source.count]); + } + }); + + for (let [broker, hits] of brokerHitsMap) { + hits.sort(function(a, b) { + return a[0] - b[0]; + }); + seriesOptions[seriesCounter] = { + name: broker, + data: hits + }; + seriesCounter += 1; + } + + + // As we're loading the data asynchronously, we don't know what + // order it will arrive. So + // we keep a counter and create the chart when all the data is + // loaded. + createChart(); + }); } function update(source) { diff --git a/src/main/resources/static/views/cluster-viz.html b/src/main/resources/static/views/cluster-viz.html index 1f02a28..606425f 100644 --- a/src/main/resources/static/views/cluster-viz.html +++ b/src/main/resources/static/views/cluster-viz.html @@ -153,6 +153,9 @@

System Info

--> + +
+ - - -
+
+
+

Choose one to show its change in 8 hours

+
+
+
+ +
+
+
+
+