commit
b55bd6962b
|
|
@ -87,39 +87,39 @@ README.html: md2roff
|
|||
# Binaries
|
||||
|
||||
build: $(BINARY)
|
||||
$(BINARY):
|
||||
$(BINARY): *.go */*.go
|
||||
go build -o $(BINARY) -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||
|
||||
linux: $(BINARY).amd64.linux
|
||||
$(BINARY).amd64.linux:
|
||||
$(BINARY).amd64.linux: *.go */*.go
|
||||
# Building linux 64-bit x86 binary.
|
||||
GOOS=linux GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||
|
||||
linux386: $(BINARY).i386.linux
|
||||
$(BINARY).i386.linux:
|
||||
$(BINARY).i386.linux: *.go */*.go
|
||||
# Building linux 32-bit x86 binary.
|
||||
GOOS=linux GOARCH=386 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||
|
||||
arm: arm64 armhf
|
||||
|
||||
arm64: $(BINARY).arm64.linux
|
||||
$(BINARY).arm64.linux:
|
||||
$(BINARY).arm64.linux: *.go */*.go
|
||||
# Building linux 64-bit ARM binary.
|
||||
GOOS=linux GOARCH=arm64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||
|
||||
armhf: $(BINARY).armhf.linux
|
||||
$(BINARY).armhf.linux:
|
||||
$(BINARY).armhf.linux: *.go */*.go
|
||||
# Building linux 32-bit ARM binary.
|
||||
GOOS=linux GOARCH=arm GOARM=6 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||
|
||||
macos: $(BINARY).amd64.macos
|
||||
$(BINARY).amd64.macos:
|
||||
$(BINARY).amd64.macos: *.go */*.go
|
||||
# Building darwin 64-bit x86 binary.
|
||||
GOOS=darwin GOARCH=amd64 go build -o $@ -ldflags "-w -s -X $(VERSION_PATH)=$(VERSION)-$(ITERATION)"
|
||||
|
||||
exe: $(BINARY).amd64.exe
|
||||
windows: $(BINARY).amd64.exe
|
||||
$(BINARY).amd64.exe:
|
||||
$(BINARY).amd64.exe: *.go */*.go
|
||||
# Building windows 64-bit x86 binary.
|
||||
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:
|
||||
# Calculate the SHA from the Github source file.
|
||||
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.
|
||||
sed -e "s/{{Version}}/$(VERSION)/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%{{Class}}%$(shell echo $(BINARY) | perl -pe 's/(?:\b|-)(\p{Ll})/\u$$1/g')%g" \
|
||||
init/homebrew/$(FORMULA).rb.tmpl | tee $(BINARY).rb
|
||||
# That perl line turns hello-world into HelloWorld, etc.
|
||||
|
||||
# Extras
|
||||
|
||||
|
|
@ -246,7 +247,7 @@ lint:
|
|||
|
||||
# This is safe; recommended even.
|
||||
dep: vendor
|
||||
vendor:
|
||||
vendor: Gopkg.*
|
||||
dep ensure --vendor-only
|
||||
|
||||
# Don't run this unless you're ready to debug untested vendored dependencies.
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
# UniFi Poller
|
||||
|
||||
[](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)
|
||||
[](https://github.com/golift/unifi)
|
||||
[](https://discord.gg/DyVsMyt)
|
||||
[](https://twitter.com/TwitchCaptain)
|
||||
[](http://grafana.com/dashboards?search=unifi-poller)
|
||||
[](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/davidnewhall/unifi-poller/pulls?utf8=✓&q=is%3Apr+)
|
||||
[](https://github.com/golift/unifi)
|
||||
[](https://github.com/golift/application-builder)
|
||||
[](https://github.com/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.
|
||||
[Grafana Dashboards](http://grafana.com/dashboards?search=unifi-poller) included.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,10 @@ OPTIONS
|
|||
|
||||
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`
|
||||
* 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.
|
||||
|
||||
**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).
|
||||
|
||||
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`.
|
||||
**They are now located at [Grafana.com](https://grafana.com/dashboards?search=unifi-poller).**
|
||||
Also see [Grafana Dashboards](https://github.com/davidnewhall/unifi-poller/wiki/Grafana-Dashboards) Wiki.
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ if [ "$CMD" = "" ]; then
|
|||
fi
|
||||
|
||||
# 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
|
||||
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 (
|
||||
// App defaults in case they're missing from the config.
|
||||
defaultConfFile = "/etc/unifi-poller/up.conf"
|
||||
defaultInterval = 30 * time.Second
|
||||
defaultInfxDb = "unifi"
|
||||
defaultInfxUser = "unifi"
|
||||
|
|
@ -26,6 +25,7 @@ const (
|
|||
// Asset is used to give all devices and clients a common interface.
|
||||
type Asset interface {
|
||||
Points() ([]*influx.Point, error)
|
||||
PointsAt(time.Time) ([]*influx.Point, error)
|
||||
}
|
||||
|
||||
// UnifiPoller contains the application startup data, and auth info for UniFi & Influx.
|
||||
|
|
@ -35,6 +35,7 @@ type UnifiPoller struct {
|
|||
ShowVer bool
|
||||
Flag *pflag.FlagSet
|
||||
errorCount int
|
||||
LastCheck time.Time
|
||||
influx.Client
|
||||
*unifi.Unifi
|
||||
*Config
|
||||
|
|
@ -42,6 +43,7 @@ type UnifiPoller struct {
|
|||
|
||||
// Metrics contains all the data from the controller and an influx endpoint to send it to.
|
||||
type Metrics struct {
|
||||
TS time.Time
|
||||
unifi.Sites
|
||||
unifi.IDSList
|
||||
unifi.Clients
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.golift.io/unifi"
|
||||
"github.com/BurntSushi/toml"
|
||||
|
|
@ -42,7 +43,7 @@ func (u *UnifiPoller) ParseFlags(args []string) {
|
|||
}
|
||||
u.Flag.StringVarP(&u.DumpJSON, "dumpjson", "j", "",
|
||||
"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.Parse(args)
|
||||
}
|
||||
|
|
@ -96,6 +97,7 @@ func (u *UnifiPoller) Run() (err error) {
|
|||
switch strings.ToLower(u.Mode) {
|
||||
case "influxlambda", "lambdainflux", "lambda_influx", "influx_lambda":
|
||||
u.LogDebugf("Lambda Mode Enabled")
|
||||
u.LastCheck = time.Now()
|
||||
return u.CollectAndReport()
|
||||
default:
|
||||
return u.PollController()
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ FIRST:
|
|||
func (u *UnifiPoller) PollController() error {
|
||||
log.Println("[INFO] Everything checks out! Poller started, interval:", 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()
|
||||
if u.MaxErrors >= 0 && 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.
|
||||
// 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
|
||||
// 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.
|
||||
func (u *UnifiPoller) CollectAndReport() error {
|
||||
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.
|
||||
// This also creates an InfluxDB writer, and returns an error if that fails.
|
||||
func (u *UnifiPoller) CollectMetrics() (*Metrics, error) {
|
||||
m := &Metrics{}
|
||||
m := &Metrics{TS: u.LastCheck} // At this point, it's the Current Check.
|
||||
var err error
|
||||
// Get the sites we care about.
|
||||
m.Sites, err = u.GetFilteredSites()
|
||||
|
|
@ -188,7 +188,7 @@ func (m *Metrics) processPoints(asset Asset) error {
|
|||
if asset == nil {
|
||||
return nil
|
||||
}
|
||||
points, err := asset.Points()
|
||||
points, err := asset.PointsAt(m.TS)
|
||||
if err != nil || points == nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue