http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-gui/src/main/webapp/home.jsp ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/home.jsp b/src/blur-gui/src/main/webapp/home.jsp index c130486..c61d2d6 100644 --- a/src/blur-gui/src/main/webapp/home.jsp +++ b/src/blur-gui/src/main/webapp/home.jsp @@ -21,9 +21,9 @@ import="javax.servlet.*" import="javax.servlet.http.*" import="java.io.*" import="java.util.*" import="java.text.DateFormat" import="java.lang.Math" import="java.net.URLEncoder" - import="com.nearinfinity.blur.thrift.*" - import="com.nearinfinity.blur.thrift.generated.*" - import="com.nearinfinity.blur.thrift.generated.Blur.*"%> + import="org.apache.blur.thrift.*" + import="org.apache.blur.thrift.generated.*" + import="org.apache.blur.thrift.generated.Blur.*"%> <%@ include file="functions.jsp" %> <%!
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-gui/src/main/webapp/livemetrics.jsp ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/livemetrics.jsp b/src/blur-gui/src/main/webapp/livemetrics.jsp new file mode 100644 index 0000000..b91c1d1 --- /dev/null +++ b/src/blur-gui/src/main/webapp/livemetrics.jsp @@ -0,0 +1,111 @@ +<% +/* + * 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. + */ +%> +<!DOCTYPE html> +<meta charset="utf-8"></meta> +<style> +.axis path { + fill:none; + stroke: black; +} + +.tick { + fill:none; + stroke:black; +} + +.axis { + font-family: arial; + font-size:0.6em; +} + +path { + fill:none; + stroke:black; + stroke-width:2px; +} +</style> +<body> +<script src="d3.v2.js"></script> +<script> +function draw(uri, id, data, margin, width, height, xLabel, yLabel, labels) { + "use strict"; + var graphSvg = d3.select("#" + id).select("svg"); + if (graphSvg) {graphSvg.remove();} + var graph = d3.select("#" + id).append("svg").attr("width", width).attr("height", height); + + var time_extent = d3.extent(data,function(d){return new Date(d.recordTime)}); + var time_scale = d3.time.scale().domain(time_extent).range([margin, width]); + + var maxArray = []; + for (var index in labels) { + var labelObject = labels[index]; + maxArray.push(d3.max(data,function(d){return d[labelObject.name];})); + } + var y_scale = d3.scale.linear().range([height-margin,margin]).domain([0, d3.max(maxArray)]); + + //add x axis + var x_axis = d3.svg.axis().scale(time_scale); + graph.append("g").attr("class","x axis " + id).attr("transform","translate(0,"+(height-margin)+")").call(x_axis); + d3.select(".x.axis."+id).append("text").text(xLabel).attr("x", (width / 2) - margin).attr("y", margin / 1.5); + + //add y axis + var y_axis = d3.svg.axis().scale(y_scale).orient("left"); + graph.append("g").attr("class","y axis " + id).attr("transform","translate(" + margin +",0)").call(y_axis); + d3.select(".y.axis."+id).append("text").text(yLabel).attr("transform", "rotate (-90, 0, 0) translate(-" + (height/2) + ",-40)"); + + //add lines + for (var index in labels) { + var labelObject = labels[index]; + var name = labelObject.name; + var line = d3.svg.line().x(function(d){return time_scale(new Date(d.recordTime))}).y(function(d){return y_scale(d[name])}).interpolate("basis"); + var l = graph.append("path").attr("d", line(data)).attr("class", name + "_line"); + var s = labelObject.style; + for (var v in s) { + if (s.hasOwnProperty(v)) { + l.style(s,v[s]); + } + } + } +} + +function drawGraphs(uri, margin, width, height) { + d3.json(uri,function(data) { + for (var graphId in data) { + if (data.hasOwnProperty(graphId)) { + draw(uri, graphId, data[graphId].lines.data, margin, width, height, data[graphId].xLabel, data[graphId].yLabel, data[graphId].lines.labels); + } + } + }); + setTimeout(function() { + drawGraphs(uri, margin, width, height); + }, 1000); +} + +var margin = 50, width = 600, height = 250; + +drawGraphs("/livemetrics", margin, width, height) + +</script> + +<div id="jvm"></div> +<div id="blur"></div> +<div id="system"></div> + +</body> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-gui/src/main/webapp/metrics.jsp ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/metrics.jsp b/src/blur-gui/src/main/webapp/metrics.jsp index 6446786..f8ee025 100644 --- a/src/blur-gui/src/main/webapp/metrics.jsp +++ b/src/blur-gui/src/main/webapp/metrics.jsp @@ -23,9 +23,9 @@ import="javax.servlet.*" import="javax.servlet.http.*" import="java.io.*" import="java.util.*" import="java.text.DateFormat" import="java.lang.Math" import="java.net.URLEncoder" - import="com.nearinfinity.blur.thrift.*" - import="com.nearinfinity.blur.thrift.generated.*" - import="com.nearinfinity.blur.thrift.generated.Blur.*"%> + import="org.apache.blur.thrift.*" + import="org.apache.blur.thrift.generated.*" + import="org.apache.blur.thrift.generated.Blur.*"%> <%@ include file="functions.jsp"%> <% String hostName = request.getServerName() + ":" + System.getProperty("blur.gui.servicing.port"); http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-gui/src/main/webapp/shardList.jsp ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/shardList.jsp b/src/blur-gui/src/main/webapp/shardList.jsp index 3819075..b709ad5 100644 --- a/src/blur-gui/src/main/webapp/shardList.jsp +++ b/src/blur-gui/src/main/webapp/shardList.jsp @@ -21,9 +21,9 @@ import="javax.servlet.*" import="javax.servlet.http.*" import="java.io.*" import="java.util.*" import="java.text.DateFormat" import="java.lang.Math" import="java.net.URLEncoder" - import="com.nearinfinity.blur.thrift.*" - import="com.nearinfinity.blur.thrift.generated.*" - import="com.nearinfinity.blur.thrift.generated.Blur.*"%> + import="org.apache.blur.thrift.*" + import="org.apache.blur.thrift.generated.*" + import="org.apache.blur.thrift.generated.Blur.*"%> <%@ include file="functions.jsp"%> <%! public String shards(Iface client, String clusterName) throws Exception { http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-gui/src/main/webapp/table.jsp ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/table.jsp b/src/blur-gui/src/main/webapp/table.jsp index a04dfcf..72bce7b 100644 --- a/src/blur-gui/src/main/webapp/table.jsp +++ b/src/blur-gui/src/main/webapp/table.jsp @@ -23,9 +23,9 @@ import="javax.servlet.*" import="javax.servlet.http.*" import="java.io.*" import="java.util.*" import="java.text.DateFormat" import="java.lang.Math" import="java.net.URLEncoder" - import="com.nearinfinity.blur.thrift.*" - import="com.nearinfinity.blur.thrift.generated.*" - import="com.nearinfinity.blur.thrift.generated.Blur.*"%> + import="org.apache.blur.thrift.*" + import="org.apache.blur.thrift.generated.*" + import="org.apache.blur.thrift.generated.Blur.*"%> <%@ include file="functions.jsp"%> <%!public boolean tableInSafeMode(Iface client, String clusterName) throws Exception { return client.isInSafeMode(clusterName); http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-util/src/main/java/org/apache/blur/metrics/HeapMetrics.java ---------------------------------------------------------------------- diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/HeapMetrics.java b/src/blur-util/src/main/java/org/apache/blur/metrics/HeapMetrics.java new file mode 100644 index 0000000..0534871 --- /dev/null +++ b/src/blur-util/src/main/java/org/apache/blur/metrics/HeapMetrics.java @@ -0,0 +1,81 @@ +package org.apache.blur.metrics; + +import java.io.PrintWriter; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +public class HeapMetrics extends TimerTask { + + private final int sampleSize = (int) TimeUnit.MINUTES.toSeconds(10); + private final Timer timer; + private final long period = TimeUnit.SECONDS.toMillis(1); + private final long[] heapMemoryUsageUsedHistory = new long[sampleSize]; + private final long[] heapMemoryUsageCommittedHistory = new long[sampleSize]; + private final long[] timestamp = new long[sampleSize]; + private volatile static HeapMetrics heapMetrics; + private volatile int position = 0; + + public static synchronized HeapMetrics getInstance() { + if (heapMetrics == null) { + heapMetrics = new HeapMetrics(); + } + return heapMetrics; + } + + private HeapMetrics() { + timer = new Timer("HeapMetrics", true); + timer.scheduleAtFixedRate(this, period, period); + } + + @Override + public void run() { + synchronized (this) { + if (position >= sampleSize) { + position = 0; + } + MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + setValue(heapMemoryUsage.getUsed(), heapMemoryUsageUsedHistory); + setValue(heapMemoryUsage.getCommitted(), heapMemoryUsageCommittedHistory); + setValue(System.currentTimeMillis(), timestamp); + position++; + } + } + + private void setValue(long value, long[] history) { + history[position] = value; + } + + public void writeJson(PrintWriter out) { + synchronized (this) { + out.print("{\"labels\":[{\"name\":\"used\",\"style\":{\"stroke\":\"RoyalBlue\"}},{\"name\":\"committed\",\"style\":{\"stroke\":\"Red\"}}],\"data\":["); + int p = position; + boolean comma = false; + for (int i = 0; i < sampleSize; i++, p++) { + if (p >= sampleSize) { + p = 0; + } + double used = ((double) heapMemoryUsageUsedHistory[p]) / 1000000000.0; + double committed = ((double) heapMemoryUsageCommittedHistory[p]) / 1000000000.0; + long t = timestamp[p]; + if (t == 0) { + continue; + } + if (comma) { + out.print(","); + } + out.print("{\"used\":"); + out.print(used); + out.print(",\"committed\":"); + out.print(committed); + out.print(",\"recordTime\":"); + out.print(t); + out.print('}'); + comma = true; + } + out.print("]}"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-util/src/main/java/org/apache/blur/metrics/QueryMetrics.java ---------------------------------------------------------------------- diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/QueryMetrics.java b/src/blur-util/src/main/java/org/apache/blur/metrics/QueryMetrics.java new file mode 100644 index 0000000..80bf733 --- /dev/null +++ b/src/blur-util/src/main/java/org/apache/blur/metrics/QueryMetrics.java @@ -0,0 +1,142 @@ +package org.apache.blur.metrics; + +import java.io.PrintWriter; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +public class QueryMetrics extends TimerTask { + + private final int sampleSize = (int) TimeUnit.MINUTES.toSeconds(10); + private final AtomicLong _queryCount = new AtomicLong(); + private final AtomicLong _queryTime = new AtomicLong(); + private final AtomicLong _queryExceptionCount = new AtomicLong(); + private final AtomicLong _dataFetchCount = new AtomicLong(); + private final AtomicLong _dataFetchTime = new AtomicLong(); + private final AtomicLong _dataFetchRecordCount = new AtomicLong(); + private final AtomicLong _dataMutateCount = new AtomicLong(); + private final AtomicLong _dataMutateTime = new AtomicLong(); + private final AtomicLong _dataMutateRecordCount = new AtomicLong(); + private final Timer timer; + private final long period = TimeUnit.SECONDS.toMillis(1); + private final double[] _queryRate = new double[sampleSize]; + private final double[] _queryResponse = new double[sampleSize]; + private final double[] _queryExceptionRate = new double[sampleSize]; + private final double[] _fetchRecordRate = new double[sampleSize]; + private final double[] _fetchResponse = new double[sampleSize]; + private final double[] _mutateRecordRate = new double[sampleSize]; + private final double[] _mutateResponse = new double[sampleSize]; + private final long[] timestamp = new long[sampleSize]; + private volatile static QueryMetrics instance; + private volatile int position; + + public static synchronized QueryMetrics getInstance() { + if (instance == null) { + instance = new QueryMetrics(); + } + return instance; + } + + private QueryMetrics() { + timer = new Timer("QueryMetrics", true); + timer.scheduleAtFixedRate(this, period, period); + } + + @Override + public void run() { + synchronized (this) { + if (position >= sampleSize) { + position = 0; + } + long queryCount = _queryCount.getAndSet(0); + long queryTime = _queryTime.getAndSet(0); + long queryExceptionCount = _queryExceptionCount.getAndSet(0); + + long dataFetchCount = _dataFetchCount.getAndSet(0); + long dataFetchTime = _dataFetchTime.getAndSet(0); + long dataFetchRecordCount = _dataFetchRecordCount.getAndSet(0); + + long dataMutateCount = _dataMutateCount.getAndSet(0); + long dataMutateTime = _dataMutateTime.getAndSet(0); + long dataMutateRecordCount = _dataMutateRecordCount.getAndSet(0); + + _queryRate[position] = queryCount; + _queryResponse[position] = TimeUnit.NANOSECONDS.toMillis(queryTime) / (double) queryCount; + + _queryExceptionRate[position] = queryExceptionCount; + + _fetchRecordRate[position] = dataFetchCount; + _fetchResponse[position] = TimeUnit.NANOSECONDS.toMillis(dataFetchTime) / (double) dataFetchCount; + + _mutateRecordRate[position] = dataMutateCount; + _mutateResponse[position] = TimeUnit.NANOSECONDS.toMillis(dataMutateTime) / (double) dataMutateCount; + + timestamp[position] = System.currentTimeMillis(); + position++; + } + } + + public void recordQuery(long totalTimeNs) { + _queryCount.incrementAndGet(); + _queryTime.addAndGet(totalTimeNs); + } + + public void recordQueryExceptions() { + _queryExceptionCount.incrementAndGet(); + } + + public void recordDataFetch(long totalTimeNs, long records) { + _dataFetchCount.incrementAndGet(); + _dataFetchTime.addAndGet(totalTimeNs); + _dataFetchRecordCount.addAndGet(records); + } + + public void recordDataMutate(long totalTimeNs, long records) { + _dataMutateCount.incrementAndGet(); + _dataMutateTime.addAndGet(totalTimeNs); + _dataMutateRecordCount.addAndGet(records); + } + + public void writeJson(PrintWriter out) { + synchronized (this) { + out.print("{\"labels\":["); + out.print("{\"name\":\"query\",\"style\":{\"stroke\":\"RoyalBlue\"}},"); + out.print("{\"name\":\"fetch\",\"style\":{\"stroke\":\"Black\"}},"); + out.print("{\"name\":\"mutate\",\"style\":{\"stroke\":\"Yellow\"}},"); + out.print("{\"name\":\"except\",\"style\":{\"stroke\":\"Red\"}}"); + out.print("],\"data\":["); + int p = position; + boolean comma = false; + for (int i = 0; i < sampleSize; i++, p++) { + if (p >= sampleSize) { + p = 0; + } + double query = _queryRate[p]; + double fetch = _fetchRecordRate[p]; + double mutate = _mutateRecordRate[p]; + double except = _queryExceptionRate[p]; + long t = timestamp[p]; + if (t == 0) { + continue; + } + if (comma) { + out.print(","); + } + out.print("{\"query\":"); + out.print(query); + out.print(",\"fetch\":"); + out.print(fetch); + out.print(",\"mutate\":"); + out.print(mutate); + out.print(",\"except\":"); + out.print(except); + out.print(",\"recordTime\":"); + out.print(t); + out.print('}'); + comma = true; + } + out.print("]}"); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/b0eda0de/src/blur-util/src/main/java/org/apache/blur/metrics/SystemLoadMetrics.java ---------------------------------------------------------------------- diff --git a/src/blur-util/src/main/java/org/apache/blur/metrics/SystemLoadMetrics.java b/src/blur-util/src/main/java/org/apache/blur/metrics/SystemLoadMetrics.java new file mode 100644 index 0000000..16627b6 --- /dev/null +++ b/src/blur-util/src/main/java/org/apache/blur/metrics/SystemLoadMetrics.java @@ -0,0 +1,72 @@ +package org.apache.blur.metrics; + +import java.io.PrintWriter; +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +public class SystemLoadMetrics extends TimerTask { + + private final int sampleSize = (int) TimeUnit.MINUTES.toSeconds(10); + private final Timer timer; + private final long period = TimeUnit.SECONDS.toMillis(1); + private final double[] systemLoadAverageHistory = new double[sampleSize]; + private final long[] timestamp = new long[sampleSize]; + private volatile static SystemLoadMetrics instance; + private volatile int position = 0; + + public static synchronized SystemLoadMetrics getInstance() { + if (instance == null) { + instance = new SystemLoadMetrics(); + } + return instance; + } + + private SystemLoadMetrics() { + timer = new Timer("SystemLoadMetrics", true); + timer.scheduleAtFixedRate(this, period, period); + } + + @Override + public void run() { + synchronized (this) { + if (position >= sampleSize) { + position = 0; + } + OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); + systemLoadAverageHistory[position] = operatingSystemMXBean.getSystemLoadAverage(); + timestamp[position] = System.currentTimeMillis(); + position++; + } + } + + public void writeJson(PrintWriter out) { + synchronized (this) { + out.print("{\"labels\":[{\"name\":\"load\",\"style\":{\"stroke\":\"Red\"}}],\"data\":["); + int p = position; + boolean comma = false; + for (int i = 0; i < sampleSize; i++, p++) { + if (p >= sampleSize) { + p = 0; + } + double load = systemLoadAverageHistory[p]; + long t = timestamp[p]; + if (t == 0) { + continue; + } + if (comma) { + out.print(","); + } + out.print("{\"load\":"); + out.print(load); + out.print(",\"recordTime\":"); + out.print(t); + out.print('}'); + comma = true; + } + out.print("]}"); + } + } +}
