<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>InfluxData Blog - Kristina Robinson</title>
    <description>Posts by Kristina Robinson on the InfluxData Blog</description>
    <link>https://www.influxdata.com/blog/author/kristina-robinson/</link>
    <language>en-us</language>
    <lastBuildDate>Mon, 25 Jan 2021 04:00:49 -0700</lastBuildDate>
    <pubDate>Mon, 25 Jan 2021 04:00:49 -0700</pubDate>
    <ttl>1800</ttl>
    <item>
      <title>Trending Aggregate Values by Downsampling with InfluxDB</title>
      <description>&lt;p&gt;&lt;em&gt;(&lt;strong&gt;Update&lt;/strong&gt;: &lt;a href="https://www.influxdata.com/products/influxdb-overview/"&gt;InfluxDB 3.0&lt;/a&gt; moved away from Flux and a built-in task engine. Users can use external tools, like Python-based &lt;a href="https://www.quix.io/kapacitor-alternative"&gt;Quix&lt;/a&gt;, to create tasks in InfluxDB 3.0.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.influxdata.com/products/influxdb/"&gt;InfluxDB&lt;/a&gt; is great at capturing many kinds of metrics and allowing end users to aggregate those metrics to custom time groupings whether you’re watching IoT devices perform at 10-minute intervals, GitHub repositories issues close over weeks, or web performance metrics over seconds. Dashboards provide that information at a glance, at precisely the intervals you’ve determined. But what about the next level? What happens when you’ve fine-tuned your dashboards, and you’ve captured the numbers you want. How do you watch them change over time? This is where downsampling and trending become critical, and can take your goals to the next level. InfluxDB makes it easy to identify what to trend, track it, and graph it.&lt;/p&gt;

&lt;p&gt;To demonstrate how to trend values over time, this blog post will cover using the &lt;a href="https://github.com/influxdata/community-templates/tree/master/speedtest"&gt;SpeedTest Community Template&lt;/a&gt;, to download internet connectivity speeds into InfluxDB every minute. The community template has a dashboard that shows current upload and download speeds. Then we will calculate the minimum, average, and maximum speeds over 5-minute intervals. It requires the installation of the &lt;a href="https://www.speedtest.net/apps/cli"&gt;SpeedTest-CLI&lt;/a&gt; executable on a local computer.&lt;/p&gt;

&lt;h2&gt;Using the SpeedTest Community Template with InfluxDB&lt;/h2&gt;
&lt;p&gt;To install the SpeedTest Community Template inside InfluxDB, click &lt;strong&gt;Settings&lt;/strong&gt;, &lt;strong&gt;Templates&lt;/strong&gt;, and enter the following url in line 2 for the resource manifest file:&lt;/p&gt;

&lt;p&gt;&lt;code class="language-markup"&gt;https://github.com/influxdata/community-templates/blob/master/speedtest/speedtest.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253740 size-full" src="/images/legacy-uploads/Templates-Screen.jpg" alt="Templates Screen" width="1200" height="352" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Templates screen, where community templates can be browsed and installed&lt;/figcaption&gt;

&lt;p&gt;Configure the following environment variables: &lt;code class="language-markup"&gt;INFLUX_HOST&lt;/code&gt; (set to your cloud URL), &lt;code class="language-markup"&gt;INFLUX_ORG&lt;/code&gt; (available by clicking on the person icon), and &lt;code class="language-markup"&gt;INFLUX_TOKEN&lt;/code&gt; (can be generated under Settings, Tokens, must be at least a WRITE token for speedtest bucket). Environment variables can be set in either a shell resource file, exported directly (export INFLUX_ORG=InfluxData) or set using User Environment Variables (Windows OS).&lt;/p&gt;

&lt;p&gt;Start &lt;a href="https://www.influxdata.com/time-series-platform/telegraf/"&gt;Telegraf&lt;/a&gt; on your local machine with the instructions provided from the &lt;strong&gt;Setup Instructions&lt;/strong&gt; popup (click &lt;strong&gt;Data&lt;/strong&gt;, &lt;strong&gt;Telegraf&lt;/strong&gt;, &lt;strong&gt;Setup Instructions&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253741 size-full" src="/images/legacy-uploads/Telegraf-Setup-Instructions-Popup.jpg" alt="Telegraf Setup Instructions Popup" width="1200" height="713" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Telegraf Setup Instructions popup&lt;/figcaption&gt;

&lt;p&gt;You should have a board that looks similar to this:&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253742 size-full" src="/images/legacy-uploads/Speedtest-dashboard-from-the-Speedtest-Community-Templates.jpg" alt="Speedtest dashboard from the Speedtest Community Templates" width="1200" height="489" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Speedtest dashboard from the Speedtest Community Template&lt;/figcaption&gt;

&lt;h3&gt;Access the Flux queries that generate the Dashboard Cells&lt;/h3&gt;
&lt;p&gt;We want to select the query &lt;em&gt;behind&lt;/em&gt; the value you’re interested in trending. In this example, it’s Download Speed.&lt;/p&gt;

&lt;p&gt;Open the dashboard labeled ‘Speedtest’.&lt;/p&gt;

&lt;p&gt;Configure the cell labeled ‘Download’’.&lt;/p&gt;

&lt;p&gt;The Query Editor opens, so you can select and copy the entire query:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;from(bucket: "speedtest")
|&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
|&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "exec_speedtest")
|&amp;gt; filter(fn: (r) =&amp;gt; r["_field"] == "download_bandwidth")
|&amp;gt; map(fn: (r) =&amp;gt; ({r with _value: r._value / 1000000.0}))
|&amp;gt; yield(name: "last")&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Visualizing multiple aggregations simultaneously with Flux in InfluxDB&lt;/h2&gt;

&lt;p&gt;The next step involves using the query that takes the existing metric, but writes it to another bucket. Or, aggregates, and then writes. Why do this?  For two reasons:&lt;/p&gt;
&lt;ol&gt;
 	&lt;li&gt;A bucket may have a limited retention policy.  For example, the source data might be available for only 30 days. We want to trend beyond 30 days, so writing to a different, smaller bucket with a longer retention policy allows us to keep the trending data for longer.&lt;/li&gt;
 	&lt;li&gt;We can write aggregated data NOT available in the original bucket, but derived from the source data. This allows us to do some interesting work on the aggregated data.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As a side note here, you &lt;em&gt;can&lt;/em&gt; visualize the aggregated data directly from a dashboard. However, this blog is intended to address aggregated data that is interesting in its own right for manipulation, and may need to be available longer than the initial source is around.&lt;/p&gt;

&lt;p&gt;Let’s track three aggregations: min, max, and mean for the download speed.&lt;/p&gt;

&lt;p&gt;Click on Explore (Data Explorer).&lt;/p&gt;

&lt;p&gt;Click on the Script Editor button on the right hand side.&lt;/p&gt;

&lt;p&gt;Paste in the copied query from above.&lt;/p&gt;

&lt;p&gt;Calculate three new values from this query: min, max and mean. You may use any aggregation functions that InfluxDB offers, but let’s keep it simple for example purposes. To begin, assign the copied query to the &lt;code class="language-markup"&gt;DATA&lt;/code&gt; tag. That saves the returned dataset for later use. Next, use that &lt;code class="language-markup"&gt;DATA&lt;/code&gt; and use the pipe forward operator to send that data set to each of the three functions, and the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/yield/"&gt;yield()&lt;/a&gt; function to show the results. Using a different name in the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/yield/"&gt;yield()&lt;/a&gt; function will allow multiple values to be displayed per submit.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;DATA = from(bucket: "speedtest")
|&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
|&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "exec_speedtest")
|&amp;gt; filter(fn: (r) =&amp;gt; r["_field"] == "download_bandwidth")
|&amp;gt; map(fn: (r) =&amp;gt; ({r with _value: r._value / 1000000.0}))

DATA
|&amp;gt; mean()
|&amp;gt; yield(name: "mean")

DATA
|&amp;gt; min()
|&amp;gt; yield(name:"min")

DATA
|&amp;gt; max()
|&amp;gt; yield(name:"max")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clicking &lt;strong&gt;Submit&lt;/strong&gt; at this point will show three lines of data on a Graph, or three sets of data using a Table. You may also look at the Raw Data and see the generated data. You may also further clean this data by dropping tagged values not needed long-term in the new table. You can add the ‘drop’ function to the top section and remove any fields you don’t wish to keep.&lt;/p&gt;

&lt;h2&gt;Writing a downsampling task to calculate the min, max, and mean Download Speed with InfluxDB&lt;/h2&gt;

&lt;p&gt;Now that we have the values we want to trend queried, we’re ready to write them to a new bucket.  Let’s create a new bucket called ‘speedtest-downsampled’.&lt;/p&gt;

&lt;p&gt;Change the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/yield/"&gt;yield()&lt;/a&gt; functions above to write statements, using the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/to/"&gt;to()&lt;/a&gt; function. Additionally, use the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/set/"&gt;set()&lt;/a&gt; function to create matching names (“min”, “mean”, “max”) in the “_field” entry for each value calculated by &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/selectors/min/"&gt;min&lt;/a&gt;(), &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/aggregates/mean/"&gt;mean&lt;/a&gt;() and &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/selectors/max/"&gt;max&lt;/a&gt;() functions. These hard-coded “_field” entries will be the keys (stored in _field) to lookup the values (stored in _value) when filtering and displaying graphs at the end.&lt;/p&gt;

&lt;p&gt;Finally, let’s look at the _time column. &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/selectors/min/"&gt;Min&lt;/a&gt;() and &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/selectors/max/"&gt;max&lt;/a&gt;() both resolve to a single record, which means they each will have their own _time value (which occur at different times). However, &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/aggregates/mean/"&gt;mean()&lt;/a&gt; is an aggregation of many records, which will not have access to a single row’s _time value. However, to snapshot these 3 values and group them together, we want to compare them at whatever interval we choose. Therefore, let’s assign the same value to the _time field for all three aggregate rows by using the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/map/"&gt;map()&lt;/a&gt; function. Assign a _time value to the value of when this query is executed by using the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/misc/now/"&gt;now()&lt;/a&gt; function and saving it to all three functions. This allows for queries based on the same _time and _measurement fields. Remember, all rows written to buckets using the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/to/"&gt;to()&lt;/a&gt; function are required to have values for the following fields: _measurement, _field, and _time. We get _measurement from the filter function in line 3. We assigned the  _field values using the &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/transformations/set/"&gt;set()&lt;/a&gt; function. And we’re now assigning a _time value.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;DATA = from(bucket: "speedtest")
|&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
|&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "exec_speedtest")
|&amp;gt; filter(fn: (r) =&amp;gt; r["_field"] == "download_bandwidth")
|&amp;gt; map(fn: (r) =&amp;gt; ({r with _value: r._value / 1000000.0}))
|&amp;gt; drop(columns:["_start", "_stop", "host"])

time = now()
DATA
|&amp;gt; mean()
|&amp;gt; map(fn: (r) =&amp;gt; ({r with _time: time}))
|&amp;gt; set(key:"_field", value:"mean")
|&amp;gt; to(bucket:"speedtest_downsampled")

DATA
|&amp;gt; min()
|&amp;gt; map(fn: (r) =&amp;gt; ({r with _time: time}))
|&amp;gt; set(key:"_field", value:"min")
|&amp;gt; to(bucket:"speedtest_downsampled")

DATA
|&amp;gt; max()
|&amp;gt; map(fn: (r) =&amp;gt; ({r with _time: time}))
|&amp;gt; set(key:"_field", value:"max")
|&amp;gt; to(bucket:"speedtest_downsampled")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Test this query by clicking on the &lt;strong&gt;Submit&lt;/strong&gt; button. Click on Query2, from the Query Builder, select FROM ‘speedtest_downsampled’, Filter ‘exec_speedtest’ and click &lt;strong&gt;Submit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With the Query1 tab selected, click &lt;strong&gt;Save As&lt;/strong&gt;. Enter a Name for the task, a frequency for how often the task should run, and select the ‘speedtest_downsampled’ bucket.&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253743" src="/images/legacy-uploads/Save-As-Popup-from-Data-Explorer.jpg" alt="Save As Popup from Data Explorer" width="600" height="472" /&gt;&lt;/p&gt;
&lt;figcaption&gt; &lt;strong&gt;Save As&lt;/strong&gt; popup from Data Explorer&lt;/figcaption&gt;

&lt;p&gt;From the &lt;strong&gt;Tasks&lt;/strong&gt; menu, the task can now be edited.&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253744 size-full" src="/images/legacy-uploads/Tasks-main-menu.jpg" alt="Tasks main menu" width="1200" height="351" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Tasks main menu&lt;/figcaption&gt;

&lt;p&gt;&lt;img class="wp-image-253745 size-full" src="/images/legacy-uploads/Edit-Task-screen-.jpg" alt="Edit Task screen" width="1200" height="995" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Edit Task screen&lt;/figcaption&gt;
&lt;ul&gt;
 	&lt;li&gt;Remove the extra &lt;strong&gt;to()&lt;/strong&gt; function at the bottom of the task. This is a known issue, every task created writes to the bucket specified on the previous screen. Since the flux written in the saved queries already contain &lt;strong&gt;to()&lt;/strong&gt; functions, this added statement can be removed.&lt;/li&gt;
 	&lt;li&gt;Verify the timeRangeStart at the top of the task, line 1 above. Use &lt;em&gt;ms&lt;/em&gt;, &lt;em&gt;s&lt;/em&gt;, &lt;em&gt;m&lt;/em&gt;, &lt;em&gt;h&lt;/em&gt;, &lt;em&gt;d&lt;/em&gt;, or &lt;em&gt;y&lt;/em&gt; to specify time intervals, or select specific dates.  In this example, -5m is used for the start time to have the task gather data for the last 5 minutes.&lt;/li&gt;
 	&lt;li&gt;Verify how often the task runs by confirming the value after "every:"  in the task declaration (line 2 above).&lt;/li&gt;
 	&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Incorporating task outputs in InfluxDB dashboard&lt;/h2&gt;

&lt;p&gt;We’re almost done! The new bucket (speedtest_downsampled) will start accumulating snapshots of the 3 aggregated data values. Query them over time and add it to a dashboard. Head back over to the &lt;strong&gt;Data Explorer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Open up a new Query tab and click on &lt;strong&gt;Script Editor&lt;/strong&gt;. Paste in this simple query to view the ‘speedtest_downsampled’ bucket, grouped by the _time field, which works well since the aggregated fields have the same timestamp.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;from(bucket: "speedtest_downsampled")
|&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
|&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "exec_speedtest")
|&amp;gt; group(columns : ["_time"])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Click &lt;strong&gt;Submit&lt;/strong&gt;, and either using the Table Graph or the Raw Data View, view three records for each timestamp:&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253746 size-full" src="/images/legacy-uploads/Data-Explorer-in-Table-Graph-View.jpg" alt="Data Explorer in Table Graph View" width="1200" height="231" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Data Explorer in Table Graph View&lt;/figcaption&gt;

&lt;p&gt;The best chart type for viewing up to three records at a time is the &lt;a href="https://influxdata.github.io/giraffe/?path=/story/xy-plot--line"&gt;Graph&lt;/a&gt; (line) visualization. It requires named &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/yield/"&gt;yield&lt;/a&gt;() functions to show more than one series. As discussed previously, use the Script Editor to add in named &lt;a href="https://docs.influxdata.com/influxdb/v2.0/reference/flux/stdlib/built-in/outputs/yield/"&gt;yield&lt;/a&gt;() functions:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;DATA = from(bucket: "speedtest_downsampled")
|&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
|&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "exec_speedtest")
|&amp;gt; filter(fn: (r) =&amp;gt; r._field == "mean" or r._field == "min" or 
r._field == "max")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Click &lt;strong&gt;Save As&lt;/strong&gt;, &lt;strong&gt;Dashboard Cell&lt;/strong&gt;, select &lt;strong&gt;Speedtest Dashboard&lt;/strong&gt;, and name the Cell “Trending Download Speeds” to make the new Graph visualization appear on the existing dashboard.&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253747" src="/images/legacy-uploads/Data-Explorer-Save-As-popup.jpg" alt="Data Explorer Save As popup" width="600" height="359" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Data Explorer &lt;strong&gt;Save As&lt;/strong&gt; popup&lt;/figcaption&gt;

&lt;p&gt;Adjust the location of the Cell on the Dashboard, and we are done.&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-253748 size-full" src="/images/legacy-uploads/Speedtest-dashboard-with-new-Graph-visualization-added.jpg" alt="Speedtest dashboard" width="1200" height="700" /&gt;&lt;/p&gt;
&lt;figcaption&gt; Speedtest dashboard with new Graph (line) visualization added&lt;/figcaption&gt;

&lt;h2&gt;Final thoughts on trending, performing multiple aggregations in one task, and visualizing the output with InfluxDB&lt;/h2&gt;

&lt;p&gt;I hope this tutorial helps you with your downsampling and visualization efforts. As always, if you run into hurdles, please share them on our &lt;a href="https://community.influxdata.com/"&gt;community site&lt;/a&gt; or &lt;a href="https://influxdata.com/slack"&gt;Slack channel&lt;/a&gt;. We’d love to get your feedback and help you with any problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credits:&lt;/strong&gt;
Ignacio Van Droogenbroeck
Anais Dotis-Georgiou&lt;/p&gt;
</description>
      <pubDate>Mon, 25 Jan 2021 04:00:49 -0700</pubDate>
      <link>https://www.influxdata.com/blog/trending-aggregate-values-by-downsampling-with-influxdb/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/trending-aggregate-values-by-downsampling-with-influxdb/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <author>Kristina Robinson (InfluxData)</author>
    </item>
  </channel>
</rss>
