diff --git a/integrations/promunifi/Gopkg.lock b/integrations/promunifi/Gopkg.lock index c037c0da..7a4f5692 100644 --- a/integrations/promunifi/Gopkg.lock +++ b/integrations/promunifi/Gopkg.lock @@ -2,12 +2,12 @@ [[projects]] - digest = "1:e7f0acf99afe9a7b03d270164bd2976b687e1aef02ab3a0abd8db0b4de44b817" + digest = "1:9543804b8019077cb769bc3b15bfb0640fc732f8b061df323a973171b979d02f" name = "github.com/golift/unifi" packages = ["."] pruneopts = "UT" - revision = "f8fec42fbe169dceb69f15276a2323fb007a4539" - version = "v1.0.0" + revision = "1779d2c07abd748d0d23868356ef517ac2e00e7e" + version = "v1.0.1" [[projects]] branch = "master" diff --git a/integrations/promunifi/cmd/unifi-poller/README.md b/integrations/promunifi/cmd/unifi-poller/README.md index b506d037..31b75051 100644 --- a/integrations/promunifi/cmd/unifi-poller/README.md +++ b/integrations/promunifi/cmd/unifi-poller/README.md @@ -30,6 +30,10 @@ unifi-poller(1) -- Utility to poll Unifi Metrics and drop them into InfluxDB `Config File Parameters` + `sites` default: ["default"] + This list of strings should represent the names of sites on the unifi + controller that should be polled for data. + `interval` default: 30s How often to poll the controller for updated client and device data. The Unifi Controller only updates traffic stats about every 30 seconds. diff --git a/integrations/promunifi/cmd/unifi-poller/config.go b/integrations/promunifi/cmd/unifi-poller/config.go index 9b69ad86..68b8e217 100644 --- a/integrations/promunifi/cmd/unifi-poller/config.go +++ b/integrations/promunifi/cmd/unifi-poller/config.go @@ -22,17 +22,18 @@ const ( // Config represents the data needed to poll a controller and report to influxdb. type Config struct { - Interval Dur `json:"interval" toml:"interval" xml:"interval" yaml:"interval"` - Debug bool `json:"debug" toml:"debug" xml:"debug" yaml:"debug"` - Quiet bool `json:"quiet" toml:"quiet" xml:"quiet" yaml:"quiet"` - VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"` - InfluxURL string `json:"influx_url" toml:"influx_url" xml:"influx_url" yaml:"influx_url"` - InfluxUser string `json:"influx_user" toml:"influx_user" xml:"influx_user" yaml:"influx_user"` - InfluxPass string `json:"influx_pass" toml:"influx_pass" xml:"influx_pass" yaml:"influx_pass"` - InfluxDB string `json:"influx_db" toml:"influx_db" xml:"influx_db" yaml:"influx_db"` - UnifiUser string `json:"unifi_user" toml:"unifi_user" xml:"unifi_user" yaml:"unifi_user"` - UnifiPass string `json:"unifi_pass" toml:"unifi_pass" xml:"unifi_pass" yaml:"unifi_pass"` - UnifiBase string `json:"unifi_url" toml:"unifi_url" xml:"unifi_url" yaml:"unifi_url"` + Interval Dur `json:"interval" toml:"interval" xml:"interval" yaml:"interval"` + Debug bool `json:"debug" toml:"debug" xml:"debug" yaml:"debug"` + Quiet bool `json:"quiet" toml:"quiet" xml:"quiet" yaml:"quiet"` + VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"` + InfluxURL string `json:"influx_url" toml:"influx_url" xml:"influx_url" yaml:"influx_url"` + InfluxUser string `json:"influx_user" toml:"influx_user" xml:"influx_user" yaml:"influx_user"` + InfluxPass string `json:"influx_pass" toml:"influx_pass" xml:"influx_pass" yaml:"influx_pass"` + InfluxDB string `json:"influx_db" toml:"influx_db" xml:"influx_db" yaml:"influx_db"` + UnifiUser string `json:"unifi_user" toml:"unifi_user" xml:"unifi_user" yaml:"unifi_user"` + UnifiPass string `json:"unifi_pass" toml:"unifi_pass" xml:"unifi_pass" yaml:"unifi_pass"` + UnifiBase string `json:"unifi_url" toml:"unifi_url" xml:"unifi_url" yaml:"unifi_url"` + Sites []string `json:"sites" toml:"sites" xml:"sites" yaml:"sites"` } // Dur is used to UnmarshalTOML into a time.Duration value. diff --git a/integrations/promunifi/cmd/unifi-poller/main.go b/integrations/promunifi/cmd/unifi-poller/main.go index a6514334..51c88a95 100644 --- a/integrations/promunifi/cmd/unifi-poller/main.go +++ b/integrations/promunifi/cmd/unifi-poller/main.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "log" "os" + "strings" "time" "github.com/golift/unifi" @@ -86,6 +87,7 @@ func GetConfig(configFile string) (Config, error) { Debug: defaultDebug, Quiet: defaultQuiet, Interval: Dur{value: defaultInterval}, + Sites: []string{"default"}, } if buf, err := ioutil.ReadFile(configFile); err != nil { return config, err @@ -102,9 +104,11 @@ func (c *Config) PollUnifiController(controller *unifi.Unifi, infdb influx.Clien log.Println("[INFO] Everyting checks out! Beginning Poller Routine.") ticker := time.NewTicker(c.Interval.value) for range ticker.C { - if clients, err := controller.GetClients(); err != nil { + if sites, err := filterSites(controller, c.Sites); err != nil { + logErrors([]error{err}, "uni.GetSites()") + } else if clients, err := controller.GetClients(sites); err != nil { logErrors([]error{err}, "uni.GetClients()") - } else if devices, err := controller.GetDevices(); err != nil { + } else if devices, err := controller.GetDevices(sites); err != nil { logErrors([]error{err}, "uni.GetDevices()") } else if bp, err := influx.NewBatchPoints(influx.BatchPointsConfig{Database: c.InfluxDB}); err != nil { logErrors([]error{err}, "influx.NewBatchPoints") @@ -113,12 +117,31 @@ func (c *Config) PollUnifiController(controller *unifi.Unifi, infdb influx.Clien } else if err := infdb.Write(bp); err != nil { logErrors([]error{err}, "infdb.Write(bp)") } else if !c.Quiet { - log.Println("[INFO] Logged Unifi States. Clients:", len(clients.UCLs), "- Wireless APs:", - len(devices.UAPs), "Gateways:", len(devices.USGs), "Switches:", len(devices.USWs)) + log.Printf("[INFO] Logged Unifi States. Sites: %d Clients: %d, Wireless APs: %d, Gateways: %d, Switches: %d", + len(sites), len(clients.UCLs), len(devices.UAPs), len(devices.USGs), len(devices.USWs)) } } } +// filterSites returns a list of sites to fetch data for. +// Omits requested but unconfigured sites. +func filterSites(controller *unifi.Unifi, filter []string) ([]string, error) { + sites, err := controller.GetSites() + if err != nil { + return filter, err + } else if len(filter) < 1 || StringInSlice("all", filter) { + return sites, nil + } + output := []string{} + for _, s := range filter { + // Do not return requested sites that are not configured. + if StringInSlice(s, sites) { + output = append(output, s) + } + } + return output, nil +} + // batchPoints combines all device and client data into influxdb data points. func batchPoints(devices *unifi.Devices, clients *unifi.Clients, batchPoints influx.BatchPoints) (errs []error) { process := func(asset Asset) error { @@ -162,3 +185,13 @@ func logErrors(errs []error, prefix string) { } } } + +// StringInSlice returns true if a string is in a slice. +func StringInSlice(str string, slc []string) bool { + for _, s := range slc { + if strings.EqualFold(s, str) { + return true + } + } + return false +} diff --git a/integrations/promunifi/up.conf.example b/integrations/promunifi/up.conf.example index 30f411f8..723779e1 100644 --- a/integrations/promunifi/up.conf.example +++ b/integrations/promunifi/up.conf.example @@ -3,6 +3,10 @@ # commented lines are defaults, uncomment to change. # ########################################################## +# If the controller has more than one site, specify which sites to poll here. +# If only one site, "default" is likely the correct name. +#sites = ["default"] + # The Unifi Controller only updates traffic stats about every 30 seconds. # Setting this to something lower may lead to "zeros" in your data. You've been warned. #interval = "30s"