func influxConnect(config StartupConfig, runningConfig RunningConfig) (influx.Client, error) { var hosts []*InfluxDBProps for _, InfluxHost := range runningConfig.InfluxDBs { if InfluxHost.InfluxClient == nil { if config.InfluxProtocol == "udp" { conf := influx.UDPConfig{ Addr: fmt.Sprintf("%s:%d", InfluxHost.Fqdn, InfluxHost.Port), } con, err := influx.NewUDPClient(conf) if err != nil { errHndlr(err, ERROR) continue } InfluxHost.InfluxClient = con } else { conf := influx.HTTPConfig{ Addr: fmt.Sprintf("%s://%s:%d", config.InfluxProtocol, InfluxHost.Fqdn, InfluxHost.Port), Username: config.InfluxUser, Password: config.InfluxPassword, } con, err := influx.NewHTTPClient(conf) if err != nil { errHndlr(err, ERROR) continue } InfluxHost.InfluxClient = con } } hosts = append(hosts, InfluxHost) } for len(hosts) > 0 { n := rand.Intn(len(hosts)) host := hosts[n] hosts = append(hosts[:n], hosts[n+1:]...) con := host.InfluxClient //client currently does not support udp queries if config.InfluxProtocol != "udp" { _, _, err := con.Ping(10) if err != nil { errHndlr(err, ERROR) host.InfluxClient = nil continue } } return con, nil } err := errors.New("Could not connect to any of the InfluxDb servers that are ONLINE in traffic ops.") return nil, err }
func influxConnect(config StartupConfig) (influx.Client, error) { hosts := config.InfluxDBs for len(hosts) > 0 { n := rand.Intn(len(hosts)) host := hosts[n] hosts = append(hosts[:n], hosts[n+1:]...) parsedURL, _ := url.Parse(host.URL) if parsedURL.Scheme == "udp" { conf := influx.UDPConfig{ Addr: parsedURL.Host, } con, err := influx.NewUDPClient(conf) if err != nil { errHndlr(fmt.Errorf("An error occurred creating udp client. %v\n", err), ERROR) continue } return con, nil } //if not udp assume HTTP client conf := influx.HTTPConfig{ Addr: parsedURL.String(), Username: config.InfluxUser, Password: config.InfluxPassword, } con, err := influx.NewHTTPClient(conf) if err != nil { errHndlr(fmt.Errorf("An error occurred creating HTTP client. %v\n", err), ERROR) continue } //Close old connections explicitly if host.InfluxClient != nil { host.InfluxClient.Close() } host.InfluxClient = con _, _, err = con.Ping(10) if err != nil { errHndlr(err, WARN) continue } return con, nil } err := errors.New("Could not connect to any of the InfluxDb servers defined in the influxUrls config.") return nil, err }
// NewSender returns a function that will accept datapoints to send to influxdb func NewSender( config interface{}, batch client.BatchPointsConfig, batchSize int, queueSize int, flush int, errFunc func(error), ) (Sender, error) { if batchSize <= 0 { batchSize = DefaultBatchSize } if queueSize <= 0 { queueSize = DefaultQueueSize } if flush <= 0 { flush = DefaultFlush } var conn client.Client var err error switch conf := config.(type) { case client.HTTPConfig: conn, err = client.NewHTTPClient(conf) if err != nil { return nil, errors.Wrap(err, "error creating HTTPClient") } _, _, err = conn.Ping(conf.Timeout) if err != nil { return nil, fmt.Errorf("cannot ping influxdb server: %s", conf.Addr) } if err := dbCheck(conn, batch.Database); err != nil { return nil, errors.Wrapf(err, "check for database %s failed", batch.Database) } case client.UDPConfig: conn, err = client.NewUDPClient(conf) if err != nil { return nil, errors.Wrap(err, "error creating UDPClient") } } pts := make(chan *client.Point, queueSize) bp, err := client.NewBatchPoints(batch) if err != nil { return nil, errors.Wrap(err, "batchpoints error") } go func() { delay := time.Duration(flush) * time.Second tick := time.Tick(delay) count := 0 for { select { case p := <-pts: bp.AddPoint(p) count++ if count < batchSize { continue } case <-tick: if len(bp.Points()) == 0 { continue } } for { if err := conn.Write(bp); err != nil { if errFunc != nil { errFunc(err) } time.Sleep(retry) continue } bp, _ = client.NewBatchPoints(batch) count = 0 break } } }() return func(key string, tags map[string]string, fields map[string]interface{}, ts time.Time) error { pt, err := client.NewPoint(key, tags, fields, ts) if err != nil { return err } pts <- pt return nil }, nil }