// NewInfluxDB returns a new InfluxDBHook. func NewInfluxDB(config *Config, clients ...influxdb.Client) (hook *InfluxDBHook, err error) { if config == nil { config = &Config{} } config.defaults() var client influxdb.Client if len(clients) == 0 { client, err = hook.newInfluxDBClient(config) if err != nil { return nil, fmt.Errorf("NewInfluxDB: Error creating InfluxDB Client, %v", err) } } else if len(clients) == 1 { client = clients[0] } else { return nil, fmt.Errorf("NewInfluxDB: Error creating InfluxDB Client, %d is too many influxdb clients", len(clients)) } // Make sure that we can connect to InfluxDB _, _, err = client.Ping(5 * time.Second) // if this takes more than 5 seconds then influxdb is probably down if err != nil { return nil, fmt.Errorf("NewInfluxDB: Error connecting to InfluxDB, %v", err) } hook = &InfluxDBHook{ client: client, database: config.Database, measurement: config.Measurement, tagList: config.Tags, batchInterval: config.BatchInterval, batchCount: config.BatchCount, precision: config.Precision, } err = hook.autocreateDatabase() if err != nil { return nil, err } go hook.handleBatch() return hook, nil }
// 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 }