use of org.rrd4j.core.RrdDb in project ddf by codice.
the class RrdMetricsRetriever method createGraph.
@Override
public byte[] createGraph(String metricName, String rrdFilename, long startTime, long endTime, String verticalAxisLabel, String title) throws IOException, MetricsGraphException {
// Create RRD DB in read-only mode for the specified RRD file
RrdDb rrdDb = new RrdDb(rrdFilename, true);
// we have a problem)
if (rrdDb.getDsCount() != 1) {
throw new MetricsGraphException("Only one data source per RRD file is supported - RRD file " + rrdFilename + " has " + rrdDb.getDsCount() + " data sources.");
}
// Define attributes of the graph to be created for this metric
RrdGraphDef graphDef = new RrdGraphDef();
graphDef.setTimeSpan(startTime, endTime);
graphDef.setImageFormat("PNG");
graphDef.setShowSignature(false);
graphDef.setStep(RRD_STEP);
graphDef.setVerticalLabel(verticalAxisLabel);
graphDef.setHeight(500);
graphDef.setWidth(1000);
graphDef.setTitle(title);
// Since we have verified only one datasource in RRD file/RRDb, then know
// that we can index by zero safely and get the metric's data
Datasource dataSource = rrdDb.getDatasource(0);
DsType dataSourceType = dataSource.getType();
// generated graph by default will show data per rrdStep interval)
if (dataSourceType == DsType.COUNTER || dataSourceType == DsType.DERIVE) {
if (LOGGER.isTraceEnabled()) {
dumpData(ConsolFun.TOTAL, "TOTAL", rrdDb, dataSourceType.name(), startTime, endTime);
}
// If we ever needed to adjust the metric's data collected by RRD by the archive step
// (which is the rrdStep * archiveSampleCount) this is how to do it.
// FetchRequest fetchRequest = rrdDb.createFetchRequest(ConsolFun.AVERAGE, startTime,
// endTime);
// Archive archive = rrdDb.findMatchingArchive(fetchRequest);
// long archiveStep = archive.getArcStep();
// LOGGER.debug("archiveStep = " + archiveStep);
long rrdStep = rrdDb.getRrdDef().getStep();
LOGGER.debug("rrdStep = {}", rrdStep);
// Still TBD if we want to graph the AVERAGE data on the same graph
// graphDef.comment(metricName + " ");
// graphDef.datasource("myAverage", rrdFilename, "data", ConsolFun.AVERAGE);
// graphDef.datasource("realAverage", "myAverage," + rrdStep + ",*");
// graphDef.line("realAverage", Color.GREEN, "Average", 2);
// Multiplied by the rrdStep to "undo" the automatic averaging that RRD does
// when it collects TOTAL data - we want the actual totals for the step, not
// the average of the totals.
graphDef.datasource("myTotal", rrdFilename, dataSource.getName(), ConsolFun.TOTAL);
graphDef.datasource("realTotal", "myTotal," + rrdStep + ",*");
// If real total exceeds the threshold value used to constrain/filter spike data out,
// then set total to UNKNOWN, which means this sample will not be graphed. This prevents
// spike data that is typically 4.2E+09 (graphed as 4.3G) from corrupting the RRD graph.
graphDef.datasource("constrainedTotal", "realTotal," + metricsMaxThreshold + ",GT,UNKN,realTotal,IF");
graphDef.line("constrainedTotal", Color.BLUE, convertCamelCase(metricName), 2);
// Add some spacing between the graph and the summary stats shown beneath the graph
graphDef.comment("\\s");
graphDef.comment("\\s");
graphDef.comment("\\c");
// Average, Min, and Max over all of the TOTAL data - displayed at bottom of the graph
graphDef.gprint("constrainedTotal", ConsolFun.AVERAGE, "Average = %.3f%s");
graphDef.gprint("constrainedTotal", ConsolFun.MIN, "Min = %.3f%s");
graphDef.gprint("constrainedTotal", ConsolFun.MAX, "Max = %.3f%s");
} else if (dataSourceType == DsType.GAUGE) {
if (LOGGER.isTraceEnabled()) {
dumpData(ConsolFun.AVERAGE, "AVERAGE", rrdDb, dataSourceType.name(), startTime, endTime);
}
graphDef.datasource("myAverage", rrdFilename, dataSource.getName(), ConsolFun.AVERAGE);
graphDef.line("myAverage", Color.RED, convertCamelCase(metricName), 2);
// Add some spacing between the graph and the summary stats shown beneath the graph
graphDef.comment("\\s");
graphDef.comment("\\s");
graphDef.comment("\\c");
// Average, Min, and Max over all of the AVERAGE data - displayed at bottom of the graph
graphDef.gprint("myAverage", ConsolFun.AVERAGE, "Average = %.3f%s");
graphDef.gprint("myAverage", ConsolFun.MIN, "Min = %.3f%s");
graphDef.gprint("myAverage", ConsolFun.MAX, "Max = %.3f%s");
} else {
rrdDb.close();
throw new MetricsGraphException("Unsupported data source type " + dataSourceType.name() + " in RRD file " + rrdFilename + ", only DERIVE, COUNTER and GAUGE data source types supported.");
}
rrdDb.close();
// Use "-" as filename so that RRD creates the graph only in memory (no file is
// created, hence no file locking problems due to race conditions between multiple clients)
graphDef.setFilename("-");
RrdGraph graph = new RrdGraph(graphDef);
return graph.getRrdGraphInfo().getBytes();
}
use of org.rrd4j.core.RrdDb in project openhab1-addons by openhab.
the class RRD4jService method query.
@Override
public Iterable<HistoricItem> query(FilterCriteria filter) {
String itemName = filter.getItemName();
RrdDb db = getDB(itemName);
if (db != null) {
ConsolFun consolidationFunction = getConsolidationFunction(db);
long start = 0L;
long end = filter.getEndDate() == null ? System.currentTimeMillis() / 1000 : filter.getEndDate().getTime() / 1000;
try {
if (filter.getBeginDate() == null) {
// want to support
if (filter.getOrdering() == Ordering.DESCENDING && filter.getPageSize() == 1 && filter.getPageNumber() == 0) {
if (filter.getEndDate() == null) {
// we are asked only for the most recent value!
double lastValue = db.getLastDatasourceValue(DATASOURCE_STATE);
if (!Double.isNaN(lastValue)) {
HistoricItem rrd4jItem = new RRD4jItem(itemName, mapToState(lastValue, itemName), new Date(db.getLastArchiveUpdateTime() * 1000));
return Collections.singletonList(rrd4jItem);
} else {
return Collections.emptyList();
}
} else {
start = end;
}
} else {
throw new UnsupportedOperationException("rrd4j does not allow querys without a begin date, " + "unless order is descending and a single value is requested");
}
} else {
start = filter.getBeginDate().getTime() / 1000;
}
FetchRequest request = db.createFetchRequest(consolidationFunction, start, end, 1);
List<HistoricItem> items = new ArrayList<HistoricItem>();
FetchData result = request.fetchData();
long ts = result.getFirstTimestamp();
long step = result.getRowCount() > 1 ? result.getStep() : 0;
for (double value : result.getValues(DATASOURCE_STATE)) {
if (!Double.isNaN(value) && (((ts >= start) && (ts <= end)) || (start == end))) {
RRD4jItem rrd4jItem = new RRD4jItem(itemName, mapToState(value, itemName), new Date(ts * 1000));
items.add(rrd4jItem);
}
ts += step;
}
return items;
} catch (IOException e) {
logger.warn("Could not query rrd4j database for item '{}': {}", itemName, e.getMessage());
}
}
return Collections.emptyList();
}
use of org.rrd4j.core.RrdDb in project ddf by codice.
the class RrdJmxCollectorTest method testRrdFileCreationForGaugeDataSource.
@Test
public void testRrdFileCreationForGaugeDataSource() throws Exception {
// Set sample rate to 1 sec (default is 60 seconds) so that unit test runs quickly
String mbeanAttributeName = "Uptime";
String metricName = name.getMethodName();
int sampleRate = 1;
createJmxCollector(mbeanAttributeName, metricName, RrdJmxCollector.GAUGE_DATA_SOURCE_TYPE, sampleRate);
String rrdFilename = jmxCollector.getRrdPath();
assertThat(rrdFilename, is(TEST_DIR + metricName + RrdJmxCollector.RRD_FILENAME_SUFFIX));
rrdDb = new RrdDb(rrdFilename);
assertThat(rrdDb, not(nullValue()));
assertThat(rrdDb.isClosed(), is(false));
Header header = rrdDb.getHeader();
assertThat(header, not(nullValue()));
assertThat(header.getStep(), is((long) sampleRate));
assertThat(rrdDb.getDsCount(), is(1));
Datasource dataSource = rrdDb.getDatasource(dataSourceName);
assertThat(dataSource, not(nullValue()));
DsType dataSourceType = dataSource.getType();
assertThat(dataSourceType, is(DsType.GAUGE));
assertThat(rrdDb.getArcCount(), is(8));
Archive archive = rrdDb.getArchive(ConsolFun.MIN, 1);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(60));
archive = rrdDb.getArchive(ConsolFun.MIN, 15);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(RrdJmxCollector.ONE_YEAR_IN_15_MINUTE_STEPS));
archive = rrdDb.getArchive(ConsolFun.MAX, 1);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(60));
archive = rrdDb.getArchive(ConsolFun.MAX, 15);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(RrdJmxCollector.ONE_YEAR_IN_15_MINUTE_STEPS));
archive = rrdDb.getArchive(ConsolFun.AVERAGE, 1);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(60));
archive = rrdDb.getArchive(ConsolFun.AVERAGE, 15);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(RrdJmxCollector.ONE_YEAR_IN_15_MINUTE_STEPS));
}
use of org.rrd4j.core.RrdDb in project ddf by codice.
the class RrdJmxCollectorTest method testRrdFileCreationWhenRrdFileAlreadyExists.
@Test
public void testRrdFileCreationWhenRrdFileAlreadyExists() throws Exception {
// Set sample rate to 1 sec (default is 60 seconds) so that unit test runs quickly
String mbeanAttributeName = "Uptime";
String metricName = name.getMethodName();
int sampleRate = 1;
createJmxCollector(mbeanAttributeName, metricName, RrdJmxCollector.DERIVE_DATA_SOURCE_TYPE, sampleRate);
String rrdFilename1 = jmxCollector.getRrdPath();
assertThat(rrdFilename1, is(TEST_DIR + metricName + RrdJmxCollector.RRD_FILENAME_SUFFIX));
rrdDb = new RrdDb(rrdFilename1);
assertThat(rrdDb, not(nullValue()));
assertThat(rrdDb.isClosed(), is(false));
// Attempt to create again
LOGGER.debug("Creating JmxCollector again ...");
dataSourceName = mbeanAttributeName.toLowerCase();
RrdJmxCollector jmxCollector2 = new RrdJmxCollector("java.lang:type=Runtime", mbeanAttributeName, metricName, RrdJmxCollector.DERIVE_DATA_SOURCE_TYPE, dataSourceName);
jmxCollector2.setSampleRate(sampleRate);
jmxCollector2.setMetricsDir(TEST_DIR);
// Simulates what blueprint would do
jmxCollector2.configureCollector();
// Verify the 2 JMX Collectors are using the same RRD file
String rrdFilename2 = jmxCollector2.getRrdPath();
assertThat(rrdFilename2, is(TEST_DIR + metricName + RrdJmxCollector.RRD_FILENAME_SUFFIX));
assertThat(rrdFilename1, equalTo(rrdFilename2));
jmxCollector2.destroy();
}
use of org.rrd4j.core.RrdDb in project ddf by codice.
the class RrdJmxCollectorTest method testRrdFileCreationForDeriveDataSource.
@Test
public void testRrdFileCreationForDeriveDataSource() throws Exception {
// Set sample rate to 1 sec (default is 60 seconds) so that unit test runs quickly
String mbeanAttributeName = "Uptime";
String metricName = name.getMethodName();
int sampleRate = 1;
createJmxCollector(mbeanAttributeName, metricName, RrdJmxCollector.DERIVE_DATA_SOURCE_TYPE, sampleRate);
String rrdFilename = jmxCollector.getRrdPath();
assertThat(rrdFilename, is(TEST_DIR + metricName + RrdJmxCollector.RRD_FILENAME_SUFFIX));
rrdDb = new RrdDb(rrdFilename);
assertThat(rrdDb, not(nullValue()));
assertThat(rrdDb.isClosed(), is(false));
Header header = rrdDb.getHeader();
assertThat(header, not(nullValue()));
assertThat(header.getStep(), is((long) sampleRate));
assertThat(rrdDb.getDsCount(), is(1));
Datasource dataSource = rrdDb.getDatasource(dataSourceName);
assertThat(dataSource, not(nullValue()));
DsType dataSourceType = dataSource.getType();
assertThat(dataSourceType, is(DsType.DERIVE));
assertThat(rrdDb.getArcCount(), is(8));
Archive archive = rrdDb.getArchive(ConsolFun.AVERAGE, 1);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(60));
archive = rrdDb.getArchive(ConsolFun.AVERAGE, 15);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(RrdJmxCollector.ONE_YEAR_IN_15_MINUTE_STEPS));
archive = rrdDb.getArchive(ConsolFun.TOTAL, 1);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(60));
archive = rrdDb.getArchive(ConsolFun.TOTAL, 15);
assertThat(archive, not(nullValue()));
assertThat(archive.getRows(), is(RrdJmxCollector.ONE_YEAR_IN_15_MINUTE_STEPS));
// LOGGER.debug(rrdDb.dump());
}
Aggregations