<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>InfluxData Blog - Jonathan Sternberg</title>
    <description>Posts by Jonathan Sternberg on the InfluxData Blog</description>
    <link>https://www.influxdata.com/blog/author/jonathan-sternberg/</link>
    <language>en-us</language>
    <lastBuildDate>Mon, 01 Nov 2021 10:13:06 -0700</lastBuildDate>
    <pubDate>Mon, 01 Nov 2021 10:13:06 -0700</pubDate>
    <ttl>1800</ttl>
    <item>
      <title>Time Zones in Flux</title>
      <description>&lt;p&gt;As a language for processing time series data, &lt;a href="https://www.influxdata.com/products/flux/"&gt;Flux&lt;/a&gt; has an important role in how we understand that data. As we create and process data, we do it for ourselves and others.&lt;/p&gt;

&lt;p&gt;The concept of time and how we as people interact with time isn’t always simple. Most of us have to adjust our schedules at least twice a year because of daylight savings time, and sometimes we have to adjust our clocks in more complex ways because — for important political, cultural, or economic reasons — we need to have our clocks read a certain time such as &lt;a href="https://www.bbc.com/news/world-asia-16351377"&gt;skipping a day&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Flux before time zone support&lt;/h2&gt;
&lt;p&gt;Flux is a language for time series data and, until recently, Flux wasn’t able to understand these subtleties. Flux would do all of its work in UTC, which is a simple linear clock, and leave it to the user to figure out the display. This works well for most circumstances! It’s what Flux should be doing! Flux shouldn’t be involved in figuring out the correct way to display the time zone. The InfluxDB UI is very capable of figuring that out better than Flux would ever be able to. In situations like monitoring servers, UTC is perfect and should be used over a specific time zone.&lt;/p&gt;

&lt;p&gt;But…what happens when we start to aggregate data for other purposes? What if I want to aggregate by days, weeks, or months and I want these aggregations to be in my own time zone for a business reason? I don’t live in the UK and, even if I did, the UK isn’t on UTC time the entire year anyway. I can just pretend and remember that my aggregations aren’t 100% accurate all the time and they are “good enough”. Sometimes “good enough” isn’t good enough. In those, I can get closer by using an offset to shift the time to my time zone. But, when daylight savings time happens, I might be back to “good enough” aggregation by time.&lt;/p&gt;
&lt;h2&gt;Time zone support in Flux&lt;/h2&gt;
&lt;p&gt;Flux now features full time zone support for those who need to perform their aggregations within a specific time zone.&lt;/p&gt;

&lt;p&gt;To enable time zones, import the &lt;code class="language-javascript"&gt;timezone&lt;/code&gt; package and set the &lt;code class="language-markup"&gt;location&lt;/code&gt; option to your location…By default, Flux uses the UTC time zone.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;import "timezone"

option location = timezone.location(name: "America/Los_Angeles")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After setting the &lt;code class="language-javascript"&gt;location&lt;/code&gt; option, the &lt;code class="language-javascript"&gt;window()&lt;/code&gt; and &lt;code class="language-javascript"&gt;aggregateWindow()&lt;/code&gt; functions become location-aware and utilize dynamic offsets to account for the clock moving forwards or backwards. In this way, you can use either of the following in your query:&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;from(bucket: "mybucket")
  |&amp;gt; range(start: -1y)
  |&amp;gt; filter(fn: ...)
  |&amp;gt; aggregateWindow(every: 1mo, fn: mean)

from(bucket: "mybucket")
  |&amp;gt; range(start: -1mo)
  |&amp;gt; filter(fn: ...)
  |&amp;gt; aggregateWindow(every: 1d, fn: mean)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both of these will always result in the time starting and stopping at midnight in the time zone specified.&lt;/p&gt;

&lt;p&gt;When the clock skips forward or moves backwards, the time window will either shrink or stretch to accommodate the change in offset.&lt;/p&gt;

&lt;p&gt;For parity, a fixed offset can also be specified in the location option.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;import "timezone"

option location = timezone.fixed(offset: -8h)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This sets the time zone with a fixed offset of -8h. This fixed offset works the same as UTC, but midnight will always be 8 hours after midnight in UTC.&lt;/p&gt;

&lt;p&gt;In a more complex situation, we might need to mix time zones or only use time zones for a single call to a window function. We can use parameters for that rather than a global option.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;import "timezone"

option location = timezone.location(name: "America/Los_Angeles")

from(bucket: "mybucket")
  |&amp;gt; range(start: -1y)
  |&amp;gt; filter(fn: ...)
  |&amp;gt; aggregateWindow(
    every: 1h,
    fn: mean,
    timeSrc: "_start",
    location: timezone.utc, // overrides the global option to use utc
  )
  |&amp;gt; aggregateWindow(every: 1w, fn: max) // global option is used&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We hope that this feature will enable many new use cases for processing time series data in Flux.&lt;/p&gt;
</description>
      <pubDate>Mon, 01 Nov 2021 10:13:06 -0700</pubDate>
      <link>https://www.influxdata.com/blog/time-zones-in-flux/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/time-zones-in-flux/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <author>Jonathan Sternberg (InfluxData)</author>
    </item>
    <item>
      <title>Aggregating by Months or Years in InfluxDB with Flux</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/influxdata/flux/commit/518f442bed2aa7298e055915a54bebd231831db9"&gt;Over a year ago&lt;/a&gt;, we made our first commit and commitment to supporting &lt;a href="https://github.com/influxdata/influxdb/issues/3991"&gt;a much wanted and needed feature for Flux&lt;/a&gt;. It was a feature that we have wanted as far back as the 1.x versions of InfluxDB, but it was one we were never able to implement as part of the database. Until now.&lt;/p&gt;

&lt;p&gt;Recently, we merged and deployed a change to the Flux language to support months and years as special intervals when windowing. Today, I am going to show you how you can use this feature and the power it can help bring to analyzing your data.&lt;/p&gt;

&lt;p&gt;This demo uses the NOAA sample dataset located &lt;a href="https://docs.influxdata.com/influxdb/v1.7/query_language/data_download/#download-and-write-the-data-to-influxdb"&gt;here&lt;/a&gt;. I modified the input slightly to remove the lines related to 1.x and used curl to write the data to a new bucket. I then wrote the following code in Flux.&lt;/p&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-javascript"&gt;from(bucket: "NOAA")
	    |&amp;gt; range(start: 2015-08-01T00:00:00Z, stop: 2015-10-01T00:00:00Z)
	    |&amp;gt; filter(fn: (r) =&amp;gt; r._measurement == "h2o_feet" and r._field == "water_level")
	    |&amp;gt; aggregateWindow(every: 1mo, fn: mean)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And it worked! When I ran this query, I get two points per series. One of them gives me the mean for the month of August and one gives me the mean for the month of September. But this doesn’t only apply to 1 month. I can also use &lt;code class="language-ini"&gt;1y&lt;/code&gt; to aggregate across years and it will account for leap years. If I wanted to aggregate how many requests happened each quarter, I would just use &lt;code class="language-ini"&gt;3mo&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;We hope that this feature will help people to better understand their data and we hope to continue expanding the functionality of Flux to help enable a better understanding of data.&lt;/p&gt;
</description>
      <pubDate>Mon, 02 Dec 2019 13:54:57 -0700</pubDate>
      <link>https://www.influxdata.com/blog/aggregating-by-months-or-years-in-flux/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/aggregating-by-months-or-years-in-flux/</guid>
      <category>Use Cases</category>
      <category>Developer</category>
      <category>Product</category>
      <author>Jonathan Sternberg (InfluxData)</author>
    </item>
    <item>
      <title>InfluxData Docker on ARM</title>
      <description>&lt;p&gt;In the beginning, Docker only supported amd64 and only ran on Linux. Later, Docker started supporting different architectures like Windows 64-bit and ARM. You could run Docker on these platforms, but the image support has been a work in progress. For a long time, some images would create a fork that supported &lt;a href="https://github.com/armhf-docker-library"&gt;armhf&lt;/a&gt;, but then you would have a separate tag for the armhf architecture. Since the default for Docker is to pull the &lt;code&gt;latest&lt;/code&gt; tag, running something like &lt;code&gt;docker pull ubuntu&lt;/code&gt;wouldn’t pull the correct architecture.&lt;/p&gt;

&lt;p&gt;Docker recently created a new &lt;a href="https://docs.docker.com/registry/spec/manifest-v2-2/"&gt;manifest&lt;/a&gt; format for the registry that allows for multiple images of different architectures to share the same tag. One of our users, @longquan, made a pull request on our Docker images offering a method to have a single Dockerfile build multiple architectures. We adapted this pull request and, with the additional help of @jcberthon, we merged support for ARMv7 32-bit and ARMv8 64-bit.&lt;/p&gt;

&lt;p&gt;That means the InfluxData stack can be run with Docker out of the box on platforms like the Raspberry Pi. This is perfect if you want a cheap and easy computer to set up for monitoring something in your home! In this post, we are going to run InfluxDB on our own laptop and configure a Telegraf instance to report to our laptop over a local network.&lt;/p&gt;
&lt;h2&gt;What You Will Need&lt;/h2&gt;
&lt;ul&gt;
 	&lt;li&gt;The Raspberry Pi&lt;/li&gt;
 	&lt;li&gt;A computer (such as a laptop)&lt;/li&gt;
 	&lt;li&gt;A router with both computers being connected to the same router&lt;/li&gt;
 	&lt;li&gt;An internet connection&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Install Docker on the Laptop&lt;/h3&gt;
&lt;p&gt;Install Docker on your laptop using the appropriate method from the &lt;a href="https://docs.docker.com/engine/installation/"&gt;Docker Documentation&lt;/a&gt;. I am using Mac OS X, so I am using &lt;code&gt;docker-machine&lt;/code&gt; as a virtual machine.&lt;/p&gt;

&lt;p&gt;Once you have installed Docker on your computer, verify it works by using &lt;code&gt;ping&lt;/code&gt; and then pulling down the InfluxDB image.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;$ docker ping
$ docker pull influxdb&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We can now run InfluxDB and Chronograf on our laptop with few simple commands.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;# Create a shared network for influxdb and chronograf to communicate over.
$ docker network create influxdb
# Launch the influxdb image.
$ docker run -d --name=influxdb --net=influxdb -p 8086:8086 influxdb
# Launch the chronograf image.
$ docker run -d --name=chronograf --net=influxdb -p 8888:8888 chronograf --influxdb-url http://influxdb:8086&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We create a shared network for influxdb and chronograf to communicate over. While it looks complicated, this simplifies networking the two containers. We then launch each one of the images using this network and expose the ports that need to be exposed to the outside world. For InfluxDB, this is port 8086. For Chronograf, this is 8888. Now, try visiting Chronograf using your computer’s web browser. If you are running Docker natively on your computer, this should be as simple as going to &lt;a href="http://localhost:8888/" rel="nofollow"&gt;http://localhost:8888&lt;/a&gt;. If you are using &lt;code&gt;docker-machine&lt;/code&gt; (such as on Mac OS X), you can use the https://github.com/jsternberg/docker-machine-proxy I created for this demo. It will proxy ports from the Docker Machine to localhost so internetwork connections between computers work correctly.&lt;/p&gt;

&lt;p&gt;When this is working and you are able to access Chronograf at localhost, you should see the Chronograf dashboard and Chronograf should say that no hosts were found.&lt;/p&gt;

&lt;p&gt;Before we add a host, there is one more thing we must do.&lt;/p&gt;
&lt;h3&gt;Retrieve the IP Address&lt;/h3&gt;
&lt;p&gt;Retrieve the IP address that your router gave you for your computer. If you are on Linux or Mac OS X, you can use &lt;code&gt;ifconfig&lt;/code&gt;. Here is an example of my output:&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;&amp;gt; ifconfig
lo0: flags=8049&amp;lt;UP,LOOPBACK,RUNNING,MULTICAST&amp;gt; mtu 16384
        options=1203&amp;lt;RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP&amp;gt;
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
        nd6 options=201&amp;lt;PERFORMNUD,DAD&amp;gt;
gif0: flags=8010&amp;lt;POINTOPOINT,MULTICAST&amp;gt; mtu 1280
stf0: flags=0&amp;lt;&amp;gt; mtu 1280
en0: flags=8863&amp;lt;UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST&amp;gt; mtu 1500
        ether ac:bc:32:cd:96:f3
        inet6 fe80::1c:121a:e9d5:fe98%en0 prefixlen 64 secured scopeid 0x4
        inet6 2605:6000:1522:c065:854:a83:ba74:7e05 prefixlen 64 autoconf secured
        inet6 2605:6000:1522:c065:9c91:edf6:d09a:e266 prefixlen 64 autoconf temporary
        inet 192.168.1.113 netmask 0xffffff00 broadcast 192.168.1.255
        nd6 options=201&amp;lt;PERFORMNUD,DAD&amp;gt;
        media: autoselect
        status: active
en1: flags=963&amp;lt;UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX&amp;gt; mtu 1500
        options=60&amp;lt;TSO4,TSO6&amp;gt;
        ether 6a:00:01:52:70:20
        media: autoselect &amp;lt;full-duplex&amp;gt;
        status: active&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;en0&lt;/code&gt; interface is the only one that looks like it has an IP address so we will use &lt;code&gt;192.168.1.113&lt;/code&gt; for this example. For your own computer, you need to use your own IP address! I am running this command on Mac OS X so the name of the interface may be different if you are using another operating system. On Windows computers, you can use &lt;code&gt;cmd.exe&lt;/code&gt; and &lt;code&gt;ipconfig&lt;/code&gt; to find your local IP address.&lt;/p&gt;

&lt;p&gt;Remember, you want the IP address given to the computer by your router. You do not want your public IP address to the internet itself. Most home networks have their networks start with &lt;code&gt;192.168.*.*&lt;/code&gt;, but some may also start with &lt;code&gt;10.*.*.*&lt;/code&gt; or &lt;code&gt;172.*.*.*&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Boot Your Raspberry Pi&lt;/h3&gt;
&lt;p&gt;Connect your Raspberry Pi to your router. If you have never installed an operating system, I suggest &lt;a href="https://www.raspberrypi.org/software/" target="_blank" rel="noopener noreferrer"&gt;Raspbian&lt;/a&gt;. It’s easy to install and use and the one I used for this article.&lt;/p&gt;

&lt;p&gt;You can then run the following to install Docker. First, download the script that Docker offers for making things easy.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;$ curl https://get.docker.com &amp;gt; get-docker.sh
$ sudo bash get-docker.sh&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;After this command finishes, you will see a message like this in the output:&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:

  sudo usermod -aG docker pi
  
Remember that you will have to log out and back in for this to take effect!&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There will be more and a warning. If you are planning to use this in production and security is something you must consider, it might be best to skip this step. For our purposes, we are going to enter the above command so we don’t have to type &lt;code&gt;sudo&lt;/code&gt;in front of the &lt;code&gt;docker&lt;/code&gt; commands. Run the above command and then reboot your Raspberry Pi.&lt;/p&gt;

&lt;p&gt;After the Pi is back up and running, open the Terminal again and run the following:&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;$ docker run --rm telegraf telegraf config &amp;gt; telegraf.conf&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You just ran Telegraf on your Raspberry Pi for the first time! But we’re not quite done. We generated a configuration file. Open &lt;code&gt;telegraf.conf&lt;/code&gt; and go to the &lt;code&gt;[[outputs.influxdb]]&lt;/code&gt; section. It should look like this:&lt;/p&gt;
&lt;div class="highlight highlight-source-toml"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;[[outputs.influxdb]]
  ## The HTTP or UDP URL for your InfluxDB instance.  Each item should be
  ## of the form:
  ##   scheme "://" host [ ":" port]
  ##
  ## Multiple urls can be specified as part of the same cluster,
  ## this means that only ONE of the urls will be written to each interval.
  # urls = ["udp://localhost:8089"] # UDP endpoint example
  urls = ["http://localhost:8086"] # required
  ## The target database for metrics (telegraf will create it if not exists).
  database = "telegraf" # required&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Modify the &lt;code&gt;urls&lt;/code&gt; option so it looks like this, but replaced with your own IP address that we found earlier:&lt;/p&gt;
&lt;div class="highlight highlight-source-toml"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;[[outputs.influxdb]]
  ## The HTTP or UDP URL for your InfluxDB instance.  Each item should be
  ## of the form:
  ##   scheme "://" host [ ":" port]
  ##
  ## Multiple urls can be specified as part of the same cluster,
  ## this means that only ONE of the urls will be written to each interval.
  # urls = ["udp://localhost:8089"] # UDP endpoint example
  urls = ["http://192.168.1.13:8086"] # required
  ## The target database for metrics (telegraf will create it if not exists).
  database = "telegraf" # required&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now we need to execute Telegraf using our custom configuration file.&lt;/p&gt;
&lt;div class="highlight highlight-text-shell-session"&gt;
&lt;pre class="line-numbers"&gt;&lt;code class="language-markup"&gt;$ docker run -d --name=telegraf -v $PWD/telegraf.conf:/etc/telegraf/telegraf.conf:ro telegraf&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now wait a bit. If you want to check if Telegraf is working, you can use &lt;code&gt;docker logs -f telegraf&lt;/code&gt; and it will follow along with the log messages. You might need to refresh the Chronograf page. If all goes well, you should see your Raspberry Pi and metrics coming in from the container on the Raspberry Pi!&lt;/p&gt;

&lt;p&gt;While this demo showed how to use Telegraf on the Raspberry Pi, all of the InfluxData products now support running them with Docker on ARM.&lt;/p&gt;
&lt;h3&gt;Help and Caveats&lt;/h3&gt;
&lt;p&gt;For those who are using an older ARM architecture without native float support, &lt;code&gt;docker pull&lt;/code&gt; will not work. This is because multiple architecture support in Docker is still ongoing. When pulling from an ARM 32-bit (&lt;code&gt;armhf&lt;/code&gt;), it may pull down the version built with emulated floating point support (&lt;code&gt;armel&lt;/code&gt;). Because of this limitation, the Dockerfiles support building on &lt;code&gt;armel&lt;/code&gt;, but we do not upload these images to the official repository. If you need to use the Docker images and have &lt;code&gt;armel&lt;/code&gt;as your architecture, you can build the images from source &lt;a href="https://github.com/influxdata/influxdata-docker"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To determine which architecture you have, you can run &lt;code&gt;dpkg --print-architecture&lt;/code&gt;. If you see &lt;code&gt;armhf&lt;/code&gt;, that’s the one that is uploaded and we support. If you see &lt;code&gt;armel&lt;/code&gt;, that’s the one you need to build from source.&lt;/p&gt;

&lt;p&gt;For those who need help, please visit our &lt;a href="https://community.influxdata.com/" target="_blank" rel="noopener noreferrer"&gt;https://community.influxdata.com&lt;/a&gt; website. If you think something isn’t working correctly with the images, please file a bug in the &lt;a href="https://github.com/influxdata/influxdata-docker"&gt;repository&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Tue, 26 Sep 2017 05:34:12 -0700</pubDate>
      <link>https://www.influxdata.com/blog/influxdata-docker-arm/</link>
      <guid isPermaLink="true">https://www.influxdata.com/blog/influxdata-docker-arm/</guid>
      <category>Product</category>
      <category>Use Cases</category>
      <category>Developer</category>
      <category>Company</category>
      <author>Jonathan Sternberg (InfluxData)</author>
    </item>
  </channel>
</rss>
