145 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
| // +build linux
 | |
| 
 | |
| package wireless
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"io/ioutil"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	"path"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/influxdata/telegraf"
 | |
| 	"github.com/influxdata/telegraf/plugins/inputs"
 | |
| )
 | |
| 
 | |
| // default host proc path
 | |
| const defaultHostProc = "/proc"
 | |
| 
 | |
| // env host proc variable name
 | |
| const envProc = "HOST_PROC"
 | |
| 
 | |
| // length of wireless interface fields
 | |
| const interfaceFieldLength = 10
 | |
| 
 | |
| var newLineByte = []byte("\n")
 | |
| 
 | |
| type wirelessInterface struct {
 | |
| 	Interface string
 | |
| 	Status    int64
 | |
| 	Link      int64
 | |
| 	Level     int64
 | |
| 	Noise     int64
 | |
| 	Nwid      int64
 | |
| 	Crypt     int64
 | |
| 	Frag      int64
 | |
| 	Retry     int64
 | |
| 	Misc      int64
 | |
| 	Beacon    int64
 | |
| }
 | |
| 
 | |
| // Gather collects the wireless information.
 | |
| func (w *Wireless) Gather(acc telegraf.Accumulator) error {
 | |
| 	// load proc path, get default value if config value and env variable are empty
 | |
| 	w.loadPath()
 | |
| 
 | |
| 	wirelessPath := path.Join(w.HostProc, "net", "wireless")
 | |
| 	table, err := ioutil.ReadFile(wirelessPath)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	interfaces, err := loadWirelessTable(table)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	for _, w := range interfaces {
 | |
| 		tags := map[string]string{
 | |
| 			"interface": w.Interface,
 | |
| 		}
 | |
| 		fieldsG := map[string]interface{}{
 | |
| 			"status": w.Status,
 | |
| 			"link":   w.Link,
 | |
| 			"level":  w.Level,
 | |
| 			"noise":  w.Noise,
 | |
| 		}
 | |
| 		fieldsC := map[string]interface{}{
 | |
| 			"nwid":   w.Nwid,
 | |
| 			"crypt":  w.Crypt,
 | |
| 			"frag":   w.Frag,
 | |
| 			"retry":  w.Retry,
 | |
| 			"misc":   w.Misc,
 | |
| 			"beacon": w.Beacon,
 | |
| 		}
 | |
| 		acc.AddGauge("wireless", fieldsG, tags)
 | |
| 		acc.AddCounter("wireless", fieldsC, tags)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func loadWirelessTable(table []byte) ([]*wirelessInterface, error) {
 | |
| 	var w []*wirelessInterface
 | |
| 	lines := bytes.Split(table, newLineByte)
 | |
| 
 | |
| 	// iterate over interfaces
 | |
| 	for i := 2; i < len(lines); i = i + 1 {
 | |
| 		if len(lines[i]) == 0 {
 | |
| 			continue
 | |
| 		}
 | |
| 		values := make([]int64, 0, interfaceFieldLength)
 | |
| 		fields := strings.Fields(string(lines[i]))
 | |
| 		for j := 1; j < len(fields); j = j + 1 {
 | |
| 			v, err := strconv.ParseInt(strings.Trim(fields[j], "."), 10, 64)
 | |
| 			if err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 			values = append(values, v)
 | |
| 		}
 | |
| 		if len(values) != interfaceFieldLength {
 | |
| 			log.Printf("E! [input.wireless] invalid length of interface values")
 | |
| 			continue
 | |
| 		}
 | |
| 		w = append(w, &wirelessInterface{
 | |
| 			Interface: strings.Trim(fields[0], ":"),
 | |
| 			Status:    values[0],
 | |
| 			Link:      values[1],
 | |
| 			Level:     values[2],
 | |
| 			Noise:     values[3],
 | |
| 			Nwid:      values[4],
 | |
| 			Crypt:     values[5],
 | |
| 			Frag:      values[6],
 | |
| 			Retry:     values[7],
 | |
| 			Misc:      values[8],
 | |
| 			Beacon:    values[9],
 | |
| 		})
 | |
| 	}
 | |
| 	return w, nil
 | |
| }
 | |
| 
 | |
| // loadPath can be used to read path firstly from config
 | |
| // if it is empty then try read from env variable
 | |
| func (w *Wireless) loadPath() {
 | |
| 	if w.HostProc == "" {
 | |
| 		w.HostProc = proc(envProc, defaultHostProc)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // proc can be used to read file paths from env
 | |
| func proc(env, path string) string {
 | |
| 	// try to read full file path
 | |
| 	if p := os.Getenv(env); p != "" {
 | |
| 		return p
 | |
| 	}
 | |
| 	// return default path
 | |
| 	return path
 | |
| }
 | |
| 
 | |
| func init() {
 | |
| 	inputs.Add("wireless", func() telegraf.Input {
 | |
| 		return &Wireless{}
 | |
| 	})
 | |
| }
 |