use of org.rrd4j.core.RrdDb in project openhab1-addons by openhab.
the class RRD4jService method getDB.
protected synchronized RrdDb getDB(String alias) {
RrdDb db = null;
File file = new File(DB_FOLDER + File.separator + alias + ".rrd");
try {
if (file.exists()) {
// recreate the RrdDb instance from the file
db = new RrdDb(file.getAbsolutePath());
} else {
File folder = new File(DB_FOLDER);
if (!folder.exists()) {
folder.mkdirs();
}
// create a new database file
// db = new RrdDb(getRrdDef(function, file));
db = new RrdDb(getRrdDef(alias, file));
}
} catch (IOException e) {
logger.error("Could not create rrd4j database file '{}': {}", file.getAbsolutePath(), e.getMessage());
} catch (RejectedExecutionException e) {
// this happens if the system is shut down
logger.debug("Could not create rrd4j database file '{}': {}", file.getAbsolutePath(), e.getMessage());
}
return db;
}
use of org.rrd4j.core.RrdDb in project openhab1-addons by openhab.
the class RRD4jService method store.
/**
* @{inheritDoc}
*/
@Override
public synchronized void store(final Item item, final String alias) {
final String name = alias == null ? item.getName() : alias;
RrdDb db = getDB(name);
if (db != null) {
ConsolFun function = getConsolidationFunction(db);
long now = System.currentTimeMillis() / 1000;
if (function != ConsolFun.AVERAGE) {
try {
// happens right at this spot
if (now - 1 > db.getLastUpdateTime()) {
// only do it if there is not already a value
double lastValue = db.getLastDatasourceValue(DATASOURCE_STATE);
if (!Double.isNaN(lastValue)) {
Sample sample = db.createSample();
sample.setTime(now - 1);
sample.setValue(DATASOURCE_STATE, lastValue);
sample.update();
logger.debug("Stored '{}' with state '{}' in rrd4j database (again)", name, mapToState(lastValue, item.getName()));
}
}
} catch (IOException e) {
logger.debug("Error storing last value (again): {}", e.getMessage());
}
}
try {
Sample sample = db.createSample();
sample.setTime(now);
DecimalType state = (DecimalType) item.getStateAs(DecimalType.class);
if (state != null) {
double value = state.toBigDecimal().doubleValue();
if (db.getDatasource(DATASOURCE_STATE).getType() == DsType.COUNTER) {
// counter
// values
// must
// be
// adjusted
// by
// stepsize
value = value * db.getRrdDef().getStep();
}
sample.setValue(DATASOURCE_STATE, value);
sample.update();
logger.debug("Stored '{}' with state '{}' in rrd4j database", name, state);
}
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("at least one second step is required")) {
// we try to store the value one second later
Runnable task = new Runnable() {
@Override
public void run() {
store(item, name);
}
};
ScheduledFuture<?> job = scheduledJobs.get(name);
if (job != null) {
job.cancel(true);
scheduledJobs.remove(name);
}
job = scheduler.schedule(task, 1, TimeUnit.SECONDS);
scheduledJobs.put(name, job);
} else {
logger.warn("Could not persist '{}' to rrd4j database: {}", name, e.getMessage());
}
} catch (Exception e) {
logger.warn("Could not persist '{}' to rrd4j database: {}", name, e.getMessage());
}
try {
db.close();
} catch (IOException e) {
logger.debug("Error closing rrd4j database: {}", e.getMessage());
}
}
}
use of org.rrd4j.core.RrdDb in project openhab1-addons by openhab.
the class RRD4jChartServlet method addLine.
/**
* Adds a line for the item to the graph definition.
* The color of the line is determined by the counter, it simply picks the according index from LINECOLORS (and
* rolls over if necessary).
*
* @param graphDef the graph definition to fill
* @param item the item to add a line for
* @param counter defines the number of the datasource and is used to determine the line color
*/
protected void addLine(RrdGraphDef graphDef, Item item, int counter) {
Color color = LINECOLORS[counter % LINECOLORS.length];
String label = itemUIRegistry.getLabel(item.getName());
String rrdName = RRD4jService.DB_FOLDER + File.separator + item.getName() + ".rrd";
ConsolFun consolFun;
if (label != null && label.contains("[") && label.contains("]")) {
label = label.substring(0, label.indexOf('['));
}
try {
RrdDb db = new RrdDb(rrdName);
consolFun = db.getRrdDef().getArcDefs()[0].getConsolFun();
db.close();
} catch (IOException e) {
consolFun = ConsolFun.MAX;
}
if (item instanceof NumberItem) {
// we only draw a line
// RRD4jService.getConsolidationFunction(item));
graphDef.datasource(Integer.toString(counter), rrdName, "state", consolFun);
graphDef.line(Integer.toString(counter), color, label, 2);
} else {
// we draw a line and fill the area beneath it with a transparent color
// RRD4jService.getConsolidationFunction(item));
graphDef.datasource(Integer.toString(counter), rrdName, "state", consolFun);
Color areaColor = AREACOLORS[counter % LINECOLORS.length];
graphDef.area(Integer.toString(counter), areaColor);
graphDef.line(Integer.toString(counter), color, label, 2);
}
}
use of org.rrd4j.core.RrdDb in project ddf by codice.
the class RrdJmxCollectorTest method collectData.
private void collectData(int numRrdStepIterations) throws Exception {
String rrdFilename = jmxCollector.getRrdPath();
rrdDb = new RrdDb(rrdFilename);
Header header = rrdDb.getHeader();
// Wait for "n" iterations of RRDB's sample rate, then see if MBean value was collected
LOGGER.debug("Sleeping for {} seconds", header.getStep() * numRrdStepIterations);
Thread.sleep((header.getStep() * numRrdStepIterations) * 1000);
// LOGGER.debug(rrdDb.dump());
long endTime = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() / 1000;
// +1 because the fetch gets data for times inclusively, e.g.,
// endTime=12345, so startTime=12345-4=12341,
// then fetch data for timestamps 12341, 12342, 12343, 12344, 12345 (which is 5 values)
long startTime = endTime - numRrdStepIterations + 1;
LOGGER.debug("startTime = {}, endTime = {}", startTime, endTime);
FetchRequest fetchRequest = rrdDb.createFetchRequest(ConsolFun.TOTAL, startTime, endTime);
FetchData fetchData = fetchRequest.fetchData();
double[] values = fetchData.getValues(dataSourceName);
assertThat(values.length, is(numRrdStepIterations));
logFetchData(fetchData, "TOTAL");
fetchRequest = rrdDb.createFetchRequest(ConsolFun.AVERAGE, startTime, endTime);
fetchData = fetchRequest.fetchData();
values = fetchData.getValues(dataSourceName);
assertThat(values.length, is(numRrdStepIterations));
logFetchData(fetchData, "AVERAGE");
fetchRequest = rrdDb.createFetchRequest(ConsolFun.MIN, startTime, endTime);
fetchData = fetchRequest.fetchData();
values = fetchData.getValues(dataSourceName);
assertThat(values.length, is(numRrdStepIterations));
logFetchData(fetchData, "MIN");
fetchRequest = rrdDb.createFetchRequest(ConsolFun.MAX, startTime, endTime);
fetchData = fetchRequest.fetchData();
values = fetchData.getValues(dataSourceName);
assertThat(values.length, is(numRrdStepIterations));
logFetchData(fetchData, "MAX");
}
use of org.rrd4j.core.RrdDb in project ddf by codice.
the class RrdMetricsRetriever method getMetricData.
/**
* Retrieves the RRD stored data for the specified metric over the specified time range.
*
* @param rrdFilename the name of the RRD file containing the metric's data
* @param startTime start time, in seconds since Unix epoch, to fetch metric's data
* @param endTime end time, in seconds since Unix epoch, to fetch metric's data
* @return domain object containing the metric's sampled data, which consists of the timestamps
* and their associated values, and the total count of the sampled data
* @throws IOException
* @throws MetricsGraphException
*/
public MetricData getMetricData(String rrdFilename, long startTime, long endTime) throws IOException, MetricsGraphException {
LOGGER.trace("ENTERING: getMetricData");
// 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.");
}
// The step (sample) interval that determines how often RRD collects the metric's data
long rrdStep = rrdDb.getRrdDef().getStep();
// Retrieve the RRD file's data source type to determine how (later)
// to store the metric's data for presentation.
DsType dataSourceType = rrdDb.getDatasource(0).getType();
// Fetch the metric's data from the RRD file for the specified time range
FetchRequest fetchRequest = rrdDb.createFetchRequest(ConsolFun.TOTAL, startTime, endTime);
FetchData fetchData = fetchRequest.fetchData();
long[] timestamps = fetchData.getTimestamps();
double[] values = fetchData.getValues(0);
// Done retrieving data from the RRD database - close it, otherwise no one else will
// be able to access it later.
rrdDb.close();
// The lists of the metric's timestamps and their associated values that have non-"NaN"
// values
List<Long> validTimestamps = new ArrayList<Long>();
List<Double> validValues = new ArrayList<Double>();
long totalCount = 0;
MetricData metricData = new MetricData();
if (dataSourceType == DsType.COUNTER || dataSourceType == DsType.DERIVE) {
// Counters are for constantly incrementing data, hence they can
// have a summation of their totals
metricData.setHasTotalCount(true);
for (int i = 0; i < timestamps.length; i++) {
long timestamp = timestamps[i];
// have been set to NaN as a placeholder when the RRD file was created)
if (timestamp >= startTime && timestamp <= endTime && !Double.toString(values[i]).equals("NaN")) {
// RRD averages the collected samples over the step interval.
// To "undo" this averaging and get the actual count, need to
// multiply the sampled data value by the RRD step interval.
double nonAveragedValue = (double) (values[i] * rrdStep);
validTimestamps.add(timestamp);
validValues.add(nonAveragedValue);
totalCount += (long) nonAveragedValue;
}
}
} else if (dataSourceType == DsType.GAUGE) {
// Gauges are for data that waxes and wanes, hence no total count
metricData.setHasTotalCount(false);
for (int i = 0; i < timestamps.length; i++) {
long timestamp = timestamps[i];
// have been set to NaN as a placeholder when the RRD file was created)
if (timestamp >= startTime && timestamp <= endTime && !Double.toString(values[i]).equals("NaN")) {
validTimestamps.add(timestamp);
validValues.add(values[i]);
}
}
}
metricData.setTimestamps(validTimestamps);
metricData.setValues(validValues);
metricData.setTotalCount(totalCount);
LOGGER.trace("EXITING: getMetricData");
return metricData;
}
Aggregations