Search in sources :

Example 36 with DataPoint

use of net.opentsdb.core.DataPoint in project opentsdb by OpenTSDB.

the class HttpJsonSerializer method formatQueryAsyncV1.

/**
   * Format the results from a timeseries data query
   * @param data_query The TSQuery object used to fetch the results
   * @param results The data fetched from storage
   * @param globals An optional list of global annotation objects
   * @return A Deferred<ChannelBuffer> object to pass on to the caller
   * @throws IOException if serialization failed
   * @since 2.2
   */
public Deferred<ChannelBuffer> formatQueryAsyncV1(final TSQuery data_query, final List<DataPoints[]> results, final List<Annotation> globals) throws IOException {
    final long start = DateTime.currentTimeMillis();
    final boolean as_arrays = this.query.hasQueryStringParam("arrays");
    final String jsonp = this.query.getQueryStringParam("jsonp");
    // buffers and an array list to stored the deferreds
    final ChannelBuffer response = ChannelBuffers.dynamicBuffer();
    final OutputStream output = new ChannelBufferOutputStream(response);
    // too bad an inner class can't modify a primitive. This is a work around 
    final List<Boolean> timeout_flag = new ArrayList<Boolean>(1);
    timeout_flag.add(false);
    // start with JSONp if we're told to
    if (jsonp != null && !jsonp.isEmpty()) {
        output.write((jsonp + "(").getBytes(query.getCharset()));
    }
    // start the JSON generator and write the opening array
    final JsonGenerator json = JSON.getFactory().createGenerator(output);
    json.writeStartArray();
    /**
     * Every individual data point set (the result of a query and possibly a
     * group by) will initiate an asynchronous metric/tag UID to name resolution
     * and then print to the buffer.
     * NOTE that because this is asynchronous, the order of results is
     * indeterminate.
     */
    class DPsResolver implements Callback<Deferred<Object>, Object> {

        /** Has to be final to be shared with the nested classes */
        final StringBuilder metric = new StringBuilder(256);

        /** Resolved tags */
        final Map<String, String> tags = new HashMap<String, String>();

        /** Resolved aggregated tags */
        final List<String> agg_tags = new ArrayList<String>();

        /** A list storing the metric and tag resolve calls */
        final List<Deferred<Object>> resolve_deferreds = new ArrayList<Deferred<Object>>();

        /** The data points to serialize */
        final DataPoints dps;

        /** Starting time in nanos when we sent the UID resolution queries off */
        long uid_start;

        public DPsResolver(final DataPoints dps) {
            this.dps = dps;
        }

        /** Resolves the metric UID to a name*/
        class MetricResolver implements Callback<Object, String> {

            public Object call(final String metric) throws Exception {
                DPsResolver.this.metric.append(metric);
                return null;
            }
        }

        /** Resolves the tag UIDs to a key/value string set */
        class TagResolver implements Callback<Object, Map<String, String>> {

            public Object call(final Map<String, String> tags) throws Exception {
                DPsResolver.this.tags.putAll(tags);
                return null;
            }
        }

        /** Resolves aggregated tags */
        class AggTagResolver implements Callback<Object, List<String>> {

            public Object call(final List<String> tags) throws Exception {
                DPsResolver.this.agg_tags.addAll(tags);
                return null;
            }
        }

        /** After the metric and tags have been resolved, this will print the
       * results to the output buffer in the proper format.
       */
        class WriteToBuffer implements Callback<Object, ArrayList<Object>> {

            final DataPoints dps;

            /**
         * Default ctor that takes a data point set
         * @param dps Datapoints to print
         */
            public WriteToBuffer(final DataPoints dps) {
                this.dps = dps;
            }

            /**
         * Handles writing the data to the output buffer. The results of the
         * deferreds don't matter as they will be stored in the class final
         * variables.
         */
            public Object call(final ArrayList<Object> deferreds) throws Exception {
                data_query.getQueryStats().addStat(dps.getQueryIndex(), QueryStat.UID_TO_STRING_TIME, (DateTime.nanoTime() - uid_start));
                final long local_serialization_start = DateTime.nanoTime();
                final TSSubQuery orig_query = data_query.getQueries().get(dps.getQueryIndex());
                json.writeStartObject();
                json.writeStringField("metric", metric.toString());
                json.writeFieldName("tags");
                json.writeStartObject();
                if (dps.getTags() != null) {
                    for (Map.Entry<String, String> tag : tags.entrySet()) {
                        json.writeStringField(tag.getKey(), tag.getValue());
                    }
                }
                json.writeEndObject();
                json.writeFieldName("aggregateTags");
                json.writeStartArray();
                if (dps.getAggregatedTags() != null) {
                    for (String atag : agg_tags) {
                        json.writeString(atag);
                    }
                }
                json.writeEndArray();
                if (data_query.getShowQuery()) {
                    json.writeObjectField("query", orig_query);
                }
                if (data_query.getShowTSUIDs()) {
                    json.writeFieldName("tsuids");
                    json.writeStartArray();
                    final List<String> tsuids = dps.getTSUIDs();
                    Collections.sort(tsuids);
                    for (String tsuid : tsuids) {
                        json.writeString(tsuid);
                    }
                    json.writeEndArray();
                }
                if (!data_query.getNoAnnotations()) {
                    final List<Annotation> annotations = dps.getAnnotations();
                    if (annotations != null) {
                        Collections.sort(annotations);
                        json.writeArrayFieldStart("annotations");
                        for (Annotation note : annotations) {
                            json.writeObject(note);
                        }
                        json.writeEndArray();
                    }
                    if (globals != null && !globals.isEmpty()) {
                        Collections.sort(globals);
                        json.writeArrayFieldStart("globalAnnotations");
                        for (Annotation note : globals) {
                            json.writeObject(note);
                        }
                        json.writeEndArray();
                    }
                }
                // now the fun stuff, dump the data and time just the iteration over
                // the data points
                final long dps_start = DateTime.nanoTime();
                json.writeFieldName("dps");
                long counter = 0;
                // default is to write a map, otherwise write arrays
                if (!timeout_flag.get(0) && as_arrays) {
                    json.writeStartArray();
                    for (final DataPoint dp : dps) {
                        if (dp.timestamp() < data_query.startTime() || dp.timestamp() > data_query.endTime()) {
                            continue;
                        }
                        final long timestamp = data_query.getMsResolution() ? dp.timestamp() : dp.timestamp() / 1000;
                        json.writeStartArray();
                        json.writeNumber(timestamp);
                        if (dp.isInteger()) {
                            json.writeNumber(dp.longValue());
                        } else {
                            // Report missing intervals as null or NaN.
                            final double value = dp.doubleValue();
                            if (Double.isNaN(value) && orig_query.fillPolicy() == FillPolicy.NULL) {
                                json.writeNull();
                            } else {
                                json.writeNumber(dp.doubleValue());
                            }
                        }
                        json.writeEndArray();
                        ++counter;
                    }
                    json.writeEndArray();
                } else if (!timeout_flag.get(0)) {
                    json.writeStartObject();
                    for (final DataPoint dp : dps) {
                        if (dp.timestamp() < (data_query.startTime()) || dp.timestamp() > (data_query.endTime())) {
                            continue;
                        }
                        final long timestamp = data_query.getMsResolution() ? dp.timestamp() : dp.timestamp() / 1000;
                        if (dp.isInteger()) {
                            json.writeNumberField(Long.toString(timestamp), dp.longValue());
                        } else {
                            // Report missing intervals as null or NaN.
                            final double value = dp.doubleValue();
                            if (Double.isNaN(value) && orig_query.fillPolicy() == FillPolicy.NULL) {
                                json.writeNumberField(Long.toString(timestamp), null);
                            } else {
                                json.writeNumberField(Long.toString(timestamp), dp.doubleValue());
                            }
                        }
                        ++counter;
                    }
                    json.writeEndObject();
                } else {
                    // skipping data points all together due to timeout
                    json.writeStartObject();
                    json.writeEndObject();
                }
                final long agg_time = DateTime.nanoTime() - dps_start;
                data_query.getQueryStats().addStat(dps.getQueryIndex(), QueryStat.AGGREGATION_TIME, agg_time);
                data_query.getQueryStats().addStat(dps.getQueryIndex(), QueryStat.AGGREGATED_SIZE, counter);
                // yeah, it's a little early but we need to dump it out with the results.
                data_query.getQueryStats().addStat(dps.getQueryIndex(), QueryStat.SERIALIZATION_TIME, DateTime.nanoTime() - local_serialization_start);
                if (!timeout_flag.get(0) && data_query.getShowStats()) {
                    int query_index = (dps == null) ? -1 : dps.getQueryIndex();
                    QueryStats stats = data_query.getQueryStats();
                    if (query_index >= 0) {
                        json.writeFieldName("stats");
                        final Map<String, Object> s = stats.getQueryStats(query_index, false);
                        if (s != null) {
                            json.writeObject(s);
                        } else {
                            json.writeStringField("ERROR", "NO STATS FOUND");
                        }
                    }
                }
                // close the results for this particular query
                json.writeEndObject();
                return null;
            }
        }

        /**
       * When called, initiates a resolution of metric and tag UIDs to names, 
       * then prints to the output buffer once they are completed.
       */
        public Deferred<Object> call(final Object obj) throws Exception {
            this.uid_start = DateTime.nanoTime();
            resolve_deferreds.add(dps.metricNameAsync().addCallback(new MetricResolver()));
            resolve_deferreds.add(dps.getTagsAsync().addCallback(new TagResolver()));
            resolve_deferreds.add(dps.getAggregatedTagsAsync().addCallback(new AggTagResolver()));
            return Deferred.group(resolve_deferreds).addCallback(new WriteToBuffer(dps));
        }
    }
    // We want the serializer to execute serially so we need to create a callback
    // chain so that when one DPsResolver is finished, it triggers the next to
    // start serializing.
    final Deferred<Object> cb_chain = new Deferred<Object>();
    for (DataPoints[] separate_dps : results) {
        for (DataPoints dps : separate_dps) {
            try {
                cb_chain.addCallback(new DPsResolver(dps));
            } catch (Exception e) {
                throw new RuntimeException("Unexpected error durring resolution", e);
            }
        }
    }
    /** Final callback to close out the JSON array and return our results */
    class FinalCB implements Callback<ChannelBuffer, Object> {

        public ChannelBuffer call(final Object obj) throws Exception {
            // Call this here so we rollup sub metrics into a summary. It's not
            // completely accurate, of course, because we still have to write the
            // summary and close the writer. But it's close.
            data_query.getQueryStats().markSerializationSuccessful();
            // TODO - yeah, I've heard this sucks, we need to figure out a better way.
            if (data_query.getShowSummary()) {
                final QueryStats stats = data_query.getQueryStats();
                json.writeStartObject();
                json.writeFieldName("statsSummary");
                json.writeObject(stats.getStats(true, true));
                json.writeEndObject();
            }
            // IMPORTANT Make sure the close the JSON array and the generator
            json.writeEndArray();
            json.close();
            if (jsonp != null && !jsonp.isEmpty()) {
                output.write(")".getBytes());
            }
            return response;
        }
    }
    // trigger the callback chain here
    cb_chain.callback(null);
    return cb_chain.addCallback(new FinalCB());
}
Also used : ChannelBufferOutputStream(org.jboss.netty.buffer.ChannelBufferOutputStream) OutputStream(java.io.OutputStream) Deferred(com.stumbleupon.async.Deferred) ArrayList(java.util.ArrayList) DataPoints(net.opentsdb.core.DataPoints) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer) DataPoint(net.opentsdb.core.DataPoint) IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) JsonGenerator(com.fasterxml.jackson.core.JsonGenerator) ArrayList(java.util.ArrayList) List(java.util.List) ChannelBufferOutputStream(org.jboss.netty.buffer.ChannelBufferOutputStream) TSSubQuery(net.opentsdb.core.TSSubQuery) QueryException(net.opentsdb.core.QueryException) IOException(java.io.IOException) Annotation(net.opentsdb.meta.Annotation) Callback(com.stumbleupon.async.Callback) QueryStats(net.opentsdb.stats.QueryStats) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 37 with DataPoint

use of net.opentsdb.core.DataPoint in project opentsdb by OpenTSDB.

the class TestMovingAverage method evaluateGroupBy.

@Test
public void evaluateGroupBy() throws Exception {
    params.add("1");
    SeekableView view2 = SeekableViewsForTest.generator(START_TIME, INTERVAL, NUM_POINTS, true, 10, 1);
    DataPoints dps2 = PowerMockito.mock(DataPoints.class);
    when(dps2.iterator()).thenReturn(view2);
    when(dps2.metricNameAsync()).thenReturn(Deferred.fromResult("sys.mem"));
    group_bys = new DataPoints[] { dps, dps2 };
    query_results.clear();
    query_results.add(group_bys);
    final DataPoints[] results = func.evaluate(data_query, query_results, params);
    assertEquals(2, results.length);
    assertEquals(METRIC, results[0].metricName());
    assertEquals("sys.mem", results[1].metricName());
    long ts = START_TIME;
    double v = 1;
    for (DataPoint dp : results[0]) {
        assertEquals(ts, dp.timestamp());
        assertFalse(dp.isInteger());
        assertEquals(v, dp.doubleValue(), 0.001);
        ts += INTERVAL;
        v += 1;
    }
    ts = START_TIME;
    v = 10;
    for (DataPoint dp : results[1]) {
        assertEquals(ts, dp.timestamp());
        assertFalse(dp.isInteger());
        assertEquals(v, dp.doubleValue(), 0.001);
        ts += INTERVAL;
        v += 1;
    }
}
Also used : DataPoint(net.opentsdb.core.DataPoint) SeekableView(net.opentsdb.core.SeekableView) DataPoints(net.opentsdb.core.DataPoints) Test(org.junit.Test) SeekableViewsForTest(net.opentsdb.core.SeekableViewsForTest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 38 with DataPoint

use of net.opentsdb.core.DataPoint in project opentsdb by OpenTSDB.

the class TestMovingAverage method evaluateWindow1min.

@Test
public void evaluateWindow1min() throws Exception {
    params.add("'1min'");
    final DataPoints[] results = func.evaluate(data_query, query_results, params);
    assertEquals(1, results.length);
    assertEquals(METRIC, results[0].metricName());
    long ts = START_TIME;
    double v = 0;
    for (DataPoint dp : results[0]) {
        assertEquals(ts, dp.timestamp());
        assertFalse(dp.isInteger());
        assertEquals(v, dp.doubleValue(), 0.001);
        ts += INTERVAL;
        if (v < 1) {
            v = 2;
        } else {
            v += 1;
        }
    }
}
Also used : DataPoint(net.opentsdb.core.DataPoint) DataPoints(net.opentsdb.core.DataPoints) Test(org.junit.Test) SeekableViewsForTest(net.opentsdb.core.SeekableViewsForTest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 39 with DataPoint

use of net.opentsdb.core.DataPoint in project opentsdb by OpenTSDB.

the class TestMovingAverage method evaluateWindow2min.

@Test
public void evaluateWindow2min() throws Exception {
    params.add("'2min'");
    final DataPoints[] results = func.evaluate(data_query, query_results, params);
    assertEquals(1, results.length);
    assertEquals(METRIC, results[0].metricName());
    long ts = START_TIME;
    double v = 0;
    for (DataPoint dp : results[0]) {
        assertEquals(ts, dp.timestamp());
        assertFalse(dp.isInteger());
        assertEquals(v, dp.doubleValue(), 0.001);
        ts += INTERVAL;
        if (ts == 1356998520000L) {
            v = 2.5;
        } else if (v > 0) {
            v += 1;
        }
    }
}
Also used : DataPoint(net.opentsdb.core.DataPoint) DataPoints(net.opentsdb.core.DataPoints) Test(org.junit.Test) SeekableViewsForTest(net.opentsdb.core.SeekableViewsForTest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 40 with DataPoint

use of net.opentsdb.core.DataPoint in project opentsdb by OpenTSDB.

the class TestMovingAverage method evaluateWindow1dps.

@Test
public void evaluateWindow1dps() throws Exception {
    params.add("1");
    final DataPoints[] results = func.evaluate(data_query, query_results, params);
    assertEquals(1, results.length);
    assertEquals(METRIC, results[0].metricName());
    long ts = START_TIME;
    double v = 1;
    for (DataPoint dp : results[0]) {
        assertEquals(ts, dp.timestamp());
        assertFalse(dp.isInteger());
        assertEquals(v, dp.doubleValue(), 0.001);
        ts += INTERVAL;
        v += 1;
    }
}
Also used : DataPoint(net.opentsdb.core.DataPoint) DataPoints(net.opentsdb.core.DataPoints) Test(org.junit.Test) SeekableViewsForTest(net.opentsdb.core.SeekableViewsForTest) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Aggregations

DataPoint (net.opentsdb.core.DataPoint)60 DataPoints (net.opentsdb.core.DataPoints)55 Test (org.junit.Test)49 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)49 SeekableViewsForTest (net.opentsdb.core.SeekableViewsForTest)47 SeekableView (net.opentsdb.core.SeekableView)46 ArrayList (java.util.ArrayList)9 MutableDataPoint (net.opentsdb.core.MutableDataPoint)7 IOException (java.io.IOException)3 Map (java.util.Map)3 AggregationIterator (net.opentsdb.core.AggregationIterator)3 Callback (com.stumbleupon.async.Callback)2 Deferred (com.stumbleupon.async.Deferred)2 PrintWriter (java.io.PrintWriter)2 HashMap (java.util.HashMap)2 Query (net.opentsdb.core.Query)2 TSSubQuery (net.opentsdb.core.TSSubQuery)2 JsonGenerator (com.fasterxml.jackson.core.JsonGenerator)1 File (java.io.File)1 OutputStream (java.io.OutputStream)1