commit
b55bd6962b
|
|
@ -87,39 +87,39 @@ README.html: md2roff
|
||||||
# Binaries
|
# Binaries
|
||||||
|
|
||||||
build: $(BINARY)
|
build: $(BINARY)
|
||||||
$(BINARY):
|
$(BINARY): *.go */*.go
|
||||||
go build -o $(BINARY) -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
go build -o $(BINARY) -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
linux: $(BINARY).amd64.linux
|
linux: $(BINARY).amd64.linux
|
||||||
$(BINARY).amd64.linux:
|
$(BINARY).amd64.linux: *.go */*.go
|
||||||
# Building linux 64-bit x86 binary.
|
# Building linux 64-bit x86 binary.
|
||||||
GOOS=linux GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
GOOS=linux GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
linux386: $(BINARY).i386.linux
|
linux386: $(BINARY).i386.linux
|
||||||
$(BINARY).i386.linux:
|
$(BINARY).i386.linux: *.go */*.go
|
||||||
# Building linux 32-bit x86 binary.
|
# Building linux 32-bit x86 binary.
|
||||||
GOOS=linux GOARCH=386 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
GOOS=linux GOARCH=386 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
arm: arm64 armhf
|
arm: arm64 armhf
|
||||||
|
|
||||||
arm64: $(BINARY).arm64.linux
|
arm64: $(BINARY).arm64.linux
|
||||||
$(BINARY).arm64.linux:
|
$(BINARY).arm64.linux: *.go */*.go
|
||||||
# Building linux 64-bit ARM binary.
|
# Building linux 64-bit ARM binary.
|
||||||
GOOS=linux GOARCH=arm64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
GOOS=linux GOARCH=arm64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
armhf: $(BINARY).armhf.linux
|
armhf: $(BINARY).armhf.linux
|
||||||
$(BINARY).armhf.linux:
|
$(BINARY).armhf.linux: *.go */*.go
|
||||||
# Building linux 32-bit ARM binary.
|
# Building linux 32-bit ARM binary.
|
||||||
GOOS=linux GOARCH=arm GOARM=6 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
GOOS=linux GOARCH=arm GOARM=6 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
macos: $(BINARY).amd64.macos
|
macos: $(BINARY).amd64.macos
|
||||||
$(BINARY).amd64.macos:
|
$(BINARY).amd64.macos: *.go */*.go
|
||||||
# Building darwin 64-bit x86 binary.
|
# Building darwin 64-bit x86 binary.
|
||||||
GOOS=darwin GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
GOOS=darwin GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
exe: $(BINARY).amd64.exe
|
exe: $(BINARY).amd64.exe
|
||||||
windows: $(BINARY).amd64.exe
|
windows: $(BINARY).amd64.exe
|
||||||
$(BINARY).amd64.exe:
|
$(BINARY).amd64.exe: *.go */*.go
|
||||||
# Building windows 64-bit x86 binary.
|
# Building windows 64-bit x86 binary.
|
||||||
GOOS=windows GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
GOOS=windows GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||||
|
|
||||||
|
|
@ -222,7 +222,7 @@ formula: $(BINARY).rb
|
||||||
v$(VERSION).tar.gz.sha256:
|
v$(VERSION).tar.gz.sha256:
|
||||||
# Calculate the SHA from the Github source file.
|
# Calculate the SHA from the Github source file.
|
||||||
curl -sL $(URL)/archive/v$(VERSION).tar.gz | openssl dgst -r -sha256 | tee $@
|
curl -sL $(URL)/archive/v$(VERSION).tar.gz | openssl dgst -r -sha256 | tee $@
|
||||||
$(BINARY).rb: v$(VERSION).tar.gz.sha256
|
$(BINARY).rb: v$(VERSION).tar.gz.sha256 init/homebrew/$(FORMULA).rb.tmpl
|
||||||
# Creating formula from template using sed.
|
# Creating formula from template using sed.
|
||||||
sed -e "s/{{Version}}/$(VERSION)/g" \
|
sed -e "s/{{Version}}/$(VERSION)/g" \
|
||||||
-e "s/{{Iter}}/$(ITERATION)/g" \
|
-e "s/{{Iter}}/$(ITERATION)/g" \
|
||||||
|
|
@ -233,6 +233,7 @@ $(BINARY).rb: v$(VERSION).tar.gz.sha256
|
||||||
-e "s%{{CONFIG_FILE}}%$(CONFIG_FILE)%g" \
|
-e "s%{{CONFIG_FILE}}%$(CONFIG_FILE)%g" \
|
||||||
-e "s%{{Class}}%$(shell echo $(BINARY) | perl -pe 's/(?:\b|-)(\p{Ll})/\u$$1/g')%g" \
|
-e "s%{{Class}}%$(shell echo $(BINARY) | perl -pe 's/(?:\b|-)(\p{Ll})/\u$$1/g')%g" \
|
||||||
init/homebrew/$(FORMULA).rb.tmpl | tee $(BINARY).rb
|
init/homebrew/$(FORMULA).rb.tmpl | tee $(BINARY).rb
|
||||||
|
# That perl line turns hello-world into HelloWorld, etc.
|
||||||
|
|
||||||
# Extras
|
# Extras
|
||||||
|
|
||||||
|
|
@ -246,7 +247,7 @@ lint:
|
||||||
|
|
||||||
# This is safe; recommended even.
|
# This is safe; recommended even.
|
||||||
dep: vendor
|
dep: vendor
|
||||||
vendor:
|
vendor: Gopkg.*
|
||||||
dep ensure --vendor-only
|
dep ensure --vendor-only
|
||||||
|
|
||||||
# Don't run this unless you're ready to debug untested vendored dependencies.
|
# Don't run this unless you're ready to debug untested vendored dependencies.
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
# UniFi Poller
|
# UniFi Poller
|
||||||
|
|
||||||
[](https://hub.docker.com/r/golift/unifi-poller)
|
[](https://discord.gg/DyVsMyt)
|
||||||
[](https://www.somsubhra.com/github-release-stats/?username=davidnewhall&repository=unifi-poller)
|
[](https://twitter.com/TwitchCaptain)
|
||||||
[](https://github.com/davidnewhall/unifi-poller)
|
[](http://grafana.com/dashboards?search=unifi-poller)
|
||||||
[](https://github.com/golift/unifi)
|
[](https://hub.docker.com/r/golift/unifi-poller)
|
||||||
|
[](https://www.somsubhra.com/github-release-stats/?username=davidnewhall&repository=unifi-poller)
|
||||||
|
|
||||||
[](https://github.com/davidnewhall/unifi-poller/issues?q=is%3Aissue+is%3Aclosed)
|
[](https://github.com/golift/unifi)
|
||||||
[](https://github.com/davidnewhall/unifi-poller/pulls?utf8=✓&q=is%3Apr+)
|
[](https://github.com/golift/application-builder)
|
||||||
|
[](https://github.com/davidnewhall/unifi-poller)
|
||||||
[](https://travis-ci.org/davidnewhall/unifi-poller)
|
[](https://travis-ci.org/davidnewhall/unifi-poller)
|
||||||
[](https://github.com/davidnewhall/unifi-poller/blob/master/LICENSE)
|
|
||||||
[](https://discord.gg/DyVsMyt)
|
|
||||||
[](https://twitter.com/TwitchCaptain)
|
|
||||||
|
|
||||||
|
|
||||||
Collect your UniFi controller data and send it to an InfluxDB instance.
|
Collect your UniFi controller data and send it to an InfluxDB instance.
|
||||||
[Grafana Dashboards](http://grafana.com/dashboards?search=unifi-poller) included.
|
[Grafana Dashboards](http://grafana.com/dashboards?search=unifi-poller) included.
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,10 @@ OPTIONS
|
||||||
|
|
||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
---
|
---
|
||||||
* Config File Default Location: `/etc/unifi-poller/up.conf`
|
* Config File Default Location:
|
||||||
|
* Linux: `/etc/unifi-poller/up.conf`
|
||||||
|
* macOS: `/usr/local/etc/unifi-poller/up.conf`
|
||||||
|
* Windows: `C:\ProgramData\unifi-poller\up.conf`
|
||||||
* Config File Default Format: `TOML`
|
* Config File Default Format: `TOML`
|
||||||
* Possible formats: `XML`, `JSON`, `TOML`, `YAML`
|
* Possible formats: `XML`, `JSON`, `TOML`, `YAML`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
# Grafana Dashboards & Examples
|
# Examples
|
||||||
|
|
||||||
|
This folder contains example configuration files in four
|
||||||
|
supported formats. You can use any format you want for
|
||||||
|
the config file, just give it the appropriate suffix for
|
||||||
|
the format. An XML file should end with `.xml`, a JSON
|
||||||
|
file with `.json`, and YAML with `.yaml`. The default
|
||||||
|
format is always TOML and may have any _other_ suffix.
|
||||||
|
|
||||||
|
#### Dashboards
|
||||||
This folder used to contain Grafana Dashboards.
|
This folder used to contain Grafana Dashboards.
|
||||||
|
**They are now located at [Grafana.com](https://grafana.com/dashboards?search=unifi-poller).**
|
||||||
**They are now located at [Grafana.com](https://grafana.com/dashboards?search=unifi-poller).** More info is available on The [Grafana Dashboards Wiki Page](https://github.com/davidnewhall/unifi-poller/wiki/Grafana-Dashboards).
|
Also see [Grafana Dashboards](https://github.com/davidnewhall/unifi-poller/wiki/Grafana-Dashboards) Wiki.
|
||||||
|
|
||||||
This folder contains example configuration files in four supported formats.
|
|
||||||
You can use any format you want for the config file, just give it the appropriate suffix for the format.
|
|
||||||
ie. an xml file should end with `.xml`.
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ if [ "$CMD" = "" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Grab latest release file from github.
|
# Grab latest release file from github.
|
||||||
URL=$($CMD ${LATEST} | egrep "browser_download_url.*\.(${ARCH})\.${FILE}\"" | cut -d\" -f 4)
|
URL=$($CMD ${LATEST} | egrep "browser_download_url.*(${ARCH})\.${FILE}\"" | cut -d\" -f 4)
|
||||||
|
|
||||||
if [ "$?" != "0" ] || [ "$URL" = "" ]; then
|
if [ "$?" != "0" ] || [ "$URL" = "" ]; then
|
||||||
echo "Error locating latest release at ${LATEST}"
|
echo "Error locating latest release at ${LATEST}"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
// DefaultConfFile is where to find config is --config is not prvided.
|
||||||
|
const DefaultConfFile = "/usr/local/etc/unifi-poller/up.conf"
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// +build !windows,!darwin
|
||||||
|
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
// DefaultConfFile is where to find config is --config is not prvided.
|
||||||
|
const DefaultConfFile = "/etc/unifi-poller/up.conf"
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package unifipoller
|
||||||
|
|
||||||
|
// DefaultConfFile is where to find config is --config is not prvided.
|
||||||
|
const DefaultConfFile = `C:\ProgramData\unifi-poller\up.conf`
|
||||||
|
|
@ -13,7 +13,6 @@ var Version = "development"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// App defaults in case they're missing from the config.
|
// App defaults in case they're missing from the config.
|
||||||
defaultConfFile = "/etc/unifi-poller/up.conf"
|
|
||||||
defaultInterval = 30 * time.Second
|
defaultInterval = 30 * time.Second
|
||||||
defaultInfxDb = "unifi"
|
defaultInfxDb = "unifi"
|
||||||
defaultInfxUser = "unifi"
|
defaultInfxUser = "unifi"
|
||||||
|
|
@ -26,6 +25,7 @@ const (
|
||||||
// Asset is used to give all devices and clients a common interface.
|
// Asset is used to give all devices and clients a common interface.
|
||||||
type Asset interface {
|
type Asset interface {
|
||||||
Points() ([]*influx.Point, error)
|
Points() ([]*influx.Point, error)
|
||||||
|
PointsAt(time.Time) ([]*influx.Point, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
|
// UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
|
||||||
|
|
@ -35,6 +35,7 @@ type UnifiPoller struct {
|
||||||
ShowVer bool
|
ShowVer bool
|
||||||
Flag *pflag.FlagSet
|
Flag *pflag.FlagSet
|
||||||
errorCount int
|
errorCount int
|
||||||
|
LastCheck time.Time
|
||||||
influx.Client
|
influx.Client
|
||||||
*unifi.Unifi
|
*unifi.Unifi
|
||||||
*Config
|
*Config
|
||||||
|
|
@ -42,6 +43,7 @@ type UnifiPoller struct {
|
||||||
|
|
||||||
// Metrics contains all the data from the controller and an influx endpoint to send it to.
|
// Metrics contains all the data from the controller and an influx endpoint to send it to.
|
||||||
type Metrics struct {
|
type Metrics struct {
|
||||||
|
TS time.Time
|
||||||
unifi.Sites
|
unifi.Sites
|
||||||
unifi.IDSList
|
unifi.IDSList
|
||||||
unifi.Clients
|
unifi.Clients
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.golift.io/unifi"
|
"code.golift.io/unifi"
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
|
|
@ -42,7 +43,7 @@ func (u *UnifiPoller) ParseFlags(args []string) {
|
||||||
}
|
}
|
||||||
u.Flag.StringVarP(&u.DumpJSON, "dumpjson", "j", "",
|
u.Flag.StringVarP(&u.DumpJSON, "dumpjson", "j", "",
|
||||||
"This debug option prints a json payload and exits. See man page for more.")
|
"This debug option prints a json payload and exits. See man page for more.")
|
||||||
u.Flag.StringVarP(&u.ConfigFile, "config", "c", defaultConfFile, "Poller Config File (TOML Format)")
|
u.Flag.StringVarP(&u.ConfigFile, "config", "c", DefaultConfFile, "Poller Config File (TOML Format)")
|
||||||
u.Flag.BoolVarP(&u.ShowVer, "version", "v", false, "Print the version and exit")
|
u.Flag.BoolVarP(&u.ShowVer, "version", "v", false, "Print the version and exit")
|
||||||
_ = u.Flag.Parse(args)
|
_ = u.Flag.Parse(args)
|
||||||
}
|
}
|
||||||
|
|
@ -96,6 +97,7 @@ func (u *UnifiPoller) Run() (err error) {
|
||||||
switch strings.ToLower(u.Mode) {
|
switch strings.ToLower(u.Mode) {
|
||||||
case "influxlambda", "lambdainflux", "lambda_influx", "influx_lambda":
|
case "influxlambda", "lambdainflux", "lambda_influx", "influx_lambda":
|
||||||
u.LogDebugf("Lambda Mode Enabled")
|
u.LogDebugf("Lambda Mode Enabled")
|
||||||
|
u.LastCheck = time.Now()
|
||||||
return u.CollectAndReport()
|
return u.CollectAndReport()
|
||||||
default:
|
default:
|
||||||
return u.PollController()
|
return u.PollController()
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ FIRST:
|
||||||
func (u *UnifiPoller) PollController() error {
|
func (u *UnifiPoller) PollController() error {
|
||||||
log.Println("[INFO] Everything checks out! Poller started, interval:", u.Interval.Round(time.Second))
|
log.Println("[INFO] Everything checks out! Poller started, interval:", u.Interval.Round(time.Second))
|
||||||
ticker := time.NewTicker(u.Interval.Round(time.Second))
|
ticker := time.NewTicker(u.Interval.Round(time.Second))
|
||||||
for range ticker.C {
|
for u.LastCheck = range ticker.C {
|
||||||
_ = u.CollectAndReport()
|
_ = u.CollectAndReport()
|
||||||
if u.MaxErrors >= 0 && u.errorCount > u.MaxErrors {
|
if u.MaxErrors >= 0 && u.errorCount > u.MaxErrors {
|
||||||
return errors.Errorf("reached maximum error count, stopping poller (%d > %d)", u.errorCount, u.MaxErrors)
|
return errors.Errorf("reached maximum error count, stopping poller (%d > %d)", u.errorCount, u.MaxErrors)
|
||||||
|
|
@ -60,7 +60,7 @@ func (u *UnifiPoller) PollController() error {
|
||||||
// CollectAndReport collects measurements and reports them to influxdb.
|
// CollectAndReport collects measurements and reports them to influxdb.
|
||||||
// Can be called once or in a ticker loop. This function and all the ones below
|
// Can be called once or in a ticker loop. This function and all the ones below
|
||||||
// handle their own logging. An error is returned so the calling function may
|
// handle their own logging. An error is returned so the calling function may
|
||||||
// determine if there was a read or write erorr and act on it. This is currently
|
// determine if there was a read or write error and act on it. This is currently
|
||||||
// called in two places in this library. One returns an error, one does not.
|
// called in two places in this library. One returns an error, one does not.
|
||||||
func (u *UnifiPoller) CollectAndReport() error {
|
func (u *UnifiPoller) CollectAndReport() error {
|
||||||
metrics, err := u.CollectMetrics()
|
metrics, err := u.CollectMetrics()
|
||||||
|
|
@ -78,7 +78,7 @@ func (u *UnifiPoller) CollectAndReport() error {
|
||||||
// CollectMetrics grabs all the measurements from a UniFi controller and returns them.
|
// CollectMetrics grabs all the measurements from a UniFi controller and returns them.
|
||||||
// This also creates an InfluxDB writer, and returns an error if that fails.
|
// This also creates an InfluxDB writer, and returns an error if that fails.
|
||||||
func (u *UnifiPoller) CollectMetrics() (*Metrics, error) {
|
func (u *UnifiPoller) CollectMetrics() (*Metrics, error) {
|
||||||
m := &Metrics{}
|
m := &Metrics{TS: u.LastCheck} // At this point, it's the Current Check.
|
||||||
var err error
|
var err error
|
||||||
// Get the sites we care about.
|
// Get the sites we care about.
|
||||||
m.Sites, err = u.GetFilteredSites()
|
m.Sites, err = u.GetFilteredSites()
|
||||||
|
|
@ -188,7 +188,7 @@ func (m *Metrics) processPoints(asset Asset) error {
|
||||||
if asset == nil {
|
if asset == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
points, err := asset.Points()
|
points, err := asset.PointsAt(m.TS)
|
||||||
if err != nil || points == nil {
|
if err != nil || points == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue