package nats import ( "fmt" "log" "strings" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/internal/tls" "github.com/influxdata/telegraf/plugins/outputs" "github.com/influxdata/telegraf/plugins/serializers" "github.com/nats-io/nats.go" ) type NATS struct { Servers []string `toml:"servers"` Secure bool `toml:"secure"` Username string `toml:"username"` Password string `toml:"password"` Credentials string `toml:"credentials"` Subject string `toml:"subject"` tls.ClientConfig conn *nats.Conn serializer serializers.Serializer } var sampleConfig = ` ## URLs of NATS servers servers = ["nats://localhost:4222"] ## Optional credentials # username = "" # password = "" ## Optional NATS 2.0 and NATS NGS compatible user credentials # credentials = "/etc/telegraf/nats.creds" ## NATS subject for producer messages subject = "telegraf" ## Use Transport Layer Security # secure = false ## Optional TLS Config # tls_ca = "/etc/telegraf/ca.pem" # tls_cert = "/etc/telegraf/cert.pem" # tls_key = "/etc/telegraf/key.pem" ## Use TLS but skip chain & host verification # insecure_skip_verify = false ## Data format to output. ## Each data format has its own unique set of configuration options, read ## more about them here: ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_OUTPUT.md data_format = "influx" ` func (n *NATS) SetSerializer(serializer serializers.Serializer) { n.serializer = serializer } func (n *NATS) Connect() error { var err error opts := []nats.Option{ nats.MaxReconnects(-1), } // override authentication, if any was specified if n.Username != "" { opts = append(opts, nats.UserInfo(n.Username, n.Password)) } if n.Secure { tlsConfig, err := n.ClientConfig.TLSConfig() if err != nil { return err } opts = append(opts, nats.Secure(tlsConfig)) } // try and connect n.conn, err = nats.Connect(strings.Join(n.Servers, ","), opts...) return err } func (n *NATS) Close() error { n.conn.Close() return nil } func (n *NATS) SampleConfig() string { return sampleConfig } func (n *NATS) Description() string { return "Send telegraf measurements to NATS" } func (n *NATS) Write(metrics []telegraf.Metric) error { if len(metrics) == 0 { return nil } for _, metric := range metrics { buf, err := n.serializer.Serialize(metric) if err != nil { log.Printf("D! [outputs.nats] Could not serialize metric: %v", err) continue } err = n.conn.Publish(n.Subject, buf) if err != nil { return fmt.Errorf("FAILED to send NATS message: %s", err) } } return nil } func init() { outputs.Add("nats", func() telegraf.Output { return &NATS{} }) }