Merge branch 'master' into feature/version-clears-localstorage
commit
86bd10e6ab
|
@ -0,0 +1,8 @@
|
|||
[bumpversion]
|
||||
current_version = 1.3.0
|
||||
files = README.md server/swagger.json
|
||||
|
||||
[bumpversion:file:ui/package.json]
|
||||
search = "version": "{current_version}"
|
||||
replace = "version": "{new_version}"
|
||||
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -3,12 +3,23 @@
|
|||
### Bug Fixes
|
||||
1. [#1450](https://github.com/influxdata/chronograf/pull/1450): Fix infinite spinner when using "/chronograf" as a basepath
|
||||
1. [#1458](https://github.com/influxdata/chronograf/pull/1458): New versions of Chronograf will automatically clear localStorage settings until further notice.
|
||||
1. [#1455](https://github.com/influxdata/chronograf/issues/1455): Fix backwards sort arrows in tables
|
||||
1. [#1423](https://github.com/influxdata/chronograf/issues/1423): Make logout nav item consistent with design
|
||||
1. [#1426](https://github.com/influxdata/chronograf/issues/1426): Fix graph loading spinner
|
||||
1. [#1485](https://github.com/influxdata/chronograf/issues/1485): Filter out any template variable values that are empty, whitespace, or duplicates
|
||||
|
||||
### Features
|
||||
1. [#1477](https://github.com/influxdata/chronograf/pull/1477): Add ability to log alerts
|
||||
1. [#1474](https://github.com/influxdata/chronograf/pull/1474): Change behavior of template variable autocomplete to filter by exact match from front of string
|
||||
1. [#1491](https://github.com/influxdata/chronograf/pull/1491): Update go vendoring to dep and committed vendor directory
|
||||
|
||||
### UI Improvements
|
||||
1. [#1451](https://github.com/influxdata/chronograf/pull/1451): Refactor scrollbars to support non-webkit browsers
|
||||
1. [#1453](https://github.com/influxdata/chronograf/pull/1453): Give QueryMaker a greater initial height than Visualization
|
||||
1. [#1464](https://github.com/influxdata/chronograf/pull/1464): Make Template Variables Manager more space efficient
|
||||
1. [#1464](https://github.com/influxdata/chronograf/pull/1464): Add page spinners to pages that did not have them
|
||||
1. [#1464](https://github.com/influxdata/chronograf/pull/1464): Denote which source is connected in the Sources table
|
||||
1. [#1478](https://github.com/influxdata/chronograf/pull/1478): InfluxDB dashboard uses milliseconds rather than nanoseconds
|
||||
|
||||
## v1.3.0 [2017-05-09]
|
||||
|
||||
|
|
19
Godeps
19
Godeps
|
@ -1,19 +0,0 @@
|
|||
github.com/NYTimes/gziphandler 6710af535839f57c687b62c4c23d649f9545d885
|
||||
github.com/Sirupsen/logrus 3ec0642a7fb6488f65b06f9040adc67e3990296a
|
||||
github.com/boltdb/bolt 5cc10bbbc5c141029940133bb33c9e969512a698
|
||||
github.com/bouk/httprouter ee8b3818a7f51fbc94cc709b5744b52c2c725e91
|
||||
github.com/dgrijalva/jwt-go 24c63f56522a87ec5339cc3567883f1039378fdb
|
||||
github.com/elazarl/go-bindata-assetfs 9a6736ed45b44bf3835afeebb3034b57ed329f3e
|
||||
github.com/gogo/protobuf 6abcf94fd4c97dcb423fdafd42fe9f96ca7e421b
|
||||
github.com/google/go-github 1bc362c7737e51014af7299e016444b654095ad9
|
||||
github.com/google/go-querystring 9235644dd9e52eeae6fa48efd539fdc351a0af53
|
||||
github.com/influxdata/influxdb af72d9b0e4ebe95be30e89b160f43eabaf0529ed
|
||||
github.com/influxdata/kapacitor 5408057e5a3493d3b5bd38d5d535ea45b587f8ff
|
||||
github.com/influxdata/usage-client 6d3895376368aa52a3a81d2a16e90f0f52371967
|
||||
github.com/jessevdk/go-flags 4cc2832a6e6d1d3b815e2b9d544b2a4dfb3ce8fa
|
||||
github.com/satori/go.uuid b061729afc07e77a8aa4fad0a2fd840958f1942a
|
||||
github.com/sergi/go-diff 1d28411638c1e67fe1930830df207bef72496ae9
|
||||
github.com/tylerb/graceful 50a48b6e73fcc75b45e22c05b79629a67c79e938
|
||||
golang.org/x/net 749a502dd1eaf3e5bfd4f8956748c502357c0bbe
|
||||
golang.org/x/oauth2 1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5
|
||||
google.golang.org/api bc20c61134e1d25265dd60049f5735381e79b631
|
|
@ -0,0 +1,132 @@
|
|||
memo = "bac138180cd86a0ae604cd3aa7b6ba300673478c880882bd58a4bd7f8bff518d"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/NYTimes/gziphandler"
|
||||
packages = ["."]
|
||||
revision = "6710af535839f57c687b62c4c23d649f9545d885"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/Sirupsen/logrus"
|
||||
packages = ["."]
|
||||
revision = "3ec0642a7fb6488f65b06f9040adc67e3990296a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/boltdb/bolt"
|
||||
packages = ["."]
|
||||
revision = "5cc10bbbc5c141029940133bb33c9e969512a698"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/bouk/httprouter"
|
||||
packages = ["."]
|
||||
revision = "ee8b3818a7f51fbc94cc709b5744b52c2c725e91"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
packages = ["."]
|
||||
revision = "24c63f56522a87ec5339cc3567883f1039378fdb"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/dustin/go-humanize"
|
||||
packages = ["."]
|
||||
revision = "259d2a102b871d17f30e3cd9881a642961a1e486"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/elazarl/go-bindata-assetfs"
|
||||
packages = ["."]
|
||||
revision = "9a6736ed45b44bf3835afeebb3034b57ed329f3e"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = ["gogoproto","jsonpb","plugin/compare","plugin/defaultcheck","plugin/description","plugin/embedcheck","plugin/enumstringer","plugin/equal","plugin/face","plugin/gostring","plugin/marshalto","plugin/oneofcheck","plugin/populate","plugin/size","plugin/stringer","plugin/testgen","plugin/union","plugin/unmarshal","proto","protoc-gen-gogo","protoc-gen-gogo/descriptor","protoc-gen-gogo/generator","protoc-gen-gogo/grpc","protoc-gen-gogo/plugin","vanity","vanity/command"]
|
||||
revision = "6abcf94fd4c97dcb423fdafd42fe9f96ca7e421b"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "8ee79997227bf9b34611aee7946ae64735e6fd93"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/go-github"
|
||||
packages = ["github"]
|
||||
revision = "1bc362c7737e51014af7299e016444b654095ad9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
revision = "9235644dd9e52eeae6fa48efd539fdc351a0af53"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/influxdata/influxdb"
|
||||
packages = ["influxql","influxql/internal","influxql/neldermead","models","pkg/escape"]
|
||||
revision = "af72d9b0e4ebe95be30e89b160f43eabaf0529ed"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/influxdata/kapacitor"
|
||||
packages = ["client/v1","influxdb","models","pipeline","services/k8s/client","tick","tick/ast","tick/stateful","udf"]
|
||||
revision = "5408057e5a3493d3b5bd38d5d535ea45b587f8ff"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/influxdata/usage-client"
|
||||
packages = ["v1"]
|
||||
revision = "6d3895376368aa52a3a81d2a16e90f0f52371967"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jessevdk/go-flags"
|
||||
packages = ["."]
|
||||
revision = "4cc2832a6e6d1d3b815e2b9d544b2a4dfb3ce8fa"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jteeuwen/go-bindata"
|
||||
packages = ["."]
|
||||
revision = "a0ff2567cfb70903282db057e799fd826784d41d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "ff09b135c25aae272398c51a07235b90a75aa4f0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/satori/go.uuid"
|
||||
packages = ["."]
|
||||
revision = "b061729afc07e77a8aa4fad0a2fd840958f1942a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/sergi/go-diff"
|
||||
packages = ["diffmatchpatch"]
|
||||
revision = "1d28411638c1e67fe1930830df207bef72496ae9"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/tylerb/graceful"
|
||||
packages = ["."]
|
||||
revision = "50a48b6e73fcc75b45e22c05b79629a67c79e938"
|
||||
version = "v1.2.13"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/net"
|
||||
packages = ["context","context/ctxhttp"]
|
||||
revision = "749a502dd1eaf3e5bfd4f8956748c502357c0bbe"
|
||||
|
||||
[[projects]]
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [".","github","heroku","internal"]
|
||||
revision = "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "f3918c30c5c2cb527c0b071a27c35120a6c0719a"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/api"
|
||||
packages = ["gensupport","googleapi","googleapi/internal/uritemplates","oauth2/v2"]
|
||||
revision = "bc20c61134e1d25265dd60049f5735381e79b631"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/appengine"
|
||||
packages = ["internal","internal/base","internal/datastore","internal/log","internal/remote_api","internal/urlfetch","urlfetch"]
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
|
@ -0,0 +1,77 @@
|
|||
required = ["github.com/jteeuwen/go-bindata","github.com/gogo/protobuf/proto","github.com/gogo/protobuf/jsonpb","github.com/gogo/protobuf/protoc-gen-gogo","github.com/gogo/protobuf/gogoproto"]
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/NYTimes/gziphandler"
|
||||
revision = "6710af535839f57c687b62c4c23d649f9545d885"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/Sirupsen/logrus"
|
||||
revision = "3ec0642a7fb6488f65b06f9040adc67e3990296a"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/boltdb/bolt"
|
||||
revision = "5cc10bbbc5c141029940133bb33c9e969512a698"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/bouk/httprouter"
|
||||
revision = "ee8b3818a7f51fbc94cc709b5744b52c2c725e91"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
revision = "24c63f56522a87ec5339cc3567883f1039378fdb"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/elazarl/go-bindata-assetfs"
|
||||
revision = "9a6736ed45b44bf3835afeebb3034b57ed329f3e"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/gogo/protobuf"
|
||||
revision = "6abcf94fd4c97dcb423fdafd42fe9f96ca7e421b"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/google/go-github"
|
||||
revision = "1bc362c7737e51014af7299e016444b654095ad9"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/influxdata/influxdb"
|
||||
revision = "af72d9b0e4ebe95be30e89b160f43eabaf0529ed"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/influxdata/kapacitor"
|
||||
version = "^1.2.0"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/influxdata/usage-client"
|
||||
revision = "6d3895376368aa52a3a81d2a16e90f0f52371967"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/jessevdk/go-flags"
|
||||
revision = "4cc2832a6e6d1d3b815e2b9d544b2a4dfb3ce8fa"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/jteeuwen/go-bindata"
|
||||
revision = "a0ff2567cfb70903282db057e799fd826784d41d"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/satori/go.uuid"
|
||||
revision = "b061729afc07e77a8aa4fad0a2fd840958f1942a"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/sergi/go-diff"
|
||||
revision = "1d28411638c1e67fe1930830df207bef72496ae9"
|
||||
|
||||
[[dependencies]]
|
||||
name = "github.com/tylerb/graceful"
|
||||
version = "^1.2.13"
|
||||
|
||||
[[dependencies]]
|
||||
name = "golang.org/x/net"
|
||||
revision = "749a502dd1eaf3e5bfd4f8956748c502357c0bbe"
|
||||
|
||||
[[dependencies]]
|
||||
name = "golang.org/x/oauth2"
|
||||
revision = "1e695b1c8febf17aad3bfa7bf0a819ef94b98ad5"
|
||||
|
||||
[[dependencies]]
|
||||
name = "google.golang.org/api"
|
||||
revision = "bc20c61134e1d25265dd60049f5735381e79b631"
|
21
Makefile
21
Makefile
|
@ -2,11 +2,10 @@
|
|||
|
||||
VERSION ?= $(shell git describe --always --tags)
|
||||
COMMIT ?= $(shell git rev-parse --short=8 HEAD)
|
||||
GDM := $(shell command -v gdm 2> /dev/null)
|
||||
GOBINDATA := $(shell go list -f {{.Root}} github.com/jteeuwen/go-bindata 2> /dev/null)
|
||||
YARN := $(shell command -v yarn 2> /dev/null)
|
||||
|
||||
SOURCES := $(shell find . -name '*.go' ! -name '*_gen.go')
|
||||
SOURCES := $(shell find . -name '*.go' ! -name '*_gen.go' -not -path "./vendor/*" )
|
||||
UISOURCES := $(shell find ui -type f -not \( -path ui/build/\* -o -path ui/node_modules/\* -prune \) )
|
||||
|
||||
LDFLAGS=-ldflags "-s -X main.version=${VERSION} -X main.commit=${COMMIT}"
|
||||
|
@ -70,16 +69,11 @@ canned/bin_gen.go: canned/*.json
|
|||
|
||||
dep: .jsdep .godep
|
||||
|
||||
.godep: Godeps
|
||||
ifndef GDM
|
||||
@echo "Installing GDM"
|
||||
go get github.com/sparrc/gdm
|
||||
endif
|
||||
.godep:
|
||||
ifndef GOBINDATA
|
||||
@echo "Installing go-bindata"
|
||||
go get -u github.com/jteeuwen/go-bindata/...
|
||||
endif
|
||||
gdm restore
|
||||
@touch .godep
|
||||
|
||||
.jsdep: ui/yarn.lock
|
||||
|
@ -90,16 +84,18 @@ else
|
|||
@touch .jsdep
|
||||
endif
|
||||
|
||||
gen: bolt/internal/internal.proto
|
||||
gen: internal.pb.go
|
||||
|
||||
internal.pb.go: bolt/internal/internal.proto
|
||||
go generate -x ./bolt/internal
|
||||
|
||||
test: jstest gotest gotestrace
|
||||
|
||||
gotest:
|
||||
go test ./...
|
||||
go test `go list ./... | grep -v /vendor/`
|
||||
|
||||
gotestrace:
|
||||
go test -race ./...
|
||||
go test -race `go list ./... | grep -v /vendor/`
|
||||
|
||||
jstest:
|
||||
cd ui && npm test
|
||||
|
@ -117,8 +113,5 @@ clean:
|
|||
rm -f dist/dist_gen.go canned/bin_gen.go server/swagger_gen.go
|
||||
@rm -f .godep .jsdep .jssrc .dev-jssrc .bindata
|
||||
|
||||
continuous:
|
||||
while true; do if fswatch -e "\.git" -r --one-event .; then echo "#-> Starting build: `date`"; make dev; pkill -9 chronograf; make run-dev & echo "#-> Build complete."; fi; sleep 0.5; done
|
||||
|
||||
ctags:
|
||||
ctags -R --languages="Go" --exclude=.git --exclude=ui .
|
||||
|
|
11
README.md
11
README.md
|
@ -110,8 +110,7 @@ Change the default root path of the Chronograf server with the `--basepath` opti
|
|||
|
||||
## Versions
|
||||
|
||||
The most recent version of Chronograf is v1.3.0.
|
||||
We will be iterating quickly based on user feedback and recommend using the [nightly builds](https://www.influxdata.com/downloads/) for the time being.
|
||||
The most recent version of Chronograf is [v1.3.0](https://www.influxdata.com/downloads/).
|
||||
|
||||
Spotted a bug or have a feature request?
|
||||
Please open [an issue](https://github.com/influxdata/chronograf/issues/new)!
|
||||
|
@ -136,16 +135,16 @@ By default, chronograf runs on port `8888`.
|
|||
|
||||
|
||||
### With Docker
|
||||
To get started right away with Docker, you can pull down our latest alpha:
|
||||
To get started right away with Docker, you can pull down our latest release:
|
||||
|
||||
```sh
|
||||
docker pull quay.io/influxdb/chronograf:latest
|
||||
docker pull chronograf:1.3.0
|
||||
```
|
||||
|
||||
### From Source
|
||||
|
||||
* Chronograf works with go 1.7.x, node 6.x/7.x, and yarn 0.18+.
|
||||
* Chronograf requires [Kapacitor](https://github.com/influxdata/kapacitor) 1.1.x+ to create and store alerts.
|
||||
* Chronograf works with go 1.8.x, node 6.x/7.x, and yarn 0.18+.
|
||||
* Chronograf requires [Kapacitor](https://github.com/influxdata/kapacitor) 1.2.x+ to create and store alerts.
|
||||
|
||||
1. [Install Go](https://golang.org/doc/install)
|
||||
1. [Install Node and NPM](https://nodejs.org/en/download/)
|
||||
|
|
|
@ -13,16 +13,18 @@
|
|||
"name": "InfluxDB - Query Performance",
|
||||
"queries": [
|
||||
{
|
||||
"query": "SELECT non_negative_derivative(max(\"queryDurationNs\"), 1s) AS \"duration\" FROM \"influxdb_queryExecutor\"",
|
||||
"query": "SELECT non_negative_derivative(max(\"queryDurationNs\"), 1s) / 1000000 AS \"duration_ms\" FROM \"influxdb_queryExecutor\"",
|
||||
"label": "ms",
|
||||
"groupbys": [],
|
||||
"wheres": []
|
||||
},
|
||||
{
|
||||
"query": "SELECT non_negative_derivative(max(\"queriesExecuted\"), 1s) AS \"queries_executed\" FROM \"influxdb_queryExecutor\"",
|
||||
"query": "SELECT non_negative_derivative(max(\"queriesExecuted\"), 1s) / 1000000 AS \"queries_executed_ms\" FROM \"influxdb_queryExecutor\"",
|
||||
"label": "ms",
|
||||
"groupbys": [],
|
||||
"wheres": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ machine:
|
|||
services:
|
||||
- docker
|
||||
environment:
|
||||
DOCKER_TAG: chronograf-20170208
|
||||
DOCKER_TAG: chronograf-20170516
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
|
|
|
@ -1,15 +1,40 @@
|
|||
## Creating a release
|
||||
The release process is handled via our [circle.yml](https://github.com/influxdata/chronograf/blob/master/circle.yml).
|
||||
|
||||
A release tag of the format `1.1.0-beta1` needs to be added. Afterwhich, circle
|
||||
A release tag of the format `1.3.0` needs to be added. Afterwhich, circle
|
||||
will build our packages for all of our platforms.
|
||||
|
||||
### Bumpversion
|
||||
We use [bumpversion](https://github.com/peritus/bumpversion) to help us
|
||||
remember all the places to increment our version number.
|
||||
|
||||
To install:
|
||||
|
||||
```sh
|
||||
pip install --upgrade bumpversion
|
||||
```
|
||||
|
||||
To use to increment third number (e.g. 1.3.0 -> 1.3.1):
|
||||
|
||||
```sh
|
||||
bumpversion patch
|
||||
```
|
||||
|
||||
|
||||
To increment minor number (e.g. 1.3.5 -> 1.4.0):
|
||||
|
||||
```sh
|
||||
bumpversion minor
|
||||
```
|
||||
|
||||
The behavior of `bumpversion` is controlled by .bumpversion.cfg
|
||||
|
||||
### Creating Release tag
|
||||
You can create a release tag from [Github](https://github.com/influxdata/chronograf/releases)
|
||||
or create an annotated tag:
|
||||
|
||||
```sh
|
||||
git tag -a 1.1.0-beta1 -m "Release 1.1.0-beta1"
|
||||
git tag -a 1.3.0 -m "Release 1.3.0"
|
||||
git push --tags
|
||||
```
|
||||
|
||||
|
@ -22,7 +47,7 @@ git push --tags
|
|||
* armel
|
||||
* static_i386
|
||||
* static_amd64
|
||||
* OS X
|
||||
* OS X
|
||||
* amd64
|
||||
* Windows
|
||||
* amd64
|
|
@ -18,9 +18,10 @@ RUN pip install boto requests python-jose --upgrade
|
|||
RUN gem install fpm
|
||||
|
||||
# Install node
|
||||
RUN wget -q https://nodejs.org/dist/latest-v6.x/node-v6.9.5-linux-x64.tar.gz; \
|
||||
tar -xvf node-v6.9.5-linux-x64.tar.gz -C / --strip-components=1; \
|
||||
rm -f node-v6.9.5-linux-x64.tar.gz
|
||||
ENV NODE_VERSION v6.10.3
|
||||
RUN wget -q https://nodejs.org/dist/latest-v6.x/node-${NODE_VERSION}-linux-x64.tar.gz; \
|
||||
tar -xvf node-${NODE_VERSION}-linux-x64.tar.gz -C / --strip-components=1; \
|
||||
rm -f node-${NODE_VERSION}-linux-x64.tar.gz
|
||||
|
||||
# Update npm
|
||||
RUN cd $(npm root -g)/npm \
|
||||
|
@ -34,7 +35,7 @@ RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
|
|||
|
||||
# Install go
|
||||
ENV GOPATH /root/go
|
||||
ENV GO_VERSION 1.7.5
|
||||
ENV GO_VERSION 1.8.1
|
||||
ENV GO_ARCH amd64
|
||||
RUN wget https://storage.googleapis.com/golang/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz; \
|
||||
tar -C /usr/local/ -xf /go${GO_VERSION}.linux-${GO_ARCH}.tar.gz ; \
|
||||
|
|
|
@ -21,7 +21,7 @@ func kapaHandler(handler string) (string, error) {
|
|||
return "email", nil
|
||||
case "http":
|
||||
return "post", nil
|
||||
case "alerta", "sensu", "slack", "email", "talk", "telegram", "post", "tcp", "exec":
|
||||
case "alerta", "sensu", "slack", "email", "talk", "telegram", "post", "tcp", "exec", "log":
|
||||
return handler, nil
|
||||
default:
|
||||
return "", fmt.Errorf("Unsupported alert handler %s", handler)
|
||||
|
|
|
@ -95,6 +95,31 @@ func TestAlertServices(t *testing.T) {
|
|||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Test log",
|
||||
rule: chronograf.AlertRule{
|
||||
AlertNodes: []chronograf.KapacitorNode{
|
||||
{
|
||||
Name: "log",
|
||||
Args: []string{"/tmp/alerts.log"},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: `alert()
|
||||
.log('/tmp/alerts.log')
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "Test log no argument",
|
||||
rule: chronograf.AlertRule{
|
||||
AlertNodes: []chronograf.KapacitorNode{
|
||||
{
|
||||
Name: "log",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Test tcp no argument with other services",
|
||||
rule: chronograf.AlertRule{
|
||||
|
|
|
@ -493,6 +493,7 @@ func extractAlertNodes(p *pipeline.Pipeline, rule *chronograf.AlertRule) {
|
|||
extractTalk(t, rule)
|
||||
extractTelegram(t, rule)
|
||||
extractTCP(t, rule)
|
||||
extractLog(t, rule)
|
||||
extractExec(t, rule)
|
||||
}
|
||||
return nil
|
||||
|
@ -801,6 +802,23 @@ func extractTCP(node *pipeline.AlertNode, rule *chronograf.AlertRule) {
|
|||
rule.AlertNodes = append(rule.AlertNodes, alert)
|
||||
}
|
||||
|
||||
func extractLog(node *pipeline.AlertNode, rule *chronograf.AlertRule) {
|
||||
if node.LogHandlers == nil {
|
||||
return
|
||||
}
|
||||
rule.Alerts = append(rule.Alerts, "log")
|
||||
log := node.LogHandlers[0]
|
||||
alert := chronograf.KapacitorNode{
|
||||
Name: "log",
|
||||
}
|
||||
|
||||
if log.FilePath != "" {
|
||||
alert.Args = []string{log.FilePath}
|
||||
}
|
||||
|
||||
rule.AlertNodes = append(rule.AlertNodes, alert)
|
||||
}
|
||||
|
||||
func extractExec(node *pipeline.AlertNode, rule *chronograf.AlertRule) {
|
||||
if node.ExecHandlers == nil {
|
||||
return
|
||||
|
|
|
@ -59,12 +59,13 @@ func TestReverse(t *testing.T) {
|
|||
.slack()
|
||||
.victorOps()
|
||||
.email('howdy@howdy.com')
|
||||
.log('/tmp/alerts.log')
|
||||
`),
|
||||
|
||||
want: chronograf.AlertRule{
|
||||
Name: "name",
|
||||
Trigger: "threshold",
|
||||
Alerts: []string{"victorops", "smtp", "slack"},
|
||||
Alerts: []string{"victorops", "smtp", "slack", "log"},
|
||||
AlertNodes: []chronograf.KapacitorNode{
|
||||
{
|
||||
Name: "victorops",
|
||||
|
@ -76,6 +77,10 @@ func TestReverse(t *testing.T) {
|
|||
{
|
||||
Name: "slack",
|
||||
},
|
||||
{
|
||||
Name: "log",
|
||||
Args: []string{"/tmp/alerts.log"},
|
||||
},
|
||||
},
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Operator: "greater than",
|
||||
|
|
|
@ -38,7 +38,7 @@ const AdminTabs = ({
|
|||
}) => {
|
||||
let tabs = [
|
||||
{
|
||||
type: 'DB Management',
|
||||
type: 'Databases',
|
||||
component: <DatabaseManagerPage source={source} />,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -176,10 +176,10 @@ class AdminPage extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<FancyScrollbar className="page-contents">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
{users
|
||||
? <AdminTabs
|
||||
{users
|
||||
? <div className="container-fluid">
|
||||
<div className="row">
|
||||
<AdminTabs
|
||||
users={users}
|
||||
roles={roles}
|
||||
source={source}
|
||||
|
@ -204,9 +204,9 @@ class AdminPage extends Component {
|
|||
onUpdateUserRoles={this.handleUpdateUserRoles}
|
||||
onUpdateUserPassword={this.handleUpdateUserPassword}
|
||||
/>
|
||||
: <span>Loading...</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
: <div className="page-spinner" />}
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -82,68 +82,83 @@ const AlertsTable = React.createClass({
|
|||
<div className="panel panel-minimal">
|
||||
<div className="panel-heading u-flex u-ai-center u-jc-space-between">
|
||||
<h2 className="panel-title">{this.props.alerts.length} Alerts</h2>
|
||||
<SearchBar onSearch={this.filterAlerts} />
|
||||
{this.props.alerts.length
|
||||
? <SearchBar onSearch={this.filterAlerts} />
|
||||
: null}
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<table className="table v-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
onClick={() => this.changeSort('name')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('level')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Level
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('time')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('host')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Host
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('value')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{alerts.map(({name, level, time, host, value}) => {
|
||||
return (
|
||||
<tr key={`${name}-${level}-${time}-${host}-${value}`}>
|
||||
<td className="monotype">{name}</td>
|
||||
<td
|
||||
className={`monotype alert-level-${level.toLowerCase()}`}
|
||||
{this.props.alerts.length
|
||||
? <table className="table v-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
onClick={() => this.changeSort('name')}
|
||||
className="sortable-header"
|
||||
>
|
||||
{level}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
{new Date(Number(time)).toISOString()}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
<Link to={`/sources/${id}/hosts/${host}`}>
|
||||
{host}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="monotype">{value}</td>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('level')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Level
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('time')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('host')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Host
|
||||
</th>
|
||||
<th
|
||||
onClick={() => this.changeSort('value')}
|
||||
className="sortable-header"
|
||||
>
|
||||
Value
|
||||
</th>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{alerts.map(({name, level, time, host, value}) => {
|
||||
return (
|
||||
<tr key={`${name}-${level}-${time}-${host}-${value}`}>
|
||||
<td className="monotype">{name}</td>
|
||||
<td
|
||||
className={`monotype alert-level-${level.toLowerCase()}`}
|
||||
>
|
||||
{level}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
{new Date(Number(time)).toISOString()}
|
||||
</td>
|
||||
<td className="monotype">
|
||||
<Link to={`/sources/${id}/hosts/${host}`}>
|
||||
{host}
|
||||
</Link>
|
||||
</td>
|
||||
<td className="monotype">{value}</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
: <div className="generic-empty-state">
|
||||
<h4 className="no-user-select">
|
||||
Alerts appear here when you have Rules
|
||||
</h4>
|
||||
<br />
|
||||
<Link
|
||||
to={`/sources/${id}/alert-rules/new`}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
Create a Rule
|
||||
</Link>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -95,18 +95,18 @@ class AlertsApp extends Component {
|
|||
}
|
||||
|
||||
renderSubComponents() {
|
||||
let component
|
||||
if (this.state.loading) {
|
||||
component = <p>Loading...</p>
|
||||
} else {
|
||||
const {source} = this.props
|
||||
if (this.state.hasKapacitor) {
|
||||
component = <AlertsTable source={source} alerts={this.state.alerts} />
|
||||
} else {
|
||||
component = <NoKapacitorError source={source} />
|
||||
}
|
||||
}
|
||||
return component
|
||||
const {source} = this.props
|
||||
return (
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
{this.state.hasKapacitor
|
||||
? <AlertsTable source={source} alerts={this.state.alerts} />
|
||||
: <NoKapacitorError source={source} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
handleToggleTime() {
|
||||
|
@ -151,13 +151,7 @@ class AlertsApp extends Component {
|
|||
</div>
|
||||
</div>
|
||||
<FancyScrollbar className="page-contents">
|
||||
<div className="container-fluid">
|
||||
<div className="row">
|
||||
<div className="col-md-12">
|
||||
{this.renderSubComponents()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{this.renderSubComponents()}
|
||||
</FancyScrollbar>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ const TemplateQueryBuilder = ({
|
|||
}) => {
|
||||
switch (selectedType) {
|
||||
case 'csv':
|
||||
return <div className="tvm-csv-instructions">Enter values below</div>
|
||||
return null
|
||||
case 'databases':
|
||||
return <div className="tvm-query-builder--text">SHOW DATABASES</div>
|
||||
case 'measurements':
|
||||
|
|
|
@ -2,6 +2,8 @@ import React, {PropTypes, Component} from 'react'
|
|||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import uniq from 'lodash/uniq'
|
||||
|
||||
import OnClickOutside from 'react-onclickoutside'
|
||||
import classnames from 'classnames'
|
||||
|
||||
|
@ -30,7 +32,9 @@ const RowValues = ({
|
|||
onStartEdit,
|
||||
autoFocusTarget,
|
||||
}) => {
|
||||
const _values = values.map(({value}) => value).join(', ')
|
||||
const _values = uniq(values.map(({value}) => value))
|
||||
.filter(value => /\S/.test(value))
|
||||
.join(', ')
|
||||
|
||||
if (selectedType === 'csv') {
|
||||
return (
|
||||
|
|
|
@ -164,7 +164,7 @@ class QueryEditor extends Component {
|
|||
const start = this.editor.selectionStart
|
||||
const end = this.editor.selectionEnd
|
||||
const filteredTemplates = templates.filter(t =>
|
||||
t.tempVar.includes(matched[0].substring(1))
|
||||
t.tempVar.startsWith(matched[0])
|
||||
)
|
||||
|
||||
const found = filteredTemplates.find(
|
||||
|
|
|
@ -84,9 +84,9 @@ const HostsTable = React.createClass({
|
|||
sortableClasses(key) {
|
||||
if (this.state.sortKey === key) {
|
||||
if (this.state.sortDirection === 'asc') {
|
||||
return 'sortable-header sorting-up'
|
||||
return 'sortable-header sorting-ascending'
|
||||
}
|
||||
return 'sortable-header sorting-down'
|
||||
return 'sortable-header sorting-descending'
|
||||
}
|
||||
return 'sortable-header'
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
import buildInfluxQLQuery from 'utils/influxql'
|
||||
import classnames from 'classnames'
|
||||
|
||||
import DatabaseList from '../../data_explorer/components/DatabaseList'
|
||||
import MeasurementList from '../../data_explorer/components/MeasurementList'
|
||||
|
@ -76,16 +77,21 @@ export const DataSection = React.createClass({
|
|||
|
||||
render() {
|
||||
const {query, timeRange: {lower}} = this.props
|
||||
const statement =
|
||||
query.rawText ||
|
||||
buildInfluxQLQuery({lower}, query) ||
|
||||
'Build a query below'
|
||||
const statement = query.rawText || buildInfluxQLQuery({lower}, query)
|
||||
|
||||
return (
|
||||
<div className="kapacitor-rule-section kapacitor-metric-selector">
|
||||
<h3 className="rule-section-heading">Select a Time Series</h3>
|
||||
<div className="rule-section-body">
|
||||
<pre><code>{statement}</code></pre>
|
||||
<pre>
|
||||
<code
|
||||
className={classnames({
|
||||
'kapacitor-metric-placeholder': !statement,
|
||||
})}
|
||||
>
|
||||
{statement || 'Build a query below'}
|
||||
</code>
|
||||
</pre>
|
||||
{this.renderQueryBuilder()}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -127,10 +127,11 @@ class KapacitorForm extends Component {
|
|||
<h2 className="panel-title">Configure Alert Endpoints</h2>
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
<br />
|
||||
<p className="text-center">
|
||||
Connect to an active Kapacitor instance to configure alerting endpoints.
|
||||
</p>
|
||||
<div className="generic-empty-state">
|
||||
<h4 className="no-user-select">
|
||||
Connect to an active Kapacitor instance to configure alerting endpoints
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -74,12 +74,13 @@ export const RULE_MESSAGE_TEMPLATES = {
|
|||
},
|
||||
}
|
||||
|
||||
export const DEFAULT_ALERTS = ['http', 'tcp', 'exec']
|
||||
export const DEFAULT_ALERTS = ['http', 'tcp', 'exec', 'log']
|
||||
|
||||
export const DEFAULT_ALERT_LABELS = {
|
||||
http: 'URL:',
|
||||
tcp: 'Address:',
|
||||
exec: 'Add Command (Arguments separated by Spaces):',
|
||||
log: 'File',
|
||||
smtp: 'Email Addresses (Separated by Spaces):',
|
||||
slack: 'Send alerts to Slack channel:',
|
||||
alerta: 'Paste Alerta TICKscript:',
|
||||
|
@ -88,6 +89,7 @@ export const DEFAULT_ALERT_PLACEHOLDERS = {
|
|||
http: 'Ex: http://example.com/api/alert',
|
||||
tcp: 'Ex: exampleendpoint.com:5678',
|
||||
exec: 'Ex: woogie boogie',
|
||||
log: 'Ex: /tmp/alerts.log',
|
||||
smtp: 'Ex: benedict@domain.com delaney@domain.com susan@domain.com',
|
||||
slack: '#alerts',
|
||||
alerta: 'alerta()',
|
||||
|
@ -97,6 +99,7 @@ export const ALERT_NODES_ACCESSORS = {
|
|||
http: rule => _.get(rule, 'alertNodes[0].args[0]', ''),
|
||||
tcp: rule => _.get(rule, 'alertNodes[0].args[0]', ''),
|
||||
exec: rule => _.get(rule, 'alertNodes[0].args', []).join(' '),
|
||||
log: rule => _.get(rule, 'alertNodes[0].args[0]', ''),
|
||||
smtp: rule => _.get(rule, 'alertNodes[0].args', []).join(' '),
|
||||
slack: rule => _.get(rule, 'alertNodes[0].properties[0].args', ''),
|
||||
alerta: rule =>
|
||||
|
|
|
@ -81,6 +81,7 @@ export default function rules(state = {}, action) {
|
|||
switch (alertType) {
|
||||
case 'http':
|
||||
case 'tcp':
|
||||
case 'log':
|
||||
alertNodesByType = [
|
||||
{
|
||||
name: alertType,
|
||||
|
|
|
@ -81,9 +81,7 @@ const SideNav = React.createClass({
|
|||
</NavBlock>
|
||||
{showLogout
|
||||
? <NavBlock icon="user-outline" className="sidebar__square-last">
|
||||
<a className="sidebar__menu-item" href={logoutLink}>
|
||||
Logout
|
||||
</a>
|
||||
<NavHeader link={logoutLink} title="Logout" />
|
||||
</NavBlock>
|
||||
: null}
|
||||
</NavBar>
|
||||
|
|
|
@ -120,12 +120,16 @@ const InfluxTable = ({
|
|||
)}
|
||||
</td>
|
||||
<td className="text-right">
|
||||
<Link
|
||||
className="btn btn-success btn-xs"
|
||||
to={`/sources/${s.id}/hosts`}
|
||||
>
|
||||
Connect
|
||||
</Link>
|
||||
{s.id === source.id
|
||||
? <span className="currently-connected-source">
|
||||
<span className="icon checkmark" /> Connected
|
||||
</span>
|
||||
: <Link
|
||||
className="btn btn-success btn-xs"
|
||||
to={`/sources/${s.id}/hosts`}
|
||||
>
|
||||
Connect
|
||||
</Link>}
|
||||
<button
|
||||
className="btn btn-danger btn-xs"
|
||||
onClick={() => handleDeleteSource(s)}
|
||||
|
|
|
@ -107,8 +107,8 @@ $graph-gutter: 16px;
|
|||
justify-content: center;
|
||||
}
|
||||
.graph-spinner {
|
||||
width: 121px;
|
||||
height: 121px;
|
||||
width: 121px !important;
|
||||
height: 121px !important;
|
||||
background-image: url(assets/images/laser-spinner.png);
|
||||
background-size: 100% 100%;
|
||||
background-position: center center;
|
||||
|
@ -123,4 +123,4 @@ $graph-gutter: 16px;
|
|||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
/* This is a hack to tell the browser to use the GPU when rendering the spinner. */
|
||||
transform: translateZ(0);
|
||||
animation: spinner 0.5s infinite linear;
|
||||
animation: spinner 0.6s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes spinner {
|
||||
|
|
|
@ -56,7 +56,7 @@ table {
|
|||
padding: 6px 8px !important;
|
||||
}
|
||||
tbody tr:hover {
|
||||
background-color: $g5-pepper;
|
||||
background-color: $g4-onyx;
|
||||
|
||||
td {
|
||||
color: $g19-ghost !important;
|
||||
|
@ -125,13 +125,9 @@ table .monotype {
|
|||
cursor: pointer;
|
||||
color: $g19-ghost;
|
||||
background-color: $g5-pepper;
|
||||
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.sorting-down,
|
||||
&.sorting-up {
|
||||
&.sorting-ascending,
|
||||
&.sorting-descending {
|
||||
background-color: $g5-pepper;
|
||||
color: $g19-ghost;
|
||||
|
||||
|
@ -139,11 +135,11 @@ table .monotype {
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
&.sorting-down {
|
||||
|
||||
&:after {
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
}
|
||||
&.sorting-ascending:after {
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
}
|
||||
&.sorting-descending:after {
|
||||
transform: translateY(-50%) rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ $tvmp-table-gutter: 8px;
|
|||
border-radius: $radius;
|
||||
border: 2px solid $g5-pepper;
|
||||
background-color: $g2-kevlar;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
border-color 0.25s ease;
|
||||
|
||||
|
|
|
@ -185,6 +185,11 @@ $kapacitor-font-sm: 13px;
|
|||
pre code {
|
||||
line-height: ($kapacitor-font-sm + 3px);
|
||||
white-space: pre-wrap;
|
||||
|
||||
&.kapacitor-metric-placeholder {
|
||||
color: $g8-storm;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
.query-builder {
|
||||
height: 240px;
|
||||
|
|
|
@ -198,6 +198,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
.currently-connected-source {
|
||||
color: $c-rainforest;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
margin: 0 4px;
|
||||
@include no-user-select();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue