diff --git a/.chloggen/feat_influxdb-1x.yaml b/.chloggen/feat_influxdb-1x.yaml new file mode 100755 index 000000000000..a1889bb0f017 --- /dev/null +++ b/.chloggen/feat_influxdb-1x.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: influxdbexporter + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add support for exporting to InfluxDB v1.X API + +# One or more tracking issues related to the change +issues: [] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/exporter/influxdbexporter/README.md b/exporter/influxdbexporter/README.md index c5bc489926ad..5445bba44eb5 100644 --- a/exporter/influxdbexporter/README.md +++ b/exporter/influxdbexporter/README.md @@ -21,6 +21,11 @@ The following configuration options are supported: * `org` (required) Name of InfluxDB organization that owns the destination bucket * `bucket` (required) name of InfluxDB bucket to which signals will be written * `token` (optional) The authentication token for InfluxDB +* `v1_compatibility` (optional) Options for exporting to InfluxDB v1.x + * `enabled` (optional) Use InfluxDB v1.x API if enabled + * `db` (required if enabled) Name of the InfluxDB database to which signals will be written + * `username` (optional) Basic auth username for authenticating with InfluxDB v1.x + * `password` (optional) Basic auth password for authenticating with InfluxDB v1.x * `metrics_schema` (default = telegraf-prometheus-v1) The chosen metrics schema to write; must be one of: * `telegraf-prometheus-v1` * `telegraf-prometheus-v2` diff --git a/exporter/influxdbexporter/config.go b/exporter/influxdbexporter/config.go index a8f3a1dc0480..e3b45dc381cf 100644 --- a/exporter/influxdbexporter/config.go +++ b/exporter/influxdbexporter/config.go @@ -30,6 +30,18 @@ const ( stability = component.StabilityLevelBeta ) +// V1Compatibility is used to specify if the exporter should use the v1.X InfluxDB API schema. +type V1Compatibility struct { + // Enabled is used to specify if the exporter should use the v1.X InfluxDB API schema + Enabled bool `mapstructure:"enabled"` + // DB is used to specify the name of the V1 InfluxDB database that telemetry will be written to. + DB string `mapstructure:"db"` + // Username is used to optionally specify the basic auth username + Username string `mapstructure:"username"` + // Password is used to optionally specify the basic auth password + Password string `mapstructure:"password"` +} + // Config defines configuration for the InfluxDB exporter. type Config struct { config.ExporterSettings `mapstructure:",squash"` @@ -43,6 +55,8 @@ type Config struct { Bucket string `mapstructure:"bucket"` // Token is used to identify InfluxDB permissions within the organization. Token string `mapstructure:"token"` + // V1Compatibility is used to specify if the exporter should use the v1.X InfluxDB API schema. + V1Compatibility V1Compatibility `mapstructure:"v1_compatibility"` // MetricsSchema indicates the metrics schema to emit to line protocol. // Options: diff --git a/exporter/influxdbexporter/writer.go b/exporter/influxdbexporter/writer.go index 735d3ee86c8b..ae58af94ef09 100644 --- a/exporter/influxdbexporter/writer.go +++ b/exporter/influxdbexporter/writer.go @@ -17,6 +17,7 @@ package influxdbexporter // import "github.com/open-telemetry/opentelemetry-coll import ( "bytes" "context" + "encoding/base64" "fmt" "io" "net/http" @@ -45,21 +46,39 @@ func newInfluxHTTPWriter(logger common.Logger, config *Config, host component.Ho return nil, err } if writeURL.Path == "" || writeURL.Path == "/" { - writeURL, err = writeURL.Parse("api/v2/write") - if err != nil { - return nil, err + if config.V1Compatibility.Enabled { + writeURL, err = writeURL.Parse("write") + if err != nil { + return nil, err + } + } else { + writeURL, err = writeURL.Parse("api/v2/write") + if err != nil { + return nil, err + } } } queryValues := writeURL.Query() - queryValues.Set("org", config.Org) - queryValues.Set("bucket", config.Bucket) queryValues.Set("precision", "ns") - writeURL.RawQuery = queryValues.Encode() - if config.Token != "" { - config.HTTPClientSettings.Headers["Authorization"] = "Token " + config.Token + if config.V1Compatibility.Enabled { + queryValues.Set("db", config.V1Compatibility.DB) + + if config.V1Compatibility.Username != "" && config.V1Compatibility.Password != "" { + var basicAuth []byte + base64.StdEncoding.Encode(basicAuth, []byte(config.V1Compatibility.Username+":"+config.V1Compatibility.Password)) + config.HTTPClientSettings.Headers["Authorization"] = "Basic " + string(basicAuth) + } + } else { + queryValues.Set("org", config.Org) + queryValues.Set("bucket", config.Bucket) + + if config.Token != "" { + config.HTTPClientSettings.Headers["Authorization"] = "Token " + config.Token + } } + writeURL.RawQuery = queryValues.Encode() httpClient, err := config.HTTPClientSettings.ToClient(host, settings) if err != nil { return nil, err