Pravin Kumar Sinha
Pravin is a Python developer and training consultant at Minh, Inc., in Bangalore, India, with 22 years of experience in object-oriented technology, mostly in C++, Qt/Qml, Python.

While relational database management systems (RDBMS) are efficient with storing tables, columns, and primary keys in a spreadsheet architecture, they become inefficient when there’s a lot of data input received over a long period of time.

Databases designed specifically to store time-series data are known as time-series databases (TSDB).

For example, an RDBMS might look like this:

In a TSDB, data is categorized in measurements. A measurement is a container, roughly equivalent to a table in RDBMS, which contains tuples of time and field data. Each entry is a tuple of (time, field data) and is recognized as a point. A point can optionally include a string tag.

A TSDB might look more like this:

The sample TSDB shown above stores temperature (measurement) and value (field data) measured across various cities (tag) during a range of time (timestamp), measured through devices (tag) manufactured from more than one company.

But TSDBs can facilitate the continuous monitoring of a variety of data, like IoT sensors, market trading data, and stock exchange data. This article shows you how to set up, configure, connect, write, and query an InfluxDB database using a C++ library.

InfluxDB is an open source time-series database built to handle high write and read/query timestamped data loads. In addition to providing a constant stream of data, like server metrics or application monitoring, InfluxDB also provides events generation, real-time analytics, automatic expiration and deletion of backed-up stored data, and easy ways to forecast and analyze time series data.

You’ll learn how to store real IoT sensor data in an InfluxDB database and then analyze the stored data as a block of time period samples. We’ll finish off by plotting the data in a graph.

Setting Up the InfluxDB Server

This tutorial is set up on Ubuntu 20.04 LTS, but you can find other installation support in InfluxDB’s documentation. You can follow along with the source code for this tutorial here.

systemctl status influxdb should show the running status:

The InfluxDB server version for this tutorial is 1.6.4. You can get more information about server configuration by running $influxd, and tweak your configuration with /etc/influxdb/influxdb.conf.

Setting Up the influxdb-cxx C++ Client Library

This tutorial uses the influxdb-cxx client library, version 0.6.7, to connect, populate, and query the InfluxDB server. The InfluxDB server is listening at IP address 127.0.0.1 and at TCP port 8086.

Prerequisites

As mentioned earlier, this tutorial is set up on Ubuntu 20.04 LTS. The rest of the software dependency list is as follows:

  • C++ 17 compiler. You can install g++ 9.3.0 through sudo apt-get install g++.
  • CMake 3.12+ tool. You can install CMake 3.16.3 through sudo apt-get install cmake.
  • Curl library. You can install curl4-openssl through sudo apt-get install libcurl4-openssl-dev.
  • Boost 1.57+ library (optional). Install Boost 1.71 c through sudo apt-get install libboost1.71-all-dev.

Get the influxdb-cxx Client Library

Create a new directory and execute the following command:

Build the influxdb-cxx Client Library

When the testing suite is not required, you can set the following options to OFF while running cmake.

Install the influxdb-cxx Client Library

The client library builds libInfluxDB.so and installs at /usr/local/lib/libInfluxDB.so. Header files InfluxDBFactory.hInfluxDB.hPoint.hTransport.h are installed at /usr/local/include/.

Header files and library files are required while compiling and linking the source code respectively.

The C++ application uses libInfluxDB.so while linking in order to generate an executable binary.

The influxdb-cxx Client Library Class Design

The influxdb-cxx client is designed to interact with the InfluxDB server through class InfluxDB. All influxdb-cxx classes are defined under the global namespace influxdb.

The InfluxDBFactory class provides the get() method, which accepts a URI string with information on IP address, port with optional protocol name, database name, database user, and password. The HTTP URI defaults to tcpInfluxDBFactory returns the InfluxDB class, which is connected to the InfluxDB server.

Read More:   Update Blockchain Hyperledger Project Generates Interest in the Enterprise

The InfluxDB class then provides methods to create the database, write to the database, and query the database. The InfluxDB class writes a point (or list of points) to the database — the point class represents a measurement container.

Since a measurement container contains tagfield, and timestamp, the point class provides methods for adding tagfield, and timestamp to itself. Calling the write() method on the InfluxDB class with point as an argument, first serialize the point class data as per Line protocol rules.

Final line protocol data is then sent to the InfluxDB server. Batch mode is also supported by the InfluxDB class, where the batchOf() method specifies the batch size. The addPointToBatch() method takes the list of points to be added, and the flushBatch() method finally writes to the database.

Making a Connection

The InfluxDBFactory.get() method is called with a URI string to create a connection with the InfluxDB server. Specify the URI as:

For example, you can call the get() method as influxdb::InfluxDBFactory::Get("http://localhost:8086?db=temperature_db").

Here, HTTP (TCP) is the protocol, localhost (127.0.0.1) is the IP address, 8086 is the TCP port, and temperature_db is the database name. You can use HTTP (TCP), UDP, and Unix Socket as protocol. The IP address, protocol, username, password, port number, and database name can also be configured through the configuration file /etc/influxdb/influxdb.conf.
In this example, you can make a connection by specifying the database name. Create the database if it doesn’t exist.

Compiling, Linking, and Creating the Executable

In a new directory, create a file called CMakeLists.txt.

Add the following lines to CMakeLists.txt:

cxx-influxdb-example is the project name, whereas example-influx-cxx is the executable name.

Write your main.cpp code, including the influxdb-cxx client header files.

Output:

Connecting with SSL/TLS

HTTP is disabled by default. You’ll need to purchase an SSL key and certificate. Modify configuration file /etc/influxdb/influxdb.conf and modify or add the following key value pairs:

Next, run the following command:

You can specify https instead of http in the InfluxDBFactory.get() URI argument to get TLS(SSL) encryption.

Writing to the InfluxDB Database

The InfluxDB database is organized into various measurements. As mentioned earlier, a measurement is like a container and is equivalent to tables in an RDBMS. Each measurement record is a point which is a tuple of (measurement, tag, field value, time).

You can write a point to the database with InfluxDB.write() method by specifying measurement name, tag name, value pair list (optional), field name, value pair list, and timestamp (optional). A missing timestamp would be added by the InfluxDB database server.

Querying Data

You can query InfluxDB by calling the InfluxDB.query() method and passing the SQL query string as an argument. Database records in InfluxDB are returned in JSON format, where each record is represented by a point class. Point.getName()Point.getTags()Point.getFields() and Point.getTimestamp() return measurement, tag, field and timestamp respectively.

Output:

You can set float type precision by setting influxdb::Point::floatsPrecision=4.

Output:

Writing to InfluxDB in a Batch

You can write data in a batch after mentioning the batch size. Call the flushBatch() method to flush the data to the database.

Debugging with the influxdb-client Utility

You can also verify data available in InfluxDB through the influxdb-client utility available on Ubuntu 20.04 through $sudo apt-get install influxdb-client.

The Finished Application

The complete program is as follows:

Real-Time Data from the Experimental IoT Sensor

The IoT sensor data measuring power, temperature, humidity, light, CO2, and dust is available at IoTSenser.
Each data sample is recorded against a timestamp:

In the example code, the database iotsensor_db is created with iotsensor as the measurement field.

Read More:   The Evolving Role of Automation in DevOps Tools – InApps 2022

The full code for inserting data in your database and plotting a graph is as follows. Also, note that the graph is drawn from the pbPlots utility available in the Cpp directory. The pbPlots.cpppbPlots.hppsupportLib.cpp, and supportLib.hpp files are copied from the cxx-influxdb-example directory and added to the CMakeLists.txt file.

Output:

It takes 5874.81 milliseconds to write 79992 points in a database where each point has six fields.

Read More:   Update ‘Reverse ETL’ Can Help Companies Operationalize Data Warehouses







Records timestamped between “2015-08-04 00:00:00” and “2015-08-08 01:00:00”.






Conclusion

To recap, time-series databases (TSDBs) are different from RDBMSes in the sense that a TSDB is highly specialized in backing up stored time-series data. As a result, writing and querying the data happens at lightning speed.

For your own applications, check out InfluxDB, a database that provides metrics, events, and data analytics for time series data.

InApps is a wholly owned subsidiary of Insight Partners, an investor in the following companies mentioned in this article: Real.

Featured image via Pixabay.