Esempio n. 1
0
  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 " + (header.getStep() * numRrdStepIterations) + " seconds");
    Thread.sleep((header.getStep() * numRrdStepIterations) * 1000);

    // LOGGER.debug(rrdDb.dump());

    long endTime = Calendar.getInstance().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 = " + startTime + ",   endTime = " + 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");
  }
  private Map<Long, ArrayList<String>> addRrdData(
      Map<Long, ArrayList<String>> data,
      String itemName,
      ConsolFun consilidationFunction,
      Date timeBegin,
      Date timeEnd,
      long resolution)
      throws IOException {
    RrdDb rrdDb = new RrdDb(RRD_FOLDER + File.separator + itemName + ".rrd");
    FetchRequest fetchRequest =
        rrdDb.createFetchRequest(
            consilidationFunction,
            Util.getTimestamp(timeBegin),
            Util.getTimestamp(timeEnd),
            resolution);
    FetchData fetchData = fetchRequest.fetchData();
    // logger.info(fetchData.toString());
    long[] timestamps = fetchData.getTimestamps();
    double[][] values = fetchData.getValues();

    logger.debug(
        "RRD fetch returned '{}' rows and '{}' columns",
        fetchData.getRowCount(),
        fetchData.getColumnCount());

    for (int row = 0; row < fetchData.getRowCount(); row++) {
      // change to microseconds
      long time = timestamps[row] * 1000;

      if (!data.containsKey(time)) {
        data.put(time, new ArrayList<String>());
      }
      ArrayList<String> vals = data.get(time);
      int indexOffset = vals.size();
      for (int dsIndex = 0; dsIndex < fetchData.getColumnCount(); dsIndex++) {
        vals.add(dsIndex + indexOffset, formatDouble(values[dsIndex][row], "null", true));
      }
    }
    rrdDb.close();

    return data;
  }
Esempio n. 3
0
  /**
   * 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
   */
  private 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);

    // Extract the data source (should always only be one data source per RRD file - otherwise 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 (COUNTER or GAUGE) 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) {
      // 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++) {
        // Filter out the RRD values that have not yet been sampled (they will
        // have been set to NaN as a placeholder when the RRD file was created)
        if (!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(timestamps[i]);
          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++) {
        // Filter out the RRD values that have not yet been sampled (they will
        // have been set to NaN as a placeholder when the RRD file was created)
        if (!Double.toString(values[i]).equals("NaN")) {
          validTimestamps.add(timestamps[i]);
          validValues.add(values[i]);
        }
      }
    }

    metricData.setTimestamps(validTimestamps);
    metricData.setValues(validValues);
    metricData.setTotalCount(totalCount);

    LOGGER.trace("EXITING: getMetricData");

    return metricData;
  }