influxdb

package module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2019 License: MIT Imports: 25 Imported by: 124

README

influxdb-client-go

A home for InfluxDB’s 2.x's golang client. This client is not compatible with InfluxDB 1.x--if you are looking for the 1.x golang client you can find it here.

Example:

influx, err := influxdb.New(myHTTPInfluxAddress, myToken, influxdb.WithHTTPClient(myHTTPClient))
if err != nil {
	panic(err) // error handling here; normally we wouldn't use fmt but it works for the example
}

// we use client.NewRowMetric for the example because it's easy, but if you need extra performance
// it is fine to manually build the []client.Metric{}.
myMetrics := []influxdb.Metric{
	influxdb.NewRowMetric(
		map[string]interface{}{"memory": 1000, "cpu": 0.93},
		"system-metrics",
		map[string]string{"hostname": "hal9000"},
		time.Date(2018, 3, 4, 5, 6, 7, 8, time.UTC)),
	influxdb.NewRowMetric(
		map[string]interface{}{"memory": 1000, "cpu": 0.93},
		"system-metrics",
		map[string]string{"hostname": "hal9000"},
		time.Date(2018, 3, 4, 5, 6, 7, 9, time.UTC)),
}

// The actual write..., this method can be called concurrently.
if _, err := influx.Write(context.Background(), "my-awesome-bucket", "my-very-awesome-org", myMetrics...); err != nil {
	log.Fatal(err) // as above use your own error handling here.
}
influx.Close() // closes the client.  After this the client is useless.

Releases

We will be using git-flow style releases, the current stable release will be listed in the master readme.

Requirements

influxdb-client-go requires go version 1.12 or newer to build.

Documentation

Index

Examples

Constants

View Source
const (
	EInternal            = "internal error"
	ENotFound            = "not found"
	EConflict            = "conflict"             // action cannot be performed
	EInvalid             = "invalid"              // validation failed
	EUnprocessableEntity = "unprocessable entity" // data type is correct, but out of range
	EEmptyValue          = "empty value"
	EUnavailable         = "unavailable"
	EForbidden           = "forbidden"
	ETooManyRequests     = "too many requests"
	EUnauthorized        = "unauthorized"
	EMethodNotAllowed    = "method not allowed"
)

Error code constants copied from influxdb

Variables

View Source
var ErrUnimplemented = errors.New("unimplemented")

ErrUnimplemented is an error for when pieces of the client's functionality is unimplemented.

Functions

func HTTPClientWithTLSConfig

func HTTPClientWithTLSConfig(conf *tls.Config) *http.Client

HTTPClientWithTLSConfig returns an *http.Client with sane timeouts and the provided TLSClientConfig.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a client for writing to influx.

func New

func New(connection string, token string, options ...Option) (*Client, error)

New creates a new Client. The client is concurrency safe, so feel free to use it and abuse it to your heart's content.

func (*Client) Close

func (c *Client) Close() error

Close closes any idle connections on the Client.

func (*Client) Ping

func (c *Client) Ping(ctx context.Context) error

Ping checks the status of cluster.

func (*Client) QueryCSV

func (c *Client) QueryCSV(ctx context.Context, flux string, org string, extern ...interface{}) (*QueryCSVResult, error)

QueryCSV returns the result of a flux query. TODO: annotations

func (*Client) Setup

func (c *Client) Setup(ctx context.Context, bucket, org string, retentionPeriodHrs int) (*SetupResult, error)

Setup sets up a new influxdb server. It requires a client be set up with a username and password. If successful will add a token to the client. RetentionPeriodHrs of zero will result in infinite retention.

Example
package main

import (
	"compress/gzip"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"strconv"
	"text/template"
	"time"

	influxdb "github.com/influxdata/influxdb-client-go"
)

func writeHandler(w http.ResponseWriter, r *http.Request) {
	reader := r.Body
	if r.Header.Get("Content-Encoding") == "gzip" {
		var err error
		reader, err = gzip.NewReader(reader)
		if err != nil {
			log.Fatal(err)
		}
	}
	buf, err := ioutil.ReadAll(reader)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(buf))
	w.WriteHeader(200)
}

func setupHandler(w http.ResponseWriter, r *http.Request) {

	resTemplate, err := template.New("result").Parse(`{"user":{"links":{"logs":"/api/v2/users/03b00a760bde3000/logs","self":"/api/v2/users/03b00a760bde3000"},"id":"03b00a760bde3000","name":"{{ .username }}"},"bucket":{"id":"03b00a761e9e3001","organizationID":"03b00a761e9e3000","organization":"{{ .org }}","name":"{{ .org }}-bucket","retentionRules":[{"type":"expire","everySeconds":{{ .retentionSeconds }}}],"links":{"labels":"/api/v2/buckets/03b00a761e9e3001/labels","logs":"/api/v2/buckets/03b00a761e9e3001/logs","members":"/api/v2/buckets/03b00a761e9e3001/members","org":"/api/v2/orgs/03b00a761e9e3000","owners":"/api/v2/buckets/03b00a761e9e3001/owners","self":"/api/v2/buckets/03b00a761e9e3001","write":"/api/v2/write?org=03b00a761e9e3000\u0026bucket=03b00a761e9e3001"},"labels":[]},"org":{"links":{"buckets":"/api/v2/buckets?org={{ .org }}","dashboards":"/api/v2/dashboards?org={{ .org }}","labels":"/api/v2/orgs/03b00a761e9e3000/labels","logs":"/api/v2/orgs/03b00a761e9e3000/logs","members":"/api/v2/orgs/03b00a761e9e3000/members","owners":"/api/v2/orgs/03b00a761e9e3000/owners","secrets":"/api/v2/orgs/03b00a761e9e3000/secrets","self":"/api/v2/orgs/03b00a761e9e3000","tasks":"/api/v2/tasks?org={{ .org }}"},"id":"03b00a761e9e3000","name":"{{ .org }}"},"auth":{"id":"03b00a761e9e3002","token":"d7odFhI50cR8WcLrbfD1pkVenWy51zEM6WC2Md5McGGTxRbOEi5KS0qrXrTEweiH2z5uQjkNa-0YVmpTQlwM3w==","status":"active","description":"{{ .username }}'s Token","orgID":"03b00a761e9e3000","org":"{{ .org }}","userID":"03b00a760bde3000","user":"{{ .username }}","permissions":[{"action":"read","resource":{"type":"authorizations"}},{"action":"write","resource":{"type":"authorizations"}},{"action":"read","resource":{"type":"buckets"}},{"action":"write","resource":{"type":"buckets"}},{"action":"read","resource":{"type":"dashboards"}},{"action":"write","resource":{"type":"dashboards"}},{"action":"read","resource":{"type":"orgs"}},{"action":"write","resource":{"type":"orgs"}},{"action":"read","resource":{"type":"sources"}},{"action":"write","resource":{"type":"sources"}},{"action":"read","resource":{"type":"tasks"}},{"action":"write","resource":{"type":"tasks"}},{"action":"read","resource":{"type":"telegrafs"}},{"action":"write","resource":{"type":"telegrafs"}},{"action":"read","resource":{"type":"users"}},{"action":"write","resource":{"type":"users"}},{"action":"read","resource":{"type":"variables"}},{"action":"write","resource":{"type":"variables"}},{"action":"read","resource":{"type":"scrapers"}},{"action":"write","resource":{"type":"scrapers"}},{"action":"read","resource":{"type":"secrets"}},{"action":"write","resource":{"type":"secrets"}},{"action":"read","resource":{"type":"labels"}},{"action":"write","resource":{"type":"labels"}},{"action":"read","resource":{"type":"views"}},{"action":"write","resource":{"type":"views"}},{"action":"read","resource":{"type":"documents"}},{"action":"write","resource":{"type":"documents"}}],"links":{"self":"/api/v2/authorizations/03b00a761e9e3002","user":"/api/v2/users/03b00a760bde3000"}}}`)
	if err != nil {
		log.Fatal(err)
	}
	req := influxdb.SetupRequest{}
	w.WriteHeader(http.StatusCreated)
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		log.Fatal(err)
	}
	if err := resTemplate.Execute(w, map[string]string{"username": req.Username, "org": string(req.Org), "retentionSeconds": strconv.Itoa(req.RetentionPeriodHrs * 60 * 60)}); err != nil {
		log.Fatal(err)
	}
}

func setupMockServer() (*http.Client, string, func()) {
	sm := http.NewServeMux()
	sm.HandleFunc("/api/v2/write", writeHandler)
	sm.HandleFunc("/api/v2/setup", setupHandler)
	sm.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.Fatal(r.RequestURI)
	})
	server := httptest.NewServer(http.HandlerFunc(sm.ServeHTTP))
	return server.Client(), server.URL, server.Close
}

func main() {
	// just us setting up the server so the example will work.  You will likely have to use the old fasioned way to get an *http.Client and address
	// alternatively you can leave the *http.Client nil, and it will intelligently create one with sane defaults.
	myHTTPClient, myHTTPInfluxAddress, teardown := setupMockServer()
	defer teardown() // we shut down our server at the end of the test, obviously you won't be doing this.

	influx, err := influxdb.New(myHTTPInfluxAddress, "", influxdb.WithUserAndPass("my-username", "my-password"), influxdb.WithHTTPClient(myHTTPClient))
	if err != nil {
		panic(err) // error handling here, normally we wouldn't use fmt, but it works for the example
	}
	resp, err := influx.Setup(context.Background(), "my-bucket", "my-org", 32)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(resp.Auth.Token)
	myMetrics := []influxdb.Metric{
		influxdb.NewRowMetric(
			map[string]interface{}{"memory": 1000, "cpu": 0.93},
			"system-metrics",
			map[string]string{"hostname": "hal9000"},
			time.Date(2018, 3, 4, 5, 6, 7, 8, time.UTC)),
	}

	// We can now do a write even though we didn't put a token in
	if _, err := influx.Write(context.Background(), "my-awesome-bucket", "my-very-awesome-org", myMetrics...); err != nil {
		log.Fatal(err)
	}
	influx.Close() // close the client after this the client is useless.
}
Output:

d7odFhI50cR8WcLrbfD1pkVenWy51zEM6WC2Md5McGGTxRbOEi5KS0qrXrTEweiH2z5uQjkNa-0YVmpTQlwM3w==
system-metrics,hostname=hal9000 cpu=0.93,memory=1000i 1520139967000000008

func (*Client) Write

func (c *Client) Write(ctx context.Context, bucket, org string, m ...Metric) (n int, err error)

Write writes metrics to a bucket, and org. It retries intelligently. If the write is too big, it retries again, after breaking the payloads into two requests.

Example (Basic)

ExampleClient_Write_basic is an example of basic writing to influxdb over http(s). While this is fine in a VPN or VPC, we recommend using TLS/HTTPS if you are sending data over the internet, or anywhere your tokens could be intercepted.

package main

import (
	"compress/gzip"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"strconv"
	"text/template"
	"time"

	influxdb "github.com/influxdata/influxdb-client-go"
)

func writeHandler(w http.ResponseWriter, r *http.Request) {
	reader := r.Body
	if r.Header.Get("Content-Encoding") == "gzip" {
		var err error
		reader, err = gzip.NewReader(reader)
		if err != nil {
			log.Fatal(err)
		}
	}
	buf, err := ioutil.ReadAll(reader)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(buf))
	w.WriteHeader(200)
}

func setupHandler(w http.ResponseWriter, r *http.Request) {

	resTemplate, err := template.New("result").Parse(`{"user":{"links":{"logs":"/api/v2/users/03b00a760bde3000/logs","self":"/api/v2/users/03b00a760bde3000"},"id":"03b00a760bde3000","name":"{{ .username }}"},"bucket":{"id":"03b00a761e9e3001","organizationID":"03b00a761e9e3000","organization":"{{ .org }}","name":"{{ .org }}-bucket","retentionRules":[{"type":"expire","everySeconds":{{ .retentionSeconds }}}],"links":{"labels":"/api/v2/buckets/03b00a761e9e3001/labels","logs":"/api/v2/buckets/03b00a761e9e3001/logs","members":"/api/v2/buckets/03b00a761e9e3001/members","org":"/api/v2/orgs/03b00a761e9e3000","owners":"/api/v2/buckets/03b00a761e9e3001/owners","self":"/api/v2/buckets/03b00a761e9e3001","write":"/api/v2/write?org=03b00a761e9e3000\u0026bucket=03b00a761e9e3001"},"labels":[]},"org":{"links":{"buckets":"/api/v2/buckets?org={{ .org }}","dashboards":"/api/v2/dashboards?org={{ .org }}","labels":"/api/v2/orgs/03b00a761e9e3000/labels","logs":"/api/v2/orgs/03b00a761e9e3000/logs","members":"/api/v2/orgs/03b00a761e9e3000/members","owners":"/api/v2/orgs/03b00a761e9e3000/owners","secrets":"/api/v2/orgs/03b00a761e9e3000/secrets","self":"/api/v2/orgs/03b00a761e9e3000","tasks":"/api/v2/tasks?org={{ .org }}"},"id":"03b00a761e9e3000","name":"{{ .org }}"},"auth":{"id":"03b00a761e9e3002","token":"d7odFhI50cR8WcLrbfD1pkVenWy51zEM6WC2Md5McGGTxRbOEi5KS0qrXrTEweiH2z5uQjkNa-0YVmpTQlwM3w==","status":"active","description":"{{ .username }}'s Token","orgID":"03b00a761e9e3000","org":"{{ .org }}","userID":"03b00a760bde3000","user":"{{ .username }}","permissions":[{"action":"read","resource":{"type":"authorizations"}},{"action":"write","resource":{"type":"authorizations"}},{"action":"read","resource":{"type":"buckets"}},{"action":"write","resource":{"type":"buckets"}},{"action":"read","resource":{"type":"dashboards"}},{"action":"write","resource":{"type":"dashboards"}},{"action":"read","resource":{"type":"orgs"}},{"action":"write","resource":{"type":"orgs"}},{"action":"read","resource":{"type":"sources"}},{"action":"write","resource":{"type":"sources"}},{"action":"read","resource":{"type":"tasks"}},{"action":"write","resource":{"type":"tasks"}},{"action":"read","resource":{"type":"telegrafs"}},{"action":"write","resource":{"type":"telegrafs"}},{"action":"read","resource":{"type":"users"}},{"action":"write","resource":{"type":"users"}},{"action":"read","resource":{"type":"variables"}},{"action":"write","resource":{"type":"variables"}},{"action":"read","resource":{"type":"scrapers"}},{"action":"write","resource":{"type":"scrapers"}},{"action":"read","resource":{"type":"secrets"}},{"action":"write","resource":{"type":"secrets"}},{"action":"read","resource":{"type":"labels"}},{"action":"write","resource":{"type":"labels"}},{"action":"read","resource":{"type":"views"}},{"action":"write","resource":{"type":"views"}},{"action":"read","resource":{"type":"documents"}},{"action":"write","resource":{"type":"documents"}}],"links":{"self":"/api/v2/authorizations/03b00a761e9e3002","user":"/api/v2/users/03b00a760bde3000"}}}`)
	if err != nil {
		log.Fatal(err)
	}
	req := influxdb.SetupRequest{}
	w.WriteHeader(http.StatusCreated)
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		log.Fatal(err)
	}
	if err := resTemplate.Execute(w, map[string]string{"username": req.Username, "org": string(req.Org), "retentionSeconds": strconv.Itoa(req.RetentionPeriodHrs * 60 * 60)}); err != nil {
		log.Fatal(err)
	}
}

func setupMockServer() (*http.Client, string, func()) {
	sm := http.NewServeMux()
	sm.HandleFunc("/api/v2/write", writeHandler)
	sm.HandleFunc("/api/v2/setup", setupHandler)
	sm.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.Fatal(r.RequestURI)
	})
	server := httptest.NewServer(http.HandlerFunc(sm.ServeHTTP))
	return server.Client(), server.URL, server.Close
}

func main() {
	// just us setting up the server so the example will work.  You will likely have to use the old fasioned way to get an *http.Client and address
	// alternatively you can leave the *http.Client nil, and it will intelligently create one with sane defaults.
	myHTTPClient, myHTTPInfluxAddress, teardown := setupMockServer()
	defer teardown() // we shut down our server at the end of the test, obviously you won't be doing this.
	influx, err := influxdb.New(myHTTPInfluxAddress, "mytoken", influxdb.WithHTTPClient(myHTTPClient))
	if err != nil {
		panic(err) // error handling here, normally we wouldn't use fmt, but it works for the example
	}

	// we use client.NewRowMetric for the example because its easy, but if you need extra performance
	// it is fine to manually build the []client.Metric{}.
	myMetrics := []influxdb.Metric{
		influxdb.NewRowMetric(
			map[string]interface{}{"memory": 1000, "cpu": 0.93},
			"system-metrics",
			map[string]string{"hostname": "hal9000"},
			time.Date(2018, 3, 4, 5, 6, 7, 8, time.UTC)),
		influxdb.NewRowMetric(
			map[string]interface{}{"memory": 1000, "cpu": 0.93},
			"system-metrics",
			map[string]string{"hostname": "hal9000"},
			time.Date(2018, 3, 4, 5, 6, 7, 9, time.UTC)),
	}

	// The actual write..., this method can be called concurrently.
	if _, err := influx.Write(context.Background(), "my-awesome-bucket", "my-very-awesome-org", myMetrics...); err != nil {
		log.Fatal(err) // as above use your own error handling here.
	}
	influx.Close() // closes the client.  After this the client is useless.
}
Output:

system-metrics,hostname=hal9000 cpu=0.93,memory=1000i 1520139967000000008
system-metrics,hostname=hal9000 cpu=0.93,memory=1000i 1520139967000000009
Example (TlsMutualAuthentication)
package main

import (
	"compress/gzip"
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
	"time"

	influxdb "github.com/influxdata/influxdb-client-go"
)

func writeHandler(w http.ResponseWriter, r *http.Request) {
	reader := r.Body
	if r.Header.Get("Content-Encoding") == "gzip" {
		var err error
		reader, err = gzip.NewReader(reader)
		if err != nil {
			log.Fatal(err)
		}
	}
	buf, err := ioutil.ReadAll(reader)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(buf))
	w.WriteHeader(200)
}

func setupTLSMockserver() (*http.Client, string, string, string, func()) {
	keyPem := []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAomQx2HLKfGpb5SEhNzxIgG/EJw2pElptgm0T4r/pKJOmzSFq
PpPU0qshHUnMqYZuvs8eTGqOSDqo9XXOETwRxHpUPmzrrbgl23HKrOatJCLAcv1N
rNx6NaGjiykTkIsBlmD3TGfH+N0wmtHiB0jjRy8sZHaFUfAUaPOT4ei/i/M/1Muk
06AXbEZ/3+c2fNm+me0hKNJq4JpD768jromhW2D3QjIKFFGroogmd7/9ZIcfvIMb
xbr2KporDK/mLdLrLGrTxjfbtYv+Fuon0ARgmZrcZdwUaFxQXSQjNRe57dr+jTZi
vl8tNFW4uCGiwfox7/vEUz0kV/LC4WssNslwcQIDAQABAoIBAA3wv/6uzAcmMkFX
OLy/JhIwhgw8NflnXeNGbeCXTPK4yibt6Wr50dlL64nSHgmnirZCnX094Hz+3CZG
OKxuFbBiN/0r6Id/OXC/MgDpxI9HlHHKoPJn8u3LtHhrzEwqQragGFqsxhPtGRER
V2/8p9YijJMLQaKpE3d3AYjxLBBdbGlCH3QvS9PwEzqS0fgvaEgKwD13Lu8ZIG2p
RuLVhFMZ3yw44R9PZ29m54EO/qDe4AZNmsZJg+w6ITV7MoodMFcIRkOnNp8pb9no
ZJFjWvkkZKQi7e7u4hSdpqCkqqCH2ml+/5H7PHwOZu8jy5oo/RnDUrsz9Xj/asKr
W8+niUkCgYEAzc8RR6eYPHT56mPMR/EGuwgSuopYkPCMrT9PikwX8njGNrEH9C0V
ikMl2eAXiEO6BaCmw1wXrEyqwgO23NyYQS/PNLxOkqpuY+Ls1H4TQhXimHHyQNcO
Dmis4oudn4xbjiN5/uLtnFhLNatzWKWUxnUkn/dIReXr+srefwFkrRMCgYEAyf6D
owz2p5UbqRzR1EprVjpwuuF7j+/eSXrgEyVFCZcPgCFoFysxREhAxIpB6HBc8Ro9
TwtAWvzf9wWtl2i4mIDnGOYrbyhqurjY5sKFFB4A/TeM5/WOpM9wR5CqGLAyORxo
V8zBRBUnCvFBOwGFwrhupQSPLzca56nKuInJMOsCgYEAonwRm23ArjJ4QMoLtNyg
wLbN+oJRDBUuK3Vpebk7ys35R6KasfeKIv+CebIHQiieS+Ua4+/oLLrWsZg3HcX3
WrfBMlRdAEQYJTo6WkUzNSCMJmkHppNi4JNZsv4hMp6gheaSYV6N07qNnlC/H0SS
4eAIS1bys2Sj2vuhj8nszwsCgYBoGjPdpKC6Xa6TybaaooAPQK84oVz9IbJ+TEWP
mHWsK55hetYamrgZaON4Z4jwMni0CcHvKu1P92O1+8crcV0xu71ep8Fa2ImpEfs3
cqkDZTM9TZPhODz7060aNQR1FNnNdUaReYVhgUVN7mif8Hjvkf30LhVdUBkdq/Q+
h0SZYQKBgQCMCNldHBO0Fj2+gsadmaOnsReCDsGTbxwjdC5psKCWUkOOBCjLXBN9
Mdnk42tqFy88udJphkt5ivBDg9BRldFDgDG0YlIgwfSzJ/7McEspFkjvYbbYctkT
Y+5yAlSc+gJXWkRXzQVA29GxFxmfAKRQrlmw1LrZe6fAxqRQcT0rfQ==
-----END RSA PRIVATE KEY-----`)
	certPem := []byte(`-----BEGIN CERTIFICATE-----
MIIDITCCAgmgAwIBAgIQQjtyVYP+gdHiKHuD8DS6nDANBgkqhkiG9w0BAQsFADAo
MRMwEQYDVQQKEwppbmZsdXhkYXRhMREwDwYDVQQDEwhpbmZsdXhkYjAgFw0xOTA0
MTIxNDI5MTBaGA8yMDgxMTAxNTIxNDEzN1owKDETMBEGA1UEChMKaW5mbHV4ZGF0
YTERMA8GA1UEAxMIaW5mbHV4ZGIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCiZDHYcsp8alvlISE3PEiAb8QnDakSWm2CbRPiv+kok6bNIWo+k9TSqyEd
Scyphm6+zx5Mao5IOqj1dc4RPBHEelQ+bOutuCXbccqs5q0kIsBy/U2s3Ho1oaOL
KROQiwGWYPdMZ8f43TCa0eIHSONHLyxkdoVR8BRo85Ph6L+L8z/Uy6TToBdsRn/f
5zZ82b6Z7SEo0mrgmkPvryOuiaFbYPdCMgoUUauiiCZ3v/1khx+8gxvFuvYqmisM
r+Yt0ussatPGN9u1i/4W6ifQBGCZmtxl3BRoXFBdJCM1F7nt2v6NNmK+Xy00Vbi4
IaLB+jHv+8RTPSRX8sLhayw2yXBxAgMBAAGjRTBDMA4GA1UdDwEB/wQEAwIB5jAP
BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0RBAgwBocEfwAA
ATANBgkqhkiG9w0BAQsFAAOCAQEALDtbwwaMqUtN3pocuai/M5ZKi2zDJuEMMhl0
PORlebvAz6voUp9ufdHaxrZMACn2zs/lkRsKl8HEy2ucusOgmW3WkHf7/6TNI6Wz
u/CryeCFIkesdm8BuSX/YLRTzktoYO5xdhv1v0DNYK4fF4W7CKR0Ln2P5/KNNzgS
wxdXhdWyoZKbNI2mS65BqDRPRA/sBPp652969hmGJxk+ZYcefWGX7WgjUdWvFMV6
iN3MeSe0Jnsa1HijHikwz2Z30VqWU2f04jwISsm0Lw2UPFGD67lNi+XgonS7BX73
13BILrvydRraUD2OHlSR3TbXH2Jcdgh7Ifl+Fc0OEaXnlNHT9w==
-----END CERTIFICATE-----`)
	cert, err := tls.X509KeyPair(certPem, keyPem)
	if err != nil {
		panic(err)

	}

	certPool := x509.NewCertPool()
	certPool.AppendCertsFromPEM(certPem)
	cfg := &tls.Config{
		ClientAuth:   tls.RequireAndVerifyClientCert,
		ClientCAs:    certPool,
		Certificates: []tls.Certificate{cert},
		RootCAs:      certPool,
	}
	cfg.BuildNameToCertificate()
	server := httptest.NewUnstartedServer(http.HandlerFunc(writeHandler))
	server.TLS = cfg

	fCert, err := ioutil.TempFile("", "influxdb_example_cert_*.pem")
	if err != nil {
		log.Fatal(err)
	}

	fKey, err := ioutil.TempFile("", "influxdb_example_key_*.pem")
	if err != nil {
		log.Fatal(err)
	}

	defer func() {
		fCert.Close()
		fKey.Close()
	}()

	_, err = fCert.Write(certPem)
	if err != nil {
		log.Fatal(err)
	}
	_, err = fKey.Write(keyPem)
	if err != nil {
		log.Fatal(err)
	}

	server.StartTLS()
	return server.Client(), fCert.Name(), fKey.Name(), server.URL, func() { server.Close(); os.Remove(fCert.Name()); os.Remove(fKey.Name()) }
}

func main() {
	// just us setting up the server so the example will work.  You will likely have to use the old fasioned way to get an *http.Client and address
	_, certFileName, keyfileName, myHTTPInfluxAddress, teardown := setupTLSMockserver()
	defer teardown() // we shut down our server at the end of the test, obviously you won't be doing this.

	certPem, err := ioutil.ReadFile(certFileName)
	if err != nil {
		log.Fatal(err)
	}
	keyPem, err := ioutil.ReadFile(keyfileName)
	if err != nil {
		log.Fatal(err)
	}
	cert, err := tls.X509KeyPair(certPem, keyPem)
	if err != nil {
		log.Fatal(err)
	}

	certPool := x509.NewCertPool()

	// read in the ca cert, in our case since we are self-signing, we are using the same cert
	caCertPem, err := ioutil.ReadFile(certFileName)
	if err != nil {
		log.Fatal(err)
	}
	certPool.AppendCertsFromPEM(caCertPem)

	if err != nil {
		log.Fatal(err)
	}
	tlsConfig := &tls.Config{
		// Reject any TLS certificate that cannot be validated
		ClientAuth: tls.RequireAndVerifyClientCert,
		// Ensure that we only use our "CA" to validate certificates
		// Force it server side
		Certificates: []tls.Certificate{cert},
		RootCAs:      certPool,
	}
	tlsConfig.BuildNameToCertificate()

	influx, err := influxdb.New(myHTTPInfluxAddress, "mytoken", influxdb.WithHTTPClient(influxdb.HTTPClientWithTLSConfig(tlsConfig)))
	if err != nil {
		log.Fatal(err)
	}

	// we use client.NewRowMetric for the example because its easy, but if you need extra performance
	// it is fine to manually build the []client.Metric{}
	myMetrics := []influxdb.Metric{
		influxdb.NewRowMetric(
			map[string]interface{}{"memory": 1000, "cpu": 0.93},
			"system-metrics",
			map[string]string{"hostname": "hal9000"},
			time.Date(2018, 3, 4, 5, 6, 7, 8, time.UTC)),
		influxdb.NewRowMetric(
			map[string]interface{}{"memory": 1000, "cpu": 0.93},
			"system-metrics",
			map[string]string{"hostname": "hal9000"},
			time.Date(2018, 3, 4, 5, 6, 7, 9, time.UTC)),
	}

	// The actual write...
	if _, err := influx.Write(context.Background(), "my-awesome-bucket", "my-very-awesome-org", myMetrics...); err != nil {
		log.Fatal(err)
	}
	influx.Close() // close the client after this the client is useless.
}
Output:

system-metrics,hostname=hal9000 cpu=0.93,memory=1000i 1520139967000000008
system-metrics,hostname=hal9000 cpu=0.93,memory=1000i 1520139967000000009

type Error

type Error struct {
	Code       string
	Message    string
	Err        string
	Op         string
	Line       *int32
	MaxLength  *int32
	RetryAfter *int32
}

Error is an error returned by a client operation It contains a number of contextual fields which describe the nature and cause of the error

func (*Error) Error

func (e *Error) Error() string

Error returns the string representation of the Error struct

type Field

type Field = lp.Field

Field is just a github.com/influxdata/line-protocol.Field. We alias here to keep abstractions from leaking.

type HTTPConfig

type HTTPConfig struct {
	// Addr should be of the form "http://host:port"
	// or "http://[ipv6-host%zone]:port".
	Addr string

	// Username is the influxdb username, optional.
	Username string

	// Password is the influxdb password, optional.
	Password string

	// UserAgent is the http User Agent, defaults to "InfluxDBClient" plus os and version info.
	UserAgent string

	// Timeout for influxdb writes, if set to zero, it defaults to a 20 second timeout. This is a difference from the influxdb1-client.
	Timeout time.Duration

	// InsecureSkipVerify gets passed to the http client, if true, it will
	// skip https certificate verification. Defaults to false.
	// this currently isn't supported, set on the http client.
	InsecureSkipVerify bool

	// TLSConfig allows the user to set their own TLS config for the HTTP
	// Client. If set, this option overrides InsecureSkipVerify.
	// this currently isn't supported, set on the http client.
	TLSConfig *tls.Config

	// Proxy configures the Proxy function on the HTTP client.
	// this currently isn't supported
	Proxy func(req *http.Request) (*url.URL, error)

	// If HTTPClient is nil, the New Client function will use an http client with sane defaults.
	HTTPClient *http.Client
}

HTTPConfig is an https://github.com/influxdata/influxdb1-client compatible client for setting config options. This is here to make transition to the influxdb2 client easy from the old influxdb 1 client library. It is recommended that you set the options using the With___ functions instead.

type Metric

type Metric = lp.Metric

Metric is just a github.com/influxdata/line-protocol.Metric. We alias here to keep abstractions from leaking.

type Option

type Option struct {
	// contains filtered or unexported fields
}

Option is an option for the client config. If you pass multiple incompatible Options the later one should override.

func WithGZIP

func WithGZIP(n int) Option

WithGZIP returns an option for setting gzip compression level. The default (should this option not be used ) is level 4.

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient returns an option for setting a custom HTTP Client

func WithMaxLineBytes

func WithMaxLineBytes(n int) Option

WithMaxLineBytes returns an option for setting the max length of a line of influx line-protocol in bytes.

func WithNoCompression

func WithNoCompression() Option

WithNoCompression returns an option for writing the data to influxdb without compression.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent returns an option for setting a custom useragent string.

func WithUserAndPass

func WithUserAndPass(username, password string) Option

WithUserAndPass returns an option for setting a username and password, which generates a session for use. TODO(docmerlin): session logic.

func WithV1Config

func WithV1Config(conf *HTTPConfig) Option

WithV1Config is an option for setting config in a way that makes it easy to convert from the old influxdb1 client config.

type QueryCSVResult

type QueryCSVResult struct {
	io.ReadCloser

	Row      []string
	ColNames []string

	Err error
	// contains filtered or unexported fields
}

QueryCSVResult is the result of a flux query in CSV format

func (*QueryCSVResult) Next

func (q *QueryCSVResult) Next() bool

Next iterates to the next row in the data set. Typically this is called like so:

for q.Next(){
	... // do thing here
}

It will call Close() on the result when it encounters EOF.

func (*QueryCSVResult) Unmarshal

func (q *QueryCSVResult) Unmarshal(x interface{}) error

Unmarshal alows you to easily unmarshal rows of results into your own types.

type RowMetric

type RowMetric struct {
	NameStr string
	Tags    []*lp.Tag
	Fields  []*lp.Field
	TS      time.Time
}

RowMetric is a Metric, that has methods to make it easy to add tags and fields

func NewRowMetric

func NewRowMetric(
	fields map[string]interface{},
	name string,
	tags map[string]string,
	ts time.Time,
) *RowMetric

NewRowMetric creates a *RowMetric from tags, fields and a timestamp.

func (*RowMetric) AddField

func (m *RowMetric) AddField(k string, v interface{})

AddField adds an lp.Field to a metric.

func (*RowMetric) AddTag

func (m *RowMetric) AddTag(k, v string)

AddTag adds an lp.Tag to a metric.

func (*RowMetric) FieldList

func (m *RowMetric) FieldList() []*lp.Field

FieldList returns a slice containing the Fields of a Metric.

func (*RowMetric) Name

func (m *RowMetric) Name() string

Name returns the name of the metric.

func (*RowMetric) SortFields

func (m *RowMetric) SortFields()

SortFields orders the fields of a metric alphnumerically by key.

func (*RowMetric) SortTags

func (m *RowMetric) SortTags()

SortTags orders the tags of a metric alphnumerically by key. This is just here as a helper, to make it easy to keep tags sorted if you are creating a RowMetric manually.

func (*RowMetric) TagList

func (m *RowMetric) TagList() []*lp.Tag

TagList returns a slice containing Tags of a Metric.

func (*RowMetric) Time

func (m *RowMetric) Time() time.Time

Time is the timestamp of a metric.

type SetupRequest

type SetupRequest struct {
	Username           string `json:"username"`
	Password           string `json:"password"`
	Org                string `json:"org"`
	Bucket             string `json:"bucket"`
	RetentionPeriodHrs int    `json:"retentionPeriodHrs"`
}

SetupRequest is a request to setup a new influx instance.

type SetupResult

type SetupResult struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	User    struct {
		Links struct {
			Logs string `json:"logs"`
			Self string `json:"self"`
		} `json:"links"`
		ID   string `json:"id"`
		Name string `json:"name"`
	} `json:"user"`
	Bucket struct {
		ID             string `json:"id"`
		OrganizationID string `json:"organizationID"`
		Organization   string `json:"organization"`
		Name           string `json:"name"`
		RetentionRules []struct {
			Type         string `json:"type"`
			EverySeconds int    `json:"everySeconds"`
		} `json:"retentionRules"`
		Links struct {
			Labels  string `json:"labels"`
			Logs    string `json:"logs"`
			Members string `json:"members"`
			Org     string `json:"org"`
			Owners  string `json:"owners"`
			Self    string `json:"self"`
			Write   string `json:"write"`
		} `json:"links"`
	} `json:"bucket"`
	Org struct {
		Links struct {
			Buckets    string `json:"buckets"`
			Dashboards string `json:"dashboards"`
			Labels     string `json:"labels"`
			Logs       string `json:"logs"`
			Members    string `json:"members"`
			Owners     string `json:"owners"`
			Secrets    string `json:"secrets"`
			Self       string `json:"self"`
			Tasks      string `json:"tasks"`
		} `json:"links"`
		ID   string `json:"id"`
		Name string `json:"name"`
	} `json:"org"`
	Auth struct {
		ID          string `json:"id"`
		Token       string `json:"token"`
		Status      string `json:"status"`
		Description string `json:"description"`
		OrgID       string `json:"orgID"`
		Org         string `json:"org"`
		UserID      string `json:"userID"`
		User        string `json:"user"`
		Permissions []struct {
			Action   string `json:"action"`
			Resource struct {
				Type string `json:"type"`
			} `json:"resource"`
		} `json:"permissions"`
		Links struct {
			Self string `json:"self"`
			User string `json:"user"`
		} `json:"links"`
	} `json:"auth"`
}

SetupResult is the result of setting up a new influx instance.

type Tag

type Tag = lp.Tag

Tag is just a github.com/influxdata/line-protocol.Tag. We alias here to keep abstractions from leaking.

Directories

Path Synopsis
Code generated for client DO NOT EDIT.
Code generated for client DO NOT EDIT.
internal
ast
Package ast provides tools for manipulating the flux ast.
Package ast provides tools for manipulating the flux ast.
Package writer contains useful types for buffering, batching and periodically syncing writes onto a provided metric writing client.
Package writer contains useful types for buffering, batching and periodically syncing writes onto a provided metric writing client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL