<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>InfluxData Blog - Nate Isley</title>
    <description>Posts by Nate Isley on the InfluxData Blog</description>
    <link>https://www.influxdata.com/blog/author/nate_isley/</link>
    <language>en-us</language>
    <lastBuildDate>Wed, 01 Jul 2020 07:00:20 -0700</lastBuildDate>
    <pubDate>Wed, 01 Jul 2020 07:00:20 -0700</pubDate>
    <ttl>1800</ttl>
    <item>
      <title>Exploring Geo-Temporal Flux</title>
      <description>&lt;p&gt;&lt;a href="/products/flux/"&gt;Flux&lt;/a&gt; recently added geo-temporal capabilities to its arsenal, and I have been exploring how to effectively use this new combination of time series and geolocation data. To help get you started, we’ll cover a geo-temporal overview and then look into a few examples.&lt;/p&gt;

&lt;p&gt;If you would like to follow along using InfluxDB 2.0 OSS (open source) or InfluxDB Cloud, &lt;a href="/blog/how-to-expand-data-collection-for-influxdb-with-cloudformation-templates/"&gt;deploy this AWS Lambda&lt;/a&gt; to collect hourly earthquake data from the U.S. Geological Survey (USGS).&lt;/p&gt;

&lt;div style="padding:56.25% 0 0 0;position:relative;"&gt;&lt;iframe src="https://player.vimeo.com/video/710832938?h=910d5b96a9&amp;amp;badge=0&amp;amp;autopause=0&amp;amp;player_id=0&amp;amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen="" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Basics of Geo-temporal data and InfluxDB"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;script src="https://player.vimeo.com/api/player.js"&gt;&lt;/script&gt;

&lt;h2&gt;Geo-temporal Flux: an overview&lt;/h2&gt;
&lt;p&gt;Flux’s geo-temporal powers are derived from a Golang &lt;a href="https://s2geometry.io/"&gt;S2 Geometry&lt;/a&gt; library. S2 is based on spherical geometry, which makes it well-suited for answering geolocation questions.&lt;/p&gt;

&lt;p&gt;S2 has many details, but the key concepts in relation to Flux are &lt;a href="https://s2geometry.io/devguide/s2cell_hierarchy"&gt;S2 Cells&lt;/a&gt; and their level (from 0 to 30). S2 Cells are bounded by four spherical geodesics. At level 0, an S2 Cell represents approximately 85M km&lt;sup&gt;2&lt;/sup&gt;, and as the level increases, S2 Cells are subdivided into smaller areas. At level 30, a single subdivision represents an area of a little less than 1 cm&lt;sup&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Technically, geo-temporal analysis in Flux requires only latitude and longitude. However, tagging your data with S2 Cell Identifiers (IDs) helps to efficiently analyze data at scale. S2 Cell IDs - sometimes referred to as S2 Cell tokens - uniquely identify an S2 Cell at the designated level. To use S2 Cell IDs, you can either calculate them at query time or as the data is written to InfluxDB.&lt;/p&gt;

&lt;p&gt;Calculating at query time uses Flux to &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/s2cellidtoken/"&gt;calculate the S2 Cell ID&lt;/a&gt;. Calculating the S2 Cell ID with each query takes time and is inefficient when multiple queries execute on the same dataset. In contrast, preparing the S2 Cell ID while ingesting the data skips query time calculations at the cost of increased &lt;a href="https://www.influxdata.com/blog/red-flags-of-high-cardinality-in-databases/"&gt;cardinality&lt;/a&gt;. For those that use Telegraf for data acquisition, there is an &lt;a href="https://github.com/influxdata/telegraf/tree/master/plugins/processors/s2geo"&gt;S2 Geo processor plugin&lt;/a&gt; that allows you to calculate and add the S2 Cell ID to your latitude and longitude data.&lt;/p&gt;

&lt;p&gt;If you decide to add the S2 Cell ID at ingest time, consider the &lt;a href="https://s2geometry.io/resources/s2cell_statistics"&gt;precision of your geo-temporal&lt;/a&gt; calculations and &lt;a href="https://www.influxdata.com/blog/red-flags-of-high-cardinality-in-databases/"&gt;cardinality&lt;/a&gt;, and adjust your S2 level accordingly. For example, at level 0, six S2 Cell IDs represent earth, but at level 16, over 25 billion are required. Of course, if you are only tracking the movement of something on land, this can significantly reduce the number of S2 Cells you need; meaning you can likely up the precision — assuming the latitude and longitude data you’ve captured has sufficient precision as well.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.influxdata.com/blog/how-to-expand-data-collection-for-influxdb-with-cloudformation-templates/"&gt;earthquake Lambda&lt;/a&gt; calculates and tags earthquakes with level 9 S2 Cell IDs at ingest time?. At level 9, each S2 Cell ID is roughly 12 miles (19.31 km) wide and there are 1.5M possible S2 Cell IDs on earth. For analyzing earthquake data, this strikes a nice balance between granularity and cardinality. For your use case, you might need a higher or lower level of precision.&lt;/p&gt;

&lt;div style="padding:56.25% 0 0 0;position:relative; margin-bottom: 30px;"&gt;&lt;iframe src="https://player.vimeo.com/video/710835979?h=ed7a0e9b56&amp;amp;badge=0&amp;amp;autopause=0&amp;amp;player_id=0&amp;amp;app_id=58479/embed" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen="" frameborder="0" style="position:absolute;top:0;left:0;width:100%;height:100%;"&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;h2&gt;Geo-temporal Flux examples&lt;/h2&gt;

&lt;div style="padding:56.25% 0 0 0;position:relative; margin-bottom: 30px;"&gt;&lt;iframe src="https://player.vimeo.com/video/710840696?h=8943f0e1d7&amp;amp;badge=0&amp;amp;autopause=0&amp;amp;player_id=0&amp;amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen="" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Using Flux to query geo-temporal data"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;script src="https://player.vimeo.com/api/player.js"&gt;&lt;/script&gt;

&lt;p&gt;Let’s dig into a real-time analysis of USGS earthquake data. This initial example finds earthquakes that occurred in the last 24 hours within a region that roughly represents the west coast of the continental United States:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;import "experimental/geo"

from(bucket: "Earthquake")
  |&amp;gt; range(start: -24h)
  |&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "geo")
  |&amp;gt; filter(fn: (r) =&amp;gt; r["_field"] == "lat" or r["_field"] == "lon")
  |&amp;gt; geo.filterRows(
    region: {
      minLat: 32.245914,
      maxLat: 49.259394,
      minLon: -126.860380,
      maxLon: -114.715901
    }
  )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We defined &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/filterrows/"&gt;a box&lt;/a&gt; with a maximum and minimum latitude and longitude, and the geo function makes sure to only provide us the list of earthquakes within those borders.&lt;/p&gt;

&lt;p&gt;For those times when a simple box does not fit your use case, &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/experimental/geo/#region-definitions"&gt;Flux provides circles and general polygons&lt;/a&gt;. For example, here I investigate the number of earthquakes in the last 7 days in an area roughly bounded by the five San Francisco Bay Area counties I regularly travel to (San Francisco, Marin, Alameda, Contra Costa, and San Mateo County):&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;import "experimental/geo"

from(bucket: "Earthquake")
  |&amp;gt; range(start: -7d)
  |&amp;gt; filter(fn: (r) =&amp;gt; r["_measurement"] == "geo")
  |&amp;gt; filter(fn: (r) =&amp;gt; r["_field"] == "lat" or r["_field"] == "lon")
  |&amp;gt; geo.filterRows(
    region: {
        points: [
        {lat: 38.296395, lon: -123.022551}, {lat: 38.320102, lon: -122.879729}, {lat: 38.190695, lon: -122.580351}, {lat: 38.060455, lon: -122.394375},
        {lat: 38.043152, lon: -121.751675}, {lat: 38.112338, lon: -121.581387}, {lat: 37.825442, lon: -121.536068}, {lat: 37.546042, lon: -121.552121},
        {lat: 37.482863, lon: -121.466977}, {lat: 37.451254, lon: -121.931149}, {lat: 37.454980, lon: -122.112390}, {lat: 37.214760, lon: -122.148095},
        {lat: 37.054918, lon: -122.406274}, {lat: 37.990496, lon: -123.027002}
        ]
    }
  )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Though, if you happen to live in the Bay Area, it’s probably best not to dwell too long on the results.&lt;/p&gt;

&lt;p&gt;This last example illustrates an iterative query by first finding the strongest earthquake the USGS observed in the last 24 hours worldwide. Then, we look at the last 7 days and count how many earthquakes occurred within 200 km of that event:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;import "experimental/geo"

max_eq = 
   from(bucket:"Earthquake")
       |&amp;gt; range(start: -24h)
       |&amp;gt; filter(fn: (r) =&amp;gt; r._measurement == "geo")
       |&amp;gt; geo.toRows()
       |&amp;gt; group()
       |&amp;gt; max(column: "mag")
       |&amp;gt; findRecord(fn: (key) =&amp;gt; true, idx: 0)

from(bucket:"Earthquake")
    |&amp;gt; range(start: -7d)
    |&amp;gt; geo.filterRows(region: {lat: max_eq.lat, lon: max_eq.lon, radius: 200.0}, strict: false)
    |&amp;gt; group()
    |&amp;gt; count(column: "mag")&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;What's next?&lt;/h2&gt;

&lt;p&gt;To explore more of InfluxDB’s emerging geo-temporal capabilities, &lt;a href="https://youtu.be/iWTHnKVJqhs?t=1707"&gt;check out Tim Hall’s InfluxDays roadmap presentation&lt;/a&gt;. Tim discusses more details about the work we’ve done on geo-temporal data acquisition, queries, and visualization. Also, I will continue publishing new blogs exploring Flux’s advanced geo-temporal capabilities.&lt;/p&gt;

&lt;p&gt;Want to analyze your own data today? Check out Flux’s geo-temporal features in &lt;a href="https://www.influxdata.com/products/influxdb-cloud/"&gt;InfluxDB Cloud 2.0&lt;/a&gt;, &lt;a href="https://www.influxdata.com/products/influxdb-enterprise/"&gt;InfluxDB Enterprise 1.8&lt;/a&gt;, and &lt;a href="https://www.influxdata.com/products/influxdb-overview/influxdb-2-0/"&gt;InfluxDB OSS 2.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, if you have questions or feedback, please let us know in our &lt;a href="https://community.influxdata.com/"&gt;community forum&lt;/a&gt; or &lt;a href="https://www.influxdata.com/slack"&gt;join us in Slack&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Wed, 01 Jul 2020 07:00:20 -0700</pubDate>
      <link>https://www.influxdata.com/blog/exploring-geo-temporal-flux/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/exploring-geo-temporal-flux/</guid>
      <category>Use Cases</category>
      <category>Developer</category>
      <category>Product</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>How to Expand Data Collection for InfluxDB with CloudFormation Templates</title>
      <description>&lt;p&gt;In a previous post, I demonstrated &lt;a href="https://w2.influxdata.com/blog/extending-influxdb-with-serverless-functions/"&gt;how to call InfluxDB APIs from AWS Lambda&lt;/a&gt;, but the setup is fairly manual and the results are not portable. Ideally, we as a community can expand and share ways to collect and process time series data. To that end, I want to share a CloudFormation template.&lt;/p&gt;

&lt;p&gt;CloudFormation is AWS’ infrastructure as code service that lets you define almost any AWS component in a configuration file. The result is a service that provides a concrete, repeatable definition of your environment that can prove useful in many scenarios. For example, if someone accidentally deletes your &lt;a href="https://aws.amazon.com/sqs/"&gt;Simple Queue Service&lt;/a&gt; topic or an &lt;a href="https://aws.amazon.com/ec2/"&gt;EC2 instance&lt;/a&gt;, you can easily recreate them by running your CloudFormation template.&lt;/p&gt;
&lt;h2&gt;A geo-temporal CloudFormation template&lt;/h2&gt;
&lt;p&gt;CloudFormation templates create AWS &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html"&gt;stacks&lt;/a&gt; that wrap the AWS components defined in the template. AWS stacks are easy to create, update, recreate, and remove.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://influxdata-lambda.s3.amazonaws.com/GeoLambda.yml"&gt;The CloudFormation template&lt;/a&gt; that I’ll walk through below pulls earthquake data from the &lt;a href="https://www.usgs.gov/"&gt;United States Geological Survey&lt;/a&gt; (USGS) every hour and writes it to InfluxDB. I will not attempt to give you a full CloudFormation tutorial, but it’s helpful to understand a breakdown of the different sections if you’d like to use this template to create your own:&lt;/p&gt;
&lt;ul&gt;
 	&lt;li&gt;The first ~20 lines define variables that the template asks for when it's installed.&lt;/li&gt;
 	&lt;li&gt;Lines 21?&amp;ndash;120 handle a quirk of Lambda deployments that requires the Lambda assets to be in your region before deployment. As there is no elegant workaround, these 100 lines create an S3 bucket in your account in the region you are creating the stack and copies in the resources.&lt;/li&gt;
 	&lt;li&gt;Lines 121?&amp;ndash;132 define a role with basic permission to run the Lambda.&lt;/li&gt;
 	&lt;li&gt;Lines 133?&amp;ndash;144 define a Python library layer. &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html"&gt;Lambda layers&lt;/a&gt; are really handy at decoupling your functions from supporting libraries. In this layer, I packaged the Python HTTP library, a Python S2 Geometry library, and the InfluxDB Python client library.&lt;/li&gt;
 	&lt;li&gt;Lines 146?&amp;ndash;165 define the Lambda function. The Lambda is a short Python script that is zipped up in a file called geo_lambda.zip.&lt;/li&gt;
 	&lt;li&gt;Lines 166?&amp;ndash;188 define an event rule with permission to run the Lambda. The rule will run the Lambda every hour.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Deploying the Lambda Stack&lt;/h2&gt;
&lt;p&gt;Now that we have explored the template, let’s deploy it. First, log into your free AWS account and search for the CloudFormation service. Make sure you’re in the AWS region you want to deploy the Lambda to? — I have deployed more stacks in the incorrect region than I would like to admit. The following screenshot shows a search for CloudFormation while in the N. Virginia region (upper right):&lt;/p&gt;

&lt;p&gt;&lt;img class=" wp-image-247263 aligncenter" src="/images/legacy-uploads/lambda-cloudformation-influxdb.png" alt="Lambda Cloudformation - InfluxDB" width="1449" height="756" /&gt;&lt;/p&gt;

&lt;p&gt;Once you navigate to CloudFormation, click the &lt;strong&gt;Create Stack&lt;/strong&gt; button. Select &lt;strong&gt;Template is ready&lt;/strong&gt; and &lt;strong&gt;Amazon S3 URL&lt;/strong&gt; options, and then copy and paste the following URL into the &lt;strong&gt;Amazon S3 URL field&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://influxdata-lambda.s3.amazonaws.com/GeoLambda.yml"&gt;https://influxdata-lambda.s3.amazonaws.com/GeoLambda.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247264 aligncenter" src="/images/legacy-uploads/cloudformation-create-stack.png" alt="CloudFormation - create stack" width="1431" height="760" /&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Next&lt;/strong&gt;, and then name your stack. Provide the following InfluxDB details:&lt;/p&gt;
&lt;ul&gt;
 	&lt;li&gt;Your organization ID&lt;/li&gt;
 	&lt;li&gt;Bucket ID of the bucket the Lambda writes to&lt;/li&gt;
 	&lt;li&gt;Token with permission to write to the bucket&lt;/li&gt;
 	&lt;li&gt;Your InfluxDB URL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also two other parameters (QSS3BucketName, QSS3KeyPrefix) with default values that you should &lt;strong&gt;not&lt;/strong&gt; change. These parameters are helpers for asset copying.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247266 aligncenter" src="/images/legacy-uploads/cloudformation-specify-stack-details.png" alt="CloudFormation - specify stack details" width="1431" height="776" /&gt;&lt;/p&gt;

&lt;p&gt;On the Specify stack details page, leave the fields blank and then click &lt;strong&gt;Next&lt;/strong&gt;. Select &lt;strong&gt;I acknowledge creating this stack will create resources&lt;/strong&gt;, and then click &lt;strong&gt;Create stack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247267 aligncenter" src="/images/legacy-uploads/cloudformation-create-resources.png" alt="CloudFormation - create resources" width="1431" height="769" /&gt;&lt;/p&gt;

&lt;p&gt;After a few minutes, the stack deploys to your region. To navigate to your new Lambda, click &lt;strong&gt;Services -&amp;gt; Lambda&lt;/strong&gt;. On the Lambda functions page, you should see your new Lambda listed there. The CopyZipsFunction is the helper copy function, and the GeoPythonLambda does the data collection and writing work:&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247268 aligncenter" src="/images/legacy-uploads/GeoPythonLambda-cloudformation.png" alt="GeoPythonLambda CloudFormation" width="1431" height="659" /&gt;&lt;/p&gt;

&lt;p&gt;GeoPythonLambda should run every hour based on the AWS Rule we set up, but you should test and confirm it works. To test, click &lt;strong&gt;GeoPythonLambda&lt;/strong&gt;, and then click &lt;strong&gt;Test&lt;/strong&gt;. Test requires an input definition, but this Lambda has no input requirements, so click through and save the default dataset.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247270 aligncenter" src="/images/legacy-uploads/cloudformation-test.png" alt="CloudFormation test" width="1431" height="708" /&gt;&lt;/p&gt;

&lt;p&gt;Here is what you should expect after a successful test — a green &lt;strong&gt;Execution result: succeeded&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247271 aligncenter" src="/images/legacy-uploads/cloudformation-test-result.png" alt="CloudFormation test result" width="1431" height="676" /&gt;&lt;/p&gt;

&lt;p&gt;With the data points written, when you log into your InfluxDB UI, you’ll be able to explore the geolocation earthquake data.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-247272 aligncenter" src="/images/legacy-uploads/geolocation-earthquake-data.png" alt="geolocation earthquake data" width="1431" height="686" /&gt;&lt;/p&gt;
&lt;h2&gt;What else?&lt;/h2&gt;
&lt;p&gt;As an aside, now that the layer asset with the Python client library is in your environment/region, you can easily create new Lambdas and experiment with the client.  Create a new Python 3.8 Lambda and select &lt;strong&gt;Layers&lt;/strong&gt; and &lt;strong&gt;Add a layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img class="alignnone size-full wp-image-247401" src="/images/legacy-uploads/create-python-lambda-cloudformation.png" alt="create Python Lambda CloudFormation" width="1600" height="855" /&gt;&lt;/p&gt;

&lt;p&gt;In Add layer to function, “my-layers” is an option under the list of runtime compatible layers:&lt;/p&gt;

&lt;p&gt;&lt;img class="alignnone size-full wp-image-247402" src="/images/legacy-uploads/add-layer-to-function-lambda.png" alt="add layer to function - Lambda" width="1600" height="846" /&gt;&lt;/p&gt;

&lt;p&gt;Once added, import and use the client library in any of your Lambda code.&lt;/p&gt;
&lt;h2&gt;What's next?&lt;/h2&gt;
&lt;p&gt;This blog covered how to distribute a data collector on AWS via CloudFormation. If you have data collection needs and workloads that run on AWS, this template could jumpstart your AWS stack creation efforts.&lt;/p&gt;

&lt;p&gt;Apart from a data collection discussion, this Lambda also directly supports an in-depth review of Flux’s new geo-temporal query capabilities. Now that you have the USGS earthquake data reporting in, you can &lt;a href="https://w2.influxdata.com/blog/exploring-geo-temporal-flux/"&gt;explore using Flux to analyze your data&lt;/a&gt; over time and space.&lt;/p&gt;

&lt;p&gt;As always, if you have questions or feedback, please reach out to me in our &lt;a href="https://community.influxdata.com/"&gt;community forum&lt;/a&gt; or &lt;a href="https://w2.influxdata.com/slack"&gt;join us in Slack&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Tue, 23 Jun 2020 07:00:42 -0700</pubDate>
      <link>https://www.influxdata.com/blog/how-to-expand-data-collection-for-influxdb-with-cloudformation-templates/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/how-to-expand-data-collection-for-influxdb-with-cloudformation-templates/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Extending InfluxDB with Serverless Functions</title>
      <description>&lt;p&gt;Data ingestion and data analysis are the yin and yang of a time series platform. There are many &lt;a href="https://v2.docs.influxdata.com/v2.0/write-data/sample-data/"&gt;resources&lt;/a&gt; to help you ingest data. Typical ingestions are &lt;a href="https://www.youtube.com/watch?v=qFS2zANwIrc&amp;amp;feature=youtu.be"&gt;agent-based&lt;/a&gt;,&lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/csv/from/#query-csv-data-from-a-file"&gt; imports via CSVs&lt;/a&gt;, &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/api/client-libraries/"&gt;using client libraries&lt;/a&gt;, or via &lt;a href="https://v2.docs.influxdata.com/v2.0/write-data/#third-party-technologies"&gt;third-party technologies&lt;/a&gt;. Once your &lt;a href="https://www.influxdata.com/what-is-time-series-data"&gt;time series data&lt;/a&gt; arrives, analysis completes the circle and often leads to additional data collection, and so on and so forth.&lt;/p&gt;

&lt;p&gt;Native InfluxDB tools such as Tasks, Dashboards, and &lt;a href="https://www.influxdata.com/blog/using-flux-to-write-data-out-to-sql-data-stores/"&gt;Flux&lt;/a&gt; typically provide the needed insight within the platform, but some use cases necessitate extending the platform. For those, InfluxDB’s unified API provides a complete set of integration endpoints. This extensibility is one of the things developers love about InfluxDB.&lt;/p&gt;

&lt;p&gt;To illustrate, I’ve provided two simple examples implemented on Amazon Web Services’ (AWS) functions as a service offering - &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/welcome.html"&gt;Lambda&lt;/a&gt;. Serverless functions such as Lambda are useful for almost any architecture because they are decoupled units of work that are relatively easy to connect.&lt;/p&gt;

&lt;h2&gt;The setup&lt;/h2&gt;

&lt;p&gt;My example incorporates a &lt;a href="https://www.influxdata.com/blog/using-serverless-flux-to-monitor-website-response-times/"&gt;Flux Task&lt;/a&gt; that synthetically monitors the response time of a web application. InfluxDB gathers the data and acts as the backend analytics engine that the service processor uses to power its business processes.&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/legacy-uploads/influxdb-aws-lambda.png" alt="InfluxDB AWS Lambda" width="1218" height="307" /&gt;&lt;/p&gt;

&lt;p&gt;I replicated the synthetic monitoring Task three times with different URLs and stored the results in a bucket with the name of the monitored company. For example, one of my tasks monitors &lt;a href="https://www.uber.com/"&gt;Uber’s&lt;/a&gt; response time, and the response time is stored in a bucket called “Uber”. The end result? Three InfluxDB tasks capturing website performance in a uniform data set differentiated only by bucket name.&lt;/p&gt;

&lt;h2&gt;Using AWS Lambda to query InfluxDB&lt;/h2&gt;

&lt;p&gt;The first decision when creating a Lambda is to pick which language to use. To make it easier to walk through development, I used NodeJS. AWS’ NodeJS Integrated Development Environment support means the first example can be created entirely within the browser.&lt;/p&gt;

&lt;p&gt;To follow along, sign up for a free AWS account and complete &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html"&gt;Lambda’s getting started steps&lt;/a&gt;.  Create a hello world NodeJS Lambda and copy/paste Example 1 &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/code-editor.html"&gt;into the console&lt;/a&gt;. On the InfluxDB side, &lt;a href="https://cloud2.influxdata.com/signup"&gt;sign up for a free InfluxDB Cloud&lt;/a&gt; account, &lt;a href="https://www.influxdata.com/blog/using-serverless-flux-to-monitor-website-response-times/"&gt;create the Flux task&lt;/a&gt;, and grab your org-id and token to insert into Example 1’s code:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;var https = require('https');

exports.handler = function(event, context) {
    var queryForCount = "from(bucket: \"Pingpire\") |&amp;gt; range(start: -1h) |&amp;gt; filter(fn: (r) =&amp;gt; r[\"_measurement\"] == \"PingService\") |&amp;gt; filter(fn: (r) =&amp;gt; r[\"_field\"] == \"response_time_ms\") |&amp;gt; filter(fn: (r) =&amp;gt; r[\"method\"] == \"GET\") |&amp;gt; count()"

    // An object of options to indicate where to post
    var post_options = {
        host: 'us-west-2-1.aws.cloud2.influxdata.com',
        path: '/api/v2/query?orgID=&amp;lt;your-ord-id&amp;gt;',
        method: 'POST',
        headers: {
            'Content-Type': 'application/vnd.flux',
            'Authorization': 'Token &amp;lt;your-user-token&amp;gt;'
        }
    };

    // Set up the request
    var post_req_uber = https.request(post_options, function(res) {
        res.on('data', function(chunk) {
            console.log('Response: ' + chunk);
            context.succeed();
        });
        res.on('error', function(e) {
            console.log("Got error: " + e.message);
            context.done(null, 'FAILURE');
        });
    });
    // post the data
    post_req_uber.write(queryForCount);
    post_req_uber.end();
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here is a screenshot of the AWS IDE output when I tested the Lambda in my browser:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/legacy-uploads/influxdb-query-workload-aws-lambda.png" alt="InfluxDB query workload - AWS Lambda" width="1346" height="736" /&gt;&lt;/p&gt;

&lt;p&gt;This first example is a straightforward use of a NodeJS HTTPS POST request to demonstrate direct use of InfluxDB’s API. Using the API is powerful and simple, but many developers would rather use libraries instead of making HTTP calls. My second example invokes InfluxDB via an InfluxDB client library to illustrate this approach.&lt;/p&gt;

&lt;p&gt;Setting up the second example takes a little more work as the base AWS NodeJS library is limited. To proceed, you will need the AWS command-line interface (CLI) to add node packages - follow &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html"&gt;installing/using the AWS CLI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you have the CLI, &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/nodejs-package.html#nodejs-package-dependencies"&gt;update the available library/packages&lt;/a&gt; for your lambda function with&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-bash"&gt;&amp;gt;npm install @influxdata/influxdb-client&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in a local directory. You can zip that directory and use the CLI to import it to an AWS Lambda directly, or do what I did and use the NodeJS IDE’s “upload a zipfile” option under code entry type.&lt;/p&gt;

&lt;p&gt;Once the Lambda has the integrated InfluxDB client library, copy/paste Example 2’s’ code:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;const { InfluxDB } = require('@influxdata/influxdb-client')

const token = '&amp;lt;your-user-token&amp;gt;'
const org = '&amp;lt;your-org-id'

const client = new InfluxDB({ url: 'https://us-west-2-1.aws.cloud2.influxdata.com', token: token })
const queryApi = client.getQueryApi(org)

exports.handler = function(event, context, callback) {
  var customerJSON = JSON.parse(JSON.stringify(event));

  var customers = [];
  var x;
  for (x in customerJSON) {
    customers.push(customerJSON[x]);
  }

  var y = 0;
  for (var i = 0; i &amp;lt; customers.length; i++) {
    var query = `from(bucket: "${customers[i]}" ) |&amp;gt; range(start: -10m) |&amp;gt; filter(fn: (r) =&amp;gt; r.method == "GET" ) |&amp;gt; count(column: "_value")`;
    console.log(query)

    queryApi.queryRows(query, {
      next(row, tableMeta) {
        const o = tableMeta.toObject(row);
        console.log(`Customer "${customers[y++]}" consumed ` + o._value + ` pings.`);
      },
      error(error) {
        console.error(error)
        console.log('\nFinished ERROR')
      },
      complete() {
        console.log('\nFinished SUCCESS')
      },
    })
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, using the client library is not drastically different from API access. You still need the token, org-id, and query, but native libraries almost always make developers more efficient.&lt;/p&gt;

&lt;p&gt;To execute and test this example, recall that my InfluxDB has several tasks for monitoring company websites, and the results are differentiated by bucket name. My Lambda takes in a JSON list of companies and loops over the list to query InfluxDB for results. Here is my test JSON:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-json"&gt;{
  "Company1": "Microsoft",
  "Company2": "Uber",
  "Company3": "Pingpire"
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a screenshot of the AWS IDE output for the second Lambda:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/legacy-uploads/aws-ide-output-influxdb-lambda.png" alt="AWS IDE Output - InfluxDB Lambda" width="1350" height="719" /&gt;&lt;/p&gt;

&lt;h2&gt;Exploring serverless integrations continues...&lt;/h2&gt;

&lt;p&gt;These initial examples demonstrate the ease with which one can get started extending InfluxDB with Lambda. Over the coming weeks, I will be expanding on this foundation to further explore using Serverless with InfluxDB.&lt;/p&gt;

&lt;p&gt;As I mentioned, please try out the above examples today by signing up for free &lt;a href="https://cloud2.influxdata.com/signup"&gt;InfluxDB Cloud&lt;/a&gt; and AWS accounts. As always, if you have questions, feedback, or want to explore these specific examples please reach out in our &lt;a href="https://community.influxdata.com/"&gt;community forum&lt;/a&gt; or &lt;a href="https://www.influxdata.com/slack"&gt;via Slack&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Thu, 04 Jun 2020 07:00:22 -0700</pubDate>
      <link>https://www.influxdata.com/blog/extending-influxdb-with-serverless-functions/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/extending-influxdb-with-serverless-functions/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <category>Company</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Using Serverless Flux to Monitor Website Response Times</title>
      <description>&lt;p&gt;My &lt;a href="https://w2.influxdata.com/blog/explaining-influxdata-at-family-holidays/"&gt;holiday challenge to explain serverless InfluxDB to my family&lt;/a&gt; produced a useful Flux script anyone can put to work today. Before we dive into the code, let me outline the high-level approach to gathering and visualizing how long it takes a website to respond to an HTTP request:&lt;/p&gt;
&lt;ol&gt;
 	&lt;li&gt;Create a Flux script to measure a website's performance.
&lt;ul&gt;
 	&lt;li&gt;Decide on the URL to monitor and assign it to &lt;code class="language-javascript"&gt;theURLtoMonitor&lt;/code&gt; variable.&lt;/li&gt;
 	&lt;li&gt;Record the current time.&lt;/li&gt;
 	&lt;li&gt;Make an HTTP call to the website.&lt;/li&gt;
 	&lt;li&gt;Record the new current time.&lt;/li&gt;
 	&lt;li&gt;Calculate the website response time by subtracting b. from d.&lt;/li&gt;
 	&lt;li&gt;Save the URL monitored, the response time, and the HTTP status code into an InfluxDB bucket.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
 	&lt;li&gt;Create a task to run this Flux script every 5 minutes.&lt;/li&gt;
 	&lt;li&gt;Build a dashboard to visualize the performance of the website.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;The Flux script&lt;/h2&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;import "strings"
import "csv"
import "experimental/http"
import "system"

differenceInNanosec = (earlierTime, laterTime) =&amp;gt; {
	return uint(v: laterTime) - uint(v: earlierTime)
}

theURLtoMonitor = "https://v2.docs.influxdata.com/v2.0/"

timeBeforeCall = system.time()
response = http.get(url: theURLtoMonitor)
timeAfterCall = system.time()

responseTime = differenceInNanosec(earlierTime: timeBeforeCall, laterTime: timeAfterCall)

data = "#group,false,false,true,true
#datatype,string,long,string,string
#default,mean,,,
,result,table,service,response_code
,,0,http_ping,${string(v: response.statusCode)}"

csv.from(csv: data)
	|&amp;gt; map(fn: (r) =&amp;gt; ({r with _time: now()}))
	|&amp;gt; map(fn: (r) =&amp;gt;
		({r with _measurement: "PingService", url: theURLtoMonitor, method: "GET"}))
	|&amp;gt; to(bucket: "&amp;lt;bucket_name&amp;gt;", orgID: "&amp;lt;orgID&amp;gt;", fieldFn: (r) =&amp;gt;
		({"response_time_ms":  uint(v: responseTime) / uint(v: 1000000)  }))&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Deciphering the Flux script&lt;/h2&gt;
&lt;p&gt;After boilerplate imports @1-4, we have a custom function named &lt;code class="language-javascript"&gt;differenceInNanosec&lt;/code&gt; @6. This is a helper function that converts time into integers for subtraction and helps keep straight which time measurement to subtract from which.&lt;/p&gt;

&lt;p&gt;The bulk of the algorithm work comes next and is completed in just a few lines @10-16. @10 assigns the website URL to the variable. Lines @12-14 perform the actual HTTP request in between recording times before and after the call, and we use the times in &lt;code class="language-javascript"&gt;differenceInNanosec&lt;/code&gt; to calculate the website’s response time @16.&lt;/p&gt;

&lt;p&gt;After securing the response time, we need to save it to InfluxDB. However, there are a couple of hoops we must jump through. The complication is that our variables are simple data values, but Flux’s InfluxDB connector only writes Flux tables to InfluxDB.&lt;/p&gt;

&lt;p&gt;Saving a Flux table sounds simple enough, but we need to create it first and as of today (Flux version 0.57), there are only two ways to create a Flux table. The first is &lt;code class="language-javascript"&gt;from(bucket:...)&lt;/code&gt;; Flux automatically creates a table when querying InfluxDB data. The second way to create a Flux table is via &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/csv/from/#query-raw-csv-formatted-text"&gt;&lt;code class="language-javascript"&gt;csv.from(csv:...)&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This second option is our only viable option, and we put it to work @18-22 by constructing &lt;code class="language-javascript"&gt;csv.from()&lt;/code&gt;’s raw input to build the csv table structure. The wrinkle @22 is that I have decided to use the Strings package to create a more dynamic table. You can see this dynamism in action with the use of the string replacement function &lt;code class="language-javascript"&gt;${string(v: response.statusCode)}&lt;/code&gt; to insert the HTTP status code.&lt;/p&gt;

&lt;p&gt;Once the raw string is put together, we create a table object @24 using &lt;code class="language-javascript"&gt;csv.from()&lt;/code&gt;. The table is close to ready for saving but needs a little more shaping to fulfill InfluxDB write requirements. @25-26 adds the required timestamp and _measurement name, and while not a strict requirement, I also add the url and http method as tags. At last, @29 we save the table into the target bucket with the response time in a response_time_ms field — &lt;code class="language-javascript"&gt;fieldFn: (r) =&amp;gt; ({"response_time_ms":  uint(v: responseTime) / uint(v: 1000000)  }))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(Note the conversion to milliseconds to make it easier for humans to understand the measurement.)&lt;/p&gt;
&lt;h2&gt;Creating the Flux task&lt;/h2&gt;
&lt;p&gt;A lot happened in the Flux script, but pulling together the code just gets us to the starting line.  We want to gather the response time every 5 minutes, and that is the perfect job for a Task.&lt;/p&gt;

&lt;p&gt;The first step in creating a task is to paste/write your code into a script editor and ensure your code successfully saves a singular data point. You can verify the above website response time Flux by copying and pasting the above code into the script editor and changing the URL, organization ID, and bucket name:&lt;/p&gt;

&lt;p&gt;&lt;img class="wp-image-241948 aligncenter" src="/images/legacy-uploads/creating-flux-task-screenshot.png" alt="Create Flux Task - screenshot" width="1206" height="670" /&gt;&lt;/p&gt;

&lt;p&gt;After confirming the script runs successfully, copy and paste your updated script into a task. To do this, go to the Tasks tab on the left and then select &lt;strong&gt;Create Task&lt;/strong&gt; -&amp;gt; New Task in the upper right to open a blank task editor. Paste the code, name the task, and specify that it runs every 5 minutes with “5m”:&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-241949 aligncenter" src="/images/legacy-uploads/create-new-flux-task-screenshot.png" alt="create new Flux task screenshot" width="1188" height="575" /&gt;&lt;/p&gt;

&lt;p&gt;After saving, the task will run every 5 minutes to collect and store the response time in response_time_ns.&lt;/p&gt;
&lt;h2&gt;Build a dashboard to visualize response time&lt;/h2&gt;
&lt;p&gt;There are almost limitless ways to visualize the collected data, but the easiest is to go to the &lt;strong&gt;Data Explorer&lt;/strong&gt;, find the response time metric, and use the upper right &lt;strong&gt;Save As&lt;/strong&gt; button to create a new dashboard.&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-241950 aligncenter" src="/images/legacy-uploads/visualize-response-time.png" alt="visualize response time" width="1159" height="722" /&gt;&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;p&gt;&lt;img class="size-full wp-image-241951 aligncenter" src="/images/legacy-uploads/monitor-website-response-time-dashboard.png" alt="monitor website response time dashboard" width="1142" height="695" /&gt;&lt;/p&gt;
&lt;h2&gt;Tell us what you think!&lt;/h2&gt;
&lt;p&gt;Try out the above example today by signing up for a free &lt;a href="https://cloud2.influxdata.com/login"&gt;Cloud 2 account&lt;/a&gt; or download the &lt;a href="https://portal.influxdata.com/downloads/"&gt;latest OSS release&lt;/a&gt; to run it locally. As always, if you have questions or feedback, please let us know in our &lt;a href="https://community.influxdata.com/"&gt;community forum&lt;/a&gt; or &lt;a href="https://influxcommunity.slack.com/join/shared_invite/enQtNjA4MTM2NDgyNDUwLTE3NjNlZDAzZjQxOTNlZDkxOGIwZmQwNDgyYmI4YzMxYmQzNzE0ODQxYjE5NGE0MWVlYjcxZGU2YzZiODQwNjU"&gt;join us in Slack&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Wed, 08 Jan 2020 07:00:01 -0700</pubDate>
      <link>https://www.influxdata.com/blog/using-serverless-flux-to-monitor-website-response-times/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/using-serverless-flux-to-monitor-website-response-times/</guid>
      <category>Use Cases</category>
      <category>Developer</category>
      <category>Product</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Explaining InfluxData at Family Holidays</title>
      <description>&lt;p&gt;After trying to explain &lt;a href="/products/influxdb-overview/"&gt;InfluxDB &lt;/a&gt;to family between hors d’oeuvres, I quickly realized I could not simply &lt;a href="/blog/use-flux-to-group-shape-and-analyze-your-time-series-data/"&gt;dive into Flux&lt;/a&gt;. I needed to show, not tell.&lt;/p&gt;

&lt;p&gt;Over two blogs, I’ll dig into how I explained InfluxData for non-technical folks, a serverless example, and deep dive into serverless Flux code so you can wow your own in-laws.&lt;/p&gt;

&lt;h2&gt;Deciphering techno-speak&lt;/h2&gt;

&lt;p&gt;This Thanksgiving, much of our family was in town to visit and fill up on turkey and ribs.  Everyone was curious about InfluxData, but conveying InfluxDB to anyone not working in technology is no small feat.&lt;/p&gt;

&lt;p&gt;While a serverless time series database platform might roll off the tongue, I would be more successful describing the weather in &lt;a href="https://en.wikipedia.org/wiki/Basque_language"&gt;Basque&lt;/a&gt; than expecting anyone who does not use databases to comprehend techno-marketing-speak. I tried different ways to share InfluxDB with my family and friends, and by Sunday, I settled on:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Folks measure almost everything constantly now, like ocean tides, house temperatures, or internet speeds. They’re measuring so much, so often that they have found they need specialized time-based collection and analysis tools. InfluxDB is an open source software project to capture and analyze this massive amount of data. InfluxData’s newest iteration includes all the tools already built to help handle this huge time-based measurement load, and now we’ve added support for running serverless code. The platform does the heavy lifting of collecting data, storing it, and providing computing power to analyze the data so software builders can focus on implementing solutions.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This elicited a few head nods, but I could tell it was still fuzzy. Not to be deterred, I retreated to my desk to create a concrete Flux example. I settled on a use case I thought most folks could relate to — how long it takes to load your favorite website.&lt;/p&gt;

&lt;p&gt;I started by tinkering with &lt;a href="https://github.com/influxdata/flux#getting-started"&gt;the Flux REPL&lt;/a&gt; and proceeded to my &lt;a href="/products/influxdb-cloud/"&gt;InfluxDB Cloud&lt;/a&gt; script builder.  I ran into a few snags, but after a couple of workarounds (covered in the deep dive), I managed to distill the data into a suitable dataset.&lt;/p&gt;

&lt;p&gt;With my Flux program generating and saving a proper dataset every time it was invoked, I put InfluxDB Cloud’s serverless capabilities to work. By saving the script as a task running every minute, my data started to flow in. From there, it was a simple matter to create and share a dashboard:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/legacy-uploads/flux-dashboard.png" alt="Flux dashboard" width="1323" height="832" /&gt;&lt;/p&gt;

&lt;p&gt;A concrete example did the trick and a lightbulb turned on in my brother’s head -  “Ah, I can gather and process any information over time with a few lines of Flux.”&lt;/p&gt;

&lt;p&gt;Exactly! - of course, now I’m stuck creating Flux to help him gather the price of Brent crude oil…&lt;/p&gt;

&lt;h2&gt;Unlock Flux's power for your use case!&lt;/h2&gt;

&lt;p&gt;Flux is a powerful language for working with data and it’s available now on top of our time series platform. It is unlocking exciting new time series use cases and allowing developers to work with data where it resides both within InfluxDB and other data sources such as mySQL, MariaDB, and Postgres. Pick up &lt;a href="https://portal.influxdata.com/downloads/"&gt;InfluxDB’s OSS&lt;/a&gt; or &lt;a href="https://cloud2.influxdata.com/login"&gt;sign up for InfluxDB Cloud&lt;/a&gt; to start exploring. If you are looking for a starting point for Flux, I highly recommend Scott Anderson’s &lt;a href="/resources/introduction-to-flux-and-functional-data-scripting/"&gt;outstanding Flux training&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, if you have questions or feature requests for Flux, head on over to &lt;a href="https://community.influxdata.com/c/fluxlang"&gt;Flux’s community forum&lt;/a&gt; or &lt;a href="https://www.influxdata.com/slack"&gt;join us in Slack&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Fri, 13 Dec 2019 07:00:46 -0700</pubDate>
      <link>https://www.influxdata.com/blog/explaining-influxdata-at-family-holidays/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/explaining-influxdata-at-family-holidays/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Using Secret Stores to Secure Flux Access</title>
      <description>&lt;p&gt;&lt;a href="https://w2.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/"&gt;Multi-data &lt;/a&gt;source Flux opens up endless variations in &lt;a href="https://www.influxdata.com/time-series-analysis-methods/"&gt;time series analysis&lt;/a&gt;, but as with all data access, new communications open potential attack vectors for shady actors. To secure your sensitive credentials, use InfluxDB’s integrated secret store and Flux’s new &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/stdlib/secrets/"&gt;secrets&lt;/a&gt; library.&lt;/p&gt;
&lt;h2&gt;Keep the keys to the kingdom secret&lt;/h2&gt;
&lt;p&gt;If you follow my multi-data source &lt;a href="https://w2.influxdata.com/blog/use-flux-to-group-shape-and-analyze-your-time-series-data/"&gt;Flux&lt;/a&gt; journey you have seen some exciting possibilities introduced by combining multiple data stores and time series analysis.  However, if you look closely at my &lt;a href="https://w2.influxdata.com/blog/using-flux-to-write-data-out-to-sql-data-stores/"&gt;SQL Flux&lt;/a&gt; scripts, you may notice something unsettling — the Flux to connect external data stores avoids usernames and passwords and is in plaintext.&lt;/p&gt;

&lt;p&gt;Simple data access methods when developing are acceptable, but when it comes to sensitive production data stores we all must be vigilant in protecting our information. Flux assists in this protection by integrating with secret stores to help you keep the secrets to your kingdom secret.&lt;/p&gt;
&lt;h2&gt;InfluxDB Cloud 2's secret store&lt;/h2&gt;
&lt;p&gt;Our InfluxDB Cloud 2 service is integrated with the industry-leading &lt;a href="https://www.vaultproject.io/"&gt;Vault&lt;/a&gt; secret store to provide every customer with a secure secret store. Users can store secrets, list their keys, and delete secrets using our fully documented &lt;a href="https://v2.docs.influxdata.com/v2.0/api/"&gt;API&lt;/a&gt;. As an example, these curl commands use an &lt;a href="https://v2.docs.influxdata.com/v2.0/organizations/view-orgs/#view-your-organization-id"&gt;organization’s ID&lt;/a&gt; and &lt;a href="https://v2.docs.influxdata.com/v2.0/security/tokens/create-token/"&gt;all access token&lt;/a&gt; to insert and retrieve secrets:&lt;/p&gt;

&lt;p&gt;Putting a secret into your secret store:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-bash"&gt;&amp;gt;curl --data '{"myuser_password": "my_password_value"}' --request PATCH --url https://us-west-2-1.aws.cloud2.influxdata.com/api/v2/orgs/&amp;lt;My_Org_ID&amp;gt;/secrets --header 'Authorization: Token &amp;lt;All_Access_Token&amp;gt;'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Listing out all the secret keys in Organization&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-bash"&gt;&amp;gt;curl --request GET --url https://us-west-2-1.aws.cloud2.influxdata.com/api/v2/orgs/&amp;lt;My_Org_ID&amp;gt;/secrets --header 'Authorization: Token &amp;lt;All_Access_Token&amp;gt;'&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Using secrets in Flux&lt;/h2&gt;
&lt;p&gt;My &lt;a href="https://w2.influxdata.com/blog/using-flux-to-write-data-out-to-sql-data-stores/"&gt;SQL.to() blog&lt;/a&gt; used this bit of Flux code to perform SQL insert magic:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-css"&gt;// Store result in Postgres
|&amp;gt; sql.to(driverName: "postgres", dataSourceName: "postgresql://localhost?sslmode=disable", table: "adjustment_billing")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Locally, that works, but a production example would use a user/password to write to a remote database with Flux:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-css"&gt;// Store result in remote Postgres database
	|&amp;gt; sql.to(driverName: "postgres", dataSourceName: "postgresql://myuser:mypass@127.0.0.1:5432/nisley?sslmode=disable", table: "sensor_billing")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without secrets, usernames and passwords are hardcoded in plaintext. Fortunately, we can leverage Cloud 2’s &lt;a href="https://www.vaultproject.io/"&gt;Vault&lt;/a&gt; to keep sensitive information safe. Here, I revamp the full fish tank vendor billing script to use the secret store for the actual password stored in myuser_password:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-css"&gt;import "sql"
import "influxdata/influxdb/secrets"

myuser_secret = secrets.get(key: "myuser_password")

from(bucket: "tank-health")
	|&amp;gt; range(start: -1w)
	|&amp;gt; filter(fn: (r) =&amp;gt; r._measurement == "water_sensor" and r.type == "adjustment")
	|&amp;gt; group(columns: ["type", "device_id"], mode:"by")
|&amp;gt; count(column: "change")
|&amp;gt; rename(columns: {change: "adjustment_actions"})
|&amp;gt; keep(columns: ["device_id", "adjustment_actions"])
|&amp;gt; sql.to(driverName: "postgres", dataSourceName: "postgresql://myuser:" + myuser_secret + "@127.0.0.1:5432/nisley?sslmode=disable", table: "adjustment_billing")&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;InfluxDB's common API and OSS&lt;/h2&gt;
&lt;p&gt;If you are developing on-premise with OSS instead of Cloud 2, don’t fret! One of our core tenets is to develop one common API across all products and services. The API examples above work with any local InfluxDB 2 OSS URLs:&lt;/p&gt;

&lt;p&gt;Get secrets from local OSS build:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-bash"&gt;&amp;gt;curl --request GET --url https://localhost:9999/api/v2/orgs/&amp;lt;My_Org_ID&amp;gt;/secrets --header 'Authorization: Token &amp;lt;All_Access_Token&amp;gt;'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that InfluxDB 2 OSS’s underlying key-value store is currently BoltDB. BoltDB is not focused on being a secret key-value store, so be mindful that if folks have access to the machine, values should not be considered secure.&lt;/p&gt;
&lt;h2&gt;Come explore Flux with us&lt;/h2&gt;
&lt;p&gt;Join us in exploring the new Secret packages in Flux by signing up for InfluxDB &lt;a href="https://w2.influxdata.com/products/influxdb-cloud-2-0/"&gt;Cloud 2&lt;/a&gt;, or use it locally with the &lt;a href="https://portal.influxdata.com/downloads/"&gt;latest OSS InfluxDB 2 alpha&lt;/a&gt;. As always, if you have questions or feature requests for Flux, head on over to &lt;a href="https://community.influxdata.com/c/fluxlang"&gt;Flux’s community forum&lt;/a&gt; and let us know!&lt;/p&gt;
</description>
      <pubDate>Tue, 22 Oct 2019 07:00:14 -0700</pubDate>
      <link>https://www.influxdata.com/blog/using-secret-stores-to-secure-flux-access/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/using-secret-stores-to-secure-flux-access/</guid>
      <category>Product</category>
      <category>Developer</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Using Flux to Write Data Out to SQL Data Stores</title>
      <description>&lt;p&gt;As discussed in &lt;a href="https://w2.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/"&gt;multi-data source Flux&lt;/a&gt;, Flux can now get data out of RDBMs with &lt;code class="language-markup"&gt;SQL.from()&lt;/code&gt; and use it to perform deeper analysis. In many cases, results from crunching data lend themselves naturally to time series storage. In others, the results are more appropriately leveraged on different data stores. In order to fulfill Flux’s general-purpose analysis engine vision, data must flow both into and out of InfluxDB.&lt;/p&gt;

&lt;p&gt;To that end, InfluxDB 2.0 Alpha 15 introduced &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/functions/sql/to/"&gt;SQL.to()&lt;/a&gt;. SQL.to() mirrors Flux’s ability to pull data out of a SQL store by enabling writes to MySQL, MariaDB, and Postgres. Below, I outline using &lt;code class="language-markup"&gt;SQL.to()&lt;/code&gt; and walk through an example of counting events and storing them into Postgres.&lt;/p&gt;

&lt;h2&gt;Tables make the world go round&lt;/h2&gt;

&lt;p&gt;Once I &lt;a href="https://w2.influxdata.com/blog/use-flux-to-group-shape-and-analyze-your-time-series-data/"&gt;understood that Flux results are truly just tables of data&lt;/a&gt;, I wondered how close a Flux result table was to an &lt;a href="https://en.wikipedia.org/wiki/Relational_model"&gt;RDBMs table&lt;/a&gt;. It turns out that they are close enough that Flux can leverage their kinship to make &lt;a href="https://www.influxdata.com/glossary/sql/"&gt;SQL&lt;/a&gt; writes exceedingly elegant.&lt;/p&gt;

&lt;p&gt;Once you shape and name your data to conform to the destination table definition, you simply pipe forward your data to &lt;code class="language-markup"&gt;SQL.to()&lt;/code&gt;. Let’s build up a use case for a new billing system to demonstrate this new functionality.&lt;/p&gt;
&lt;h2&gt;Fishtank health vendor - a new business model&lt;/h2&gt;
&lt;p&gt;My favorite fictional &lt;a href="https://w2.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/#fishtank"&gt;fish tank health vendor&lt;/a&gt; notices a large variation in the cost of supporting different customers. After studying their data closely, they learn costs are almost entirely driven by the number of corrective actions their automated water system performs. They decide to adjust their subscription model to one that charges customers for the number of weekly corrective events.&lt;/p&gt;

&lt;p&gt;Luckily, every time the devices deployed into their customers’ fish tanks take corrective action, like adjusting pH or nitrate levels, the devices send an event to InfluxDB. Events are similar to the stream of sensor data, except for being emitted on demand instead of every X seconds. These on-demand events are also known as “irregular time series” because they can occur at any time.&lt;/p&gt;

&lt;p&gt;The specific format and content of events can be anything you want, but let’s assume the events look like these two examples below (displayed in &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/line-protocol/"&gt;line protocol&lt;/a&gt;):&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;# Adjustment events - note timestamp will be added by InfluxDB at arrival time
water_sensor,type=adjustment,adjust_what=nitrates,change=up,device_id=TLM0101 triggering_value=5
water_sensor,type=adjustment,adjust_what=pH,change=down,device_id=TLM0102 triggering_value=9&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Why use a SQL data store?&lt;/h2&gt;
&lt;p&gt;The events are already in InfluxDB. Why introduce a SQL data store? There are several characteristics of a time series database that, generally speaking, do not make them an ideal foundation for a billing system.&lt;/p&gt;

&lt;p&gt;InfluxDB is designed to flexibly adjust to large volumes of data that change quite often, either due to endpoint changes or data variability because clients can do things like schema at write.  Often, users pour tens of millions of data points in very quickly but then downsample or delete most of them after a few weeks. This flexibility is great when you have, say, millions of different sensors or thousands of servers you constantly upgrade.&lt;/p&gt;

&lt;p&gt;In contrast, anyone trying to create a billing system wants to keep many years of stable customer billing data. While capturing the raw data at scale makes sense to store within a time series database like InfluxDB, the aggregated and processed data represents a “finished product” that may make more sense to store with other customer data such as billing address and telephone number. A relational database designed for stable, infrequent table changes could be a much better foundation for a billing system.&lt;/p&gt;
&lt;h2&gt;Come on already, crunch the numbers!&lt;/h2&gt;
&lt;p&gt;To collect the data for the new subscription billing model, our fish tank vendor decides to create a simple &lt;a href="https://v2.docs.influxdata.com/v2.0/process-data/get-started/"&gt;weekly task&lt;/a&gt; to count adjustments for each device and save them to their Postgres database. (Note: this naive scenario will not scale — at some large count of devices, both Postgres and InfluxDB will bottleneck. A more comprehensive approach might be to create a task per customer.)&lt;/p&gt;

&lt;p&gt;The first step for storing the adjustment count is to create a table in Postgres. Here is the Postgres SQL command I used to create a simple example table:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;CREATE TABLE adjustment_billing 
     (billing_record SERIAL PRIMARY KEY,  device_id VARCHAR NOT NULL, 
             adjustment_actions integer,  created_on TIMESTAMP);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Armed with a table to store results, the vendor begins to put together the pieces of the Flux script. We start by getting the last week of data from the tank-health bucket, filtering in only the adjustment events, and grouping the data:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;import "sql"

adjustmentActions = from(bucket: "tank-health")
  |&amp;gt; range(start: -1w)
  |&amp;gt; filter(fn: (r) =&amp;gt; r._measurement == "water_sensor" and r.type == "adjustment")
  |&amp;gt; group(columns: ["type", "device_id"], mode:"by")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="alignnone size-full wp-image-235824 aligncenter" src="/images/legacy-uploads/write-data-out-to-SQL-data-stores-with-flux-table-1.png" alt="Write data out to SQL data stores with Flux" width="628" height="171" /&gt;&lt;/p&gt;

&lt;p&gt;The result of grouping by type and device IDs is a table for every device. To get a count of adjustments for each device (table), we pipe forward the result to count the number of rows with a value in the change column:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// Count the number of changes for each device
  |&amp;gt; count(column: "change")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="alignnone size-full wp-image-235825 aligncenter" src="/images/legacy-uploads/write-data-out-to-SQL-data-stores-with-flux-table-2.png" alt="Write data out to SQL data stores with Flux - table 2" width="392" height="139" /&gt;&lt;/p&gt;

&lt;p&gt;Note that at this point, only the columns called out by grouping and the count are retained. (Technically, _start and _stop times exist, but they are dropped in the next step).&lt;/p&gt;

&lt;p&gt;This result is very close to the format of the SQL billing table we created, but it doesn’t quite line up and a final adjustment is required.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// Adjust the table to match the SQL destination schema/format
  |&amp;gt; rename(columns: {change: "adjustment_actions"})
  |&amp;gt; keep(columns: ["device_id", "adjustment_actions"])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="alignnone size-full wp-image-235826 aligncenter" src="/images/legacy-uploads/write-data-out-to-SQL-data-stores-with-flux-table-3.png" alt="Write data out to SQL data stores - with - Flux - table3" width="323" height="143" /&gt;&lt;/p&gt;

&lt;p&gt;Now, the data columns perfectly match the billing table, and the Flux script can simply store the result.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// Store result in Postgres
|&amp;gt; sql.to(driverName: "postgres", dataSourceName: "postgresql://localhost?sslmode=disable", table: "adjustment_billing")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After the task is saved and set to run weekly, the adjustment event counts for every device will be stored in Postgres. If you query Postgres directly with a “SELECT * from adjustment_billing” after a task runs, you can see the fruit of all your Flux labors.&lt;/p&gt;
&lt;h2&gt;Get started with Flux today&lt;/h2&gt;
&lt;p&gt;Hopefully, this example of using Flux to write data to a data store other than InfluxDB illustrates the power and flexibility of multi-data source Flux. I am excited to explore all the different possibilities multi-data source Flux is sure to open up over the next few months.&lt;/p&gt;

&lt;p&gt;Come join me in exploring Flux by signing up for InfluxDB &lt;a href="https://w2.influxdata.com/products/influxdb-cloud-2-0/"&gt;Cloud 2&lt;/a&gt; or by downloading the &lt;a href="https://portal.influxdata.com/downloads/"&gt;latest OSS alpha&lt;/a&gt;. As always, if you have questions or feature requests for Flux, head on over to &lt;a href="https://community.influxdata.com/c/fluxlang"&gt;Flux’s community forum&lt;/a&gt; and let us know!&lt;/p&gt;
</description>
      <pubDate>Wed, 28 Aug 2019 11:22:42 -0700</pubDate>
      <link>https://www.influxdata.com/blog/using-flux-to-write-data-out-to-sql-data-stores/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/using-flux-to-write-data-out-to-sql-data-stores/</guid>
      <category>Use Cases</category>
      <category>Developer</category>
      <category>Product</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Use Flux to Group, Shape, and Analyze Your Time Series Data</title>
      <description>&lt;p&gt;Flux is a programming language designed from the ground up for &lt;a href="https://www.influxdata.com/time-series-analysis-methods/"&gt;time series analysis&lt;/a&gt;. Traditionally, grouping, shaping, and performing mathematical operations across large dynamic time series datasets is cumbersome. Flux’s goal is to make it working with these datasets much more elegant.&lt;/p&gt;

&lt;p&gt;Several new exciting Flux features were added to the &lt;a href="https://www.influxdata.com/products/influxdb-overview/influxdb-2-0/"&gt;InfluxDB 2 OSS&lt;/a&gt; Alpha that compelled me to jump in with two feet to see how they would work in practice. My initial foray was promising, but something wasn’t quite right.&lt;/p&gt;
&lt;h2&gt;My key insight to understanding Flux&lt;/h2&gt;
&lt;p&gt;As I researched how to &lt;a href="https://www.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/"&gt;crunch data across multiple data stores&lt;/a&gt;, I quickly realized I was missing something fundamental. I kept getting unexpected answers and many of my graphs looked off.&lt;/p&gt;

&lt;p&gt;Looking for answers, I reached out to &lt;a href="https://www.linkedin.com/in/aanthony1243/"&gt;Adam Anthony on the Flux team&lt;/a&gt; and he walked me step- by-step through a more complex use case. After a few steps, it clicked — the key part I had to pay close attention to was table results.&lt;/p&gt;
&lt;h2&gt;Tables as data&lt;/h2&gt;
&lt;p&gt;The first few examples you encounter in Flux seem very straightforward. This is a typical first query you might see on system metrics collected by a local telegraf agent:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;from(bucket:"my-bucket")
  |&amp;gt; range(start: -10m)
  |&amp;gt; filter(fn: (r) =&amp;gt; r._measurement == "cpu" and r._field == "usage_system" and r.cpu != "cpu-total" )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Flux query pulls all of the data that a &lt;a href="https://docs.influxdata.com/telegraf/v1.11/"&gt;Telegraf&lt;/a&gt; agent wrote into my-bucket in the prior ten minutes and filters it down to cpu system usage metrics excluding cpu-total values.&lt;/p&gt;

&lt;p&gt;&lt;img class="alignnone wp-image-234925" src="/images/legacy-uploads/flux-time-series-data-dashboard.png" alt="Flux time series data - dashboard" width="1203" height="658" /&gt;&lt;/p&gt;

&lt;p&gt;When I saw the result of this query in my &lt;a href="https://www.influxdata.com/products/influxdb-cloud-2-0/"&gt;InfluxDB Cloud 2&lt;/a&gt; UI for the first time, I jumped to the conclusion that Flux simply returned four arrays — each with a litany of numbers. Turns out this initial impression was very wrong and the source of my missteps when trying to solve more complex scenarios.&lt;/p&gt;

&lt;p&gt;After Adam’s lessons, I realized that using and understanding Flux depended on understanding each part of the Flux results. Flux results are tables, and at times, results are a rather extensive set of tables. I learned that the most useful tool to lean on when stepping through Flux analysis is not the graphing tool, but the UI toggle to View Raw Data.&lt;/p&gt;

&lt;p&gt;&lt;img class="alignnone size-full wp-image-234928" src="/images/legacy-uploads/flux-time-series-data-dashboard-flux-results.png" alt="Flux time series data dashboard - Flux results" width="1158" height="795" /&gt;&lt;/p&gt;

&lt;p&gt;Raw view is exactly that — the complete raw output from Flux. When I first looked at raw view, I thought perhaps the UI was adding things like labels, timestamps, or expanded descriptions. In fact, the UI adds nothing to the result — every label, row, and column here is straight from the Flux response.&lt;/p&gt;

&lt;p&gt;Digging into the response, the easiest thing to overlook is the table column — the 3rd column in this example. The UI above is scrolled to display data from two tables (table 0 and table 1). We can see the above system cpu Flux query did not return four arrays at all, but rather four tables — one table for each of the four CPUs Telegraf is monitoring.&lt;/p&gt;

&lt;p&gt;As you manipulate, analyze, and shape your data, if you keep the fact that every in-between calculation and result is a table at the forefront of your mind, you will find yourself much closer to the answers you seek. The final example below walks through a more complex use case to demonstrate stepping towards an answer by focusing on tables.&lt;/p&gt;
&lt;h2&gt;Revisiting the fish tank health vendor&lt;/h2&gt;
&lt;p&gt;Let’s continue the use case of a &lt;a href="https://www.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/#fishtank"&gt;fish tank health vendor that stored IoT metadata in Postgres and sensor data in InfluxDB&lt;/a&gt;. In that example, the vendor wanted their customer success reps to know the pH balances of all the customer’s fish tanks. After a join, the table result looked like:&lt;/p&gt;

&lt;p&gt;&lt;img class="alignnone size-full wp-image-234930 aligncenter" src="/images/legacy-uploads/time-series-data-sensor-data-influxdb.png" alt="time series data - sensor data InfluxDB" width="995" height="336" /&gt;&lt;/p&gt;

&lt;p&gt;This result is simple enough for a customer success rep to read and digest, but add a couple of dozen tanks and sensors and reps will be swimming in data. To make it simpler, management realized what reps really need to know is the location of the fish tanks with a &lt;a href="https://www.wikihow.pet/Lower-the-pH-in-an-Aquarium"&gt;pH higher than 8&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, they are using Flux and can use the awesome built-in pipe forward operator to simply push the initial table result above into additional calculations to find the highest average pH.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;//  group by location so that we can analyze each location independently of the others. (creates 3 tables out of 1)
|&amp;gt; group(columns: ["customer_location"])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="alignnone size-full wp-image-234933 aligncenter" src="/images/legacy-uploads/flux-table-results.png" alt="Flux table results" width="995" height="572" /&gt;&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// find the mean value inside of each table
 |&amp;gt; mean(column: "_value")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="size-full wp-image-234939 aligncenter" src="/images/legacy-uploads/flux-table-results-mean-value.png" alt="Flux table results mean value" width="995" height="506" /&gt;&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// grouping by no columns puts all of the tables together into one table
|&amp;gt; group(columns: [])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="alignnone wp-image-234935 aligncenter" src="/images/legacy-uploads/flux-group-by-no-columns.png" alt="" width="1013" height="256" /&gt;&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// filter out all rows of data below a value of 8
|&amp;gt; filter(fn: (r) =&amp;gt; r._value &amp;gt;  8)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class=" wp-image-234936 aligncenter" src="/images/legacy-uploads/flux-filter-rows.png" alt="Flux - filter rows" width="1014" height="211" /&gt;&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;// sort the list to ensure the highest priority fish tanks are at the top of the list
|&amp;gt; sort(columns: ["_value"], desc: true)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img class="alignnone size-full wp-image-234937 aligncenter" src="/images/legacy-uploads/flux-sort-columns.png" alt="Flux - sort columns" width="995" height="207" /&gt;&lt;/p&gt;

&lt;p&gt;After crunching and filtering all the data, the customer success rep should have a manageable list of fish tanks to focus on.  In this case, at the top of the list is the Lobby fish tank, which looks like it needs some serious attention.&lt;/p&gt;
&lt;h2&gt;Flux's future is bright&lt;/h2&gt;
&lt;p&gt;Flux is starting to hit its stride as many powerful features such as conditionals and multi-data stores are released. Now is a great time to jump in and have a close look at Flux if you are tackling any time series analysis use cases. Easily get started by signing up for InfluxDB &lt;a href="https://www.influxdata.com/products/influxdb-cloud-2-0/"&gt;Cloud 2&lt;/a&gt;, or by downloading the &lt;a href="https://portal.influxdata.com/downloads/"&gt;latest OSS alpha&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As always, if you have questions or feature requests for Flux, head on over to &lt;a href="https://community.influxdata.com/c/fluxlang"&gt;Flux’s community forum&lt;/a&gt; and let us know.&lt;/p&gt;
</description>
      <pubDate>Mon, 29 Jul 2019 08:00:39 -0700</pubDate>
      <link>https://www.influxdata.com/blog/use-flux-to-group-shape-and-analyze-your-time-series-data/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/use-flux-to-group-shape-and-analyze-your-time-series-data/</guid>
      <category>Product</category>
      <category>Developer</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
    <item>
      <title>Multi-Data Source Flux Introduced in InfluxDB 2 Alpha 14</title>
      <description>&lt;p&gt;As our co-founder Paul wrote extensively in &lt;a href="https://w2.influxdata.com/blog/influxdb-2-0-alpha-release-and-the-road-ahead/"&gt;InfluxDB 2.0’s Alpha Release announcement&lt;/a&gt;, we believe Flux will play an important role in combining time series data with many different data sources. Flux’s first official multi-data store step is InfluxDB 2.0 Alpha 14’s &lt;code class="language-markup"&gt;&lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/functions/sql/from/"&gt;from SQL&lt;/a&gt;&lt;/code&gt; release. This Flux addition is significant given the increasing number of data stores and the need to cater to them.&lt;/p&gt;
&lt;h2&gt;It's a multi-data store world&lt;/h2&gt;
&lt;p&gt;Years ago, as a consultant for &lt;a href="https://en.wikipedia.org/wiki/Wily_Technology"&gt;Wily Technology&lt;/a&gt; during the nascent &lt;a href="https://en.wikipedia.org/wiki/Application_performance_management"&gt;APM&lt;/a&gt; industry explosion, I dealt with hundreds of applications in varying states of distress. Time and again, I would see applications ignoring the nature of their particular data, which invariably led to slowdowns and errors from data stores that were abused in ways they simply were not suited for.&lt;/p&gt;

&lt;p&gt;As different application datasets scale, they are imbued with characteristics that make them suitable for specific data store handlers. Working with, storing, and processing each dataset with tools and storage mechanisms built specifically for them results in well-built systems that are maintainable and scale with growth.&lt;/p&gt;

&lt;p&gt;Here are some examples of different datasets and data store types built for them:&lt;/p&gt;
&lt;ul&gt;
 	&lt;li&gt;Relational data like an e-commerce store's inventory, customer orders, and customer data and their relationships are best handled by an RDBMS system built to model that relationship.&lt;/li&gt;
 	&lt;li&gt;Asset information related to IoT devices is finding great success with specialized data stores like &lt;a href="https://www.ibm.com/products/maximo"&gt;IBM's Maximo&lt;/a&gt; and &lt;a href="https://news.sap.com/2018/11/sap-intelligent-asset-management-insight-optimization/" target="_blank" rel="noopener noreferrer"&gt;SAP's Intelligent Asset Management&lt;/a&gt;. Asset metadata is available via an exposed integration API from these applications.&lt;/li&gt;
 	&lt;li&gt;Dependency data such as business processes, integrated applications, and underlying network topology is best handled by a [graph database](https://www.influxdata.com/graph-database/)&lt;/li&gt;
 	&lt;li&gt;Time series data such as the millions of streaming data points from stacks, sensors and systems are best handled by a time series database.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the distant past, some argued using different data stores put too much strain on programmers to learn different data tools. Before today’s widespread and uniform API use that may have been true. But nowadays, developers are quite comfortable using data source drivers and APIs to pull data from different places to mold them together.&lt;/p&gt;

&lt;p&gt;Relying on developers to shape and crunch data works great for purpose-built custom software solving specific problems. But there are never enough developers to go around, and general-purpose data analytics and visualization tools have proven their value for many analysts and data scientists. Single data source analytic tools work at times, but analysts often want to merge data from different data stores and frequently find pulling data sources together is a monumental task.&lt;/p&gt;

&lt;p&gt;Providing a tool to flexibly merge together data sources and analyze them across time is one of Flux’s primary use cases. Open source Flux is meant to empower every query and visualization tool so that they may bring together related data sets to generate insights using a common, powerful and unified language.&lt;/p&gt;
&lt;h2&gt;Using time series data with data from SQL data stores&lt;/h2&gt;
&lt;p&gt;Flux’s first implementation of a function that can extract data out of non-InfluxDB data stores is &lt;a href="https://w2.influxdata.com/blog/release-announcement-influxdb-2-0-0-alpha-14/"&gt;InfluxDB 2.0 Alpha 14’s&lt;/a&gt; &lt;a href="https://v2.docs.influxdata.com/v2.0/reference/flux/functions/sql/from/"&gt;SQL.from()&lt;/a&gt; function. Let’s dive into a specific IoT use case to explore this function.&lt;/p&gt;
&lt;h3&gt;IoT asset data store&lt;/h3&gt;
&lt;p&gt;Recently, I have had several InfluxDB deep dives with customers using InfluxDB in IoT use cases. These IoT practitioners have tens of thousands of devices and sensors streaming all the data they capture into InfluxDB, and dealing with all that data presents some unique challenges.&lt;/p&gt;

&lt;p&gt;Without a way to connect different data stores, many IoT practitioners reuse all their metadata as tags on their time series metrics so they can crunch metadata-based time series analysis such as:&lt;/p&gt;

&lt;p&gt;“What is the error rate reported over the last day for each device type?”&lt;/p&gt;

&lt;p&gt;Of course, prior to SQL.from(), the only way to have InfluxDB answer that question is to add device type as a tag to every time-series metric coming from their sensors.&lt;/p&gt;

&lt;p&gt;This works ok but has issues reacting to changes in metadata sets over time. For example, if an IoT device maker initially tags time series metrics with a certain security classification but the classification changes, only new data shows up when querying with the new classification as the old data has the old value in the tag.&lt;/p&gt;

&lt;p&gt;A better solution is a clean separation of data by keeping metadata in a relational store and time-series data in InfluxDB. The key to making a two data store solution work is a Flux language that can seamlessly query both time series data and relational data.&lt;/p&gt;
&lt;div id="fishtank"&gt;
&lt;h4&gt;Fishtank health service vendor&lt;/h4&gt;
To flesh out an example, let's suppose there is a vendor that provides a service for automatically monitoring and adjusting customer fish tank water health. This vendor leases thousands of IoT devices that &lt;a href="https://docs.influxdata.com/telegraf/v1.11/plugins/plugin-list/#neptune_apex"&gt;monitor many aspects of fishtank water&lt;/a&gt; and streams their data to InfluxDB.  In this example, instead of tagging the streaming metrics with all the metadata, the vendor tags every metric with only the unique device ID the data originates from.

The ID ties the device's metrics to sensor metadata that might include information such as the device type, purchaser's customer id, installation street city and state, device revision number, device name, etc. Our fishtank vendor has implemented a homegrown asset tracker in a MySQL database to keep track of all this relational information.

Many of this vendor's customers are large corporate customers with dozens of fish tanks.  Whenever a customer calls, it's very important for their customer success representative to know the pH balance of their customer's fish tanks over the last hour and where they are located.

Here is what a Flux script might look like for finding one customer's fishtank pH balances:
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;import "sql"

phBalances = from(bucket: "PH_Balances")
  |&amp;gt; range(start: now-60)
  |&amp;gt; filter(fn: (r) =&amp;gt; r._measurement == "water_sensor" )

deviceIds = sql.from(driverName: "mysql", dataSourceName: "username:password@tcp(host)/dbname", query: "SELECT customer_name, customer_location, device_id AS device FROM DeviceTable WHERE customer_name = 'InfluxData'")

join(tables: {t1: phBalances, t2: deviceIds}, on: ["device"])
	|&amp;gt; aggregateWindow(every: v.windowPeriod, fn: mean)
 	 |&amp;gt; yield(name: "mean")&lt;/code&gt;&lt;/pre&gt;
This result of this script is a table that might look like this:

&lt;a href="/images/legacy-uploads/data-table.svg"&gt;&lt;img class="aligncenter size-full wp-image-234400" role="img" src="/images/legacy-uploads/data-table.svg" alt="" width="995" height="336" /&gt;&lt;/a&gt;

The data in green is from MySQL, the orange data is from InfluxDB, and the blue data is the joined data in both data stores.

Several things to note from this simple example:

First, this is a very naive example as the first query that builds the phBalances table pulls the entire data set from InfluxDB.  There is an implicit dropping of data when the two data tables join on device id. However, until the join completes, the whole dataset is in query memory and it is easy to imagine tens of millions of datapoints overwhelming all available memory.

Second, there is no special need for a join per se. What we are really trying to do is filter down the pH Balances data set to a subset of metrics I am interested in. The Flux team has several initiatives underway that simplify these kinds of queries so I can directly use the SQL result in a filter.

Lastly, the example Flux script is all low-level SQL and Flux. It requires a user to piece together their own rather complete prior knowledge of the data stores. Flux's long-term plan is to deliver libraries and tooling that could ease low-level knowledge prerequisites and provide a more approachable experience; for example, ORM tooling or data store visualizations to help users identify, merge, and shape their data and analysis.
&lt;h2&gt;The multi-data store road ahead&lt;/h2&gt;
Flux has entered an exciting new chapter as a multi-data store time-series-focused programming language with the debut of &lt;code class="language-markup"&gt;SQL.from()&lt;/code&gt;. This initial SQL release enables pulling data from MySQL and Postgres, but we have a long list of data stores we would like to pull data from and write data to.

The list of possible connectors on the Flux team's radar is long and dynamic. High on the list are &lt;a href="https://www.sqlite.org/index.html"&gt;SQLite&lt;/a&gt;, &lt;a href="https://www.microsoft.com/en-us/sql-server/default.aspx"&gt;MS SQL Server&lt;/a&gt;, connectors for our &lt;a href="https://cloud.google.com/blog/products/open-source/bringing-the-best-of-open-source-to-google-cloud-customers"&gt;open source Google Cloud Compute partners&lt;/a&gt; and, of course, for Google's data sources as well such as BigQuery.

But we want to hear from you — what top data sources do you want Flux to connect to? Head over to &lt;a href="https://community.influxdata.com/c/fluxlang"&gt;Flux's community forum&lt;/a&gt; and let us know!

&lt;/div&gt;
</description>
      <pubDate>Thu, 18 Jul 2019 07:00:31 -0700</pubDate>
      <link>https://www.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/multi-data-source-flux-introduced-in-influxdb-2-alpha-14/</guid>
      <category>Product</category>
      <category>Developer</category>
      <author>Nate Isley (InfluxData)</author>
    </item>
  </channel>
</rss>
