Skip to content

Commit

Permalink
[HPM-258] [HPM-274] Standarize metric data output to CSV. Add --group…
Browse files Browse the repository at this point in the history
…Id option for metric data summaries.
  • Loading branch information
Ryan Morgan committed Jun 10, 2010
1 parent 183ae6d commit a9d0283
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 23 deletions.
8 changes: 6 additions & 2 deletions ChangeLog
@@ -1,12 +1,16 @@

Changes in HQApi 3.2

*) [HHQ-4060] Add --groupId option to metricData list CLI command.

*) [HHQ-4059] Standardize output from metricData list CLI command to
CSV format.

*) [HHQ-3962] Allow deletion of alerts in bulk via stdin.

*) Updated MetricDataApi to get metrics data summary for a resource
or group within a specified time range. Functionality added primarily
to do integration testing for HHQ-3803 and HHQ-3748. No
corresponding CLI command was added.
to do integration testing for HHQ-3803 and HHQ-3748.

*) Add support to sync alert definitions with SNMP actions.
Functionality added primarily to do integration testing
Expand Down
172 changes: 151 additions & 21 deletions src/org/hyperic/hq/hqapi1/tools/MetricDataCommand.java
Expand Up @@ -29,31 +29,43 @@

import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.hyperic.hq.hqapi1.GroupApi;
import org.hyperic.hq.hqapi1.HQApi;
import org.hyperic.hq.hqapi1.MetricApi;
import org.hyperic.hq.hqapi1.MetricDataApi;
import org.hyperic.hq.hqapi1.ResourceApi;
import org.hyperic.hq.hqapi1.types.GroupResponse;
import org.hyperic.hq.hqapi1.types.MetricDataResponse;
import org.hyperic.hq.hqapi1.types.DataPoint;
import org.hyperic.hq.hqapi1.types.LastMetricsDataResponse;
import org.hyperic.hq.hqapi1.types.MetricDataSummary;
import org.hyperic.hq.hqapi1.types.MetricsDataSummaryResponse;
import org.hyperic.hq.hqapi1.types.MetricsResponse;
import org.hyperic.hq.hqapi1.types.ResourceResponse;
import org.hyperic.hq.hqapi1.types.LastMetricData;
import org.hyperic.hq.hqapi1.types.MetricResponse;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

@Component
public class MetricDataCommand extends AbstractCommand {

private static String CMD_LIST = "list";

private static String[] COMMANDS = { CMD_LIST };

private static final String OPT_RESOURCE_ID = "resourceId";
private static final String OPT_METRIC_ID = "metricId";
private static final String OPT_HOURS = "hours";
private static final String OPT_RESOURCE_ID = "resourceId";
private static final String OPT_METRIC_ID = "metricId";
private static final String OPT_GROUP_ID = "groupId";
private static final String OPT_FORMAT_DATES = "formatDates";
private static final String OPT_HOURS = "hours";

private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";

private void printUsage() {
System.err.println("One of " + Arrays.toString(COMMANDS) + " required");
Expand Down Expand Up @@ -85,20 +97,27 @@ private void list(String[] args) throws Exception {

p.accepts(OPT_RESOURCE_ID, "The resource id to query for metric data")
.withRequiredArg().ofType(Integer.class);
p.accepts(OPT_METRIC_ID, "The metric id to query for data")
p.accepts(OPT_METRIC_ID, "The metric id to query for metric data")
.withRequiredArg().ofType(Integer.class);
p.accepts(OPT_GROUP_ID, "The group id to query for metric data")
.withRequiredArg().ofType(Integer.class);
p.accepts(OPT_HOURS, "The number of hours of data to query. Defaults to 8")
.withRequiredArg().ofType(Integer.class);
p.accepts(OPT_FORMAT_DATES, "When specified timestamps will be formatted " +
"using the given format. Defaults to " + FORMAT)
.withOptionalArg().ofType(String.class);

OptionSet options = getOptions(p, args);

HQApi api = getApi(options);
ResourceApi resourceApi = api.getResourceApi();
GroupApi groupApi = api.getGroupApi();
MetricApi metricApi = api.getMetricApi();
MetricDataApi dataApi = api.getMetricDataApi();

final long MS_IN_HOUR = 60l * 60l * 1000l;
final long end = System.currentTimeMillis();
long end = System.currentTimeMillis();
end = end - (end%60000); // Make sure end is on a 1 minute boundary.
long start;
if (options.has(OPT_HOURS)) {
int hours = (Integer)options.valueOf(OPT_HOURS);
Expand All @@ -107,6 +126,14 @@ private void list(String[] args) throws Exception {
start = end - (8 * MS_IN_HOUR);
}

String format = null;
if (options.has(OPT_FORMAT_DATES)) {
format = (String)options.valueOf(OPT_FORMAT_DATES);
if (format == null) {
format = FORMAT;
}
}

if (options.has(OPT_METRIC_ID)) {
MetricResponse metric =
metricApi.getMetric((Integer)getRequired(options,
Expand All @@ -117,12 +144,11 @@ private void list(String[] args) throws Exception {
dataApi.getData(metric.getMetric(), start, end);
checkSuccess(data);

System.out.println("Values for " + data.getMetricData().getMetricName() +
" on " + data.getMetricData().getResourceName());
CsvTable table = new CsvTable(new String[] {"Value"}, format);
for (DataPoint dp : data.getMetricData().getDataPoint()) {
System.out.println(" " + new Date(dp.getTimestamp()) +
" = " + dp.getValue());
table.add(dp.getTimestamp(), 0, dp.getValue());
}
table.output();
} else if (options.has(OPT_RESOURCE_ID)){
ResourceResponse resource =
resourceApi.getResource((Integer)getRequired(options,
Expand All @@ -133,20 +159,124 @@ private void list(String[] args) throws Exception {
MetricsResponse metrics = metricApi.getMetrics(resource.getResource(), true);
checkSuccess(metrics);

LastMetricsDataResponse data = dataApi.getData(metrics.getMetric());
String[] metricNames = new String[metrics.getMetric().size()];
for (int i = 0; i < metrics.getMetric().size(); i++) {
metricNames[i] = metrics.getMetric().get(i).getName() + "(id=" +
metrics.getMetric().get(i).getId() + ")";
}

CsvTable table = new CsvTable(metricNames, format);
for (int i = 0; i < metrics.getMetric().size(); i++) {
MetricDataResponse data =
dataApi.getData(metrics.getMetric().get(i), start, end);
checkSuccess(data);

for (DataPoint dp : data.getMetricData().getDataPoint()) {
table.add(dp.getTimestamp(), i, dp.getValue());
}
}
table.output();
} else if (options.has(OPT_GROUP_ID)) {
GroupResponse group =
groupApi.getGroup((Integer)getRequired(options,
OPT_GROUP_ID));
checkSuccess(group);

if (group.getGroup().getResourcePrototype() == null) {
System.err.println("Group " + group.getGroup().getName() +
" is not a compatible group.");
}

MetricsDataSummaryResponse data =
dataApi.getSummary(group.getGroup(), start, end);
checkSuccess(data);

System.out.println("Last metric values for " + resource.getResource().getName());
for (LastMetricData d : data.getLastMetricData()) {
String value;
if (d.getDataPoint() != null) {
value = d.getDataPoint().getValue() + " (at " +
new Date(d.getDataPoint().getTimestamp()) + ")";
System.out.println("Metric Name, Template Id, Min, Max, Avg, Last");
for (MetricDataSummary s : data.getMetricDataSummary()) {
System.out.println(s.getMetricName() + "," +
s.getMetricTemplateId() + "," +
s.getMinMetric() + "," +
s.getMaxMetric() + "," +
s.getAvgMetric() + "," +
s.getLastMetric());
}
}
}

private class CsvTable {

private Map<Long,Row> _rows = new TreeMap<Long,Row>();
private List<String> _headers = new ArrayList<String>();
private TimeFormat _tsFormat;

CsvTable(String[] headers, String dateFormat) {
_tsFormat = new TimeFormat(dateFormat);
_headers.addAll(Arrays.asList(headers));
}

private class TimeFormat {

SimpleDateFormat _df;

TimeFormat(String format) {
if (format != null) {
_df = new SimpleDateFormat(format);
}
}

public String format(Long ts) {
if (_df != null) {
return _df.format(new Date(ts));
} else {
value = "No data";
return String.valueOf(ts);
}
}
}

private class Row {
private Object[] _values;

Row(int columns) {
_values = new Object[columns];
}

public void add(int idx, Object val) {
_values[idx] = val;
}

public Object[] getValues() {
return _values;
}
}

public void add(long ts, int idx, Object value) {
Row r = _rows.get(ts);
if (r == null) {
r = new Row(_headers.size());
r.add(idx, value);
_rows.put(ts, r);
} else {
r.add(idx, value);
}
}

public void output() {
for (String header : _headers) {
System.out.print("," + header);
}
System.out.println();

for (Long ts : _rows.keySet()) {
Row r = _rows.get(ts);
System.out.print(_tsFormat.format(ts));
for (Object val : r.getValues()) {
if (val == null) {
System.out.print(",");
} else {
System.out.print("," + val);
}
}
System.out.println(" " + d.getMetricName() +
" (id=" + d.getMetricId() + ") = " + value);
System.out.println();
}
}
}
Expand Down

0 comments on commit a9d0283

Please sign in to comment.