package lanz import ( "net/url" "strconv" "sync" "time" "github.com/aristanetworks/goarista/lanz" pb "github.com/aristanetworks/goarista/lanz/proto" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/plugins/inputs" ) var sampleConfig = ` ## URL to Arista LANZ endpoint servers = [ "tcp://127.0.0.1:50001" ] ` func init() { inputs.Add("lanz", func() telegraf.Input { return NewLanz() }) } type Lanz struct { Servers []string `toml:"servers"` clients []lanz.Client wg sync.WaitGroup } func NewLanz() *Lanz { return &Lanz{} } func (l *Lanz) SampleConfig() string { return sampleConfig } func (l *Lanz) Description() string { return "Read metrics off Arista LANZ, via socket" } func (l *Lanz) Gather(acc telegraf.Accumulator) error { return nil } func (l *Lanz) Start(acc telegraf.Accumulator) error { if len(l.Servers) == 0 { l.Servers = append(l.Servers, "tcp://127.0.0.1:50001") } for _, server := range l.Servers { deviceUrl, err := url.Parse(server) if err != nil { return err } client := lanz.New( lanz.WithAddr(deviceUrl.Host), lanz.WithBackoff(1*time.Second), lanz.WithTimeout(10*time.Second), ) l.clients = append(l.clients, client) in := make(chan *pb.LanzRecord) go func() { client.Run(in) }() l.wg.Add(1) go func() { l.wg.Done() receive(acc, in, deviceUrl) }() } return nil } func (l *Lanz) Stop() { for _, client := range l.clients { client.Stop() } l.wg.Wait() } func receive(acc telegraf.Accumulator, in <-chan *pb.LanzRecord, deviceUrl *url.URL) { for { select { case msg, ok := <-in: if !ok { return } msgToAccumulator(acc, msg, deviceUrl) } } } func msgToAccumulator(acc telegraf.Accumulator, msg *pb.LanzRecord, deviceUrl *url.URL) { cr := msg.GetCongestionRecord() if cr != nil { vals := map[string]interface{}{ "timestamp": int64(cr.GetTimestamp()), "queue_size": int64(cr.GetQueueSize()), "time_of_max_qlen": int64(cr.GetTimeOfMaxQLen()), "tx_latency": int64(cr.GetTxLatency()), "q_drop_count": int64(cr.GetQDropCount()), } tags := map[string]string{ "intf_name": cr.GetIntfName(), "switch_id": strconv.FormatInt(int64(cr.GetSwitchId()), 10), "port_id": strconv.FormatInt(int64(cr.GetPortId()), 10), "entry_type": strconv.FormatInt(int64(cr.GetEntryType()), 10), "traffic_class": strconv.FormatInt(int64(cr.GetTrafficClass()), 10), "fabric_peer_intf_name": cr.GetFabricPeerIntfName(), "source": deviceUrl.Hostname(), "port": deviceUrl.Port(), } acc.AddFields("lanz_congestion_record", vals, tags) } gbur := msg.GetGlobalBufferUsageRecord() if gbur != nil { vals := map[string]interface{}{ "timestamp": int64(gbur.GetTimestamp()), "buffer_size": int64(gbur.GetBufferSize()), "duration": int64(gbur.GetDuration()), } tags := map[string]string{ "entry_type": strconv.FormatInt(int64(gbur.GetEntryType()), 10), "source": deviceUrl.Hostname(), "port": deviceUrl.Port(), } acc.AddFields("lanz_global_buffer_usage_record", vals, tags) } }