<commit_before>package influxdb

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"net/url"
	"strings"

	"github.com/influxdb/influxdb/client/v2"
	"github.com/influxdb/telegraf/duration"
	"github.com/influxdb/telegraf/outputs"
)

type InfluxDB struct {
	// URL is only for backwards compatability
	URL       string
	URLs      []string `toml:"urls"`
	Username  string
	Password  string
	Database  string
	UserAgent string
	Precision string
	Timeout   duration.Duration

	conns []client.Client
}

var sampleConfig = `
  # The full HTTP endpoint URL for your InfluxDB instance
  # Multiple urls can be specified for InfluxDB cluster support.
  urls = ["http://localhost:8086"] # required
  # The target database for metrics (telegraf will create it if not exists)
  database = "telegraf" # required
  # Precision of writes, valid values are n, u, ms, s, m, and h
  # note: using second precision greatly helps InfluxDB compression
  precision = "s"

  # Connection timeout (for the connection with InfluxDB), formatted as a string.
  # If not provided, will default to 0 (no timeout)
  # timeout = "5s"
  # username = "telegraf"
  # password = "<PASSWORD>"
  # Set the user agent for the POSTs (can be useful for log differentiation)
  # user_agent = "telegraf"
`

func (i *InfluxDB) Connect() error {
	var urls []*url.URL
	for _, URL := range i.URLs {
		u, err := url.Parse(URL)
		if err != nil {
			return err
		}
		urls = append(urls, u)
	}

	// Backward-compatability with single Influx URL config files
	// This could eventually be removed in favor of specifying the urls as a list
	if i.URL != "" {
		u, err := url.Parse(i.URL)
		if err != nil {
			return err
		}
		urls = append(urls, u)
	}

	var conns []client.Client
	for _, parsed_url := range urls {
		c := client.NewClient(client.Config{
			URL:       parsed_url,
			Username:  i.Username,
			Password:  <PASSWORD>,
			UserAgent: i.UserAgent,
			Timeout:   i.Timeout.Duration,
		})
		conns = append(conns, c)
	}

	// This will get set to nil if a successful connection is made
	err := errors.New("Could not create database on any server")

	for _, conn := range conns {
		_, e := conn.Query(client.Query{
			Command: fmt.Sprintf("CREATE DATABASE %s", i.Database),
		})

		if e != nil && !strings.Contains(e.Error(), "database already exists") {
			log.Println("ERROR: " + e.Error())
		} else {
			err = nil
			break
		}
	}

	i.conns = conns
	return err
}

func (i *InfluxDB) Close() error {
	// InfluxDB client does not provide a Close() function
	return nil
}

func (i *InfluxDB) SampleConfig() string {<commit_msg>Do not fail Connect() in influxdb output when db creation fails<commit_after>package influxdb

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"net/url"
	"strings"

	"github.com/influxdb/influxdb/client/v2"
	"github.com/influxdb/telegraf/duration"
	"github.com/influxdb/telegraf/outputs"
)

type InfluxDB struct {
	// URL is only for backwards compatability
	URL       string
	URLs      []string `toml:"urls"`
	Username  string
	Password  string
	Database  string
	UserAgent string
	Precision string
	Timeout   duration.Duration

	conns []client.Client
}

var sampleConfig = `
  # The full HTTP endpoint URL for your InfluxDB instance
  # Multiple urls can be specified for InfluxDB cluster support.
  urls = ["http://localhost:8086"] # required
  # The target database for metrics (telegraf will create it if not exists)
  database = "telegraf" # required
  # Precision of writes, valid values are n, u, ms, s, m, and h
  # note: using second precision greatly helps InfluxDB compression
  precision = "s"

  # Connection timeout (for the connection with InfluxDB), formatted as a string.
  # If not provided, will default to 0 (no timeout)
  # timeout = "5s"
  # username = "telegraf"
  # password = "<PASSWORD>"
  # Set the user agent for the POSTs (can be useful for log differentiation)
  # user_agent = "telegraf"
`

func (i *InfluxDB) Connect() error {
	var urls []*url.URL
	for _, URL := range i.URLs {
		u, err := url.Parse(URL)
		if err != nil {
			return err
		}
		urls = append(urls, u)
	}

	// Backward-compatability with single Influx URL config files
	// This could eventually be removed in favor of specifying the urls as a list
	if i.URL != "" {
		u, err := url.Parse(i.URL)
		if err != nil {
			return err
		}
		urls = append(urls, u)
	}

	var conns []client.Client
	for _, parsed_url := range urls {
		c := client.NewClient(client.Config{
			URL:       parsed_url,
			Username:  i.Username,
			Password:  <PASSWORD>,
			UserAgent: i.UserAgent,
			Timeout:   i.Timeout.Duration,
		})
		conns = append(conns, c)
	}

	for _, conn := range conns {
		_, e := conn.Query(client.Query{
			Command: fmt.Sprintf("CREATE DATABASE %s", i.Database),
		})

		if e != nil && !strings.Contains(e.Error(), "database already exists") {
			log.Println("Database creation failed: " + e.Error())
		} else {
			break
		}
	}

	i.conns = conns
	return nil
}

func (i *InfluxDB) Close() error {
	// InfluxDB client does not provide a Close() function
	return nil
}

func (i *InfluxDB) SampleConfig() string {
{'fraction_non_alphanumeric': 0.11389162561576355, 'fraction_numerical': 0.002758620689655172, 'mean_word_length': 3.3273657289002556, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6484293', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1706, 'n_words': 568}