blob: f828ff1f39fcfcb731f61457e1ed631e7571b816 [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 org.apache.hadoop.chukwa.datastore;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.chukwa.hicc.bean.Chart;
import org.apache.hadoop.chukwa.hicc.bean.Dashboard;
import org.apache.hadoop.chukwa.hicc.bean.HeatMapPoint;
import org.apache.hadoop.chukwa.hicc.bean.Heatmap;
import org.apache.hadoop.chukwa.hicc.bean.LineOptions;
import org.apache.hadoop.chukwa.hicc.bean.Series;
import org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData;
import org.apache.hadoop.chukwa.hicc.bean.Widget;
import org.apache.hadoop.chukwa.util.ExceptionUtil;
import org.apache.hadoop.chukwa.util.HBaseUtil;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.ColumnPrefixFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import com.google.gson.Gson;
public class ChukwaHBaseStore {
static Logger LOG = Logger.getLogger(ChukwaHBaseStore.class);
static int MINUTES_IN_HOUR = 60;
static double RESOLUTION = 360;
static int MINUTE = 60000; //60 milliseconds
final static int SECOND = (int) TimeUnit.SECONDS.toMillis(1);
private final static Charset UTF8 = Charset.forName("UTF-8");
final static byte[] COLUMN_FAMILY = "t".getBytes(UTF8);
final static byte[] ANNOTATION_FAMILY = "a".getBytes(UTF8);
final static byte[] KEY_NAMES = "k".getBytes(UTF8);
final static byte[] CHART_TYPE = "chart_meta".getBytes(UTF8);
final static byte[] CHART_FAMILY = "c".getBytes(UTF8);
final static byte[] COMMON_FAMILY = "c".getBytes(UTF8);
final static byte[] WIDGET_TYPE = "widget_meta".getBytes(UTF8);
final static byte[] DASHBOARD_TYPE = "dashboard_meta".getBytes(UTF8);
private static final String CHUKWA = "chukwa";
private static final String CHUKWA_META = "chukwa_meta";
private static long MILLISECONDS_IN_DAY = 86400000L;
private static Connection connection = null;
public ChukwaHBaseStore() {
super();
}
public static synchronized void getHBaseConnection() throws IOException {
if (connection == null || connection.isClosed()) {
connection = ConnectionFactory.createConnection();
}
}
public static synchronized void closeHBase() {
try {
if(connection != null) {
connection.close();
}
} catch(IOException e) {
LOG.warn("Unable to release HBase connection.");
}
}
/**
* Scan chukwa table for a particular metric group and metric name based on
* time ranges.
*
* @param metricGroup
* @param metric
* @param source
* @param startTime
* @param endTime
* @return
*/
public static Series getSeries(String metricGroup, String metric,
String source, long startTime, long endTime) {
String fullMetricName = new StringBuilder(metricGroup).append(".")
.append(metric).toString();
return getSeries(fullMetricName, source, startTime, endTime);
}
/**
* Scan chukwa table for a full metric name based on time ranges.
*
* @param metric
* @param source
* @param startTime
* @param endTime
* @return
*/
public static synchronized Series getSeries(String metric, String source, long startTime,
long endTime) {
String seriesName = new StringBuilder(metric).append(":").append(source).toString();
Series series = new Series(seriesName);
try {
// Swap start and end if the values are inverted.
if (startTime > endTime) {
long temp = endTime;
startTime = endTime;
endTime = temp;
}
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA));
Scan scan = new Scan();
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c.setTimeInMillis(startTime);
int startDay = c.get(Calendar.DAY_OF_YEAR);
c.setTimeInMillis(endTime);
int endDay = c.get(Calendar.DAY_OF_YEAR);
long currentDay = startTime;
for (int i = startDay; i <= endDay; i++) {
byte[] rowKey = HBaseUtil.buildKey(currentDay, metric, source);
scan.addFamily(COLUMN_FAMILY);
scan.setStartRow(rowKey);
scan.setStopRow(rowKey);
scan.setTimeRange(startTime, endTime);
scan.setBatch(10000);
ResultScanner results = table.getScanner(scan);
Iterator<Result> it = results.iterator();
while (it.hasNext()) {
Result result = it.next();
for (Cell kv : result.rawCells()) {
byte[] key = CellUtil.cloneQualifier(kv);
long timestamp = ByteBuffer.wrap(key).getLong();
double value = Double
.parseDouble(new String(CellUtil.cloneValue(kv), UTF8));
series.add(timestamp, value);
}
}
results.close();
currentDay = currentDay + (i * MILLISECONDS_IN_DAY);
}
table.close();
} catch (IOException e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return series;
}
public static Set<String> getMetricNames(String metricGroup) {
Set<String> familyNames = new CopyOnWriteArraySet<String>();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get get = new Get(metricGroup.getBytes(UTF8));
Result result = table.get(get);
for (Cell kv : result.rawCells()) {
JSONObject json = (JSONObject) JSONValue.parse(new String(CellUtil.cloneValue(kv), UTF8));
if (json.get("type").equals("metric")) {
familyNames.add(new String(CellUtil.cloneQualifier(kv), UTF8));
}
}
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return familyNames;
}
public static Set<String> getMetricGroups() {
Set<String> metricGroups = new CopyOnWriteArraySet<String>();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.addFamily(KEY_NAMES);
ResultScanner rs = table.getScanner(scan);
Iterator<Result> it = rs.iterator();
while (it.hasNext()) {
Result result = it.next();
metricGroups.add(new String(result.getRow(), UTF8));
}
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return metricGroups;
}
public static Set<String> getSourceNames(String dataType) {
Set<String> pk = new HashSet<String>();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.addFamily(KEY_NAMES);
ResultScanner rs = table.getScanner(scan);
Iterator<Result> it = rs.iterator();
while (it.hasNext()) {
Result result = it.next();
for (Cell cell : result.rawCells()) {
JSONObject json = (JSONObject) JSONValue.parse(new String(CellUtil.cloneValue(cell), UTF8));
if (json!=null && json.get("type")!=null && json.get("type").equals("source")) {
pk.add(new String(CellUtil.cloneQualifier(cell), UTF8));
}
}
}
rs.close();
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return pk;
}
public static Heatmap getHeatmap(String metricGroup, String metric,
long startTime, long endTime, double max, double scale, int width, int height) {
Heatmap heatmap = new Heatmap();
Set<String> sources = getSourceNames(metricGroup);
Set<String> metrics = getMetricNames(metricGroup);
List<Get> series = new ArrayList<Get>();
String fullName = new StringBuilder(metricGroup).append(".").append(metric).toString();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA));
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c.setTimeInMillis(startTime);
int startDay = c.get(Calendar.DAY_OF_YEAR);
c.setTimeInMillis(endTime);
int endDay = c.get(Calendar.DAY_OF_YEAR);
long currentDay = startTime;
for (int i = startDay; i <= endDay; i++) {
for (String m : metrics) {
if (m.startsWith(fullName)) {
for (String source : sources) {
byte[] rowKey = HBaseUtil.buildKey(currentDay, m, source);
Get serie = new Get(rowKey);
serie.addFamily(COLUMN_FAMILY);
serie.setTimeRange(startTime, endTime);
series.add(serie);
}
}
}
currentDay = currentDay + (i * MILLISECONDS_IN_DAY);
}
long timeRange = (endTime - startTime);
Result[] rs = table.get(series);
int index = 1;
// Series display in y axis
int y = 0;
HashMap<String, Integer> keyMap = new HashMap<String, Integer>();
for (Result result : rs) {
for(Cell cell : result.rawCells()) {
byte[] dest = new byte[5];
System.arraycopy(CellUtil.cloneRow(cell), 3, dest, 0, 5);
String source = new String(dest, UTF8);
long time = cell.getTimestamp();
// Time display in x axis
long delta = time - startTime;
double f = (double) delta / timeRange;
f = (double) f * width;
int x = (int) Math.round(f);
if (keyMap.containsKey(source)) {
y = keyMap.get(source);
} else {
keyMap.put(source, Integer.valueOf(index));
y = index;
index++;
}
double v = Double.parseDouble(new String(CellUtil.cloneValue(cell), UTF8));
heatmap.put(x, y, v);
if (v > max) {
max = v;
}
}
}
table.close();
int radius = height / index;
// Usually scale max from 0 to 100 for visualization
heatmap.putMax(scale);
for (HeatMapPoint point : heatmap.getHeatmap()) {
double round = point.count / max * scale;
round = Math.round(round * 100.0) / 100.0;
point.put(point.x, point.y * radius, round);
}
heatmap.putRadius(radius);
heatmap.putSeries(index -1);
} catch (IOException e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return heatmap;
}
/**
* Scan chukwa table and find cluster tag from annotation column family from a
* range of entries.
*
* @param startTime
* @param endTime
* @return
*/
public static Set<String> getClusterNames(long startTime, long endTime) {
Set<String> clusters = new HashSet<String>();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.addFamily(KEY_NAMES);
ResultScanner rs = table.getScanner(scan);
Iterator<Result> it = rs.iterator();
while (it.hasNext()) {
Result result = it.next();
for (Cell cell : result.rawCells()) {
JSONObject json = (JSONObject) JSONValue.parse(new String(CellUtil.cloneValue(cell), UTF8));
if (json.get("type").equals("cluster")) {
clusters.add(new String(CellUtil.cloneQualifier(cell), UTF8));
}
}
}
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return clusters;
}
/**
* Get a chart from HBase by ID.
*
* @param id
* @return
*/
public static Chart getChart(String id) {
Chart chart = null;
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get get = new Get(CHART_TYPE);
Result r = table.get(get);
byte[] value = r.getValue(CHART_FAMILY, id.getBytes(UTF8));
Gson gson = new Gson();
if(value!=null) {
chart = gson.fromJson(new String(value, UTF8), Chart.class);
}
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return chart;
}
/**
* Update a chart in HBase by ID.
*
* @param id
* @param chart
*/
public static void putChart(String id, Chart chart) {
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Put put = new Put(CHART_TYPE);
Gson gson = new Gson();
String buffer = gson.toJson(chart);
put.addColumn(CHART_FAMILY, id.getBytes(UTF8), buffer.getBytes(UTF8));
table.put(put);
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
}
/**
* Create a chart in HBase by specifying parameters.
* @throws URISyntaxException
*/
public static synchronized String createChart(String id, String yunitType,
String title, String[] metrics, String source) throws URISyntaxException {
Chart chart = new Chart(id);
chart.setYUnitType(yunitType);
chart.setTitle(title);
ArrayList<SeriesMetaData> series = new ArrayList<SeriesMetaData>();
for(String metric : metrics) {
SeriesMetaData s = new SeriesMetaData();
s.setLabel(metric + "/" + source);
s.setUrl(new URI("/hicc/v1/metrics/series/" + metric + "/"
+ source));
LineOptions l = new LineOptions();
s.setLineOptions(l);
series.add(s);
}
chart.setSeries(series);
return createChart(chart);
}
/**
* Create a chart in HBase.
*
* @param chart
* @return id of newly created chart
* @throws IOException
*/
public static synchronized String createChart(Chart chart) {
String id = chart.getId();
try {
getHBaseConnection();
if (id != null) {
// Check if there is existing chart with same id.
Chart test = getChart(id);
if (test != null) {
// If id already exists, randomly generate an id.
id = String.valueOf(UUID.randomUUID());
}
} else {
// If id is not provided, randomly generate an id.
id = String.valueOf(UUID.randomUUID());
}
chart.setId(id);
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Put put = new Put(CHART_TYPE);
Gson gson = new Gson();
String buffer = gson.toJson(chart);
put.addColumn(CHART_FAMILY, id.getBytes(UTF8), buffer.getBytes(UTF8));
table.put(put);
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
id = null;
}
return id;
}
/**
* Return data for multiple series of metrics stored in HBase.
*
* @param series
* @param startTime
* @param endTime
* @return
*/
public static synchronized ArrayList<org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData> getChartSeries(ArrayList<org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData> series, long startTime, long endTime) {
ArrayList<org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData> list = new ArrayList<org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData>();
try {
// Swap start and end if the values are inverted.
if (startTime > endTime) {
long temp = endTime;
startTime = endTime;
endTime = temp;
}
// Figure out the time range and determine the best resolution
// to fetch the data
long range = (endTime - startTime)
/ (long) (MINUTES_IN_HOUR * MINUTE);
long sampleRate = 1;
if (range <= 1) {
sampleRate = 5;
} else if(range <= 24) {
sampleRate = 240;
} else if (range <= 720) {
sampleRate = 7200;
} else if(range >= 720) {
sampleRate = 87600;
}
double smoothing = (endTime - startTime)
/ (double) (sampleRate * SECOND ) / (double) RESOLUTION;
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA));
Scan scan = new Scan();
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
c.setTimeInMillis(startTime);
int startDay = c.get(Calendar.DAY_OF_YEAR);
c.setTimeInMillis(endTime);
int endDay = c.get(Calendar.DAY_OF_YEAR);
for (org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData s : series) {
org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData clone = (org.apache.hadoop.chukwa.hicc.bean.SeriesMetaData) s.clone();
long currentDay = startTime;
String[] parts = s.getUrl().toString().split("/");
String metric = parts[5];
String source = parts[6];
ArrayList<ArrayList<Number>> data = new ArrayList<ArrayList<Number>>();
for (int i = startDay; i <= endDay; i++) {
byte[] rowKey = HBaseUtil.buildKey(currentDay, metric, source);
scan.addFamily(COLUMN_FAMILY);
scan.setStartRow(rowKey);
scan.setStopRow(rowKey);
scan.setTimeRange(startTime, endTime);
scan.setBatch(10000);
ResultScanner results = table.getScanner(scan);
Iterator<Result> it = results.iterator();
double filteredValue = 0.0d;
long lastTime = startTime;
long totalElapsedTime = 0;
int initial = 0;
while (it.hasNext()) {
Result result = it.next();
for (Cell kv : result.rawCells()) {
byte[] key = CellUtil.cloneQualifier(kv);
long timestamp = ByteBuffer.wrap(key).getLong();
double value = Double.parseDouble(new String(CellUtil.cloneValue(kv),
UTF8));
if(initial==0) {
filteredValue = value;
}
long elapsedTime = (timestamp - lastTime) / SECOND;
lastTime = timestamp;
// Determine if there is any gap, if there is gap in data, reset
// calculation.
if (elapsedTime > (sampleRate * 5)) {
filteredValue = 0.0d;
} else {
if (smoothing != 0.0d) {
// Apply low pass filter to calculate
filteredValue = filteredValue + (double) ((double) elapsedTime * (double) ((double) (value - filteredValue) / smoothing));
} else {
// Use original value
filteredValue = value;
}
}
totalElapsedTime = totalElapsedTime + elapsedTime;
if (totalElapsedTime >= sampleRate) {
ArrayList<Number> points = new ArrayList<Number>();
points.add(timestamp);
points.add(filteredValue);
data.add(points);
totalElapsedTime = 0;
}
}
initial++;
}
results.close();
currentDay = currentDay + (i * MILLISECONDS_IN_DAY);
}
clone.setData(data);
list.add(clone);
}
table.close();
} catch (IOException|CloneNotSupportedException e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return list;
}
/**
* List widgets stored in HBase.
*
* @param limit
* @param offset
* @return
*/
public static synchronized List<Widget> listWidget(int limit, int offset) {
ArrayList<Widget> list = new ArrayList<Widget>();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Scan scan = new Scan();
scan.setStartRow(WIDGET_TYPE);
scan.setStopRow(WIDGET_TYPE);
ResultScanner rs = table.getScanner(scan);
Iterator<Result> it = rs.iterator();
int c = 0;
while(it.hasNext()) {
Result result = it.next();
for(Cell kv : result.rawCells()) {
if(c > limit) {
break;
}
if(c < offset) {
continue;
}
Gson gson = new Gson();
Widget widget = gson.fromJson(new String(CellUtil.cloneValue(kv), UTF8), Widget.class);
list.add(widget);
c++;
}
}
rs.close();
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return list;
}
/**
* Find widget by title prefix in HBase.
*
* @param query - Prefix query of widget title.
* @return
*/
public static synchronized List<Widget> searchWidget(String query) {
ArrayList<Widget> list = new ArrayList<Widget>();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Filter filter = new ColumnPrefixFilter(Bytes.toBytes(query));
Scan scan = new Scan();
scan.setStartRow(WIDGET_TYPE);
scan.setStopRow(WIDGET_TYPE);
scan.setFilter(filter);
ResultScanner rs = table.getScanner(scan);
Iterator<Result> it = rs.iterator();
while(it.hasNext()) {
Result result = it.next();
for(Cell kv : result.rawCells()) {
Gson gson = new Gson();
Widget widget = gson.fromJson(new String(CellUtil.cloneValue(kv), UTF8), Widget.class);
list.add(widget);
}
}
rs.close();
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return list;
}
/**
* View a widget information in HBase.
*
* @param title - Title of the widget.
* @return
*/
public static synchronized Widget viewWidget(String title) {
Widget w = null;
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get widget = new Get(WIDGET_TYPE);
widget.addColumn(COMMON_FAMILY, title.getBytes(UTF8));
Result rs = table.get(widget);
byte[] buffer = rs.getValue(COMMON_FAMILY, title.getBytes(UTF8));
Gson gson = new Gson();
w = gson.fromJson(new String(buffer, UTF8), Widget.class);
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return w;
}
/**
* Create a widget in HBase.
*
* @param widget
*/
public static synchronized boolean createWidget(Widget widget) {
boolean created = false;
try {
widget.tokenize();
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get widgetTest = new Get(WIDGET_TYPE);
widgetTest.addColumn(COMMON_FAMILY, widget.getTitle().getBytes(UTF8));
if (table.exists(widgetTest)) {
LOG.warn("Widget: " + widget.getTitle() + " already exists.");
created = false;
} else {
Put put = new Put(WIDGET_TYPE);
Gson gson = new Gson();
String buffer = gson.toJson(widget);
put.addColumn(COMMON_FAMILY, widget.getTitle().getBytes(UTF8), buffer.getBytes(UTF8));
table.put(put);
created = true;
}
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return created;
}
/**
* Update a widget in HBase.
*
* @param title
* @param widget
* @throws IOException
*/
public static synchronized boolean updateWidget(String title, Widget widget) {
boolean result = false;
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Delete oldWidget = new Delete(WIDGET_TYPE);
oldWidget.addColumn(COMMON_FAMILY, title.getBytes(UTF8));
table.delete(oldWidget);
Put put = new Put(WIDGET_TYPE);
Gson gson = new Gson();
String buffer = gson.toJson(widget);
put.addColumn(COMMON_FAMILY, title.getBytes(UTF8), buffer.getBytes(UTF8));
table.put(put);
table.close();
result = true;
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
LOG.error("Error in updating widget, original title: " +
title + " new title:" + widget.getTitle());
}
return result;
}
/**
* Delete a widget in HBase.
*
* @param title
* @param widget
* @throws IOException
*/
public static synchronized boolean deleteWidget(String title) {
boolean result = false;
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Delete oldWidget = new Delete(WIDGET_TYPE);
oldWidget.addColumn(COMMON_FAMILY, title.getBytes(UTF8));
table.delete(oldWidget);
table.close();
result = true;
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
LOG.error("Error in deleting widget: "+ title);
}
return result;
}
public static boolean isDefaultExists() {
boolean exists = false;
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get dashboardTest = new Get(DASHBOARD_TYPE);
dashboardTest.addColumn(COMMON_FAMILY, "default".getBytes(UTF8));
exists = table.exists(dashboardTest);
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
}
return exists;
}
public static void populateDefaults() {
boolean defaultExists = isDefaultExists();
try {
if(defaultExists) {
return;
}
String hostname = InetAddress.getLocalHost().getHostName();
// Populate example chart widgets
String[] metrics = { "SystemMetrics.LoadAverage.1" };
createChart("1", "", "System Load Average", metrics, hostname);
String[] cpuMetrics = { "SystemMetrics.cpu.combined", "SystemMetrics.cpu.sys", "SystemMetrics.cpu.user" };
createChart("2", "percent", "CPU Utilization", cpuMetrics, hostname);
String[] memMetrics = { "SystemMetrics.memory.FreePercent", "SystemMetrics.memory.UsedPercent"};
createChart("3", "percent", "Memory Utilization", memMetrics, hostname);
String[] diskMetrics = { "SystemMetrics.disk.ReadBytes", "SystemMetrics.disk.WriteBytes" };
createChart("4", "bytes-decimal", "Disk Utilization", diskMetrics, hostname);
String[] netMetrics = { "SystemMetrics.network.TxBytes", "SystemMetrics.network.RxBytes" };
createChart("5", "bytes", "Network Utilization", netMetrics, hostname);
String[] swapMetrics = { "SystemMetrics.swap.Total", "SystemMetrics.swap.Used", "SystemMetrics.swap.Free" };
createChart("6", "bytes-decimal", "Swap Utilization", swapMetrics, hostname);
// Populate default widgets
Widget widget = new Widget();
widget.setTitle("System Load Average");
widget.setSrc(new URI("/hicc/v1/chart/draw/1"));
widget.setCol(1);
widget.setRow(1);
widget.setSize_x(2);
widget.setSize_y(1);
createWidget(widget);
// CPU heatmap
widget = new Widget();
widget.setTitle("CPU Heatmap");
widget.setSrc(new URI("/hicc/jsp/heatmap.jsp"));
widget.setCol(1);
widget.setRow(1);
widget.setSize_x(5);
widget.setSize_y(1);
createWidget(widget);
Dashboard dashboard = new Dashboard();
// Log Search widget
widget = new Widget();
widget.setTitle("Log Search");
widget.setSrc(new URI("/hicc/ajax-solr/chukwa"));
widget.setCol(1);
widget.setRow(1);
widget.setSize_x(7);
widget.setSize_y(4);
createWidget(widget);
dashboard.add(widget);
updateDashboard("default", "", dashboard);
// Populate system dashboards
dashboard = new Dashboard();
widget = new Widget();
widget.setTitle("CPU Utilization");
widget.setSrc(new URI("/hicc/v1/chart/draw/2"));
widget.setCol(1);
widget.setRow(1);
widget.setSize_x(3);
widget.setSize_y(1);
createWidget(widget);
dashboard.add(widget);
widget = new Widget();
widget.setTitle("Memory Utilization");
widget.setSrc(new URI("/hicc/v1/chart/draw/3"));
widget.setCol(4);
widget.setRow(1);
widget.setSize_x(3);
widget.setSize_y(1);
createWidget(widget);
dashboard.add(widget);
widget = new Widget();
widget.setTitle("Disk Utilization");
widget.setSrc(new URI("/hicc/v1/chart/draw/4"));
widget.setCol(1);
widget.setRow(2);
widget.setSize_x(3);
widget.setSize_y(1);
createWidget(widget);
dashboard.add(widget);
widget = new Widget();
widget.setTitle("Network Utilization");
widget.setSrc(new URI("/hicc/v1/chart/draw/5"));
widget.setCol(4);
widget.setRow(2);
widget.setSize_x(3);
widget.setSize_y(1);
createWidget(widget);
dashboard.add(widget);
widget = new Widget();
widget.setTitle("Swap Utilization");
widget.setSrc(new URI("/hicc/v1/chart/draw/6"));
widget.setCol(1);
widget.setRow(3);
widget.setSize_x(3);
widget.setSize_y(1);
createWidget(widget);
dashboard.add(widget);
widget = new Widget();
widget.setTitle("System Load Average");
widget.setSrc(new URI("/hicc/v1/chart/draw/1"));
widget.setCol(4);
widget.setRow(3);
widget.setSize_x(3);
widget.setSize_y(1);
createWidget(widget);
dashboard.add(widget);
updateDashboard("system", "", dashboard);
} catch (Throwable ex) {
LOG.error(ExceptionUtil.getStackTrace(ex));
}
}
public static synchronized Dashboard getDashboard(String id, String user) {
Dashboard dash = null;
String key = new StringBuilder().append(id).
append("|").append(user).toString();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Get dashboard = new Get(DASHBOARD_TYPE);
dashboard.addColumn(COMMON_FAMILY, key.getBytes(UTF8));
Result rs = table.get(dashboard);
byte[] buffer = rs.getValue(COMMON_FAMILY, key.getBytes(UTF8));
if(buffer == null) {
// If user dashboard is not found, use default dashboard.
key = new StringBuilder().append(id).append("|").toString();
dashboard = new Get(DASHBOARD_TYPE);
dashboard.addColumn(COMMON_FAMILY, key.getBytes(UTF8));
rs = table.get(dashboard);
buffer = rs.getValue(COMMON_FAMILY, key.getBytes(UTF8));
}
Gson gson = new Gson();
dash = gson.fromJson(new String(buffer, UTF8), Dashboard.class);
table.close();
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
LOG.error("Error retrieving dashboard, id: " +
id + " user:" + user);
}
return dash;
}
public static boolean updateDashboard(String id, String user, Dashboard dash) {
boolean result = false;
String key = new StringBuilder().append(id).
append("|").append(user).toString();
try {
getHBaseConnection();
Table table = connection.getTable(TableName.valueOf(CHUKWA_META));
Put put = new Put(DASHBOARD_TYPE);
Gson gson = new Gson();
String buffer = gson.toJson(dash);
put.addColumn(COMMON_FAMILY, key.getBytes(UTF8), buffer.getBytes(UTF8));
table.put(put);
table.close();
result = true;
} catch (Exception e) {
closeHBase();
LOG.error(ExceptionUtil.getStackTrace(e));
LOG.error("Error in updating dashboard, id: " +
id + " user:" + user);
}
return result;
}
}