Documentation ¶
Index ¶
- Constants
- Variables
- func HTTPClientWithTLSConfig(conf *tls.Config) *http.Client
- type Client
- func (c *Client) Close() error
- func (c *Client) Ping(ctx context.Context) error
- func (c *Client) QueryCSV(ctx context.Context, flux string, org string, extern ...interface{}) (*QueryCSVResult, error)
- func (c *Client) Setup(ctx context.Context, bucket, org string, retentionPeriodHrs int) (*SetupResult, error)
- func (c *Client) Write(ctx context.Context, bucket, org string, m ...Metric) (n int, err error)
- type Error
- type Field
- type HTTPConfig
- type Metric
- type Option
- type QueryCSVResult
- type RowMetric
- func (m *RowMetric) AddField(k string, v interface{})
- func (m *RowMetric) AddTag(k, v string)
- func (m *RowMetric) FieldList() []*lp.Field
- func (m *RowMetric) Name() string
- func (m *RowMetric) SortFields()
- func (m *RowMetric) SortTags()
- func (m *RowMetric) TagList() []*lp.Tag
- func (m *RowMetric) Time() time.Time
- type SetupRequest
- type SetupResult
- type Tag
Examples ¶
Constants ¶
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" EForbidden = "forbidden" ETooManyRequests = "too many requests" EMethodNotAllowed = "method not allowed" )
Error code constants copied from influxdb
Variables ¶
var ErrUnimplemented = errors.New("unimplemented")
ErrUnimplemented is an error for when pieces of the client's functionality is unimplemented.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a client for writing to influx.
func New ¶
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) 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 ¶
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
type 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 ¶
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 ¶
WithGZIP returns an option for setting gzip compression level. The default (should this option not be used ) is level 4.
func WithHTTPClient ¶
WithHTTPClient returns an option for setting a custom HTTP Client
func WithMaxLineBytes ¶
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 ¶
WithUserAgent returns an option for setting a custom useragent string.
func WithUserAndPass ¶
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 ¶
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) 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.
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.
Source Files ¶
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. |