<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>InfluxData Blog - Faith Chikwekwe</title>
    <description>Posts by Faith Chikwekwe on the InfluxData Blog</description>
    <link>https://www.influxdata.com/blog/author/faith-chikwekwe/</link>
    <language>en-us</language>
    <lastBuildDate>Thu, 07 May 2020 07:00:44 -0700</lastBuildDate>
    <pubDate>Thu, 07 May 2020 07:00:44 -0700</pubDate>
    <ttl>1800</ttl>
    <item>
      <title>Writing Tasks and Setting Up Alerts for InfluxDB Cloud</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;If you are using InfluxDB to monitor your data and systems, then alerts may be an essential part of your workflow. We currently have a system for monitoring your data whether it enters a critical or non-critical state.&lt;/p&gt;

&lt;p&gt;Here I’m going to give a detailed guide on setting up alerts using our &lt;a href="https://influxdata.com/products/influxdb-cloud/"&gt;InfluxDB Cloud&lt;/a&gt; product as well as some best practices for having a good experience using alerts.&lt;/p&gt;

&lt;p&gt;We’ll be working with the &lt;a href="https://influxdata.com/products/flux/"&gt;Flux scripting language&lt;/a&gt;, to make it super easy to write tasks and understand the checks that we set up for our alerts.&lt;/p&gt;

&lt;p&gt;For this tutorial, imagine that you are interested in monitoring and receiving alerts for your fruit collection company. You would probably think a lot about the amount of fruit that you are collecting and the farms that you’re collecting fruit from. You’ll also want to know when there are critical decreases in the amount of collected fruit. This is the kind of information that you’ll want to keep in mind as we go through this tutorial.&lt;/p&gt;
&lt;h2&gt;Step 1: Write your Flux query&lt;/h2&gt;
&lt;p&gt;An alert is only as good as the Flux query you write. Once signed in to InfluxDB Cloud, I like to start by using the Data Explorer or the &lt;a href="https://marketplace.visualstudio.com/items?itemName=influxdata.flux"&gt;Flux plugin in VSCode&lt;/a&gt; to examine the initial shape of my data.&lt;/p&gt;

&lt;p&gt;If you’re using the Data Explorer, the Query Builder can be helpful for looking at the available buckets, fields, and measurements. Eventually, you may want to switch to using the Script Editor to write a more nuanced query.&lt;/p&gt;

&lt;p&gt;You are going to turn this query into a task. You may also want to visualize the query/task output in order to see what you’re getting back. To that end, you might want to think about preserving columns that might give you clues as to why a metric changed from a critical to a non-critical state or vice versa.&lt;/p&gt;

&lt;p&gt;For example, if you have initial data with the following columns:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-markup"&gt;_start, _stop, _time, _field,_measurement,farmName&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you’d like to be able to monitor the total fruit collected every hour by looking at the &lt;code class="language-markup"&gt;totalFruitsCollected&lt;/code&gt; measurement, it might also be helpful to preserve the &lt;code class="language-markup"&gt;farmName&lt;/code&gt; column to be able to visualize which farms have increased or decreased their output later.&lt;/p&gt;

&lt;p&gt;Generally, Flux queries that translate well into tasks and alerts will window their data using the &lt;code class="language-markup"&gt;aggregateWindow()&lt;/code&gt; function to examine changes over time intervals.&lt;/p&gt;

&lt;p&gt;A simple query for our fruit collection example might look like this:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;from(bucket: "farming")
  |&amp;gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |&amp;gt; filter(fn: (r)  =&amp;gt; (r._measurement == "totalFruitsCollected))
  |&amp;gt; filter(fn: (r)  =&amp;gt; (r._field == "fruits))
  |&amp;gt; group(columns: ["farmName"])
  |&amp;gt; aggregateWindow(fn: sum, every: 1h)
  |&amp;gt; map(fn: (r) =&amp;gt; {
    return: _time: r._time,  _stop: r._stop, _start: r._start, _measurement: "fruitCollectionRate", _field: "fruits", _value: r._value, farmName: farmName, 
  }
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that since the &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/built-in/transformations/aggregates/aggregatewindow/"&gt;&lt;code class="language-javascript"&gt;aggregateWindow()&lt;/code&gt;&lt;/a&gt; function eliminates all columns except &lt;code class="language-markup"&gt;_time&lt;/code&gt;, &lt;code class="language-markup"&gt;_stop&lt;/code&gt;, &lt;code class="language-markup"&gt;_start&lt;/code&gt; and &lt;code class="language-markup"&gt;_value&lt;/code&gt;, we have to use the &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/built-in/transformations/map/"&gt;&lt;code class="language-javascript"&gt;map()&lt;/code&gt;&lt;/a&gt; function to restore our other columns.&lt;/p&gt;
&lt;h2&gt;Step 2: Convert your Flux query to a task&lt;/h2&gt;
&lt;p&gt;A task is a Flux query that runs on a schedule. To that end, once you’ve queried for the right data, converting your query to a task is fairly straightforward.&lt;/p&gt;

&lt;p&gt;In InfluxDB Cloud, you can use the “Save as Task” option to convert your query. In this dialog box, you need an &lt;code class="language-markup"&gt;every&lt;/code&gt; parameter (and perhaps an offset) for this task. After you’ve saved, I would recommend finding your task on the Tasks page and updating the &lt;code class="language-javascript"&gt;range()&lt;/code&gt; function to use our &lt;code class="language-markup"&gt;task.every&lt;/code&gt; parameter instead of the built in &lt;code class="language-markup"&gt;start&lt;/code&gt; and &lt;code class="language-markup"&gt;stop&lt;/code&gt; values. We’ll use a negative value, so that we’re looking back at that time interval every time the task runs.&lt;/p&gt;

&lt;p&gt;&lt;code class="language-markup"&gt;task.every&lt;/code&gt; is often also used as the window for the &lt;code class="language-javascript"&gt;aggregateWindow()&lt;/code&gt; function. This will be different for every case, but you’ll want to keep in mind how much data will be written within the selected interval and decide accordingly.&lt;/p&gt;

&lt;p&gt;Our fruit collection company collects hundreds of fruits per hour. We’d like to be able to see the fruit collection in 1-hour intervals.&lt;/p&gt;

&lt;p&gt;Next, you’ll want to update. I’m also going to update the &lt;code class="language-javascript"&gt;aggregateWindow()&lt;/code&gt; function to use my &lt;code class="language-markup"&gt;task.every&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;In order to preserve the results of my task, I’m going to use the &lt;code class="language-javascript"&gt;to()&lt;/code&gt; function to write my new &lt;code class="language-javascript"&gt;fruitCollectionRate&lt;/code&gt; measurement back into the &lt;code class="language-javascript"&gt;farming&lt;/code&gt; bucket. This way I can access the data for my dashboard and my notification checks.&lt;/p&gt;

&lt;p&gt;My task will end up like this:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;option task = {name: "fruitCollectedRate", every: 1h}

fruitCollected = from(bucket: "farming")
  |&amp;gt; range(start: -task.every)
  |&amp;gt; filter(fn: (r)  =&amp;gt; (r._measurement == "totalFruitsCollected))
  |&amp;gt; filter(fn: (r)  =&amp;gt; (r._field == "fruits))
  |&amp;gt; group(columns: ["farmName"])
  |&amp;gt; aggregateWindow(fn: sum, every: task.every)
  |&amp;gt; map(fn: (r) =&amp;gt; {
    return: _time: r._time,  _stop: r._stop, _start: r._start, _measurement: "fruitCollectionRate", _field: "fruits", _value: r._value, farmName: farmName, 
  }
})

fruitCollected 
  |&amp;gt; to(bucket: "farming")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that you don’t have to add the task variable as shown above. If you add the task name and every value in the text boxes via the UI, the system will add the variable for you.&lt;/p&gt;
&lt;h2&gt;Step 3: Create a dashboard to visualize your task output&lt;/h2&gt;
&lt;p&gt;This step is optional, but it’s a great way to validate that your task is operating properly before setting up your alerts.&lt;/p&gt;

&lt;p&gt;You can head over to the Dashboards tab and click to create a dashboard. If you had additional metrics that you were monitoring about fruit like &lt;code class="language-markup"&gt;badApplesPerBunch&lt;/code&gt; or &lt;code class="language-markup"&gt;rateOfLifeGivingLemons&lt;/code&gt; you could add them to this dashboard as well.&lt;/p&gt;

&lt;p&gt;My simple query to see my task’s output data could look like this:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;from(bucket: "farming")
  |&amp;gt; range(start: -task.every)
  |&amp;gt; filter(fn: (r)  =&amp;gt; (r._measurement == "fruitCollectionRate"))
  |&amp;gt; filter(fn: (r)  =&amp;gt; (r._field == "fruits"))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are many tricks to visualize this data in more interesting ways, but this works well for now. Since we preserved &lt;code class="language-markup"&gt;farmName&lt;/code&gt; and grouped on it, every farm will have its own table in the output stream and its own line on the resulting graph, giving us more detailed visibility.&lt;/p&gt;
&lt;h2&gt;Step 4: Create a check for your alert&lt;/h2&gt;
&lt;p&gt;Besides writing a well-formed query, setting up a well-calibrated check is the most important part of writing a good alert. In most cases, this will be an iterative process. You’ll want to make sure that critical alerts are not sent out too frequently, but that they quickly inform the recipient when something goes wrong.&lt;/p&gt;

&lt;p&gt;We need to be alerted when there are not enough fruits coming into the collection center. Let’s say that our operation is critical when less than 20 fruits are collected within a 1-hour period from any farm.&lt;/p&gt;

&lt;p&gt;Head over to the Monitoring and Alerting tab, and in the Checks column, let’s create an alert. We’re going to work with threshold checks for now. You’ll use the UI here to look in the &lt;code class="language-markup"&gt;farming&lt;/code&gt; bucket, filter on the &lt;code class="language-javascript"&gt;fruitCollectionRate&lt;/code&gt; measurement and the “fruits” field. You can also use the UI to window further and set an &lt;code class="language-javascript"&gt;aggregateFunction&lt;/code&gt;. Once you’ve built your threshold query, let’s configure the check.&lt;/p&gt;

&lt;p&gt;It is &lt;em&gt;very&lt;/em&gt; important to set a tag here to associate with your notification rules later. Tags ensure that the alerts you fire off go to the right recipient. I only want the head collector to be alerted when things get critical. I’ll set my tag to be &lt;code class="language-javascript"&gt;role&lt;/code&gt; == &lt;code class="language-javascript"&gt;headCollector&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also configure your status message here. Remember how we preserved the &lt;code class="language-markup"&gt;farmName&lt;/code&gt;? Let’s add that column here in the status message so the head collector knows which farm is having collection issues.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-markup"&gt;Check: ${ r._check_name } is: ${ r._level }. ${ r.farmName } is below collection threshold.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for my check: &lt;code class="language-markup"&gt;When value is below 20, set status to CRI&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Step 5: Set up a notification endpoint&lt;/h2&gt;
&lt;p&gt;This is the way that the alert will be sent out to your recipient. It is pretty easy to set up a Slack webhook for this purpose. Other options such as PagerDuty or setting up your own HTTP endpoint are available for paid InfluxDB Cloud users.&lt;/p&gt;

&lt;p&gt;Name your endpoint, then add the URL and other necessary parameters.&lt;/p&gt;
&lt;h2&gt;Step 6: Make notification rules for your alert&lt;/h2&gt;
&lt;p&gt;Finally, we’re ready to start sending alerts about your data. For our purposes, we only care about critical alerts. We’d like to send out alerts every hour about how fruit collection is going.&lt;/p&gt;

&lt;p&gt;Remember, to add your tag here, &lt;code class="language-javascript"&gt;role == headCollector&lt;/code&gt;. Any checks with a matching tag will be sent out using this notification rule. I’m going to send my head collector alerts via Slack. I’ll select the right endpoint from the dropdown menu. You can also further customize your message template here if you’d like.&lt;/p&gt;

&lt;p&gt;When you click to create your notification rule, you should be good to go. Now you’ll be informed anytime you hit that critical status.&lt;/p&gt;
&lt;h2&gt;Resources to learn more about alerting&lt;/h2&gt;
&lt;p&gt;If you need more information about how alerts work, check out the &lt;a href="https://v2.docs.influxdata.com/v2.0/monitor-alert/"&gt;docs here&lt;/a&gt;. The &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/"&gt;Flux documentation can be found here&lt;/a&gt; for information on writing good queries and tasks. &lt;a href="https://w2.influxdata.com/blog/monitoring-alerting-in-influxdb-cloud-2-0/"&gt;Here’s a previous blog&lt;/a&gt; that gives another overview of our alerts system. If you have any questions about setting up your alerts, join our &lt;a href="https://w2.influxdata.com/slack"&gt;community Slack channel&lt;/a&gt; or post them in our &lt;a href="https://community.influxdata.com/"&gt;community forums&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Thu, 07 May 2020 07:00:44 -0700</pubDate>
      <link>https://www.influxdata.com/blog/writing-tasks-and-setting-up-alerts-for-influxdb-cloud/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/writing-tasks-and-setting-up-alerts-for-influxdb-cloud/</guid>
      <category>Use Cases</category>
      <category>Product</category>
      <category>Developer</category>
      <author>Faith Chikwekwe (InfluxData)</author>
    </item>
  </channel>
</rss>
