2022-05-25 22:48:59 +08:00
|
|
|
//go:generate ../../../tools/readme_config_includer/generator
|
2018-09-13 05:48:59 +08:00
|
|
|
package influxdb_v2
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2022-05-25 22:48:59 +08:00
|
|
|
_ "embed"
|
2018-09-13 05:48:59 +08:00
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"math/rand"
|
|
|
|
|
"net/url"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/influxdata/telegraf"
|
2021-04-10 01:15:04 +08:00
|
|
|
"github.com/influxdata/telegraf/config"
|
2020-06-26 02:44:22 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/common/tls"
|
2018-09-13 05:48:59 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/outputs"
|
|
|
|
|
"github.com/influxdata/telegraf/plugins/serializers/influx"
|
|
|
|
|
)
|
|
|
|
|
|
2022-05-25 22:48:59 +08:00
|
|
|
// DO NOT REMOVE THE NEXT TWO LINES! This is required to embedd the sampleConfig data.
|
|
|
|
|
//go:embed sample.conf
|
|
|
|
|
var sampleConfig string
|
|
|
|
|
|
2018-09-13 05:48:59 +08:00
|
|
|
var (
|
2020-10-07 23:54:51 +08:00
|
|
|
defaultURL = "http://localhost:8086"
|
2018-09-13 05:48:59 +08:00
|
|
|
|
|
|
|
|
ErrMissingURL = errors.New("missing URL")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Client interface {
|
|
|
|
|
Write(context.Context, []telegraf.Metric) error
|
|
|
|
|
|
|
|
|
|
URL() string // for logging
|
2019-06-01 07:55:31 +08:00
|
|
|
Close()
|
2018-09-13 05:48:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type InfluxDB struct {
|
2019-07-31 05:16:51 +08:00
|
|
|
URLs []string `toml:"urls"`
|
|
|
|
|
Token string `toml:"token"`
|
|
|
|
|
Organization string `toml:"organization"`
|
|
|
|
|
Bucket string `toml:"bucket"`
|
|
|
|
|
BucketTag string `toml:"bucket_tag"`
|
|
|
|
|
ExcludeBucketTag bool `toml:"exclude_bucket_tag"`
|
2021-04-10 01:15:04 +08:00
|
|
|
Timeout config.Duration `toml:"timeout"`
|
2019-07-31 05:16:51 +08:00
|
|
|
HTTPHeaders map[string]string `toml:"http_headers"`
|
|
|
|
|
HTTPProxy string `toml:"http_proxy"`
|
|
|
|
|
UserAgent string `toml:"user_agent"`
|
|
|
|
|
ContentEncoding string `toml:"content_encoding"`
|
|
|
|
|
UintSupport bool `toml:"influx_uint_support"`
|
2018-09-13 05:48:59 +08:00
|
|
|
tls.ClientConfig
|
|
|
|
|
|
2021-02-17 07:19:50 +08:00
|
|
|
Log telegraf.Logger `toml:"-"`
|
|
|
|
|
|
2019-11-14 04:56:01 +08:00
|
|
|
clients []Client
|
2018-09-13 05:48:59 +08:00
|
|
|
}
|
|
|
|
|
|
2022-05-25 22:48:59 +08:00
|
|
|
func (*InfluxDB) SampleConfig() string {
|
|
|
|
|
return sampleConfig
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-13 05:48:59 +08:00
|
|
|
func (i *InfluxDB) Connect() error {
|
|
|
|
|
if len(i.URLs) == 0 {
|
|
|
|
|
i.URLs = append(i.URLs, defaultURL)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, u := range i.URLs {
|
|
|
|
|
parts, err := url.Parse(u)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("error parsing url [%q]: %v", u, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var proxy *url.URL
|
|
|
|
|
if len(i.HTTPProxy) > 0 {
|
|
|
|
|
proxy, err = url.Parse(i.HTTPProxy)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("error parsing proxy_url [%s]: %v", i.HTTPProxy, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch parts.Scheme {
|
|
|
|
|
case "http", "https", "unix":
|
2021-02-17 07:19:50 +08:00
|
|
|
c, err := i.getHTTPClient(parts, proxy)
|
2018-09-13 05:48:59 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i.clients = append(i.clients, c)
|
|
|
|
|
default:
|
|
|
|
|
return fmt.Errorf("unsupported scheme [%q]: %q", u, parts.Scheme)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (i *InfluxDB) Close() error {
|
2019-06-01 07:55:31 +08:00
|
|
|
for _, client := range i.clients {
|
|
|
|
|
client.Close()
|
|
|
|
|
}
|
2018-09-13 05:48:59 +08:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write sends metrics to one of the configured servers, logging each
|
|
|
|
|
// unsuccessful. If all servers fail, return an error.
|
|
|
|
|
func (i *InfluxDB) Write(metrics []telegraf.Metric) error {
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
p := rand.Perm(len(i.clients))
|
|
|
|
|
for _, n := range p {
|
|
|
|
|
client := i.clients[n]
|
|
|
|
|
err = client.Write(ctx, metrics)
|
|
|
|
|
if err == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-17 07:19:50 +08:00
|
|
|
i.Log.Errorf("When writing to [%s]: %v", client.URL(), err)
|
2018-09-13 05:48:59 +08:00
|
|
|
}
|
|
|
|
|
|
2022-04-12 04:45:48 +08:00
|
|
|
return fmt.Errorf("failed to send metrics to any configured server(s)")
|
2018-09-13 05:48:59 +08:00
|
|
|
}
|
|
|
|
|
|
2021-11-25 03:40:25 +08:00
|
|
|
func (i *InfluxDB) getHTTPClient(address *url.URL, proxy *url.URL) (Client, error) {
|
2018-09-13 05:48:59 +08:00
|
|
|
tlsConfig, err := i.ClientConfig.TLSConfig()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-25 03:40:25 +08:00
|
|
|
httpConfig := &HTTPConfig{
|
|
|
|
|
URL: address,
|
2019-07-31 05:16:51 +08:00
|
|
|
Token: i.Token,
|
|
|
|
|
Organization: i.Organization,
|
|
|
|
|
Bucket: i.Bucket,
|
|
|
|
|
BucketTag: i.BucketTag,
|
|
|
|
|
ExcludeBucketTag: i.ExcludeBucketTag,
|
2021-04-10 01:15:04 +08:00
|
|
|
Timeout: time.Duration(i.Timeout),
|
2019-07-31 05:16:51 +08:00
|
|
|
Headers: i.HTTPHeaders,
|
|
|
|
|
Proxy: proxy,
|
|
|
|
|
UserAgent: i.UserAgent,
|
|
|
|
|
ContentEncoding: i.ContentEncoding,
|
|
|
|
|
TLSConfig: tlsConfig,
|
2019-11-14 04:56:01 +08:00
|
|
|
Serializer: i.newSerializer(),
|
2021-11-25 03:40:25 +08:00
|
|
|
Log: i.Log,
|
2018-09-13 05:48:59 +08:00
|
|
|
}
|
|
|
|
|
|
2021-11-25 03:40:25 +08:00
|
|
|
c, err := NewHTTPClient(httpConfig)
|
2018-09-13 05:48:59 +08:00
|
|
|
if err != nil {
|
2021-11-25 03:40:25 +08:00
|
|
|
return nil, fmt.Errorf("error creating HTTP client [%s]: %v", address, err)
|
2018-09-13 05:48:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c, nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-14 04:56:01 +08:00
|
|
|
func (i *InfluxDB) newSerializer() *influx.Serializer {
|
|
|
|
|
serializer := influx.NewSerializer()
|
|
|
|
|
if i.UintSupport {
|
|
|
|
|
serializer.SetFieldTypeSupport(influx.UintSupport)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return serializer
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-13 05:48:59 +08:00
|
|
|
func init() {
|
|
|
|
|
outputs.Add("influxdb_v2", func() telegraf.Output {
|
|
|
|
|
return &InfluxDB{
|
2021-04-10 01:15:04 +08:00
|
|
|
Timeout: config.Duration(time.Second * 5),
|
2018-09-13 05:48:59 +08:00
|
|
|
ContentEncoding: "gzip",
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|