How to Use the InfluxDB with Golang on Ubuntu 20.04
Introduction
InfluxDB is an open-source time-series database specifically suitable for IoT projects, cloud-native services, and more. The package is written in the Golang programming language. You can use it for data exploration, data visualization, and to run dashboard applications.
While InfluxDB comes with great tools for storing, querying, and processing data, you can still use its API libraries inside your Golang project. This enhances flexibility when working with the time series data since you can pass it through custom functions that may not be available in the InfluxDB codebase.
In this guide, you'll implement the InfluxDB database functions with Golang on your Ubuntu 20.04 server.
Prerequisites
To proceed with this guide, make sure you have the following:
1. Create an InfluxDB Database
In this tutorial, you'll set up an InfluxDB database and insert some time-series data for testing purposes. Later, you'll query your InfluxDB server via a Golang script to retrieve or insert points to the database.
Connect to your server to complete the following steps:
Log in to the InfluxDB server. Replace
admin
with the name of your InfluxDBsuper-user
account. Pass the-password ''
option to allow the followinginflux
command to prompt you for a password.$ influx -username 'admin' -password ''
Key in your password and press Enter to proceed. Next, execute the following statement to create a
sample_db
database.> CREATE DATABASE sample_db
Switch to the new
sample_db
database.> USE sample_db
Insert the following points into your
sample_db
database under thepower_usage
measurement. In this application, you're tracking the power loads for users in different homes where a solar system has been installed. In this step, you'll enter the data manually, but this data may originate from IoT devices installed in all homes requiring measurement tracking in a production environment.> INSERT power_usage,client_id=100731,location=BRANSON current_load_in_amperes=0.2 > INSERT power_usage,client_id=800478,location=MIAMI current_load_in_amperes=0.1 > INSERT power_usage,client_id=907854,location=CHICAGO current_load_in_amperes=0.4 > INSERT power_usage,client_id=532681,location=CHARLESTON current_load_in_amperes=0.1
Query the
power_usage
measurement to make sure the data is in place.> SELECT "client_id", "location", "current_load_in_amperes" FROM power_usage
You should get the following output showing time-stamped data as you entered it in the
sample_db
database.time client_id location current_load_in_amperes ---- --------- -------- ----------------------- 1638542140183389389 100731 BRANSON 0.2 1638542147803130270 800478 MIAMI 0.1 1638542155163864457 907854 CHICAGO 0.4 1638542162283179983 532681 CHARLESTON 0.1
Log out from the InfluxDB server.
> QUIT
2. Create a main.go
File
In this application, you'll create a main.go
file. This runs the main(...)
function that fires when you start the application.
Separate your source code files from the rest of the Linux files by creating a new
project
directory.$ mkdir project
Next, navigate to the
project
directory.$ cd project
Then, use
nano
to open a newmain.go
file.$ nano main.go
Enter the following information into the
main.go
file.package main import ( "net/http" "encoding/json" "fmt" ) func main() { http.HandleFunc("/power-consumptions", httpHandler) http.ListenAndServe(":8080", nil) } func httpHandler(w http.ResponseWriter, req *http.Request) { var err error resp := map[string]interface{}{} if req.Method == "POST" { params := map[string]interface{}{} err = json.NewDecoder(req.Body).Decode(¶ms) if err != nil { fmt.Fprintf(w, err.Error()) } resp, err = createPoint(params) } if req.Method == "GET" { resp, err = getPoints() } enc := json.NewEncoder(w) enc.SetIndent("", " ") if err != nil { fmt.Println(err.Error()) } else { if err := enc.Encode(resp); err != nil { fmt.Println(err.Error()) } } }
Save and close the
main.go
file when you're through with editing.In the above file, you've created a
main()
function to listen for incoming HTTP requests on port8080
. You've then redirected the request to thehttpHandler()
function to determine the HTTPreq.Method
. ForPOST
requests, you're calling acreatePoint(params)
function, which you'll create in a new file later. This function accepts the JSON payload as an argument for the point that you want to create to the database.Next, you're redirecting
GET
requests to thegetPoints()
function, which retrieves data from the database and returns a map.
3. Create an influxdb.go
File
You'll create a file to interact with your InfluxDB server in this step. This file contains two functions. You'll use the createPoint()
function to enter new points into the database and the getPoints()
function to retrieve entries from your power_usage
measurement.
Use
nano
to create a newinfluxdb.go
file.$ nano influxdb.go
Next, enter the following information into the
influxdb.go
file. Replace constUSERNAME
and constPASSWORD
with the correct authentication credentials for your InfluxDB server.package main import ( "github.com/influxdata/influxdb1-client/v2" "time" "errors" ) const ( USERNAME string = "admin" PASSWORD string = "EXAMPLE_PASSWORD" DATABASE string = "sample_db" ) func createPoint(params map[string]interface{}) (map[string]interface{}, error) { influxClient, err := client.NewHTTPClient(client.HTTPConfig{ Addr: "http://localhost:8086", Username: USERNAME, Password: PASSWORD, }) if err != nil { return nil, err } bp, err := client.NewBatchPoints(client.BatchPointsConfig{ Database: DATABASE, }) if err != nil { return nil, err } clientId := params["client_id"].(string) location := params["location"].(string) currentLoadInAmperes := params["current_load_in_amperes"] pt, err := client.NewPoint("power_usage", map[string]string{"client_id": clientId, "location": location}, map[string]interface{}{"current_load_in_amperes": currentLoadInAmperes}, time.Now()) if err != nil { return nil, err } bp.AddPoint(pt) err = influxClient.Write(bp) if err != nil { return nil, err } resp := map[string]interface{}{"data" : "Success"} return resp, nil } func getPoints() (map[string]interface{}, error) { influxClient, err := client.NewHTTPClient(client.HTTPConfig{ Addr: "http://localhost:8086", Username: USERNAME, Password: PASSWORD, }) if err != nil { return nil, err } queryString := "SELECT client_id, location, current_load_in_amperes FROM power_usage" q := client.NewQuery(queryString, DATABASE, "ns") response, err := influxClient.Query(q) if err != nil { return nil, err } err = response.Error() if err != nil { return nil, errors.New("Empty record set") } else { res := response.Results if (len(res) == 0) { return nil, err } columns := response.Results[0].Series[0].Columns points := response.Results[0].Series[0].Values data := []map[string]interface{}{} for i := 0; i <= len(points) - 1 ; i++ { record := map[string]interface{}{} for j := 0; j <= len(columns) - 1; j++ { record[string(columns[j])] = points[i][j] } data = append(data, record) } resp := map[string]interface{}{"data" : data} return resp, nil } }
Save and close the
influxdb.go
file when you're through with editing.In the above file, you have two functions. You're using the
createPoint
function to connect and create a point in your InfluxDB database using the payload passed from themain.go
file. Then, you're using thegetPoints()
function to connect and retrieve points from thepower_usage
measurement. In each case, you're returning a map to the calling function or an error, if any.
4. Test the Golang InfluxDb Application.
You now have a main.go
file that listens for incoming requests and an influxdb.go
that creates and retrieves points from your InfluxDB database. Your application is now ready for testing.
Download the InfluxDB packages that you've used in the project.
$ go get github.com/influxdata/influxdb1-client/v2
Next, run the application. A web server should now listen on port
8080
. Don't enter any other command in thisSSH
session.$ go run ./
SSH to your server on another terminal window and execute the following
curl
POST
command to create a new entry into your InfluxDB database.$ curl -i -X POST localhost:8080/power-consumptions -H "Content-Type: application/json" -d '{"client_id": "656565", "location": "NAIROBI", "current_load_in_amperes": 0.3}'
Confirm the following output. This means you've successfully created a new point into the database.
{ "data": "Success" }
Then, issue the following
GET
command to retrieve points from the database.$ curl -i -X GET localhost:8080/power-consumptions
You should get the following output with all points, including the latest
NAIROBI
entry you've created with thecurl
command.{ "data": [ { "client_id": "100731", "current_load_in_amperes": 0.2, "location": "BRANSON", "time": 1638542140183389389 }, { "client_id": "800478", "current_load_in_amperes": 0.1, "location": "MIAMI", "time": 1638542147803130270 }, { "client_id": "907854", "current_load_in_amperes": 0.4, "location": "CHICAGO", "time": 1638542155163864457 }, { "client_id": "532681", "current_load_in_amperes": 0.1, "location": "CHARLESTON", "time": 1638542162283179983 }, { "client_id": "656565", "current_load_in_amperes": 0.3, "location": "NAIROBI", "time": 1638542346252178453 } ] }
Your application is working as expected.
Conclusion
In this guide, you've implemented InfluxDB database functions with Golang on your Ubuntu 20.04 server to create and retrieve points using a custom JSON API.
Follow the links below to read more Golang tutorials: