Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a04ef6cefc | ||
|
|
c5ea64c2c2 | ||
|
|
423a25fc32 | ||
|
|
86241d8bff | ||
|
|
670ee15dbd | ||
|
|
9abfbf18e0 | ||
|
|
882ed637c1 | ||
|
|
676972e798 | ||
|
|
3be4685589 | ||
|
|
aa227c5c20 | ||
|
|
ba26ac343b | ||
|
|
27a8112e06 | ||
|
|
a0a9ca220c | ||
|
|
0287819e36 | ||
|
|
16f3fe7e15 | ||
|
|
ca6d08d5cb | ||
|
|
d01bdb517d | ||
|
|
63dfdb7066 | ||
|
|
e95667fffb | ||
|
|
c08b901664 | ||
|
|
7cd6fef466 | ||
|
|
1b4f93b88c | ||
|
|
c4656a885d | ||
|
|
818a2f3d64 | ||
|
|
7f52e023b5 | ||
|
|
962a06545a | ||
|
|
79aeeaa10a | ||
|
|
ea483c0ce1 | ||
|
|
3e88197f96 | ||
|
|
66df54db80 | ||
|
|
e4b4480064 | ||
|
|
4e4f69b5f6 | ||
|
|
a4b7209e39 | ||
|
|
6c001d9c09 | ||
|
|
312600aa2c | ||
|
|
26d701dcf9 | ||
|
|
e347b62cee | ||
|
|
36232857df | ||
|
|
9d605bdd04 | ||
|
|
4d235b978e | ||
|
|
6575c9cb6e | ||
|
|
0ad27a6596 | ||
|
|
a0c6afa0a5 | ||
|
|
3d0bc141c7 | ||
|
|
ed307897e7 | ||
|
|
1d63f57caf | ||
|
|
e00f393a17 | ||
|
|
277e00aaed | ||
|
|
ba6104190e | ||
|
|
eaaca91f25 | ||
|
|
a551cd2470 |
16
.bra.toml
16
.bra.toml
@@ -1,19 +1,19 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["go", "run", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
["go", "run", "-mod=vendor", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "-mod=vendor", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
]
|
||||
watch_all = true
|
||||
follow_symlinks = true
|
||||
watch_dirs = [
|
||||
"$WORKDIR/pkg",
|
||||
"$WORKDIR/public/views",
|
||||
"$WORKDIR/conf",
|
||||
"$WORKDIR/pkg",
|
||||
"$WORKDIR/public/views",
|
||||
"$WORKDIR/conf",
|
||||
]
|
||||
watch_exts = [".go", ".ini", ".toml", ".template.html"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
["go", "run", "-mod=vendor", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
]
|
||||
|
||||
1349
.circleci/config.yml
1349
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -14,10 +14,8 @@
|
||||
# Documentation owner: Diana Payton
|
||||
/docs/ @oddlittlebird
|
||||
/contribute/ @oddlittlebird @marcusolsson
|
||||
# @grafana/ui component documentation
|
||||
*.mdx @marcusolsson @jessover9000
|
||||
|
||||
# Backend code
|
||||
*.go @grafana/backend-platform
|
||||
go.mod @grafana/backend-platform
|
||||
go.sum @grafana/backend-platform
|
||||
go.sum @grafana/backend-platform
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -11,18 +11,13 @@ awsconfig
|
||||
/public/views/error.html
|
||||
/emails/dist
|
||||
/reports
|
||||
/e2e/tmp
|
||||
.yarnrc
|
||||
.yarn/
|
||||
vendor/
|
||||
|
||||
# Enterprise emails
|
||||
/emails/templates/enterprise_*
|
||||
/public/emails/enterprise_*
|
||||
|
||||
# Enterprise devenv
|
||||
/devenv/docker/blocks/grafana-enterprise
|
||||
|
||||
/tmp
|
||||
tools/phantomjs/phantomjs
|
||||
tools/phantomjs/phantomjs.exe
|
||||
@@ -88,8 +83,6 @@ debug.test
|
||||
|
||||
/devenv/bulk-dashboards/*.json
|
||||
/devenv/bulk_alerting_dashboards/*.json
|
||||
/devenv/datasources_bulk.yaml
|
||||
/devenv/bulk_alerting_dashboards/bulk_alerting_datasources.yaml
|
||||
|
||||
/scripts/build/release_publisher/release_publisher
|
||||
*.patch
|
||||
@@ -110,10 +103,6 @@ compilation-stats.json
|
||||
/packages/grafana-e2e/cypress/screenshots
|
||||
/packages/grafana-e2e/cypress/videos
|
||||
/packages/grafana-e2e/cypress/logs
|
||||
/e2e/server.log
|
||||
/e2e/**/screenshots
|
||||
!/e2e/**/screenshots/expeced/*
|
||||
/e2e/**/videos/*
|
||||
|
||||
# report dumping the whole system env
|
||||
/report.*.json
|
||||
/public/e2e-test/screenShots/theOutput
|
||||
/public/e2e-tests/screenShots/theOutput/*.png
|
||||
/public/e2e-tests/videos
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
...require('@grafana/toolkit/src/config/prettier.plugin.config.json'),
|
||||
};
|
||||
3892
CHANGELOG.md
3892
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
71
Dockerfile
71
Dockerfile
@@ -1,28 +1,12 @@
|
||||
FROM node:12.16.3-alpine3.11 as js-builder
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
|
||||
RUN yarn install --pure-lockfile --no-progress
|
||||
|
||||
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
|
||||
COPY public public
|
||||
COPY tools tools
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM golang:1.14.2-alpine3.11 as go-builder
|
||||
# Golang build container
|
||||
FROM golang:1.13.4-alpine
|
||||
|
||||
RUN apk add --no-cache gcc g++
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/grafana/grafana
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
COPY vendor vendor
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
@@ -31,8 +15,36 @@ COPY build.go package.json ./
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
# Final stage
|
||||
FROM alpine:3.11
|
||||
# Node build container
|
||||
FROM node:12.13.0-alpine
|
||||
|
||||
# PhantomJS
|
||||
RUN apk add --no-cache curl &&\
|
||||
cd /tmp && curl -Ls https://github.com/dustinblackman/phantomized/releases/download/2.1.1/dockerized-phantomjs.tar.gz | tar xz &&\
|
||||
cp -R lib lib64 / &&\
|
||||
cp -R usr/lib/x86_64-linux-gnu /usr/lib &&\
|
||||
cp -R usr/share /usr/share &&\
|
||||
cp -R etc/fonts /etc &&\
|
||||
curl -k -Ls https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 | tar -jxf - &&\
|
||||
cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
|
||||
RUN yarn install --pure-lockfile --no-progress
|
||||
|
||||
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc ./
|
||||
COPY public public
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
# Final container
|
||||
FROM alpine:3.10
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
|
||||
@@ -50,7 +62,7 @@ ENV PATH="/usr/share/grafana/bin:$PATH" \
|
||||
WORKDIR $GF_PATHS_HOME
|
||||
|
||||
RUN apk add --no-cache ca-certificates bash tzdata && \
|
||||
apk add --no-cache --upgrade openssl musl-utils
|
||||
apk add --no-cache --upgrade --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main openssl musl-utils
|
||||
|
||||
COPY conf ./conf
|
||||
|
||||
@@ -68,9 +80,18 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
|
||||
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
|
||||
|
||||
COPY --from=go-builder /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-server /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-cli ./bin/
|
||||
COPY --from=js-builder /usr/src/app/public ./public
|
||||
COPY --from=js-builder /usr/src/app/tools ./tools
|
||||
# PhantomJS
|
||||
COPY --from=1 /tmp/lib /lib
|
||||
COPY --from=1 /tmp/lib64 /lib64
|
||||
COPY --from=1 /tmp/usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
|
||||
COPY --from=1 /tmp/usr/share /usr/share
|
||||
COPY --from=1 /tmp/etc/fonts /etc/fonts
|
||||
COPY --from=1 /usr/local/bin/phantomjs /usr/local/bin
|
||||
|
||||
COPY --from=0 /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-server /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-cli ./bin/
|
||||
COPY --from=1 /usr/src/app/public ./public
|
||||
COPY --from=1 /usr/src/app/tools ./tools
|
||||
COPY tools/phantomjs/render.js ./tools/phantomjs/render.js
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
|
||||
@@ -1,26 +1,9 @@
|
||||
FROM node:12.16.3-slim AS js-builder
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
|
||||
RUN yarn install --pure-lockfile
|
||||
|
||||
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
|
||||
COPY public public
|
||||
COPY tools tools
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM golang:1.14.2 AS go-builder
|
||||
FROM golang:1.13.4 AS go-builder
|
||||
|
||||
WORKDIR /src/grafana
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
COPY vendor vendor/
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
@@ -29,7 +12,29 @@ COPY pkg pkg/
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
FROM ubuntu:20.04
|
||||
FROM node:12.13 AS js-builder
|
||||
|
||||
# PhantomJS
|
||||
RUN apt-get update && apt-get install -y curl &&\
|
||||
curl -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 | tar xj &&\
|
||||
cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
COPY packages packages
|
||||
|
||||
RUN yarn install --pure-lockfile
|
||||
|
||||
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc ./
|
||||
COPY public public
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM ubuntu:19.10
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
EXPOSE 3000
|
||||
@@ -49,8 +54,8 @@ WORKDIR $GF_PATHS_HOME
|
||||
|
||||
COPY conf conf
|
||||
|
||||
# curl should be part of the image
|
||||
RUN apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates curl
|
||||
# We need font libs for phantomjs, and curl should be part of the image
|
||||
RUN apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates libfontconfig1 curl
|
||||
|
||||
RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
addgroup --system --gid $GF_GID grafana && \
|
||||
@@ -66,11 +71,14 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
|
||||
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
|
||||
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
|
||||
|
||||
# PhantomJS
|
||||
COPY --from=js-builder /usr/local/bin/phantomjs /usr/local/bin/
|
||||
|
||||
COPY --from=go-builder /src/grafana/bin/linux-amd64/grafana-server /src/grafana/bin/linux-amd64/grafana-cli bin/
|
||||
COPY --from=js-builder /usr/src/app/public public
|
||||
COPY --from=js-builder /usr/src/app/tools tools
|
||||
|
||||
COPY tools/phantomjs/render.js tools/phantomjs/
|
||||
COPY packaging/docker/run.sh /
|
||||
|
||||
USER grafana
|
||||
|
||||
@@ -35,6 +35,7 @@ module.exports = function (grunt) {
|
||||
config.libc = grunt.option('libc');
|
||||
}
|
||||
|
||||
config.phjs = grunt.option('phjsToRelease');
|
||||
config.pkg.version = grunt.option('pkgVer') || config.pkg.version;
|
||||
|
||||
console.log('Version', config.pkg.version);
|
||||
|
||||
17
Makefile
17
Makefile
@@ -4,7 +4,7 @@
|
||||
|
||||
-include local/Makefile
|
||||
|
||||
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go gosec revive golangci-lint go-vet test-go test-js test run run-frontend clean devenv devenv-down revive-alerting protobuf help
|
||||
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go gosec revive golangci-lint go-vet test-go test-js test run run-frontend clean devenv devenv-down revive-alerting help
|
||||
|
||||
GO = GO111MODULE=on go
|
||||
GO_FILES ?= ./pkg/...
|
||||
@@ -84,10 +84,7 @@ revive-alerting: scripts/go/bin/revive
|
||||
@echo "lint alerting via revive"
|
||||
@scripts/go/bin/revive \
|
||||
-formatter stylish \
|
||||
-config ./scripts/go/configs/revive-strict.toml \
|
||||
./pkg/services/alerting/... \
|
||||
./pkg/services/provisioning/datasources/... \
|
||||
./pkg/services/provisioning/dashboards/...
|
||||
./pkg/services/alerting/...
|
||||
|
||||
scripts/go/bin/golangci-lint: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
@@ -161,16 +158,6 @@ devenv-down: ## Stop optional services.
|
||||
|
||||
##@ Helpers
|
||||
|
||||
# We separate the protobuf generation because most development tasks on
|
||||
# Grafana do not involve changing protobuf files and protoc is not a
|
||||
# go-gettable dependency and so getting it installed can be inconvenient.
|
||||
#
|
||||
# If you are working on changes to protobuf interfaces you may either use
|
||||
# this target or run the individual scripts below directly.
|
||||
protobuf: ## Compile protobuf definitions
|
||||
bash scripts/protobuf-check.sh
|
||||
bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh
|
||||
|
||||
clean: ## Clean up intermediate build artifacts.
|
||||
@echo "cleaning"
|
||||
rm -rf node_modules
|
||||
|
||||
@@ -15,15 +15,6 @@ Grafana allows you to query, visualize, alert on and understand your metrics no
|
||||
- **Alerting:** Visually define alert rules for your most important metrics. Grafana will continuously evaluate and send notifications to systems like Slack, PagerDuty, VictorOps, OpsGenie.
|
||||
- **Mixed Data Sources:** Mix different data sources in the same graph! You can specify a data source on a per-query basis. This works for even custom datasources.
|
||||
|
||||
### Grafana 7.0 and GrafanaCONline
|
||||
|
||||
- Grafana 7.0 Beta is [available for download](https://grafana.com/grafana/download).
|
||||
- Read [what's is new](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v7-0/).
|
||||
|
||||
Want to learn more about Grafana 7 and more? Sign up for our online conference!
|
||||
|
||||
[](https://grafana.com/about/events/grafanacon/2020/?source=grafana-readme)
|
||||
|
||||
## Get started
|
||||
|
||||
- [Get Grafana](https://grafana.com/get)
|
||||
|
||||
@@ -20,6 +20,8 @@ Upgrading Go or Node.js requires making changes in many different files. See bel
|
||||
|
||||
The Grafana project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.11 or greater installed.
|
||||
|
||||
All dependencies are vendored in the `vendor/` directory.
|
||||
|
||||
_Note:_ Since most developers of Grafana still use the `GOPATH` we need to specify `GO111MODULE=on` to make `go mod` and `got get` work as intended. If you have setup Grafana outside of the `GOPATH` on your machine you can skip `GO111MODULE=on` when running the commands below.
|
||||
|
||||
To add or update a new dependency, use the `go get` command:
|
||||
@@ -33,14 +35,16 @@ GO111MODULE=on go get example.com/some/module/pkg
|
||||
GO111MODULE=on go get example.com/some/module/pkg@vX.Y.Z
|
||||
```
|
||||
|
||||
Tidy up the `go.mod` and `go.sum` files:
|
||||
Tidy up the `go.mod` and `go.sum` files and copy the new/updated dependency to the `vendor/` directory:
|
||||
|
||||
```bash
|
||||
# The GO111MODULE variable can be omitted when the code isn't located in GOPATH.
|
||||
GO111MODULE=on go mod tidy
|
||||
|
||||
GO111MODULE=on go mod vendor
|
||||
```
|
||||
|
||||
You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request.
|
||||
You have to commit the changes to `go.mod`, `go.sum` and the `vendor/` directory before submitting the pull request.
|
||||
|
||||
## Node.js dependencies
|
||||
|
||||
|
||||
@@ -23,10 +23,6 @@
|
||||
"extractorMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
},
|
||||
"ae-internal-missing-underscore": {
|
||||
"logLevel": "none",
|
||||
"addToApiReportFile": false
|
||||
}
|
||||
},
|
||||
"tsdocMessageReporting": {
|
||||
|
||||
11
build.go
11
build.go
@@ -40,6 +40,7 @@ var (
|
||||
linuxPackageVersion string = "v1"
|
||||
linuxPackageIteration string = ""
|
||||
race bool
|
||||
phjsToRelease string
|
||||
workingDir string
|
||||
includeBuildId bool = true
|
||||
buildId string = "0"
|
||||
@@ -51,6 +52,7 @@ var (
|
||||
skipRpmGen bool = false
|
||||
skipDebGen bool = false
|
||||
printGenVersion bool = false
|
||||
modVendor bool = true
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -67,7 +69,9 @@ func main() {
|
||||
flag.StringVar(&libc, "libc", "", "LIBC")
|
||||
flag.BoolVar(&cgo, "cgo-enabled", cgo, "Enable cgo")
|
||||
flag.StringVar(&pkgArch, "pkg-arch", "", "PKG ARCH")
|
||||
flag.StringVar(&phjsToRelease, "phjs", "", "PhantomJS binary")
|
||||
flag.BoolVar(&race, "race", race, "Use race detector")
|
||||
flag.BoolVar(&modVendor, "modVendor", modVendor, "Go modules use vendor folder")
|
||||
flag.BoolVar(&includeBuildId, "includeBuildId", includeBuildId, "IncludeBuildId in package name")
|
||||
flag.BoolVar(&enterprise, "enterprise", enterprise, "Build enterprise version of Grafana")
|
||||
flag.StringVar(&buildIdRaw, "buildId", "0", "Build ID from CI system")
|
||||
@@ -385,6 +389,7 @@ func createPackage(options linuxPackageOptions) {
|
||||
if enterprise {
|
||||
description += " Enterprise"
|
||||
}
|
||||
args = append(args, "--vendor", description)
|
||||
|
||||
if !enterprise {
|
||||
args = append(args, "--license", "\"Apache 2.0\"")
|
||||
@@ -454,6 +459,9 @@ func gruntBuildArg(task string) []string {
|
||||
if libc != "" {
|
||||
args = append(args, fmt.Sprintf("--libc=%s", libc))
|
||||
}
|
||||
if phjsToRelease != "" {
|
||||
args = append(args, fmt.Sprintf("--phjsToRelease=%v", phjsToRelease))
|
||||
}
|
||||
if enterprise {
|
||||
args = append(args, "--enterprise")
|
||||
}
|
||||
@@ -501,6 +509,9 @@ func build(binaryName, pkg string, tags []string) {
|
||||
if race {
|
||||
args = append(args, "-race")
|
||||
}
|
||||
if modVendor {
|
||||
args = append(args, "-mod=vendor")
|
||||
}
|
||||
|
||||
args = append(args, "-o", binary)
|
||||
args = append(args, pkg)
|
||||
|
||||
@@ -230,9 +230,9 @@ snapshot_remove_expired = true
|
||||
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
|
||||
versions_to_keep = 20
|
||||
|
||||
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
|
||||
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is not set/unrestricted.
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
min_refresh_interval = 5s
|
||||
min_refresh_interval =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
@@ -298,9 +298,6 @@ signout_redirect_url =
|
||||
# This setting is ignored if multiple OAuth providers are configured.
|
||||
oauth_auto_login = false
|
||||
|
||||
# OAuth state max age cookie duration. Defaults to 60 seconds.
|
||||
oauth_state_cookie_max_age = 60
|
||||
|
||||
# limit of api_key seconds to live before expiration
|
||||
api_key_max_seconds_to_live = -1
|
||||
|
||||
@@ -386,21 +383,6 @@ token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
|
||||
#################################### Okta OAuth #######################
|
||||
[auth.okta]
|
||||
name = Okta
|
||||
enabled = false
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret = some_secret
|
||||
scopes = openid profile email groups
|
||||
auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
|
||||
token_url = https://<tenant-id>.okta.com/oauth2/v1/token
|
||||
api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
role_attribute_path =
|
||||
|
||||
#################################### Generic OAuth #######################
|
||||
[auth.generic_oauth]
|
||||
name = OAuth
|
||||
@@ -423,6 +405,47 @@ tls_client_cert =
|
||||
tls_client_key =
|
||||
tls_client_ca =
|
||||
|
||||
#################################### SAML Auth ###########################
|
||||
[auth.saml] # Enterprise only
|
||||
# Defaults to false. If true, the feature is enabled
|
||||
enabled = false
|
||||
|
||||
# Base64-encoded public X.509 certificate. Used to sign requests to the IdP
|
||||
certificate =
|
||||
|
||||
# Path to the public X.509 certificate. Used to sign requests to the IdP
|
||||
certificate_path =
|
||||
|
||||
# Base64-encoded private key. Used to decrypt assertions from the IdP
|
||||
private_key =
|
||||
|
||||
# Path to the private key. Used to decrypt assertions from the IdP
|
||||
private_key_path =
|
||||
|
||||
# Base64-encoded IdP SAML metadata XML. Used to verify and obtain binding locations from the IdP
|
||||
idp_metadata =
|
||||
|
||||
# Path to the SAML metadata XML. Used to verify and obtain binding locations from the IdP
|
||||
idp_metadata_path =
|
||||
|
||||
# URL to fetch SAML IdP metadata. Used to verify and obtain binding locations from the IdP
|
||||
idp_metadata_url =
|
||||
|
||||
# Duration, since the IdP issued a response and the SP is allowed to process it. Defaults to 90 seconds
|
||||
max_issue_delay = 90s
|
||||
|
||||
# Duration, for how long the SP's metadata should be valid. Defaults to 48 hours
|
||||
metadata_valid_duration = 48h
|
||||
|
||||
# Friendly name or name of the attribute within the SAML assertion to use as the user's name
|
||||
assertion_attribute_name = displayName
|
||||
|
||||
# Friendly name or name of the attribute within the SAML assertion to use as the user's login handle
|
||||
assertion_attribute_login = mail
|
||||
|
||||
# Friendly name or name of the attribute within the SAML assertion to use as the user's email
|
||||
assertion_attribute_email = mail
|
||||
|
||||
#################################### Basic Auth ##########################
|
||||
[auth.basic]
|
||||
enabled = true
|
||||
@@ -683,9 +706,6 @@ container_name =
|
||||
server_url =
|
||||
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
|
||||
callback_url =
|
||||
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
|
||||
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
|
||||
concurrent_render_request_limit = 30
|
||||
|
||||
[panels]
|
||||
# here for to support old env variables, can remove after a few months
|
||||
@@ -695,68 +715,6 @@ disable_sanitize_html = false
|
||||
[plugins]
|
||||
enable_alpha = false
|
||||
app_tls_skip_verify_insecure = false
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
|
||||
allow_loading_unsigned_plugins =
|
||||
|
||||
#################################### Grafana Image Renderer Plugin ##########################
|
||||
[plugin.grafana-image-renderer]
|
||||
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
|
||||
# timezone IDs. Fallbacks to TZ environment variable if not set.
|
||||
rendering_timezone =
|
||||
|
||||
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
|
||||
rendering_language =
|
||||
|
||||
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
|
||||
rendering_viewport_device_scale_factor =
|
||||
|
||||
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
|
||||
# the security risk it's not recommended to ignore HTTPS errors.
|
||||
rendering_ignore_https_errors =
|
||||
|
||||
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
|
||||
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
|
||||
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
|
||||
# [log].filter = rendering:debug.
|
||||
rendering_verbose_logging =
|
||||
|
||||
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
|
||||
# Default is false. This can be useful to enable (true) when troubleshooting.
|
||||
rendering_dumpio =
|
||||
|
||||
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
|
||||
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
|
||||
rendering_args =
|
||||
|
||||
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
|
||||
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
|
||||
# compatible with the plugin.
|
||||
rendering_chrome_bin =
|
||||
|
||||
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
|
||||
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
|
||||
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
|
||||
rendering_mode =
|
||||
|
||||
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
|
||||
# and will cluster using browser instances.
|
||||
# Mode 'context' will cluster using incognito pages.
|
||||
rendering_clustering_mode =
|
||||
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
|
||||
rendering_clustering_max_concurrency =
|
||||
|
||||
# Limit the maxiumum viewport width, height and device scale factor that can be requested.
|
||||
rendering_viewport_max_width =
|
||||
rendering_viewport_max_height =
|
||||
rendering_viewport_max_device_scale_factor =
|
||||
|
||||
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
|
||||
# a port not in use.
|
||||
grpc_host =
|
||||
grpc_port =
|
||||
|
||||
[enterprise]
|
||||
license_path =
|
||||
|
||||
128
conf/sample.ini
128
conf/sample.ini
@@ -229,9 +229,9 @@
|
||||
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
|
||||
;versions_to_keep = 20
|
||||
|
||||
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
|
||||
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is not set/unrestricted.
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;min_refresh_interval = 5s
|
||||
;min_refresh_interval =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
@@ -297,9 +297,6 @@
|
||||
# This setting is ignored if multiple OAuth providers are configured.
|
||||
;oauth_auto_login = false
|
||||
|
||||
# OAuth state max age cookie duration. Defaults to 60 seconds.
|
||||
;oauth_state_cookie_max_age = 60
|
||||
|
||||
# limit of api_key seconds to live before expiration
|
||||
;api_key_max_seconds_to_live = -1
|
||||
|
||||
@@ -376,21 +373,6 @@
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
|
||||
#################################### Okta OAuth #######################
|
||||
[auth.okta]
|
||||
;name = Okta
|
||||
;enabled = false
|
||||
;allow_sign_up = true
|
||||
;client_id = some_id
|
||||
;client_secret = some_secret
|
||||
;scopes = openid profile email groups
|
||||
;auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
|
||||
;token_url = https://<tenant-id>.okta.com/oauth2/v1/token
|
||||
;api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
|
||||
;allowed_domains =
|
||||
;allowed_groups =
|
||||
;role_attribute_path =
|
||||
|
||||
#################################### Generic OAuth ##########################
|
||||
[auth.generic_oauth]
|
||||
;enabled = false
|
||||
@@ -413,6 +395,47 @@
|
||||
;tls_client_key =
|
||||
;tls_client_ca =
|
||||
|
||||
#################################### SAML Auth ###########################
|
||||
[auth.saml] # Enterprise only
|
||||
# Defaults to false. If true, the feature is enabled.
|
||||
;enabled = false
|
||||
|
||||
# Base64-encoded public X.509 certificate. Used to sign requests to the IdP
|
||||
;certificate =
|
||||
|
||||
# Path to the public X.509 certificate. Used to sign requests to the IdP
|
||||
;certificate_path =
|
||||
|
||||
# Base64-encoded private key. Used to decrypt assertions from the IdP
|
||||
;private_key =
|
||||
|
||||
;# Path to the private key. Used to decrypt assertions from the IdP
|
||||
;private_key_path =
|
||||
|
||||
# Base64-encoded IdP SAML metadata XML. Used to verify and obtain binding locations from the IdP
|
||||
;idp_metadata =
|
||||
|
||||
# Path to the SAML metadata XML. Used to verify and obtain binding locations from the IdP
|
||||
;idp_metadata_path =
|
||||
|
||||
# URL to fetch SAML IdP metadata. Used to verify and obtain binding locations from the IdP
|
||||
;idp_metadata_url =
|
||||
|
||||
# Duration, since the IdP issued a response and the SP is allowed to process it. Defaults to 90 seconds.
|
||||
;max_issue_delay = 90s
|
||||
|
||||
# Duration, for how long the SP's metadata should be valid. Defaults to 48 hours.
|
||||
;metadata_valid_duration = 48h
|
||||
|
||||
# Friendly name or name of the attribute within the SAML assertion to use as the user's name
|
||||
;assertion_attribute_name = displayName
|
||||
|
||||
# Friendly name or name of the attribute within the SAML assertion to use as the user's login handle
|
||||
;assertion_attribute_login = mail
|
||||
|
||||
# Friendly name or name of the attribute within the SAML assertion to use as the user's email
|
||||
;assertion_attribute_email = mail
|
||||
|
||||
#################################### Basic Auth ##########################
|
||||
[auth.basic]
|
||||
;enabled = true
|
||||
@@ -673,9 +696,6 @@
|
||||
;server_url =
|
||||
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
|
||||
;callback_url =
|
||||
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
|
||||
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
|
||||
;concurrent_render_request_limit = 30
|
||||
|
||||
[panels]
|
||||
# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
|
||||
@@ -684,68 +704,6 @@
|
||||
[plugins]
|
||||
;enable_alpha = false
|
||||
;app_tls_skip_verify_insecure = false
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
|
||||
;allow_loading_unsigned_plugins =
|
||||
|
||||
#################################### Grafana Image Renderer Plugin ##########################
|
||||
[plugin.grafana-image-renderer]
|
||||
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
|
||||
# timezone IDs. Fallbacks to TZ environment variable if not set.
|
||||
;rendering_timezone =
|
||||
|
||||
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
|
||||
;rendering_language =
|
||||
|
||||
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
|
||||
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
|
||||
;rendering_viewport_device_scale_factor =
|
||||
|
||||
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
|
||||
# the security risk it's not recommended to ignore HTTPS errors.
|
||||
;rendering_ignore_https_errors =
|
||||
|
||||
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
|
||||
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
|
||||
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
|
||||
# [log].filter = rendering:debug.
|
||||
;rendering_verbose_logging =
|
||||
|
||||
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
|
||||
# Default is false. This can be useful to enable (true) when troubleshooting.
|
||||
;rendering_dumpio =
|
||||
|
||||
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
|
||||
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
|
||||
;rendering_args =
|
||||
|
||||
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
|
||||
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
|
||||
# compatible with the plugin.
|
||||
;rendering_chrome_bin =
|
||||
|
||||
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
|
||||
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
|
||||
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
|
||||
;rendering_mode =
|
||||
|
||||
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
|
||||
# and will cluster using browser instances.
|
||||
# Mode 'context' will cluster using incognito pages.
|
||||
;rendering_clustering_mode =
|
||||
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
|
||||
;rendering_clustering_max_concurrency =
|
||||
|
||||
# Limit the maxiumum viewport width, height and device scale factor that can be requested.
|
||||
;rendering_viewport_max_width =
|
||||
;rendering_viewport_max_height =
|
||||
;rendering_viewport_max_device_scale_factor =
|
||||
|
||||
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
|
||||
# a port not in use.
|
||||
;grpc_host =
|
||||
;grpc_port =
|
||||
|
||||
[enterprise]
|
||||
# Path to a valid Grafana Enterprise license.jwt file
|
||||
|
||||
@@ -4,6 +4,7 @@ This guide helps you get started developing Grafana.
|
||||
|
||||
Before you begin, you might want to read [How to contribute to Grafana as a junior dev](https://medium.com/@ivanahuckova/how-to-contribute-to-grafana-as-junior-dev-c01fe3064502) by [Ivana Huckova](https://medium.com/@ivanahuckova).
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
Make sure you have the following dependencies installed before setting up your developer environment:
|
||||
@@ -20,7 +21,7 @@ We recommend using [Homebrew](https://brew.sh/) for installing any missing depen
|
||||
```
|
||||
brew install git
|
||||
brew install go
|
||||
brew install node@12
|
||||
brew install node
|
||||
|
||||
npm install -g yarn
|
||||
```
|
||||
@@ -51,7 +52,7 @@ After the command has finished, we can start building our source code:
|
||||
yarn start
|
||||
```
|
||||
|
||||
Once `yarn start` has built the assets, it will continue to do so whenever any of the files change. This means you don't have to manually build the assets every time you change the code.
|
||||
Once `yarn start` has built the assets, it will continue to do so whenever any of the files change. This means you don't have to manually build the assets whenever every time you change the code.
|
||||
|
||||
Next, we'll build the web server that will serve the frontend assets we just built.
|
||||
|
||||
@@ -97,35 +98,29 @@ go test -v ./pkg/...
|
||||
|
||||
### Run end-to-end tests
|
||||
|
||||
The end to end tests in Grafana use [Cypress](https://www.cypress.io/) to run automated scripts in a headless Chromium browser. Read more about our [e2e framework](/contribute/style-guides/e2e.md).
|
||||
The end to end tests in Grafana use [Cypress](https://www.cypress.io/) to run automated scripts in a headless Chromium browser. Read more about our [e2e framework](/contribute/style-guides/e2e.md).
|
||||
|
||||
To run the tests:
|
||||
|
||||
```
|
||||
yarn e2e
|
||||
yarn e2e-tests
|
||||
```
|
||||
|
||||
By default, the end-to-end tests starts a Grafana instance listening on `localhost:3001`. To use a specific URL, set the `BASE_URL` environment variable:
|
||||
By default, the end-to-end tests assumes Grafana is available on `localhost:3000`. To use a specific URL, set the `BASE_URL` environment variable:
|
||||
|
||||
```
|
||||
BASE_URL=http://localhost:3333 yarn e2e
|
||||
BASE_URL=http://localhost:3333 yarn e2e-tests
|
||||
```
|
||||
|
||||
To follow the tests in the browser while they're running, use the `yarn e2e:debug`.
|
||||
To follow the tests in the browser while they're running, use the `yarn e2e-tests:debug` instead.
|
||||
|
||||
```
|
||||
yarn e2e:debug
|
||||
```
|
||||
|
||||
If you want to pick a test first, use the `yarn e2e:dev`, to pick a test and follow the test in the browser while it runs.
|
||||
|
||||
```
|
||||
yarn e2e:dev
|
||||
yarn e2e-tests:debug
|
||||
```
|
||||
|
||||
## Configure Grafana for development
|
||||
|
||||
The default configuration, `grafana.ini`, is located in the `conf` directory.
|
||||
The default configuration, `grafana.ini`, is located in the `conf` directory.
|
||||
|
||||
To override the default configuration, create a `custom.ini` file in the `conf` directory. You only need to add the options you wish to override.
|
||||
|
||||
@@ -135,6 +130,7 @@ Enable the development mode, by adding the following line in your `custom.ini`:
|
||||
app_mode = development
|
||||
```
|
||||
|
||||
|
||||
### Add data sources
|
||||
|
||||
By now, you should be able to build and test a change you've made to the Grafana source code. In most cases, you need to add at least one data source to verify the change.
|
||||
@@ -176,7 +172,7 @@ The resulting image will be tagged as grafana/grafana:dev.
|
||||
1. Build the frontend: `go run build.go build-frontend`.
|
||||
1. Build the Docker image: `make build-docker-dev`.
|
||||
|
||||
**Note:** If you are using Docker for macOS, be sure to set the memory limit to be larger than 2 GiB. Otherwise, `grunt build` may fail. The memory limit settings are available under **Docker Desktop** -> **Preferences** -> **Advanced**.
|
||||
**Note:** If you are using Docker for macOS, be sure to set the memory limit to be larger than 2 GiB. Otherwise `grunt build` may fail. The memory limit settings are available under **Docker Desktop** -> **Preferences** -> **Advanced**.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -184,7 +180,7 @@ Are you having issues with setting up your environment? Here are some tips that
|
||||
|
||||
### Too many open files when running `make run`
|
||||
|
||||
Depending on your environment, you may have to increase the maximum number of open files allowed. For the rest of this section, we will assume you are on a Unix like OS (e.g. Linux/MacOS), where you can control the maximum number of open files through the [ulimit](https://ss64.com/bash/ulimit.html) shell command.
|
||||
Depending on your environment, you may have to increase the maximum number of open files allowed.
|
||||
|
||||
To see how many open files are allowed, run:
|
||||
|
||||
@@ -204,28 +200,7 @@ The number of files needed may be different on your environment. To determine th
|
||||
find ./conf ./pkg ./public/views | wc -l
|
||||
```
|
||||
|
||||
Another alternative is to limit the files being watched. The directories that are watched for changes are listed in the `.bra.toml` file in the root directory.
|
||||
|
||||
To retain your `ulimit` configuration, i.e. so it will be remembered for future sessions, you need to commit it to your command line shell initialization file. Which file this will be depends on the shell you are using, here are some examples:
|
||||
|
||||
* zsh -> ~/.zshrc
|
||||
* bash -> ~/.bashrc
|
||||
|
||||
Commit your ulimit configuration to your shell initialization file as follows ($LIMIT being your chosen limit and $INIT_FILE being the initialization file for your shell):
|
||||
|
||||
```
|
||||
echo ulimit -S -n $LIMIT >> $INIT_FILE
|
||||
```
|
||||
|
||||
Your command shell should read the initialization file in question every time it gets started, and apply your `ulimit` command.
|
||||
|
||||
For some people, typically using the bash shell, ulimit fails with an error similar to the following:
|
||||
|
||||
```
|
||||
ulimit: open files: cannot modify limit: Operation not permitted
|
||||
```
|
||||
|
||||
If that happens to you, chances are you've already set a lower limit and your shell won't let you set a higher one. Try looking in your shell initalization files (~/.bashrc typically), if there's already a ulimit command that you can tweak.
|
||||
Another alternative is to limit the files being watched. The directories that are watched for changes are listed in the `.bra.toml` file in the root directory.
|
||||
|
||||
## Next steps
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ This style guide applies to all documentation created for Grafana products.
|
||||
|
||||
For information about how to write technical documentation, we suggest reviewing the content of the [Google Technical Writing courses](https://developers.google.com/tech-writing).
|
||||
|
||||
The [Divio documentation system](https://documentation.divio.com/) site is also a good resource.
|
||||
|
||||
## Contributing
|
||||
|
||||
The *Documentation style guide* is a living document. Add to it whenever a style decision is made or a question is answered regarding style, grammar, or word choice.
|
||||
@@ -33,7 +31,6 @@ The following sections provide general guidelines on topics specific to Grafana
|
||||
- Use: The panel opens. Grafana opens the panel.
|
||||
* Do not use an ampersand (&) as an abbreviation for "and."
|
||||
- **Exceptions:** If an ampersand is used in the Grafana UI, then match the UI.
|
||||
* Avoid using internal slang and jargon in technical documentation.
|
||||
|
||||
### File naming conventions
|
||||
|
||||
@@ -113,7 +110,7 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
|
||||
|
||||
### Word usage
|
||||
|
||||
Grafana products has some words, abbreviations, and terms particular to the Grafana discourse community.
|
||||
Grafana products has some words, abbreviations, and slang particular to this discourse community.
|
||||
|
||||
#### checkout, check out
|
||||
|
||||
@@ -142,14 +139,6 @@ Two words, not one
|
||||
* Correct, but passive voice: Your list of active alarms is displayed.
|
||||
* Incorrect: The list of active alarms displays.
|
||||
|
||||
#### drawer
|
||||
|
||||
Do not use. This is developer jargon that refers to a UI panel. Refer to the panel or feature by its proper name.
|
||||
|
||||
#### intro, introduction
|
||||
|
||||
"Introduction" is the preferred word. Use "intro" if there are space constraints (like on the side menu) or you are specifically trying for a less formal, more conversational tone.
|
||||
|
||||
#### metadata
|
||||
|
||||
One word, not two.
|
||||
|
||||
@@ -1,51 +1,19 @@
|
||||
# End to end test framework
|
||||
|
||||
Grafana Labs uses a minimal home grown solution built on top of Cypress for our end to end (e2e) tests.
|
||||
|
||||
## Commands
|
||||
|
||||
- `yarn e2e` Creates an isolated grafana-server home under `<repo-root>/e2e/tmp` with provisioned data sources and dashboards. This
|
||||
copies locally build binary and frontend assets from your repo root so you need to have a built backend and frontend
|
||||
for this to run locally. The server starts on port 3001 so it does not conflict with your normal dev server.
|
||||
- `yarn e2e:debug` Same as above but runs the tests in chrome and does not shutdown after completion.
|
||||
- `yarn e2e:dev` Same as above but does not run any tests on startup. It lets you pick a test first.
|
||||
|
||||
If you already have a Grafana instance running, you can provide a specific URL by setting the `BASE_URL` environment variable:
|
||||
|
||||
```
|
||||
BASE_URL=http://172.0.10.2:3333 yarn e2e
|
||||
```
|
||||
|
||||
The above commands use some utils scripts under `<repo-root>/e2e` that can also be used for more control.
|
||||
|
||||
- `./e2e/start-server` This creates a fresh new grafana server working dir, setup's config and starts the server. It
|
||||
will also kill any previously started server that is still running using pid file at `<repo-root>/e2e/tmp/pid`.
|
||||
- `./e2e/wait-for-grafana` waits for `$HOST` and `$PORT` to be available. Per default localhost and 3001.
|
||||
- `./e2e/run-suite <debug|dev|noarg>` Starts cypress in different modes.
|
||||
|
||||
## Test Suites
|
||||
|
||||
All the integration tests are located at `e2e/suite<x>/specs`. The page objects and reusable flows are in the
|
||||
`packages/grafana-e2e` package.
|
||||
|
||||
## Basic concepts
|
||||
|
||||
Here is a good introduction to e2e best practices: https://martinfowler.com/bliki/PageObject.html.
|
||||
|
||||
- `Selector`: A unique identifier that is used from the e2e framework to retrieve an element from the Browser
|
||||
- `Page`: An abstraction for an object that contains one or more `Selectors` with `visit` function to navigate to the page.
|
||||
- `Component`: An abstraction for an object that contains one or more `Selectors` but without `visit` function
|
||||
- `Page`: An abstraction for an object that contains one or more `Selectors`
|
||||
- `Flow`: An abstraction that contains a sequence of actions on one or more `Pages` that can be reused and shared between tests
|
||||
|
||||
## Basic example
|
||||
|
||||
Let's start with a simple example with a single selector. For simplicity, all examples are in JSX.
|
||||
|
||||
In our example app, we have an input that we want to type some text into during our e2e test.
|
||||
|
||||
```jsx harmony
|
||||
<div>
|
||||
<input type="text" className="gf-form-input login-form-input" />
|
||||
<input type="text" className="gf-form-input login-form-input"/>
|
||||
</div>
|
||||
```
|
||||
|
||||
@@ -53,26 +21,25 @@ We could define a selector using `JQuery` [type selectors](https://api.jquery.co
|
||||
|
||||
At Grafana, we use `aria-label` as our preferred way of defining selectors instead of `data-*` attributes. This also aids in accessibility.
|
||||
Let's add a descriptive `aria-label` to our simple example.
|
||||
|
||||
```jsx harmony
|
||||
<div>
|
||||
<input type="text" className="gf-form-input login-form-input" aria-label="Username input field" />
|
||||
<input type="text" className="gf-form-input login-form-input" aria-label="Username input field"/>
|
||||
</div>
|
||||
```
|
||||
|
||||
Now that we added the `aria-label` we suddenly get more information about this particular field. It's an input field that represents a username, but there it's still not really signaling that it's part of an e2e test.
|
||||
|
||||
The next step is to create a `Page` representation in our e2e test framework to glue the test with the real implementation using the `pageFactory` function. For that function we can supply a `url` and `selectors` like in the example below:
|
||||
|
||||
```typescript
|
||||
export const Login = {
|
||||
url: "/login", // used when called from Login.visit()
|
||||
username: "Username input field", // used when called from Login.username().type('Hello World')
|
||||
};
|
||||
export const Login = pageFactory({
|
||||
url: '/login', // used when called from Login.visit()
|
||||
selectors: {
|
||||
username: 'Username input field', // used when called from Login.username().type('Hello World')
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The next step is to add the `Login` page to the exported const `Pages` in `packages/grafana-e2e-selectors/src/selectors/pages.ts` so that it appears when we type `e2e.pages` in our IDE.
|
||||
|
||||
The next step is to add the `Login` page to the exported const `Pages` in `packages/grafana-e2e/src/pages/index.ts` so that it appears when we type `e2e.pages` in our IDE.
|
||||
```ecmascript 6
|
||||
export const Pages = {
|
||||
Login,
|
||||
@@ -82,21 +49,17 @@ export const Pages = {
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
Now that we have a `Page` called `Login` in our `Pages` const we can use that to add a selector in our html like shown below and now this really signals to future developers that it is part of an e2e test.
|
||||
|
||||
```jsx harmony
|
||||
<div>
|
||||
<input type="text" className="gf-form-input login-form-input" aria-label={selectors.pages.Login.username} />
|
||||
<input type="text" className="gf-form-input login-form-input" aria-label={e2e.pages.Login.selectors.username}/>
|
||||
</div>
|
||||
```
|
||||
|
||||
The last step in our example is to use our `Login` page as part of a test.
|
||||
|
||||
The last step in our example is to use our `Login` page as part of a test. The `pageFactory` function we used before gives us two things:
|
||||
- The `url` property is used whenever we call the `visit` function and is equivalent to the Cypress function [cy.visit()](https://docs.cypress.io/api/commands/visit.html#Syntax).
|
||||
> Best practice after calling `visit` is to always call `should` on a selector to prevent flaky tests when you try to access an element that isn't ready. For more information, refer to [Commands vs. assertions](https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions).
|
||||
- Any defined selector can be accessed from the `Login` page by invoking it. This is equivalent to the result of the Cypress function [cy.get(...)](https://docs.cypress.io/api/commands/get.html#Syntax).
|
||||
|
||||
> Best practice after calling `visit` is to always call `should` on a selector to prevent flaky tests when you try to access an element that isn't ready. For more information, refer to [Commands vs. assertions](https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions).
|
||||
- Any defined selector in the `selectors` property can be accessed from the `Login` page by invoking it. This is equivalent to the result of the Cypress function [cy.get(...)](https://docs.cypress.io/api/commands/get.html#Syntax).
|
||||
```ecmascript 6
|
||||
describe('Login test', () => {
|
||||
it('Should pass', () => {
|
||||
@@ -110,7 +73,6 @@ describe('Login test', () => {
|
||||
```
|
||||
|
||||
## Advanced example
|
||||
|
||||
Let's take a look at an example that uses the same `selector` for multiple items in a list for instance. In this example app we have a list of data sources that we want to click on during an e2e test.
|
||||
|
||||
```jsx harmony
|
||||
@@ -118,35 +80,36 @@ Let's take a look at an example that uses the same `selector` for multiple items
|
||||
{dataSources.map(dataSource => (
|
||||
<li className="card-item-wrapper" key={dataSource.id}>
|
||||
<a className="card-item" href={`datasources/edit/${dataSource.id}`}>
|
||||
<div className="card-item-name">{dataSource.name}</div>
|
||||
<div className="card-item-name">
|
||||
{dataSource.name}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
```
|
||||
|
||||
````
|
||||
```
|
||||
|
||||
Just as before in the basic example we'll start by creating a page abstraction using the `pageFactory` function:
|
||||
```typescript
|
||||
export const DataSources = {
|
||||
export const DataSources = pageFactory({
|
||||
url: '/datasources',
|
||||
dataSources: (dataSourceName: string) => `Data source list item ${dataSourceName}`,
|
||||
};
|
||||
````
|
||||
|
||||
selectors: {
|
||||
dataSources: (dataSourceName: string) => `Data source list item ${dataSourceName}`,
|
||||
},
|
||||
});
|
||||
```
|
||||
You might have noticed that instead of a simple `string` as the `selector`, we're using a `function` that takes a string parameter as an argument and returns a formatted string using the argument.
|
||||
|
||||
Just as before we need to add the `DataSources` page to the exported const `Pages` in `packages/grafana-e2e-selectors/src/selectors/pages.ts`.
|
||||
Just as before we need to add the `DataSources` page to the exported const `Pages` in `packages/grafana-e2e/src/pages/index.ts`.
|
||||
|
||||
The next step is to use the `dataSources` selector function as in our example below:
|
||||
|
||||
```jsx harmony
|
||||
<ul>
|
||||
{dataSources.map(dataSource => (
|
||||
<li className="card-item-wrapper" key={dataSource.id}>
|
||||
<a className="card-item" href={`datasources/edit/${dataSource.id}`}>
|
||||
<div className="card-item-name" aria-label={selectors.pages.DataSources.dataSources(dataSource.name)}>
|
||||
<div className="card-item-name" aria-label={e2e.pages.DataSources.selectors.dataSources(dataSource.name)}>
|
||||
{dataSource.name}
|
||||
</div>
|
||||
</a>
|
||||
@@ -156,7 +119,6 @@ The next step is to use the `dataSources` selector function as in our example be
|
||||
```
|
||||
|
||||
When this list is rendered with the data sources with names `A`, `B`, `C` the resulting html would become:
|
||||
|
||||
```jsx harmony
|
||||
<div class="card-item-name" aria-label="Data source list item A">
|
||||
A
|
||||
@@ -172,9 +134,7 @@ When this list is rendered with the data sources with names `A`, `B`, `C` the re
|
||||
```
|
||||
|
||||
Now we can write our test. The one thing that differs from the `Basic example` is that we pass in which data source we want to click on as an argument to the selector function:
|
||||
|
||||
> Best practice after calling `visit` is to always call `should` on a selector to prevent flaky tests when you try to access an element that isn't ready. For more information, refer to [Commands vs. assertions](https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions).
|
||||
|
||||
```ecmascript 6
|
||||
describe('List test', () => {
|
||||
it('Clicking on data source named B', () => {
|
||||
@@ -187,18 +147,17 @@ describe('List test', () => {
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Debugging PhantomJS image rendering
|
||||
|
||||
### Common Error
|
||||
|
||||
The most common error with PhantomJs image rendering is when a PR introduces an import that has functionality that's not supported by PhantomJs. To quickly identify which new import causes this you can use a tool like `es-check`.
|
||||
|
||||
|
||||
1. Run > `npx es-check es5 './public/build/*.js'`
|
||||
2. Check the output for files that break es5 compatibility.
|
||||
3. Lazy load the failing imports if possible.
|
||||
3. Lazy load the failing imports if possible.
|
||||
|
||||
### Debugging
|
||||
|
||||
There is no easy or comprehensive way to debug PhantomJS smoke test (image rendering) failures. However, PhantomJS exposes remote debugging interface which can give you a sense of what is going wrong in the smoke test. Before performing the steps described below make sure your local Grafana instance is running:
|
||||
|
||||
1. Go to `tools/phantomjs` directory
|
||||
|
||||
@@ -8,7 +8,7 @@ Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/jav
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Basic rules](#basic-rules)
|
||||
- [Naming conventions](#naming-conventions)
|
||||
- [File and directory naming conventions](#file-and-directory-naming-conventions)
|
||||
- [Files and directories naming conventions](#files-and-directories-naming-conventions)
|
||||
- [Code organization](#code-organization)
|
||||
- [Exports](#exports)
|
||||
- [Comments](#comments)
|
||||
@@ -172,44 +172,6 @@ const CONSTANT_VALUE = "This string won't change";
|
||||
|
||||
_SASS styles are deprecated. Please migrate to Emotion whenever you need to modify SASS styles._
|
||||
|
||||
### Typing
|
||||
|
||||
In general, you should let Typescript infer the types so that there's no need to explicitly define type for each variable.
|
||||
|
||||
There are some exceptions to this:
|
||||
|
||||
```typescript
|
||||
// Typescript needs to know type of arrays or objects otherwise it would infer it as array of any
|
||||
|
||||
// bad
|
||||
const stringArray = [];
|
||||
|
||||
// good
|
||||
const stringArray: string[] = [];
|
||||
```
|
||||
|
||||
Specify function return types explicitly in new code. This improves readability by being able to tell what a function returns just by looking at the signature. It also prevents errors when a function's return type is broader than expected by the author.
|
||||
|
||||
> Note: We don't have linting for this enabled because of lots of old code that needs to be fixed first.
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
function transform(value?: string) {
|
||||
if (!value) {
|
||||
return undefined
|
||||
}
|
||||
return applyTransform(value)
|
||||
};
|
||||
|
||||
// good
|
||||
function transform(value?: string): TransformedValue | undefined {
|
||||
if (!value) {
|
||||
return undefined
|
||||
}
|
||||
return applyTransform(value)
|
||||
};
|
||||
```
|
||||
|
||||
### File and directory naming conventions
|
||||
|
||||
Name files according to the primary export:
|
||||
|
||||
@@ -10,7 +10,7 @@ Storybook is:
|
||||
|
||||
## How to create stories
|
||||
|
||||
Stories for a component should be placed next to the component file. The Storybook file requires the same name as the component file. For example, a story for `SomeComponent.tsx` will have the file name `SomeComponent.story.tsx`. If a story should be internal, not visible in production, name the file `SomeComponent.story.internal.tsx`.
|
||||
Stories for a component should be placed next to the component file. The Storybook file requires the same name as the component file. For example, a story for `SomeComponent.tsx` will have the file name `SomeComponent.story.tsx`.
|
||||
|
||||
### Writing stories
|
||||
|
||||
@@ -101,10 +101,7 @@ import { MyComponent } from "./MyComponent";
|
||||
|
||||
### MDX file without a relationship to a component
|
||||
|
||||
An MDX file can exist by itself without any connection to a story. This can be good for writing things such as a general guidelines page. Two things are required for this to work:
|
||||
|
||||
- The file needs to be named `*.story.mdx`
|
||||
- A `Meta` tag must exist that says where in the hierarchy the component lives. It can look like this:
|
||||
An MDX file can exist by itself without any connection to a story. This can be good for writing things such as a general guidelines page. Something that is required when the MDX file has no relation to a component is a `Meta` tag that says where in the hierarchy the component will live. It can look like this:
|
||||
|
||||
```jsx
|
||||
<Meta title="Docs Overview/Color Palettes"/>
|
||||
|
||||
@@ -23,7 +23,7 @@ Try to *chunk* your content. This means you should organize the document so that
|
||||
|
||||
### Chunking example
|
||||
|
||||
If I was writing content for a site called *Doggie handbook*, I might organize it like this.
|
||||
If I was writing a topic called *Doggie handbook*, I might organize it like this.
|
||||
|
||||
**Concept**
|
||||
* What a dog is
|
||||
|
||||
@@ -26,7 +26,7 @@ In the case of a long task, then you probably won't need any headings except for
|
||||
1. Use second-person imperative tense.
|
||||
1. Basically, "You, do this" with every sentence.
|
||||
1. Do not use the third-person "user" for steps you want the reader ("you") to perform.
|
||||
1. Write steps that contain one action, possibly two related actions, such as copy and paste a thing or save and quit the program.
|
||||
1. Write steps that contain one action, possibly two related actions, such as copy and paste a thing or save and quite the program.
|
||||
If a sentence is not telling the reader to do something, then it is not a step. You can use nested images or paragraphs like this one to add information if necessary.
|
||||
|
||||
In many cases, you should tell the reader what the outcome should be so that they know when they are done.
|
||||
|
||||
@@ -36,14 +36,5 @@ make devenv sources=influxdb,prometheus2,elastic5
|
||||
Some of the blocks support dynamic change of the image version used in the Docker file. The signature looks like this:
|
||||
|
||||
```bash
|
||||
make devenv sources=postgres,openldap,grafana postgres_version=9.2 grafana_version=6.7.0-beta1
|
||||
make devenv sources=postgres,openldap postgres_version=9.2
|
||||
```
|
||||
|
||||
|
||||
### Notes per block
|
||||
|
||||
#### Grafana
|
||||
The grafana block is pre-configured with the dev-datasources and dashboards.
|
||||
|
||||
#### Jaeger
|
||||
Jaeger block runs both Jaeger and Loki container. Loki container sends traces to Jaeger and also logs its own logs into itself so it is possible to setup derived field for traceID from Loki to Jaeger. You need to install a docker plugin for the self logging to work, without it the container won't start. See https://github.com/grafana/loki/tree/master/cmd/docker-driver#plugin-installation for installation instructions.
|
||||
|
||||
168
devenv/bulk_alerting_dashboards/bulkdash_alerting.jsonnet
Normal file
168
devenv/bulk_alerting_dashboards/bulkdash_alerting.jsonnet
Normal file
@@ -0,0 +1,168 @@
|
||||
{
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"alert": {
|
||||
"conditions": [
|
||||
{
|
||||
"evaluator": {
|
||||
"params": [
|
||||
65
|
||||
],
|
||||
"type": "gt"
|
||||
},
|
||||
"operator": {
|
||||
"type": "and"
|
||||
},
|
||||
"query": {
|
||||
"params": [
|
||||
"A",
|
||||
"5m",
|
||||
"now"
|
||||
]
|
||||
},
|
||||
"reducer": {
|
||||
"params": [],
|
||||
"type": "avg"
|
||||
},
|
||||
"type": "query"
|
||||
}
|
||||
],
|
||||
"executionErrorState": "alerting",
|
||||
"frequency": "10s",
|
||||
"handler": 1,
|
||||
"name": "bulk alerting",
|
||||
"noDataState": "no_data",
|
||||
"notifications": []
|
||||
},
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-prometheus",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"$$hashKey": "object:117",
|
||||
"expr": "go_goroutines",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"colorMode": "critical",
|
||||
"fill": true,
|
||||
"line": true,
|
||||
"op": "gt",
|
||||
"value": 50
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Panel Title",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"schemaVersion": 16,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": [
|
||||
"5s",
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
],
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "New dashboard",
|
||||
"uid": null,
|
||||
"version": 0
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
{
|
||||
alertingDashboard(dashboardCounter, datasourceCounter):: {
|
||||
title: "alerting-title-" + dashboardCounter,
|
||||
editable: true,
|
||||
gnetId: null,
|
||||
graphTooltip: 0,
|
||||
id: null,
|
||||
links: [],
|
||||
panels: [
|
||||
{
|
||||
alert: {
|
||||
conditions: [
|
||||
{
|
||||
evaluator: {
|
||||
params: [
|
||||
65
|
||||
],
|
||||
type: "gt"
|
||||
},
|
||||
operator: {
|
||||
type: "and"
|
||||
},
|
||||
query: {
|
||||
params: [
|
||||
"A",
|
||||
"5m",
|
||||
"now"
|
||||
]
|
||||
},
|
||||
reducer: {
|
||||
params: [],
|
||||
type: "avg"
|
||||
},
|
||||
type: "query"
|
||||
}
|
||||
],
|
||||
executionErrorState: "alerting",
|
||||
frequency: "24h",
|
||||
handler: 1,
|
||||
name: "bulk alerting " + dashboardCounter,
|
||||
noDataState: "no_data",
|
||||
notifications: []
|
||||
},
|
||||
aliasColors: {},
|
||||
bars: false,
|
||||
dashLength: 10,
|
||||
dashes: false,
|
||||
datasource: "gfdev-bulkalerting-" + datasourceCounter,
|
||||
fill: 1,
|
||||
gridPos: {
|
||||
h: 9,
|
||||
w: 12,
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
id: 1,
|
||||
legend: {
|
||||
avg: false,
|
||||
current: false,
|
||||
max: false,
|
||||
min: false,
|
||||
show: true,
|
||||
total: false,
|
||||
values: false
|
||||
},
|
||||
lines: true,
|
||||
linewidth: 1,
|
||||
nullPointMode: "null",
|
||||
percentage: false,
|
||||
pointradius: 5,
|
||||
points: false,
|
||||
renderer: "flot",
|
||||
seriesOverrides: [],
|
||||
spaceLength: 10,
|
||||
stack: false,
|
||||
steppedLine: false,
|
||||
targets: [
|
||||
{
|
||||
expr: "go_goroutines",
|
||||
format: "time_series",
|
||||
intervalFactor: 1,
|
||||
refId: "A"
|
||||
}
|
||||
],
|
||||
thresholds: [
|
||||
{
|
||||
colorMode: "critical",
|
||||
fill: true,
|
||||
line: true,
|
||||
op: "gt",
|
||||
value: 50
|
||||
}
|
||||
],
|
||||
timeFrom: null,
|
||||
timeShift: null,
|
||||
title: "Panel Title",
|
||||
tooltip: {
|
||||
shared: true,
|
||||
sort: 0,
|
||||
value_type: "individual"
|
||||
},
|
||||
type: "graph",
|
||||
xaxis: {
|
||||
buckets: null,
|
||||
mode: "time",
|
||||
name: null,
|
||||
show: true,
|
||||
values: []
|
||||
},
|
||||
yaxes: [
|
||||
{
|
||||
format: "short",
|
||||
label: null,
|
||||
logBase: 1,
|
||||
max: null,
|
||||
min: null,
|
||||
show: true
|
||||
},
|
||||
{
|
||||
format: "short",
|
||||
label: null,
|
||||
logBase: 1,
|
||||
max: null,
|
||||
min: null,
|
||||
show: true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
schemaVersion: 16,
|
||||
style: "dark",
|
||||
tags: [],
|
||||
templating: {
|
||||
list: []
|
||||
},
|
||||
time: {
|
||||
from: "now-6h",
|
||||
to: "now"
|
||||
},
|
||||
timepicker: {
|
||||
refresh_intervals: [
|
||||
"5s",
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
],
|
||||
time_options: [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
timezone: "",
|
||||
uid: null,
|
||||
version: 0
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
local arr = std.range(1, 100);
|
||||
|
||||
{
|
||||
"apiVersion": 1,
|
||||
"datasources": [
|
||||
{
|
||||
"name": 'gfdev-bulkalerting-' + counter,
|
||||
"type": "prometheus",
|
||||
"access": "proxy",
|
||||
"url": "http://localhost:9090"
|
||||
}
|
||||
for counter in arr
|
||||
],
|
||||
}
|
||||
@@ -246,29 +246,5 @@ datasources:
|
||||
access: proxy
|
||||
url: http://localhost:3100
|
||||
editable: false
|
||||
jsonData:
|
||||
derivedFields:
|
||||
- name: "traceID"
|
||||
matcherRegex: "traceID=(\\w+)"
|
||||
url: "$${__value.raw}"
|
||||
datasourceUid: gdev-jaeger
|
||||
- name: "traceID"
|
||||
matcherRegex: "traceID=(\\w+)"
|
||||
url: "$${__value.raw}"
|
||||
datasourceUid: gdev-zipkin
|
||||
|
||||
- name: gdev-jaeger
|
||||
type: jaeger
|
||||
uid: gdev-jaeger
|
||||
access: proxy
|
||||
url: http://localhost:16686
|
||||
editable: false
|
||||
|
||||
- name: gdev-zipkin
|
||||
type: zipkin
|
||||
uid: gdev-zipkin
|
||||
access: proxy
|
||||
url: http://localhost:9411
|
||||
editable: false
|
||||
|
||||
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: gdev-graphite
|
||||
type: graphite
|
||||
access: proxy
|
||||
url: http://graphite11:80
|
||||
jsonData:
|
||||
graphiteVersion: "1.1"
|
||||
|
||||
- name: gdev-prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:9090
|
||||
|
||||
- name: gdev-slow-prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:3011
|
||||
|
||||
- name: gdev-testdata
|
||||
isDefault: true
|
||||
type: testdata
|
||||
|
||||
- name: gdev-influxdb
|
||||
type: influxdb
|
||||
access: proxy
|
||||
database: site
|
||||
user: grafana
|
||||
url: http://influxdb:8086
|
||||
jsonData:
|
||||
timeInterval: "15s"
|
||||
secureJsonData:
|
||||
password: grafana
|
||||
|
||||
- name: gdev-influxdb-telegraf
|
||||
type: influxdb
|
||||
access: proxy
|
||||
database: telegraf
|
||||
user: grafana
|
||||
url: http://telegraf:8086
|
||||
jsonData:
|
||||
timeInterval: "10s"
|
||||
secureJsonData:
|
||||
password: grafana
|
||||
|
||||
- name: gdev-opentsdb
|
||||
type: opentsdb
|
||||
access: proxy
|
||||
url: http://opentsdb:4242
|
||||
jsonData:
|
||||
tsdbResolution: 1
|
||||
tsdbVersion: 1
|
||||
|
||||
- name: gdev-elasticsearch-v2-metrics
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[metrics-]YYYY.MM.DD"
|
||||
url: http://elasticsearch:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 2
|
||||
|
||||
- name: gdev-elasticsearch-v2-logs
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[logs-]YYYY.MM.DD"
|
||||
url: http://elasticsearch:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 2
|
||||
|
||||
- name: gdev-elasticsearch-v5-metrics
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[metrics-]YYYY.MM.DD"
|
||||
url: http://elasticsearch5:10200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 5
|
||||
|
||||
- name: gdev-elasticsearch-v5-logs
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[logs-]YYYY.MM.DD"
|
||||
url: http://elasticsearch5:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 5
|
||||
|
||||
- name: gdev-elasticsearch-v6-metrics
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[metrics-]YYYY.MM.DD"
|
||||
url: http://elasticsearch6:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 60
|
||||
|
||||
- name: gdev-elasticsearch-v6-logs
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[logs-]YYYY.MM.DD"
|
||||
url: http://elasticsearch6:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 60
|
||||
|
||||
- name: gdev-elasticsearch-v6-filebeat
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[filebeat-]YYYY.MM.DD"
|
||||
url: http://elasticsearch6:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 60
|
||||
|
||||
- name: gdev-elasticsearch-v7-metrics
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[metrics-]YYYY.MM.DD"
|
||||
url: http://elasticsearch7:9200
|
||||
jsonData:
|
||||
timeInterval: 10s
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 70
|
||||
|
||||
- name: gdev-elasticsearch-v7-logs
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[logs-]YYYY.MM.DD"
|
||||
url: http://elasticsearch7:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 70
|
||||
|
||||
- name: gdev-elasticsearch-v7-filebeat
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[filebeat-]YYYY.MM.DD"
|
||||
url: http://elasticsearch7:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 70
|
||||
timeInterval: "10s"
|
||||
logMessageField: message
|
||||
logLevelField: fields.level
|
||||
|
||||
- name: gdev-elasticsearch-v7-metricbeat
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
database: "[metricbeat-]YYYY.MM.DD"
|
||||
url: http://elasticsearch7:9200
|
||||
jsonData:
|
||||
interval: Daily
|
||||
timeField: "@timestamp"
|
||||
esVersion: 70
|
||||
timeInterval: "10s"
|
||||
|
||||
- name: gdev-mysql
|
||||
type: mysql
|
||||
url: mysql:3306
|
||||
database: grafana
|
||||
user: grafana
|
||||
secureJsonData:
|
||||
password: password
|
||||
|
||||
- name: gdev-mysql-ds-tests
|
||||
type: mysql
|
||||
url: mysqltests:3306
|
||||
database: grafana_ds_tests
|
||||
user: grafana
|
||||
secureJsonData:
|
||||
password: password
|
||||
|
||||
- name: gdev-mssql
|
||||
type: mssql
|
||||
url: mssql:1433
|
||||
database: grafana
|
||||
user: grafana
|
||||
secureJsonData:
|
||||
password: Password!
|
||||
|
||||
- name: gdev-mssql-ds-tests
|
||||
type: mssql
|
||||
url: mssqltests:1433
|
||||
database: grafanatest
|
||||
user: grafana
|
||||
secureJsonData:
|
||||
password: Password!
|
||||
|
||||
- name: gdev-postgres
|
||||
type: postgres
|
||||
url: postgres:5432
|
||||
database: grafana
|
||||
user: grafana
|
||||
secureJsonData:
|
||||
password: password
|
||||
jsonData:
|
||||
sslmode: "disable"
|
||||
|
||||
- name: gdev-postgres-ds-tests
|
||||
type: postgres
|
||||
url: postgrestest:5432
|
||||
database: grafanadstest
|
||||
user: grafanatest
|
||||
secureJsonData:
|
||||
password: grafanatest
|
||||
jsonData:
|
||||
sslmode: "disable"
|
||||
|
||||
- name: gdev-cloudwatch
|
||||
type: cloudwatch
|
||||
editable: true
|
||||
jsonData:
|
||||
authType: credentials
|
||||
defaultRegion: eu-west-2
|
||||
|
||||
# Keep to test old /api/prom API
|
||||
- name: gdev-loki-0.3
|
||||
type: loki
|
||||
access: proxy
|
||||
url: http://loki0.3:3100
|
||||
editable: false
|
||||
|
||||
# First version with new v1 API (remove once v1 is out)
|
||||
- name: gdev-loki-0.4
|
||||
type: loki
|
||||
access: proxy
|
||||
url: http://loki0.4:3100
|
||||
editable: false
|
||||
|
||||
- name: gdev-loki
|
||||
type: loki
|
||||
access: proxy
|
||||
url: http://loki:3100
|
||||
editable: false
|
||||
@@ -1,195 +0,0 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"iteration": 1584435937931,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": null,
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 14,
|
||||
"w": 19,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": true,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"alias": "updatesOnTime: $updatesOnTime",
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk"
|
||||
},
|
||||
{
|
||||
"alias": "dependsOnFirst: $dependsOnFirst",
|
||||
"refId": "B",
|
||||
"scenarioId": "random_walk"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Panel Title",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"schemaVersion": 22,
|
||||
"style": "dark",
|
||||
"tags": ["gdev", "templating"],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {
|
||||
"text": "value.1584434137814",
|
||||
"value": "value.1584434137814"
|
||||
},
|
||||
"datasource": "gdev-testdata",
|
||||
"definition": "value.$__from",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"index": -1,
|
||||
"label": null,
|
||||
"multi": false,
|
||||
"name": "updatesOnTime",
|
||||
"options": [],
|
||||
"query": "value.$__from",
|
||||
"refresh": 2,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 0,
|
||||
"tagValuesQuery": "",
|
||||
"tags": [],
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
},
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {
|
||||
"text": "value.value.1584434072074",
|
||||
"value": "value.value.1584434072074"
|
||||
},
|
||||
"datasource": "gdev-testdata",
|
||||
"definition": "value.$updatesOnTime",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"index": -1,
|
||||
"label": null,
|
||||
"multi": false,
|
||||
"name": "dependsOnFirst",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "value.value.1584434072074",
|
||||
"value": "value.value.1584434072074"
|
||||
}
|
||||
],
|
||||
"query": "value.$updatesOnTime",
|
||||
"refresh": 0,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 0,
|
||||
"tagValuesQuery": "",
|
||||
"tags": [],
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Templating - Variables That Refresh On Time Change",
|
||||
"uid": "HeUnbEuZk",
|
||||
"variables": {
|
||||
"list": []
|
||||
},
|
||||
"version": 13
|
||||
}
|
||||
@@ -1,602 +0,0 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 7,
|
||||
"title": "Cell styles",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": "center",
|
||||
"displayMode": "color-background"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 60
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "degree"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Max"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 84
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Last"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 78
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Mean"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 74
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Field"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.align",
|
||||
"value": "left"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 16,
|
||||
"w": 7,
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"showHeader": true,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": true,
|
||||
"displayName": "Last"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 15,
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Colored background",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "reduce",
|
||||
"options": {
|
||||
"reducers": ["max", "mean", "last"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": null
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "orange",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Value"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.displayMode",
|
||||
"value": "gradient-gauge"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Info"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 92
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Min"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 76
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Max"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 89
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Time"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 165
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 16,
|
||||
"w": 8,
|
||||
"x": 7,
|
||||
"y": 1
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"showHeader": true,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": false,
|
||||
"displayName": "Min"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk_table",
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Bar gauge cells",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Time": true
|
||||
},
|
||||
"indexByName": {
|
||||
"Info": 1,
|
||||
"Max": 3,
|
||||
"Min": 2,
|
||||
"Time": 0,
|
||||
"Value": 4
|
||||
},
|
||||
"renameByName": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": null
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"value": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Value"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.displayMode",
|
||||
"value": "lcd-gauge"
|
||||
},
|
||||
{
|
||||
"id": "custom.align",
|
||||
"value": "center"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 16,
|
||||
"w": 9,
|
||||
"x": 15,
|
||||
"y": 1
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"showHeader": true,
|
||||
"sortBy": []
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk_table",
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Retro LCD cell",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Info": false,
|
||||
"Max": true,
|
||||
"Min": true,
|
||||
"Time": false
|
||||
},
|
||||
"indexByName": {
|
||||
"Info": 1,
|
||||
"Max": 3,
|
||||
"Min": 2,
|
||||
"Time": 0,
|
||||
"Value": 4
|
||||
},
|
||||
"renameByName": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 17
|
||||
},
|
||||
"id": 9,
|
||||
"panels": [],
|
||||
"title": "Data links",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": "center",
|
||||
"displayMode": "color-text"
|
||||
},
|
||||
"decimals": 2,
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 50
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "percent"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Time"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.align",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "{name=\"S1\", server=\"A\"}"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "links",
|
||||
"value": [
|
||||
{
|
||||
"title": "Details",
|
||||
"url": "http://detail?serverLabel=${__field.labels.server}&valueNumeric=${__value.numeric}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 18
|
||||
},
|
||||
"id": 3,
|
||||
"maxDataPoints": "10",
|
||||
"options": {
|
||||
"showHeader": true
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"alias": "S1",
|
||||
"labels": "server=A",
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 1,
|
||||
"stringInput": ""
|
||||
},
|
||||
{
|
||||
"alias": "S2",
|
||||
"labels": "server=B",
|
||||
"refId": "B",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 1,
|
||||
"stringInput": ""
|
||||
},
|
||||
{
|
||||
"alias": "S3",
|
||||
"labels": "server=C",
|
||||
"refId": "C",
|
||||
"scenarioId": "random_walk",
|
||||
"seriesCount": 1,
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Data link with labels and numeric value",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "seriesToColumns",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": "gdev-testdata",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {
|
||||
"align": "center",
|
||||
"displayMode": "auto"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"value": 20
|
||||
},
|
||||
{
|
||||
"color": "orange",
|
||||
"value": 60
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 70
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "degree"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 5,
|
||||
"x": 12,
|
||||
"y": 18
|
||||
},
|
||||
"id": 10,
|
||||
"options": {
|
||||
"showHeader": false,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": true,
|
||||
"displayName": "Last"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "7.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "random_walk_table",
|
||||
"seriesCount": 5,
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "No header",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Min": true,
|
||||
"Time": true,
|
||||
"Value": true
|
||||
},
|
||||
"indexByName": {
|
||||
"Info": 2,
|
||||
"Max": 4,
|
||||
"Min": 3,
|
||||
"Time": 0,
|
||||
"Value": 1
|
||||
},
|
||||
"renameByName": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 25,
|
||||
"style": "dark",
|
||||
"tags": ["gdev", "panel-tests"],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - React Table",
|
||||
"uid": "U_bZIMRMk",
|
||||
"version": 17
|
||||
}
|
||||
@@ -1,695 +0,0 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 28,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-testdata",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "connected",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenario": "random_walk",
|
||||
"scenarioId": "random_walk",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": "2s",
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Millisecond res x-axis and tooltip",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-testdata",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "connected",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenario": "random_walk",
|
||||
"scenarioId": "random_walk",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Random walk series",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-testdata",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 7
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 5,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "connected",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "B-series",
|
||||
"yaxis": 2
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,0",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "2000,3000,4000,1000,3000,10000",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "2 yaxis and axis labels",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "percent",
|
||||
"label": "Perecent",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": "Pressure",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-testdata",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 7
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 9,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "B-series",
|
||||
"zindex": -3
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"stack": true,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"hide": false,
|
||||
"refId": "B",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,null,null,null,null,null,null,100,10,10,20,30,40,10",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"alias": "",
|
||||
"hide": false,
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,10,20,30,40,40,40,100,10,20,20",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"alias": "",
|
||||
"hide": false,
|
||||
"refId": "C",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,10,20,30,40,40,40,100,10,20,20",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Stacking value ontop of nulls",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-testdata",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 0,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 15
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 21,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "C-series",
|
||||
"steppedLine": true
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"alias": "",
|
||||
"hide": false,
|
||||
"refId": "B",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,null,40,null,90,null,null,100,null,null,100,null,null,80,null",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"alias": "",
|
||||
"hide": false,
|
||||
"refId": "C",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "20,null40,null,null,50,null,70,null,100,null,10,null,30,null",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Null between points",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-testdata",
|
||||
"decimals": 3,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 15
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 16,
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": true,
|
||||
"current": true,
|
||||
"max": true,
|
||||
"min": true,
|
||||
"show": true,
|
||||
"total": true,
|
||||
"values": true
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"dataLinks": []
|
||||
},
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,0",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,0",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"refId": "C",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,0",
|
||||
"target": ""
|
||||
},
|
||||
{
|
||||
"refId": "D",
|
||||
"scenarioId": "csv_metric_values",
|
||||
"stringInput": "1,20,90,30,5,0",
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Legend Table No Scroll Visible",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"refresh": false,
|
||||
"revision": 8,
|
||||
"schemaVersion": 25,
|
||||
"style": "dark",
|
||||
"tags": ["gdev", "panel-tests", "graph", "table"],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
|
||||
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
|
||||
},
|
||||
"timezone": "utc",
|
||||
"title": "Panel Tests - Time zone support",
|
||||
"uid": "5SdHCasdf",
|
||||
"version": 1
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
grafana_version=6.6.2
|
||||
@@ -1,14 +0,0 @@
|
||||
grafana:
|
||||
image: grafana/grafana:${grafana_version}
|
||||
ports:
|
||||
- "3001:3000"
|
||||
volumes:
|
||||
- "./dashboards.yaml:/etc/grafana/provisioning/dashboards/dashboards.yaml"
|
||||
- "./dev-dashboards:/usr/share/grafana/devenv/dev-dashboards"
|
||||
- "./datasources_docker.yaml:/etc/grafana/provisioning/datasources/datasources.yaml"
|
||||
environment:
|
||||
GF_RENDERING_SERVER_URL: http://renderer:8081/render
|
||||
GF_RENDERING_CALLBACK_URL: http://grafana:3000/
|
||||
|
||||
renderer:
|
||||
image: grafana/grafana-image-renderer:latest
|
||||
@@ -10,11 +10,6 @@
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
# For this to work you need to install the logging driver see https://github.com/grafana/loki/tree/master/cmd/docker-driver#plugin-installation
|
||||
logging:
|
||||
driver: loki
|
||||
options:
|
||||
loki-url: "http://localhost:3100/loki/api/v1/push"
|
||||
# Optional jaeger tracing
|
||||
environment:
|
||||
- JAEGER_AGENT_HOST=jaeger
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
prometheus:
|
||||
build: docker/blocks/prometheus
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9090:9090"
|
||||
|
||||
node_exporter:
|
||||
image: prom/node-exporter
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9100:9100"
|
||||
|
||||
fake-prometheus-data:
|
||||
image: grafana/fake-data-gen
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9091:9091"
|
||||
environment:
|
||||
@@ -17,10 +20,12 @@
|
||||
|
||||
alertmanager:
|
||||
image: quay.io/prometheus/alertmanager
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9093:9093"
|
||||
|
||||
prometheus-random-data:
|
||||
build: docker/blocks/prometheus_random_data
|
||||
network_mode: host
|
||||
ports:
|
||||
- "8081:8080"
|
||||
|
||||
@@ -15,7 +15,7 @@ alerting:
|
||||
- scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- "alertmanager:9093"
|
||||
- "127.0.0.1:9093"
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
@@ -24,16 +24,16 @@ scrape_configs:
|
||||
|
||||
- job_name: 'node_exporter'
|
||||
static_configs:
|
||||
- targets: ['node_exporter:9100']
|
||||
- targets: ['127.0.0.1:9100']
|
||||
|
||||
- job_name: 'fake-data-gen'
|
||||
static_configs:
|
||||
- targets: ['fake-prometheus-data:9091']
|
||||
- targets: ['127.0.0.1:9091']
|
||||
|
||||
- job_name: 'grafana'
|
||||
static_configs:
|
||||
- targets: ['grafana:3000']
|
||||
- targets: ['127.0.0.1:3000']
|
||||
|
||||
- job_name: 'prometheus-random-data'
|
||||
static_configs:
|
||||
- targets: ['prometheus-random-data:8080']
|
||||
- targets: ['127.0.0.1:8081']
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
FROM prom/prometheus:v2.7.2
|
||||
ADD prometheus.yml /etc/prometheus/
|
||||
ADD recording.yml /etc/prometheus/
|
||||
ADD alert.yml /etc/prometheus/
|
||||
ADD alert.rules /etc/prometheus/
|
||||
|
||||
10
devenv/docker/blocks/prometheus2/alert.rules
Normal file
10
devenv/docker/blocks/prometheus2/alert.rules
Normal file
@@ -0,0 +1,10 @@
|
||||
# Alert Rules
|
||||
|
||||
ALERT AppCrash
|
||||
IF process_open_fds > 0
|
||||
FOR 15s
|
||||
LABELS { severity="critical" }
|
||||
ANNOTATIONS {
|
||||
summary = "Number of open fds > 0",
|
||||
description = "Just testing"
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
groups:
|
||||
- name: ALERT
|
||||
rules:
|
||||
- alert: AppCrash
|
||||
expr: process_open_fds > 0
|
||||
for: 15s
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: Number of open fds > 0
|
||||
description: Just testing
|
||||
@@ -1,15 +1,18 @@
|
||||
prometheus:
|
||||
build: docker/blocks/prometheus2
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9090:9090"
|
||||
|
||||
node_exporter:
|
||||
image: prom/node-exporter
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9100:9100"
|
||||
|
||||
fake-prometheus-data:
|
||||
image: grafana/fake-data-gen
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9091:9091"
|
||||
environment:
|
||||
@@ -17,10 +20,12 @@
|
||||
|
||||
alertmanager:
|
||||
image: quay.io/prometheus/alertmanager
|
||||
network_mode: host
|
||||
ports:
|
||||
- "9093:9093"
|
||||
|
||||
prometheus-random-data:
|
||||
build: docker/blocks/prometheus_random_data
|
||||
network_mode: host
|
||||
ports:
|
||||
- "8081:8080"
|
||||
|
||||
@@ -5,17 +5,17 @@ global:
|
||||
# scrape_timeout is set to the global default (10s).
|
||||
|
||||
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
|
||||
rule_files:
|
||||
- "alert.yml"
|
||||
- "recording.yml"
|
||||
#rule_files:
|
||||
# - "alert.rules"
|
||||
# - "first.rules"
|
||||
# - "second.rules"
|
||||
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- "alertmanager:9093"
|
||||
# alerting:
|
||||
# alertmanagers:
|
||||
# - scheme: http
|
||||
# static_configs:
|
||||
# - targets:
|
||||
# - "127.0.0.1:9093"
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
@@ -24,16 +24,16 @@ scrape_configs:
|
||||
|
||||
- job_name: 'node_exporter'
|
||||
static_configs:
|
||||
- targets: ['node_exporter:9100']
|
||||
- targets: ['127.0.0.1:9100']
|
||||
|
||||
- job_name: 'fake-data-gen'
|
||||
static_configs:
|
||||
- targets: ['fake-prometheus-data:9091']
|
||||
- targets: ['127.0.0.1:9091']
|
||||
|
||||
- job_name: 'grafana'
|
||||
static_configs:
|
||||
- targets: ['grafana:3000']
|
||||
- targets: ['127.0.0.1:3000']
|
||||
|
||||
- job_name: 'prometheus-random-data'
|
||||
static_configs:
|
||||
- targets: ['prometheus-random-data:8080']
|
||||
- targets: ['127.0.0.1:8081']
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
groups:
|
||||
- name: RECORDING_RULES
|
||||
rules:
|
||||
- record: instance_path:requests:rate5m
|
||||
expr: rate(prometheus_http_requests_total{job="prometheus"}[5m])
|
||||
- record: path:requests:rate5m
|
||||
expr: sum without (instance)(instance_path:requests:rate5m{job="prometheus"})
|
||||
- record: instance_path:reloads_failures:rate5m
|
||||
expr: rate(prometheus_tsdb_reloads_failures_total{job="prometheus"}[5m])
|
||||
- record: instance_path:reloads:rate5m
|
||||
expr: rate(prometheus_tsdb_reloads_total{job="prometheus"}[5m])
|
||||
- record: instance_path:request_failures_per_requests:ratio_rate5m
|
||||
expr: |2
|
||||
instance_path:reloads_failures:rate5m{job="prometheus"}
|
||||
/
|
||||
instance_path:reloads:rate5m{job="prometheus"}
|
||||
3
devenv/docker/blocks/prometheus_mac/Dockerfile
Normal file
3
devenv/docker/blocks/prometheus_mac/Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM prom/prometheus:v1.8.2
|
||||
ADD prometheus.yml /etc/prometheus/
|
||||
ADD alert.rules /etc/prometheus/
|
||||
10
devenv/docker/blocks/prometheus_mac/alert.rules
Normal file
10
devenv/docker/blocks/prometheus_mac/alert.rules
Normal file
@@ -0,0 +1,10 @@
|
||||
# Alert Rules
|
||||
|
||||
ALERT AppCrash
|
||||
IF process_open_fds > 0
|
||||
FOR 15s
|
||||
LABELS { severity="critical" }
|
||||
ANNOTATIONS {
|
||||
summary = "Number of open fds > 0",
|
||||
description = "Just testing"
|
||||
}
|
||||
26
devenv/docker/blocks/prometheus_mac/docker-compose.yaml
Normal file
26
devenv/docker/blocks/prometheus_mac/docker-compose.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
prometheus:
|
||||
build: docker/blocks/prometheus_mac
|
||||
ports:
|
||||
- "9090:9090"
|
||||
|
||||
node_exporter:
|
||||
image: prom/node-exporter
|
||||
ports:
|
||||
- "9100:9100"
|
||||
|
||||
fake-prometheus-data:
|
||||
image: grafana/fake-data-gen
|
||||
ports:
|
||||
- "9091:9091"
|
||||
environment:
|
||||
FD_DATASOURCE: prom
|
||||
|
||||
alertmanager:
|
||||
image: quay.io/prometheus/alertmanager
|
||||
ports:
|
||||
- "9093:9093"
|
||||
|
||||
prometheus-random-data:
|
||||
build: docker/blocks/prometheus_random_data
|
||||
ports:
|
||||
- "8081:8080"
|
||||
39
devenv/docker/blocks/prometheus_mac/prometheus.yml
Normal file
39
devenv/docker/blocks/prometheus_mac/prometheus.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
# my global config
|
||||
global:
|
||||
scrape_interval: 10s # By default, scrape targets every 15 seconds.
|
||||
evaluation_interval: 10s # By default, scrape targets every 15 seconds.
|
||||
# scrape_timeout is set to the global default (10s).
|
||||
|
||||
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
|
||||
rule_files:
|
||||
- "alert.rules"
|
||||
# - "first.rules"
|
||||
# - "second.rules"
|
||||
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- "alertmanager:9093"
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
- job_name: 'node_exporter'
|
||||
static_configs:
|
||||
- targets: ['node_exporter:9100']
|
||||
|
||||
- job_name: 'fake-data-gen'
|
||||
static_configs:
|
||||
- targets: ['fake-prometheus-data:9091']
|
||||
|
||||
- job_name: 'grafana'
|
||||
static_configs:
|
||||
- targets: ['host.docker.internal:3000']
|
||||
|
||||
- job_name: 'prometheus-random-data'
|
||||
static_configs:
|
||||
- targets: ['prometheus-random-data:8080']
|
||||
@@ -1,7 +1,7 @@
|
||||
# This Dockerfile builds an image for a client_golang example.
|
||||
|
||||
# Builder image, where we build the example.
|
||||
FROM golang:1.14.1 AS builder
|
||||
FROM golang:1.13.4 AS builder
|
||||
# Download prometheus/client_golang/examples/random first
|
||||
RUN go get github.com/prometheus/client_golang/examples/random
|
||||
WORKDIR /go/src/github.com/prometheus/client_golang
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# There is no data generator for this so easiest way to get some data here is run this example app
|
||||
# https://github.com/openzipkin/zipkin-js-example/tree/master/web
|
||||
zipkin:
|
||||
image: openzipkin/zipkin:latest
|
||||
ports:
|
||||
- "9411:9411"
|
||||
@@ -35,12 +35,6 @@ Run load test for 10 virtual users:
|
||||
$ ./run.sh -v 10
|
||||
```
|
||||
|
||||
Run load test and send the results to the database "myDb" in influxDB running locally on port 8086 (with no authentication):
|
||||
|
||||
```bash
|
||||
$ ./run.sh -o influxdb=http://localhost:8086/myDb
|
||||
```
|
||||
|
||||
Run auth token slow test (random query latency between 1 and 30 seconds):
|
||||
|
||||
```bash
|
||||
|
||||
@@ -8,9 +8,8 @@ run() {
|
||||
vus='2'
|
||||
testcase='auth_token_test'
|
||||
slowQuery=''
|
||||
out=''
|
||||
|
||||
while getopts ":d:u:v:c:s:o:" o; do
|
||||
while getopts ":d:u:v:c:s:" o; do
|
||||
case "${o}" in
|
||||
d)
|
||||
duration=${OPTARG}
|
||||
@@ -27,14 +26,11 @@ run() {
|
||||
s)
|
||||
slowQuery=${OPTARG}
|
||||
;;
|
||||
o) out=${OPTARG}
|
||||
;;
|
||||
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
docker run -t --network=host -v $PWD:/src -e URL=$url -e SLOW_QUERY=$slowQuery -e K6_OUT=$out --rm -i loadimpact/k6:master run --vus $vus --duration $duration src/$testcase.js
|
||||
docker run -t --network=host -v $PWD:/src -e URL=$url -e SLOW_QUERY=$slowQuery --rm -i loadimpact/k6:master run --vus $vus --duration $duration src/$testcase.js
|
||||
}
|
||||
|
||||
run "$@"
|
||||
|
||||
@@ -18,21 +18,14 @@ bulkAlertingDashboard() {
|
||||
|
||||
requiresJsonnet
|
||||
|
||||
jsonnet -o "bulk_alerting_dashboards/bulk_alerting_datasources.yaml" ./bulk_alerting_dashboards/datasources.jsonnet
|
||||
|
||||
COUNTER=1
|
||||
DS=1
|
||||
MAX=1000
|
||||
COUNTER=0
|
||||
MAX=100
|
||||
while [ $COUNTER -lt $MAX ]; do
|
||||
jsonnet -o "bulk_alerting_dashboards/alerting_dashboard${COUNTER}.json" \
|
||||
-e "local bulkDash = import 'bulk_alerting_dashboards/dashboard.libsonnet'; bulkDash.alertingDashboard(${COUNTER}, ${DS})"
|
||||
jsonnet -o "bulk_alerting_dashboards/alerting_dashboard${COUNTER}.json" -e "local bulkDash = import 'bulk_alerting_dashboards/bulkdash_alerting.jsonnet'; bulkDash + { uid: 'bd-${COUNTER}', title: 'alerting-title-${COUNTER}' }"
|
||||
let COUNTER=COUNTER+1
|
||||
let DS=COUNTER/10
|
||||
let DS=DS+1
|
||||
done
|
||||
|
||||
ln -s -f ../../../devenv/bulk_alerting_dashboards/bulk_alerting_dashboards.yaml ../conf/provisioning/dashboards/custom.yaml
|
||||
ln -s -f ../../../devenv/bulk_alerting_dashboards/bulk_alerting_datasources.yaml ../conf/provisioning/datasources/custom.yaml
|
||||
}
|
||||
|
||||
requiresJsonnet() {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
.PHONY: docs docs-test
|
||||
|
||||
IMAGE = grafana/docs-base:latest
|
||||
.PHONY: docs docs-no-pull docs-test
|
||||
|
||||
docs:
|
||||
docker pull ${IMAGE}
|
||||
docker run -v $(shell pwd)/sources:/hugo/content/docs/grafana/latest -p 3002:3002 --rm -it $(IMAGE) /bin/bash -c 'make server'
|
||||
docker pull grafana/docs-base:latest
|
||||
docker run -v $(PWD)/sources:/hugo/content/docs/grafana/latest -p 3002:3002 --rm -it grafana/docs-base:latest /bin/bash -c 'npm i && make webpack && make docs-menu && hugo server -p 3002 -D --ignoreCache --baseUrl http://localhost:3002 --bind 0.0.0.0'
|
||||
|
||||
docs-no-pull:
|
||||
docker run -v $(PWD)/sources:/hugo/content/docs/grafana/latest -p 3002:3002 --rm -it grafana/docs-base:latest /bin/bash -c 'make docs-menu && hugo server -p 3002 -D --ignoreCache --baseUrl http://localhost:3002 --bind 0.0.0.0'
|
||||
|
||||
docs-test:
|
||||
docker pull ${IMAGE}
|
||||
docker run -v $(shell pwd)/sources:/hugo/content/docs/grafana/latest --rm -it $(IMAGE) /bin/bash -c 'make prod'
|
||||
docker pull grafana/docs-base:latest
|
||||
docker run -v $(PWD)/sources:/hugo/content/docs/grafana/latest --rm -it grafana/docs-base:latest /bin/bash -c 'npm i && make prod'
|
||||
|
||||
@@ -8,8 +8,7 @@ aliases = ["/docs/grafana/v1.1", "/docs/grafana/latest/guides/reference/admin",
|
||||
|
||||
# Grafana documentation
|
||||
|
||||
## Installing Grafana
|
||||
|
||||
<h2>Installing Grafana</h2>
|
||||
<div class="nav-cards">
|
||||
<a href="{{< relref "installation/debian.md" >}}" class="nav-cards__item nav-cards__item--install">
|
||||
<div class="nav-cards__icon fa fa-linux">
|
||||
@@ -27,8 +26,8 @@ aliases = ["/docs/grafana/v1.1", "/docs/grafana/latest/guides/reference/admin",
|
||||
<h5>Install on Windows</h5>
|
||||
</a>
|
||||
<a href="{{< relref "installation/docker.md" >}}" class="nav-cards__item nav-cards__item--install">
|
||||
<img src="/static/img/logos/logo-docker.svg">
|
||||
<h5>Run Docker image</h5>
|
||||
<h4>Run Docker image</h4>
|
||||
<p>Run Grafana on a Docker image.</p>
|
||||
</a>
|
||||
<a href="https://grafana.com/cloud/grafana" class="nav-cards__item nav-cards__item--install">
|
||||
<div class="nav-cards__icon fa fa-cloud">
|
||||
@@ -42,14 +41,14 @@ aliases = ["/docs/grafana/v1.1", "/docs/grafana/latest/guides/reference/admin",
|
||||
</a>
|
||||
</div>
|
||||
|
||||
## Guides
|
||||
<h2>Guides</h2>
|
||||
|
||||
<div class="nav-cards">
|
||||
<a href="{{< relref "getting-started/what-is-grafana.md" >}}" class="nav-cards__item nav-cards__item--guide">
|
||||
<a href="{{< relref "guides/what-is-grafana.md" >}}" class="nav-cards__item nav-cards__item--guide">
|
||||
<h4>What is Grafana?</h4>
|
||||
<p>Get an overview of Grafana's key features.</p>
|
||||
</a>
|
||||
<a href="{{< relref "getting-started/getting-started.md" >}}" class="nav-cards__item nav-cards__item--guide">
|
||||
<a href="{{< relref "guides/getting_started.md" >}}" class="nav-cards__item nav-cards__item--guide">
|
||||
<h4>Getting started</h4>
|
||||
<p>Learn the basics of using Grafana.</p>
|
||||
</a>
|
||||
@@ -57,7 +56,7 @@ aliases = ["/docs/grafana/v1.1", "/docs/grafana/latest/guides/reference/admin",
|
||||
<h4>Configure Grafana</h4>
|
||||
<p>Review the configuration and setup options.</p>
|
||||
</a>
|
||||
<a href="{{< relref "getting-started/timeseries.md" >}}" class="nav-cards__item nav-cards__item--guide">
|
||||
<a href="{{< relref "guides/timeseries.md" >}}" class="nav-cards__item nav-cards__item--guide">
|
||||
<h4>Intro to time series</h4>
|
||||
<p>Learn about time series data.</p>
|
||||
</a>
|
||||
@@ -72,8 +71,7 @@ aliases = ["/docs/grafana/v1.1", "/docs/grafana/latest/guides/reference/admin",
|
||||
|
||||
</div>
|
||||
|
||||
## Data source guides
|
||||
|
||||
<h2>Data source guides</h2>
|
||||
<div class="nav-cards">
|
||||
<a href="{{< relref "features/datasources/graphite.md" >}}" class="nav-cards__item nav-cards__item--ds">
|
||||
<img src="/img/docs/logos/icon_graphite.svg" >
|
||||
|
||||
@@ -112,7 +112,7 @@ grafana-cli --debug plugins install <plugin-id>
|
||||
|
||||
`--configOverrides` is a command line argument that acts like an environmental variable override.
|
||||
|
||||
For example, you can use it to redirect logging to another file (maybe to log plugin installations in a service like Hosted Grafana) or when resetting the admin password and you have non-default values for some important config value (like where the database is located).
|
||||
For example, you can use it to redirect logging to another file (maybe to log plugin installs in a service like Hosted Grafana) or when resetting the admin password and you have non-default values for some important config value (like where the database is located).
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
|
||||
@@ -12,7 +12,7 @@ weight = 8
|
||||
|
||||
Grafana supports automatic rendering of panels and dashboards as PNG images. This allows Grafana to automatically generate images of your panels to include in [alert notifications]({{< relref "../alerting/notifications.md" >}}).
|
||||
|
||||
While an image is being rendered, the PNG image is temporarily written to the file system. When the image is rendered, the PNG image is temporarily written to the `png` folder in the Grafana `data` folder.
|
||||
When an image is being rendered the PNG-image is temporarily written to the file system. When an image is rendered, the PNG image is temporary written to the `png` folder in the Grafana `data` folder.
|
||||
|
||||
A background job runs every 10 minutes and removes temporary images. You can configure how long an image should be stored before being removed by configuring the [temp-data-lifetime]({{< relref "../installation/configuration/#temp-data-lifetime" >}}) setting.
|
||||
|
||||
@@ -108,7 +108,7 @@ The following example describes how to build and run the remote HTTP rendering s
|
||||
|
||||
## PhantomJS
|
||||
|
||||
> Starting from Grafana v7.0.0, all PhantomJS support has been removed. Please use the Grafana Image Renderer plugin or remote rendering service.
|
||||
> PhantomJS is deprecated since Grafana v6.4 and will be removed in a future release. Please migrate to the Grafana Image Renderer plugin or remote rendering service.
|
||||
|
||||
## Troubleshoot image rendering
|
||||
|
||||
@@ -156,7 +156,7 @@ libx11-6 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3
|
||||
|
||||
**Centos:**
|
||||
|
||||
On a minimal Centos installation, the following dependencies have been confirmed as needed for the image rendering to function:
|
||||
On a minimal Centos install the following dependencies have been confirmed as needed for the image rendering to function:
|
||||
|
||||
```bash
|
||||
libXcomposite libXdamage libXtst cups libXScrnSaver pango atk adwaita-cursor-theme adwaita-icon-theme at at-spi2-atk at-spi2-core cairo-gobject colord-libs dconf desktop-file-utils ed emacs-filesystem gdk-pixbuf2 glib-networking gnutls gsettings-desktop-schemas gtk-update-icon-cache gtk3 hicolor-icon-theme jasper-libs json-glib libappindicator-gtk3 libdbusmenu libdbusmenu-gtk3 libepoxy liberation-fonts liberation-narrow-fonts liberation-sans-fonts liberation-serif-fonts libgusb libindicator-gtk3 libmodman libproxy libsoup libwayland-cursor libwayland-egl libxkbcommon m4 mailx nettle patch psmisc redhat-lsb-core redhat-lsb-submod-security rest spax time trousers xdg-utils xkeyboard-config
|
||||
@@ -164,7 +164,7 @@ libXcomposite libXdamage libXtst cups libXScrnSaver pango atk adwaita-cursor-the
|
||||
|
||||
### Certificate signed by internal certificate authorities
|
||||
|
||||
In many cases, Grafana runs on internal servers and uses certificates that have not been signed by a CA ([Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)) known to Chrome, and therefore cannot be validated. Chrome internally uses NSS ([Network Security Services](https://en.wikipedia.org/wiki/Network_Security_Services)) for cryptogtraphic operations such as the validation of certificates.
|
||||
In many cases Grafana, runs on internal servers and uses certificates that have not been signed by a CA ([Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)) known to Chrome, and therefore cannot be validated. Chrome internally uses NSS ([Network Security Services](https://en.wikipedia.org/wiki/Network_Security_Services)) for cryptogtraphic operations such as the validation of certificates.
|
||||
|
||||
If you are using the Grafana Image Renderer with a Grafana server that uses a certificate signed by such a custom CA (for example a company-internal CA), rendering images will fail and you will see messages like this in the Grafana log:
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
+++
|
||||
title = "Internal Grafana metrics"
|
||||
title = "Internal metrics"
|
||||
description = "Internal metrics exposed by Grafana"
|
||||
keywords = ["grafana", "metrics", "internal metrics"]
|
||||
type = "docs"
|
||||
@@ -8,87 +8,8 @@ parent = "admin"
|
||||
weight = 8
|
||||
+++
|
||||
|
||||
# Internal Grafana metrics
|
||||
# Internal metrics
|
||||
|
||||
Grafana collects some metrics about itself internally. Grafana supports pushing metrics to Graphite or exposing them to be scraped by Prometheus.
|
||||
Grafana collects some metrics about itself internally. Currently, Grafana supports pushing metrics to Graphite or exposing them to be scraped by Prometheus.
|
||||
|
||||
For more information about configuration options related to Grafana metrics, refer to [metrics]({{< relref "../installation/configuration/#metrics" >}}) and [metrics.graphite]({{< relref "../installation/configuration/#metrics-graphite" >}}) in [Configuration]({{< relref "../installation/configuration.md" >}}).
|
||||
|
||||
## Available metrics
|
||||
|
||||
When enabled, Grafana exposes a number of metrics, including:
|
||||
|
||||
* Active Grafana instances
|
||||
* Number of dashboards, users, and playlists
|
||||
* HTTP status codes
|
||||
* Requests by routing group
|
||||
* Grafana active alerts
|
||||
* Grafana performance
|
||||
|
||||
## Pull metrics from Grafana into Prometheus
|
||||
|
||||
These instructions assume you have already added Prometheus as a data source in Grafana.
|
||||
|
||||
1. Enable Prometheus to scrape metrics from Grafana. In your configuration file (`grafana.ini` or `custom.ini` depending on your operating system) remove the semicolon to enable the following configuration options:
|
||||
|
||||
```
|
||||
# Metrics available at HTTP API Url /metrics
|
||||
[metrics]
|
||||
# Disable / Enable internal metrics
|
||||
enabled = true
|
||||
|
||||
# Disable total stats (stat_totals_*) metrics to be generated
|
||||
disable_total_stats = false
|
||||
```
|
||||
|
||||
1. (optional) If you want to require authorization to view the metrics endpoint, then uncomment and set the following options:
|
||||
|
||||
```
|
||||
basic_auth_username =
|
||||
basic_auth_password =
|
||||
```
|
||||
|
||||
1. Restart Grafana. Grafana now exposes metrics at http://localhost:3000/metrics.
|
||||
1. Add the job to your prometheus.yml file.
|
||||
Example:
|
||||
|
||||
```
|
||||
- job_name: 'grafana_metrics'
|
||||
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 5s
|
||||
|
||||
static_configs:
|
||||
- targets: ['localhost:3000']
|
||||
```
|
||||
1. Restart Prometheus. Your new job should appear on the Targets tab.
|
||||
1. In Grafana, hover your mouse over the **Configuration** (gear) icon on the left sidebar and then click **Data Sources**.
|
||||
1. Select the **Prometheus** data source.
|
||||
1. On the Dashboards tab, **Import** the Grafana metrics dashboard. All scraped Grafana metrics are available in the dashboard.
|
||||
|
||||
## View Grafana metrics in Graphite
|
||||
|
||||
These instructions assume you have already added Graphite as a data source in Grafana.
|
||||
|
||||
1. Enable sending metrics to Graphite. In your configuration file (`grafana.ini` or `custom.ini` depending on your operating system) remove the semicolon to enable the following configuration options:
|
||||
|
||||
```
|
||||
# Metrics available at HTTP API Url /metrics
|
||||
[metrics]
|
||||
# Disable / Enable internal metrics
|
||||
enabled = true
|
||||
|
||||
# Disable total stats (stat_totals_*) metrics to be generated
|
||||
disable_total_stats = false
|
||||
```
|
||||
|
||||
1. Enable [metrics.graphite] options:
|
||||
```
|
||||
# Send internal metrics to Graphite
|
||||
[metrics.graphite]
|
||||
# Enable by setting the address setting (ex localhost:2003)
|
||||
address = <hostname or ip>:<port#>
|
||||
prefix = prod.grafana.%(instance_name)s.
|
||||
```
|
||||
|
||||
1. Restart Grafana. Grafana now exposes metrics at http://localhost:3000/metrics and sends them to the Graphite location you specified.
|
||||
To emit internal metrics you have to enable the option under the [metrics] section in your [grafana.ini](http://docs.grafana.org/installation/configuration/#enabled-6) config file. If you want to push metrics to Graphite, you must also configure the [metrics.graphite](http://docs.grafana.org/installation/configuration/#metrics-graphite) section.
|
||||
|
||||
@@ -51,7 +51,7 @@ If you have a literal `$` in your value and want to avoid interpolation, `$$` ca
|
||||
|
||||
## Configuration Management Tools
|
||||
|
||||
Currently we do not provide any scripts/manifests for configuring Grafana. Rather than spending time learning and creating scripts/manifests for each tool, we think our time is better spent making Grafana easier to provision. Therefore, we heavily rely on the expertise of the community.
|
||||
Currently we do not provide any scripts/manifests for configuring Grafana. Rather than spending time learning and creating scripts/manifests for each tool, we think our time is better spent making Grafana easier to provision. Therefore, we heavily relay on the expertise of the community.
|
||||
|
||||
Tool | Project
|
||||
-----|------------
|
||||
@@ -93,8 +93,6 @@ datasources:
|
||||
access: proxy
|
||||
# <int> org id. will default to orgId 1 if not specified
|
||||
orgId: 1
|
||||
# <string> custom UID which can be used to reference this datasource in other parts of the configuration, if not specified will be generated automatically
|
||||
uid: my_unique_uid
|
||||
# <string> url
|
||||
url: http://localhost:8080
|
||||
# <string> Deprecated, use secureJsonData.password
|
||||
@@ -162,9 +160,6 @@ Since not all datasources have the same configuration settings we only have the
|
||||
| tsdbVersion | string | OpenTSDB | Version |
|
||||
| tsdbResolution | string | OpenTSDB | Resolution |
|
||||
| sslmode | string | PostgreSQL | SSLmode. 'disable', 'require', 'verify-ca' or 'verify-full' |
|
||||
| sslRootCertFile | string | PostgreSQL | SSL server root certificate file, must be readable by the Grafana user |
|
||||
| sslCertFile | string | PostgreSQL | SSL client certificate file, must be readable by the Grafana user |
|
||||
| sslKeyFile | string | PostgreSQL | SSL client key file, must be readable by *only* the Grafana user |
|
||||
| encrypt | string | MSSQL | Connection SSL encryption handling. 'disable', 'false' or 'true' |
|
||||
| postgresVersion | number | PostgreSQL | Postgres version as a number (903/904/905/906/1000) meaning v9.3, v9.4, ..., v10 |
|
||||
| timescaledb | boolean | PostgreSQL | Enable usage of TimescaleDB extension |
|
||||
@@ -206,9 +201,9 @@ datasources:
|
||||
httpHeaderValue2: "Bearer XXXXXXXXX"
|
||||
```
|
||||
|
||||
## Dashboards
|
||||
### Dashboards
|
||||
|
||||
It's possible to manage dashboards in Grafana by adding one or more yaml config files in the [`provisioning/dashboards`]({{< relref "../installation/configuration.md" >}}) directory. Each config file can contain a list of `dashboards providers` that will load dashboards into Grafana from the local filesystem.
|
||||
It's possible to manage dashboards in Grafana by adding one or more yaml config files in the [`provisioning/dashboards`](/installation/configuration/#provisioning) directory. Each config file can contain a list of `dashboards providers` that will load dashboards into Grafana from the local filesystem.
|
||||
|
||||
The dashboard provider config file looks somewhat like this:
|
||||
|
||||
@@ -245,9 +240,9 @@ When Grafana starts, it will update/insert all dashboards available in the confi
|
||||
It's possible to make changes to a provisioned dashboard in the Grafana UI. However, it is not possible to automatically save the changes back to the provisioning source.
|
||||
If `allowUiUpdates` is set to `true` and you make changes to a provisioned dashboard, you can `Save` the dashboard then changes will be persisted to the Grafana database.
|
||||
|
||||
> **Note:**
|
||||
> **Note.**
|
||||
> If a provisioned dashboard is saved from the UI and then later updated from the source, the dashboard stored in the database will always be overwritten. The `version` property in the JSON file will not affect this, even if it is lower than the existing dashboard.
|
||||
>
|
||||
>
|
||||
> If a provisioned dashboard is saved from the UI and the source is removed, the dashboard stored in the database will be deleted unless the configuration option `disableDeletion` is set to true.
|
||||
|
||||
If `allowUiUpdates` is configured to `false`, you are not able to make changes to a provisioned dashboard. When you click `Save`, Grafana brings up a *Cannot save provisioned dashboard* dialog. The screenshot below illustrates this behavior.
|
||||
@@ -255,7 +250,7 @@ If `allowUiUpdates` is configured to `false`, you are not able to make changes t
|
||||
Grafana offers options to export the JSON definition of a dashboard. Either `Copy JSON to Clipboard` or `Save JSON to file` can help you synchronize your dashboard changes back to the provisioning source.
|
||||
|
||||
Note: The JSON definition in the input field when using `Copy JSON to Clipboard` or `Save JSON to file` will have the `id` field automatically removed to aid the provisioning workflow.
|
||||
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v51/provisioning_cannot_save_dashboard.png" max-width="500px" class="docs-image--no-shadow" >}}
|
||||
|
||||
### Reusable Dashboard URLs
|
||||
@@ -403,8 +398,6 @@ The following sections detail the supported settings for each alert notification
|
||||
| Name |
|
||||
| ---- |
|
||||
| url |
|
||||
| basicAuthUser |
|
||||
| basicAuthPassword |
|
||||
|
||||
#### Alert notification `teams`
|
||||
|
||||
@@ -422,7 +415,6 @@ The following sections detail the supported settings for each alert notification
|
||||
|
||||
| Name |
|
||||
| ---- |
|
||||
| singleEmail |
|
||||
| addresses |
|
||||
|
||||
#### Alert notification `hipchat`
|
||||
@@ -471,3 +463,4 @@ The following sections detail the supported settings for each alert notification
|
||||
| Name |
|
||||
| ---- |
|
||||
| url |
|
||||
|
||||
|
||||
@@ -71,19 +71,14 @@ external image destination if available or fallback to attaching the image to th
|
||||
Be aware that if you use the `local` image storage email servers and clients might not be
|
||||
able to access the image.
|
||||
|
||||
Setting | Description
|
||||
---------- | -----------
|
||||
Single email | Send a single email to all recipients. Disabled per default.
|
||||
Addresses | Email addresses to recipients. You can enter multiple email addresses using a ";" separator.
|
||||
|
||||
### Slack
|
||||
|
||||
{{< imgbox max-width="40%" img="/img/docs/v4/slack_notification.png" caption="Alerting Slack Notification" >}}
|
||||
|
||||
To set up Slack, you need to configure an incoming Slack webhook URL. You can follow
|
||||
[Sending messages using Incoming Webhooks](https://api.slack.com/incoming-webhooks) on how to do that. If you want to include screenshots of the
|
||||
firing alerts in the Slack messages you have to configure either the [external image destination](#external-image-store)
|
||||
in Grafana or a bot integration via Slack Apps. Follow Slack's guide to set up a bot integration and use the token
|
||||
To set up Slack, you need to configure an incoming Slack webhook URL. You can follow
|
||||
[their guide](https://api.slack.com/incoming-webhooks) on how to do that. If you want to include screenshots of the
|
||||
firing alerts in the Slack messages you have to configure either the [external image destination](#external-image-store)
|
||||
in Grafana, or a bot integration via Slack Apps. Follow Slack's guide to set up a bot integration and use the token
|
||||
provided (https://api.slack.com/bot-users), which starts with "xoxb".
|
||||
|
||||
Setting | Description
|
||||
@@ -110,7 +105,7 @@ Integration Key | Integration key for PagerDuty.
|
||||
Severity | Level for dynamic notifications, default is `critical`
|
||||
Auto resolve incidents | Resolve incidents in PagerDuty once the alert goes back to ok
|
||||
|
||||
**Note:** The tags `Severity`, `Class`, `Group`, and `Component` have special meaning in the [Pagerduty Common Event Format - PD-CEF](https://support.pagerduty.com/docs/pd-cef). If an alert panel defines these tag keys, then they are transposed to the root of the event sent to Pagerduty. This means they will be available within the Pagerduty UI and Filtering tools. A Severity tag set on an alert overrides the global Severity set on the notification channel if it's a valid level.
|
||||
**Note:** The tags `Class`, `Group`, and `Component` have special meaning in the [Pagerduty Common Event Format - PD-CEF](https://support.pagerduty.com/docs/pd-cef). If an alert panel defines these tag keys they will be transposed to the root of the event sent to Pagerduty. This means they will be available within the Pagerduty UI and Filtering tools.
|
||||
|
||||
### Webhook
|
||||
|
||||
@@ -203,24 +198,25 @@ Prometheus Alertmanager | `prometheus-alertmanager` | yes, external only | yes
|
||||
Pushover | `pushover` | yes | no
|
||||
Sensu | `sensu` | yes, external only | no
|
||||
Slack | `slack` | yes | no
|
||||
Squadcast | `webhook` | no | no
|
||||
Telegram | `telegram` | yes | no
|
||||
Threema | `threema` | yes, external only | no
|
||||
VictorOps | `victorops` | yes, external only | no
|
||||
Webhook | `webhook` | yes, external only | yes
|
||||
|
||||
## Enable images in notifications {#external-image-store}
|
||||
# Enable images in notifications {#external-image-store}
|
||||
|
||||
Grafana can render the panel associated with the alert rule as a PNG image and include that in the notification. Read more about the requirements and how to configure
|
||||
Grafana can render the panel associated with the alert rule as a PNG image and include that in the notification. Read more about the requirements and how to configure
|
||||
[image rendering]({{< relref "../administration/image_rendering/" >}}).
|
||||
|
||||
Most Notification Channels require that this image be publicly accessible (Slack and PagerDuty for example). In order to include images in alert notifications, Grafana can upload the image to an image store. It currently supports
|
||||
Amazon S3, Webdav, Google Cloud Storage and Azure Blob Storage. So to set that up you need to configure the [external image uploader]({{< relref "../installation/configuration/#external-image-storage" >}}) in your grafana-server ini config file.
|
||||
|
||||
Be aware that some notifiers require public access to the image to be able to include it in the notification. So make sure to enable public access to the images. If you're using local image uploader, your Grafana instance need to be accessible by the internet.
|
||||
Be aware that some notifiers requires public access to the image to be able to include it in the notification. So make sure to enable public access to the images. If you're using local image uploader, your Grafana instance need to be accessible by the internet.
|
||||
|
||||
Notification services which need public image access are marked as 'external only'.
|
||||
|
||||
## Use alert rule tags in notifications {#alert-rule-tags}
|
||||
# Use alert rule tags in notifications {#alert-rule-tags}
|
||||
|
||||
> Only available in Grafana v6.3+.
|
||||
|
||||
@@ -230,7 +226,7 @@ It currently supports only the Prometheus Alertmanager notifier.
|
||||
|
||||
This is an optional feature. You can get notifications without using alert rule tags.
|
||||
|
||||
## Configure the link back to Grafana from alert notifications
|
||||
# Configure the link back to Grafana from alert notifications
|
||||
|
||||
All alert notifications contain a link back to the triggered alert in the Grafana instance.
|
||||
This URL is based on the [domain]({{< relref "../installation/configuration/#domain" >}}) setting in Grafana.
|
||||
|
||||
@@ -11,7 +11,7 @@ weight = 1
|
||||
|
||||
# Alerting Engine and Rules Guide
|
||||
|
||||
Alerting in Grafana allows you to attach rules to your dashboard panels. When you save the dashboard,
|
||||
Alerting in Grafana allows you to attach rules to your dashboard panels. When you save the dashboard
|
||||
Grafana will extract the alert rules into a separate alert rule storage and schedule them for evaluation.
|
||||
|
||||
{{< imgbox max-width="40%" img="/img/docs/v4/drag_handles_gif.gif" caption="Alerting overview" >}}
|
||||
|
||||
@@ -122,12 +122,6 @@ only give access to members of the group `example` which has Id `8bab1c86-8fba-3
|
||||
allowed_groups = 8bab1c86-8fba-33e5-2089-1d1c80ec267d
|
||||
```
|
||||
|
||||
You'll need to ensure that you've [enabled group attributes](https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-fed-group-claims#configure-the-azure-ad-application-registration-for-group-attributes) in your Azure AD Application Registration manifest file (Azure Portal -> Azure Active Directory -> Application Registrations -> Select Application -> Manifest)
|
||||
|
||||
```json
|
||||
"groupMembershipClaims": "ApplicationGroup"
|
||||
```
|
||||
|
||||
The `allowed_domains` option limits access to the users belonging to the specific domains. Domains should be separated by space or comma.
|
||||
|
||||
```ini
|
||||
|
||||
@@ -54,6 +54,24 @@ Check for the presence of a role using the [JMESPath](http://jmespath.org/exampl
|
||||
|
||||
See [JMESPath examples](#jmespath-examples) for more information.
|
||||
|
||||
## Set up OAuth2 with Okta
|
||||
|
||||
First set up Grafana as an OpenId client "webapplication" in Okta. Then set the Base URIs to `https://<grafana domain>/` and set the Login redirect URIs to `https://<grafana domain>/login/generic_oauth`.
|
||||
|
||||
Finally set up the generic oauth module like this:
|
||||
|
||||
```bash
|
||||
[auth.generic_oauth]
|
||||
name = Okta
|
||||
enabled = true
|
||||
scopes = openid profile email
|
||||
client_id = <okta application Client ID>
|
||||
client_secret = <okta application Client Secret>
|
||||
auth_url = https://<okta domain>/oauth2/v1/authorize
|
||||
token_url = https://<okta domain>/oauth2/v1/token
|
||||
api_url = https://<okta domain>/oauth2/v1/userinfo
|
||||
```
|
||||
|
||||
## Set up OAuth2 with Bitbucket
|
||||
|
||||
```bash
|
||||
@@ -132,6 +150,46 @@ allowed_organizations =
|
||||
api_url = https://<domain>/userinfo
|
||||
```
|
||||
|
||||
## Set up OAuth2 with Azure Active Directory
|
||||
|
||||
1. Log in to portal.azure.com and click "Azure Active Directory" in the side menu, then click the "Properties" sub-menu item.
|
||||
|
||||
2. Copy the "Directory ID", this is needed for setting URLs later
|
||||
|
||||
3. Click "App Registrations" and add a new application registration:
|
||||
- Name: Grafana
|
||||
- Application type: Web app / API
|
||||
- Sign-on URL: `https://<grafana domain>/login/generic_oauth`
|
||||
|
||||
4. Click the name of the new application to open the application details page.
|
||||
|
||||
5. Note down the "Application ID", this will be the OAuth client id.
|
||||
|
||||
6. Click "Certificates & secrets" and add a new entry under Client secrets
|
||||
- Description: Grafana OAuth
|
||||
- Expires: Never
|
||||
|
||||
7. Click Add then copy the key value, this will be the OAuth client secret.
|
||||
|
||||
8. Configure Grafana as follows:
|
||||
|
||||
```bash
|
||||
[auth.generic_oauth]
|
||||
name = Azure AD
|
||||
enabled = true
|
||||
allow_sign_up = true
|
||||
client_id = <application id>
|
||||
client_secret = <key value>
|
||||
scopes = openid email name
|
||||
auth_url = https://login.microsoftonline.com/<directory id>/oauth2/authorize
|
||||
token_url = https://login.microsoftonline.com/<directory id>/oauth2/token
|
||||
api_url =
|
||||
team_ids =
|
||||
allowed_organizations =
|
||||
```
|
||||
|
||||
> Note: It's important to ensure that the [root_url]({{< relref "../installation/configuration/#root-url" >}}) in Grafana is set in your Azure Application Reply URLs (App -> Settings -> Reply URLs)
|
||||
|
||||
## Set up OAuth2 with Centrify
|
||||
|
||||
1. Create a new Custom OpenID Connect application configuration in the Centrify dashboard.
|
||||
|
||||
@@ -92,14 +92,6 @@ member_of = "memberOf"
|
||||
email = "email"
|
||||
```
|
||||
|
||||
### Using environment variables
|
||||
|
||||
You can interpolate variables in the TOML config from environment variables. For instance, you could externalize your `bind_password` that way:
|
||||
|
||||
```bash
|
||||
bind_password = "${LDAP_ADMIN_PASSWORD}"
|
||||
```
|
||||
|
||||
## LDAP Debug View
|
||||
|
||||
> Only available in Grafana v6.4+
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
+++
|
||||
title = "Okta OAuth2 authentication"
|
||||
description = "Grafana Okta OAuth Guide "
|
||||
keywords = ["grafana", "configuration", "documentation", "oauth"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Okta"
|
||||
identifier = "okta_oauth2"
|
||||
parent = "authentication"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
# Okta OAuth2 authentication
|
||||
|
||||
> Only available in Grafana v7.0+
|
||||
|
||||
The Okta authentication allows your Grafana users to log in by using an external Okta authorization server.
|
||||
|
||||
## Create an Okta application
|
||||
|
||||
Before you can sign a user in, you need to create an Okta application from the Okta Developer Console.
|
||||
|
||||
1. Log in to the [Okta portal](https://login.okta.com/).
|
||||
|
||||
1. Go to Admin and then select **Developer Console**.
|
||||
|
||||
1. Select **Applications**, then **Add Application**.
|
||||
|
||||
1. Pick **Web** as the platform.
|
||||
|
||||
1. Enter a name for your application (or leave the default value).
|
||||
|
||||
1. Add the **Base URI** of your application, such as https://grafana.example.com.
|
||||
|
||||
1. Enter values for the **Login redirect URI**. Use **Base URI** and append it with `/login/okta`, for example: https://grafana.example.com/login/okta.
|
||||
|
||||
1. Click **Done** to finish creating the Okta application.
|
||||
|
||||
## Enable Okta Oauth in Grafana
|
||||
|
||||
1. Add the following to the [Grafana configuration file]({{< relref "../installation/configuration.md#config-file-locations" >}}):
|
||||
|
||||
```ini
|
||||
[auth.okta]
|
||||
name = Okta
|
||||
enabled = true
|
||||
allow_sign_up = true
|
||||
client_id = some_id
|
||||
client_secret = some_secret
|
||||
scopes = openid profile email groups
|
||||
auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
|
||||
token_url = https://<tenant-id>.okta.com/oauth2/v1/token
|
||||
api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
|
||||
allowed_domains =
|
||||
allowed_groups =
|
||||
role_attribute_path =
|
||||
```
|
||||
|
||||
### Configure allowed groups and domains
|
||||
|
||||
To limit access to authenticated users that are members of one or more groups, set `allowed_groups`
|
||||
to a comma- or space-separated list of Okta groups.
|
||||
|
||||
```ini
|
||||
allowed_groups = Developers, Admins
|
||||
```
|
||||
|
||||
The `allowed_domains` option limits access to the users belonging to the specific domains. Domains should be separated by space or comma.
|
||||
|
||||
```ini
|
||||
allowed_domains = mycompany.com mycompany.org
|
||||
```
|
||||
|
||||
### Map roles
|
||||
|
||||
Grafana can attempt to do role mapping through Okta OAuth. In order to achieve this, Grafana checks for the presence of a role using the [JMESPath](http://jmespath.org/examples.html) specified via the `role_attribute_path` configuration option.
|
||||
|
||||
Grafana uses JSON obtained from querying the `/userinfo` endpoint for the path lookup. The result after evaluating the `role_attribute_path` JMESPath expression needs to be a valid Grafana role, i.e. `Viewer`, `Editor` or `Admin`. Refer to [Organization roles]({{< relref "../permissions/organization_roles.md" >}}) for more information about roles and permissions in Grafana.
|
||||
|
||||
Read about how to [add custom claims](https://developer.okta.com/docs/guides/customize-tokens-returned-from-okta/add-custom-claim/) to the user info in Okta. Also, check Generic OAuth page for [JMESPath examples]({{< relref "generic-oauth.md/#jmespath-examples" >}}).
|
||||
|
||||
### Team Sync (Enterprise only)
|
||||
|
||||
Map your Okta groups to teams in Grafana so that your users will automatically be added to
|
||||
the correct teams.
|
||||
|
||||
Okta groups can be referenced by group name, like `Admins`.
|
||||
|
||||
[Learn more about Team Sync]({{< relref "../enterprise/team-sync.md" >}})
|
||||
@@ -12,7 +12,7 @@ weight = 5
|
||||
|
||||
# Team sync
|
||||
|
||||
With Team Sync, you can set up synchronization between your auth provider's teams and teams in Grafana. This enables LDAP or GitHub OAuth users which are members
|
||||
With the Team Sync it's possible to setup synchronization between your auth providers teams and teams in Grafana. This enables LDAP or GitHub OAuth users which are members
|
||||
of certain teams/groups to automatically be added/removed as members to certain teams in Grafana. Currently the synchronization will only happen every
|
||||
time a user logs in, unless LDAP is used together with active background synchronization that was added in Grafana 6.3.
|
||||
|
||||
@@ -23,4 +23,4 @@ This mechanism allows Grafana to remove an existing synchronized user from a tea
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
> Team Sync is only available in Grafana Enterprise. For more information, refer to [Team sync]({{< relref "../enterprise/team-sync.md" >}}) in [Grafana Enterprise]({{< relref "../enterprise" >}}).
|
||||
> Team Sync is only available in Grafana Enterprise. For more information, refer to [Team sync]({{< relref "../enterprise/team-sync.md" >}}) in [Grafana Enterprise]({{< relref "../enterprise" >}}).
|
||||
@@ -1,7 +0,0 @@
|
||||
+++
|
||||
title = "Dashboards"
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
identifier = "dashboards"
|
||||
weight = 4
|
||||
+++
|
||||
@@ -1,4 +1,9 @@
|
||||
+++
|
||||
title = "Developers"
|
||||
title = "Contribute"
|
||||
description = "Contribute"
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Contribute"
|
||||
identifier = "contribute"
|
||||
weight = 20
|
||||
+++
|
||||
|
||||
@@ -3,6 +3,9 @@ title = "Contributor License Agreement (CLA)"
|
||||
description = "Contributor License Agreement (CLA)"
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/project/cla", "docs/contributing/cla.html"]
|
||||
[menu.docs]
|
||||
parent = "contribute"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
# Grafana Labs Contributor License Agreement
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
+++
|
||||
title = "Contribute to Grafana"
|
||||
keywords = ["grafana", "documentation", "developers", "resources"]
|
||||
type = "docs"
|
||||
+++
|
||||
|
||||
# Contribute to Grafana
|
||||
|
||||
This page lists resources for developers who want to contribute to the Grafana software ecosystem or build plugins for Grafana.
|
||||
|
||||
##
|
||||
General resources
|
||||
These resources are useful for all developers.
|
||||
|
||||
* [Contributing to Grafana](https://github.com/grafana/grafana/blob/master/CONTRIBUTING.md): Start here to learn how you can contribute your skills to make Grafana even better.
|
||||
|
||||
* [Developer guide](https://github.com/grafana/grafana/blob/master/contribute/developer-guide.md): A guide to help you get started developing Grafana software, includes instructions for how to configure Grafana for development.
|
||||
|
||||
* [Contributing to documentation](https://github.com/grafana/grafana/blob/master/contribute/documentation.md): A guide to help you contribute to Grafana documentation, includes links to beginner-friendly issues.
|
||||
|
||||
* [Architecture guides](https://github.com/grafana/grafana/tree/master/contribute/architecture): These guides explain Grafana’s background architecture.
|
||||
|
||||
* [Create a pull request](https://github.com/grafana/grafana/blob/master/contribute/create-pull-request.md): A guide for new contributors about how to create your first Grafana pull request.
|
||||
|
||||
* [REST APIs](https://grafana.com/docs/grafana/latest/http_api/) allow you to interact programmatically with the Grafana backend.
|
||||
|
||||
## Best practices and style
|
||||
|
||||
Our [style guides](https://github.com/grafana/grafana/tree/master/contribute/style-guides) outline Grafana style for frontend, backend, documentation, and more, including best practices. Please read through them before you start editing or coding!
|
||||
|
||||
* [Backend style guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/backend.md) explains how we want to write Go code in the future.
|
||||
|
||||
* [Documentation style guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/documentation-style-guide.md) applies to all documentation created for Grafana products.
|
||||
|
||||
* [End to end test framework](https://github.com/grafana/grafana/blob/master/contribute/style-guides/e2e.md) provides guidance for Grafana e2e tests.
|
||||
|
||||
* [Frontend style guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/frontend.md) provides rules and guidance on developing in React for Grafana.
|
||||
|
||||
* [Redux framework](https://github.com/grafana/grafana/blob/master/contribute/style-guides/redux.md) explains how Grafana handles Redux boilerplate code.
|
||||
|
||||
* [Styling Grafana](https://github.com/grafana/grafana/blob/master/contribute/style-guides/styling.md) expands on styling React components with Emotion.
|
||||
|
||||
* [Theming Grafana](https://github.com/grafana/grafana/blob/master/contribute/style-guides/themes.md) explains how to use themes and ThemeContext in Grafana code.
|
||||
48
docs/sources/developers/developer-resources.md
Normal file
48
docs/sources/developers/developer-resources.md
Normal file
@@ -0,0 +1,48 @@
|
||||
+++
|
||||
title = "Developer resources"
|
||||
description = "Resources for Grafana developers"
|
||||
keywords = ["grafana", "documentation", "developers", "resources"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Grafana resources"
|
||||
identifier = "Developer resources"
|
||||
weight = 30
|
||||
+++
|
||||
|
||||
# Developer resources
|
||||
|
||||
This page lists resources for developers who want to contribute to the Grafana software ecosystem or build plugins for Grafana.
|
||||
|
||||
##
|
||||
General resources
|
||||
These resources are useful for all developers.
|
||||
|
||||
* [Contributing to Grafana](https://github.com/grafana/grafana/blob/master/CONTRIBUTING.md): Start here to learn how you can contribute your skills to make Grafana even better.
|
||||
|
||||
* [Developer guide](https://github.com/grafana/grafana/blob/master/contribute/developer-guide.md): A guide to help you get started developing Grafana software, includes instructions for how to configure Grafana for development.
|
||||
|
||||
* [Contributing to documentation](https://github.com/grafana/grafana/blob/master/contribute/documentation.md): A guide to help you contribute to Grafana documentation, includes links to beginner-friendly issues.
|
||||
|
||||
* [Architecture guides](https://github.com/grafana/grafana/tree/master/contribute/architecture): These guides explain Grafana’s background architecture.
|
||||
|
||||
* [Create a pull request](https://github.com/grafana/grafana/blob/master/contribute/create-pull-request.md): A guide for new contributors about how to create your first Grafana pull request.
|
||||
|
||||
* [REST APIs](https://grafana.com/docs/grafana/latest/http_api/) allow you to interact programmatically with the Grafana backend.
|
||||
|
||||
## Best practices and style
|
||||
|
||||
Our [style guides](https://github.com/grafana/grafana/tree/master/contribute/style-guides) outline Grafana style for frontend, backend, documentation, and more, including best practices. Please read through them before you start editing or coding!
|
||||
|
||||
* [Backend style guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/backend.md) explains how we want to write Go code in the future.
|
||||
|
||||
* [Documentation style guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/documentation-style-guide.md) applies to all documentation created for Grafana products.
|
||||
|
||||
* [End to end test framework](https://github.com/grafana/grafana/blob/master/contribute/style-guides/e2e.md) provides guidance for Grafana e2e tests.
|
||||
|
||||
* [Frontend style guide](https://github.com/grafana/grafana/blob/master/contribute/style-guides/frontend.md) provides rules and guidance on developing in React for Grafana.
|
||||
|
||||
* [Redux framework](https://github.com/grafana/grafana/blob/master/contribute/style-guides/redux.md) explains how Grafana handles Redux boilerplate code.
|
||||
|
||||
* [Styling Grafana](https://github.com/grafana/grafana/blob/master/contribute/style-guides/styling.md) expands on styling React components with Emotion.
|
||||
|
||||
* [Theming Grafana](https://github.com/grafana/grafana/blob/master/contribute/style-guides/themes.md) explains how to use themes and ThemeContext in Grafana code.
|
||||
@@ -1,67 +0,0 @@
|
||||
+++
|
||||
title = "Build a plugin"
|
||||
type = "docs"
|
||||
+++
|
||||
|
||||
# Build a plugin
|
||||
|
||||
For more information on the types of plugins you can build, refer to the [Plugin Overview]({{< relref "../../plugins/_index.md" >}}).
|
||||
|
||||
## Get started
|
||||
|
||||
The easiest way to start developing Grafana plugins is to use the [Grafana Toolkit](https://www.npmjs.com/package/@grafana/toolkit).
|
||||
|
||||
Open the terminal, and run the following command in your [plugin directory]({{< relref "../../installation/configuration/_index.md#plugins" >}}):
|
||||
|
||||
```bash
|
||||
npx @grafana/toolkit plugin:create my-grafana-plugin
|
||||
```
|
||||
|
||||
If you want a more guided introduction to plugin development, check out our tutorials:
|
||||
|
||||
- [Build a panel plugin]({{< relref "../../../../../tutorials/build-a-panel-plugin.md" >}})
|
||||
- [Build a data source plugin]({{< relref "../../../../../tutorials/build-a-data-source-plugin.md" >}})
|
||||
|
||||
## Go further
|
||||
|
||||
Learn more about specific areas of plugin development.
|
||||
|
||||
### Concepts
|
||||
|
||||
Deepen your knowledge through a series of high-level overviews of plugin concepts.
|
||||
|
||||
- [Data frames]({{< relref "data-frames.md" >}})
|
||||
- [Authentication for data source plugins]({{< relref "authentication.md" >}})
|
||||
|
||||
### UI library
|
||||
|
||||
Explore the many UI components in our [Grafana UI library](https://developers.grafana.com/ui).
|
||||
|
||||
### Tutorials
|
||||
|
||||
If you're looking to build your first plugin, check out these introductory tutorials:
|
||||
|
||||
- [Build a panel plugin]({{< relref "../../../../../tutorials/build-a-panel-plugin.md" >}})
|
||||
- [Build a data source plugin]({{< relref "../../../../../tutorials/build-a-data-source-plugin.md" >}})
|
||||
|
||||
Ready to learn more? Check out our other tutorials:
|
||||
|
||||
- [Build a panel plugin with D3.js]({{< relref "../../../../../tutorials/build-a-panel-plugin-with-d3.md" >}})
|
||||
|
||||
### API reference
|
||||
|
||||
Learn more about Grafana options and packages.
|
||||
|
||||
#### Metadata
|
||||
|
||||
- [Plugin metadata]({{< relref "metadata.md" >}})
|
||||
|
||||
#### Typescript
|
||||
|
||||
- [Grafana Data]({{< relref "../../packages_api/data/_index.md" >}})
|
||||
- [Grafana Runtime]({{< relref "../../packages_api/runtime/_index.md" >}})
|
||||
- [Grafana UI]({{< relref "../../packages_api/ui/_index.md" >}})
|
||||
|
||||
#### Go
|
||||
|
||||
- [Grafana Plugin SDK](https://pkg.go.dev/mod/github.com/grafana/grafana-plugin-sdk-go?tab=overview)
|
||||
@@ -1,137 +0,0 @@
|
||||
+++
|
||||
title = "Authentication for data source plugins"
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/auth-for-datasources/"]
|
||||
+++
|
||||
|
||||
# Authentication for data source plugins
|
||||
|
||||
Grafana has a proxy feature that proxies all data requests through the Grafana backend. The main benefit of using the proxy is secure handling of credentials when authenticating against an external/third-party API. The Grafana proxy also adds [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) headers to the proxied requests.
|
||||
|
||||
The proxy supports:
|
||||
|
||||
- [authentication with HTTP Headers]({{< relref "#api-key-http-header-authentication" >}}).
|
||||
- [token authentication]({{< relref "#how-token-authentication-works" >}}) and can automatically renew a token for the user when the token expires.
|
||||
|
||||
## How the proxy works
|
||||
|
||||
The user saves the API key/password on the plugin config page and it is encrypted (using the `secureJsonData` feature) and saved in the Grafana database. When a request from the data source is made, the Grafana proxy will:
|
||||
|
||||
1. Intercept the original request sent from the data source plugin.
|
||||
1. Load the `secureJsonData` data from the database and decrypt the API key or password on the Grafana backend.
|
||||
1. If using token authentication, carry out authentication and generate an OAuth token that will be added as an `Authorization` HTTP header to the requests (or alternatively it will add a HTTP header with the API key).
|
||||
1. Renew the token if it has expired.
|
||||
1. After adding CORS headers and authorization headers, forward the request to the external API.
|
||||
|
||||
This means that users that access the data source config page cannot access the API key or password after they have saved it the first time and that no secret keys are sent in plain text through the browser where they can be spied on.
|
||||
|
||||
For backend authentication to work, the external/third-party API must either have an OAuth endpoint or that the API accepts an API key as a HTTP header for authentication.
|
||||
|
||||
## Encrypting sensitive data
|
||||
|
||||
When a user saves a password or secret with your data source plugin's Config page, then you can save data in an encrypted blob in the Grafana database called `secureJsonData`. Any data saved in the blob is encrypted by Grafana and can only be decrypted by the Grafana server on the backend. This means once a password is saved, no sensitive data is sent to the browser. If the password is saved in the `jsonData` blob or the `password` field then it is unencrypted and anyone with Admin access (with the help of Chrome Developer Tools) can read it.
|
||||
|
||||
This is an example of using the `secureJsonData` blob to save a property called `password` in a html input:
|
||||
|
||||
```html
|
||||
<input type="password" class="gf-form-input" ng-model="ctrl.current.secureJsonData.password" placeholder="password" />
|
||||
```
|
||||
|
||||
## Plugin routes
|
||||
|
||||
A plugin route describes where the intercepted request should be forwarded to and how to authenticate for the external API. You can define multiple routes that can match multiple external API endpoints.
|
||||
|
||||
You specify routes in the `plugin.json` file for your data source plugin. [Here is an example](https://github.com/grafana/azure-monitor-datasource/blob/d74c82145c0a4af07a7e96cc8dde231bfd449bd9/src/plugin.json#L30-L95) with lots of routes (though most plugins will just have one route).
|
||||
|
||||
When you build your URL to the third-party API in your data source class, the URL should start with the text specified in the path field for a route. The proxy will strip out the path text and replace it with the value in the URL field.
|
||||
|
||||
### Simple plugin route example
|
||||
|
||||
- If my code makes a call to URL `azuremonitor/foo/bar` with this code:
|
||||
|
||||
```js
|
||||
this.backendSrv.datasourceRequest({
|
||||
url: url,
|
||||
method: "GET",
|
||||
});
|
||||
```
|
||||
|
||||
- and the plugin has this route:
|
||||
|
||||
```json
|
||||
"routes": [{
|
||||
"path": "azuremonitor",
|
||||
"method": "GET",
|
||||
"url": "https://management.azure.com"
|
||||
}]
|
||||
```
|
||||
|
||||
- then the Grafana proxy will transform the URL from the original request into `https://management.azure.com/foo/bar`
|
||||
- finally, it will add CORS headers and forward the request to the new URL. This example does not do any authentication.
|
||||
|
||||
The `method` parameter is optional. It can be set to a specific HTTP verb to provide more fine-grained control. For example you might have two plugin routes, one for GET requests and one for POST requests.
|
||||
|
||||
### Dynamic routes
|
||||
|
||||
When using routes, you can also reference a variable stored in JsonData or SecureJsonData which is interpolated (replacing the variable text with a value) when the data source makes a request to the proxy. These are variables that were entered by the user on the data source configuration page and saved in the Grafana database.
|
||||
|
||||
In this example, the value for `dynamicUrl` comes from the JsonData blob and the api key's value is set from the SecureJsonData blob. The `urlParams` field is for query string parameters for HTTP GET requests.
|
||||
|
||||
```json
|
||||
"routes": [
|
||||
{
|
||||
"path": "custom/api/v5/*",
|
||||
"method": "GET",
|
||||
"url": "{{.JsonData.dynamicUrl}}",
|
||||
"urlParams": [
|
||||
{"name": "apiKey", "content": "{{.SecureJsonData.apiKey}}"}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Given that:
|
||||
|
||||
- `JsonData.dynamicUrl` has the value `http://example.com/api`
|
||||
- `SecureJsonData.apiKey` has the value `secretKey`
|
||||
|
||||
a call to the URL: `custom/api/v5/some/path`
|
||||
|
||||
will be proxied to the following URL: `http://example.com/api/some/path?apiKey=secretKey`
|
||||
|
||||
An app using this feature can be found [here](https://github.com/grafana/kentik-app).
|
||||
|
||||
## API key/HTTP header authentication
|
||||
|
||||
Some third-party API's accept a HTTP Header for authentication. The [example](https://github.com/grafana/azure-monitor-datasource/blob/d74c82145c0a4af07a7e96cc8dde231bfd449bd9/src/plugin.json#L91-L93) below has a `headers` section that defines the name of the HTTP Header that the API expects and it uses the `SecureJSONData` blob to fetch an encrypted API key. The Grafana server proxy will decrypt the key, add the `X-API-Key` header to the request and forward it to the third-party API.
|
||||
|
||||
```json
|
||||
{
|
||||
"path": "appinsights",
|
||||
"method": "GET",
|
||||
"url": "https://api.applicationinsights.io",
|
||||
"headers": [{ "name": "X-API-Key", "content": "{{.SecureJsonData.appInsightsApiKey}}" }]
|
||||
}
|
||||
```
|
||||
|
||||
## How token authentication works
|
||||
|
||||
The token auth section in the `plugin.json` file looks like this:
|
||||
|
||||
```json
|
||||
"tokenAuth": {
|
||||
"url": "https://login.microsoftonline.com/{{.JsonData.tenantId}}/oauth2/token",
|
||||
"params": {
|
||||
"grant_type": "client_credentials",
|
||||
"client_id": "{{.JsonData.clientId}}",
|
||||
"client_secret": "{{.SecureJsonData.clientSecret}}",
|
||||
"resource": "https://management.azure.com/"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This interpolates in data from both `jsonData` and `secureJsonData` to generate the token request to the third-party API. It is common for tokens to have a short expiry period (30 minutes). The Grafana proxy automatically renews the token if it has expired.
|
||||
|
||||
## Always restart the Grafana server after route changes
|
||||
|
||||
The plugin.json files are only loaded when the Grafana server starts so when a route is added or changed then the Grafana server has to be restarted for the changes to take effect.
|
||||
@@ -1,285 +0,0 @@
|
||||
+++
|
||||
title = "Backend plugins"
|
||||
keywords = ["grafana", "plugins", "backend", "plugin", "backend-plugins", "documentation"]
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/backend-plugins-guide/"]
|
||||
+++
|
||||
|
||||
# Backend plugins
|
||||
|
||||
Grafana added support for plugins in Grafana 3.0 and this enabled the Grafana community to create panel plugins and data source plugins. It was wildly successful and has made Grafana much more useful as you can integrate it with anything and do any type of custom visualization that you want. However, these plugin hooks are on the frontend only and we also want to provide hooks into the Grafana backend to allow the community to extend and improve Grafana in new ways.
|
||||
|
||||
Once Grafana introduced the alerting feature, external data source plugins needed a backend component for the Grafana server to execute queries for evaluating alert rules (as the alerting engine cannot call frontend JavaScript code). So the obvious first backend plugin type is the **Datasource backend plugin** and it is a new component for an existing data source plugin. This new plugin type will enable alerting for external data source plugins but can also be used for achieving different goals such as query caching, request proxying, custom authentication methods, and more.
|
||||
|
||||
## Grafana's Backend Plugin System
|
||||
|
||||
The backend plugin feature is implemented with the [HashiCorp plugin system](https://github.com/hashicorp/go-plugin) which is a Go plugin system over RPC. Grafana server launches each plugin as a subprocess and communicates with it over RPC. This approach has a number of benefits:
|
||||
|
||||
- Plugins can't crash your grafana process: a panic in a plugin doesn't panic the server.
|
||||
- Plugins are easy to develop: just write a Go application and `go build` (or use any other language which supports gRPC).
|
||||
- Plugins can be relatively secure: The plugin only has access to the interfaces and args given to it, not to the entire memory space of the process.
|
||||
|
||||
## Data source plugin interface
|
||||
|
||||
The plugin interface is very simple and described as a Go interface type in [Grafana](https://github.com/grafana/grafana/blob/6724aaeff9a332dc73b4ee0f8abe0621f7253142/pkg/tsdb/query_endpoint.go#L10-L12) and as a general [RPC service](https://github.com/grafana/grafana-plugin-model/blob/84176c64269d8060f99e750ee8aba6f062753336/datasource.proto#L96-L98) in the corresponding `.proto` (protocol buffer file):
|
||||
|
||||
```go
|
||||
type TsdbQueryEndpoint interface {
|
||||
Query(ctx context.Context, ds *models.DataSource, query *TsdbQuery) (*Response, error)
|
||||
}
|
||||
```
|
||||
|
||||
```protobuf
|
||||
service DatasourcePlugin {
|
||||
rpc Query(DatasourceRequest) returns (DatasourceResponse);
|
||||
}
|
||||
```
|
||||
|
||||
Thus, a datasource plugin should only implement the `Query()` method.
|
||||
|
||||
## Introduction to building a backend component for a plugin
|
||||
|
||||
The [Simple JSON backend](https://github.com/grafana/simple-json-backend-datasource) data source is a good example of writing a simple backend plugin in Go. Let's take a look at some key points.
|
||||
|
||||
### Metadata
|
||||
|
||||
The plugin needs to know it has a backend component, this is done in the `plugin.json` file by setting two fields: `backend` and `executable`. If you want to enable alerting for your data source, set the `alerting` field to `true` as well.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "grafana-simple-json-backend-datasource",
|
||||
"name": "Simple Json backend",
|
||||
"type": "datasource",
|
||||
|
||||
"metrics": true,
|
||||
"annotations": true,
|
||||
"backend": true,
|
||||
"alerting": true,
|
||||
"executable": "simple-json-plugin",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
`executable` should be the the the first part of the binary filename. The actual binary filename has 3 possible endings:
|
||||
|
||||
- \_linux_amd64
|
||||
- \_darwin_amd64
|
||||
- \_windows_amd64.exe
|
||||
|
||||
When Grafana loads the plugin binary, it uses the executable field plus the current OS (Grafana knows which OS it is running on) to load in the correct version of the plugin. So in Simple JSON the executable field is `simple-json-plugin` and the 3 binaries are named:
|
||||
|
||||
- `simple-json-plugin_darwin_amd64`
|
||||
- `simple-json-plugin_linux_amd64`
|
||||
- `simple-json-plugin_windows_amd64.exe`
|
||||
|
||||
The resulting plugin directory will look like this:
|
||||
|
||||
```text
|
||||
simple-json-backend-datasource/
|
||||
|-- dist/
|
||||
| |-- partials/
|
||||
| |-- module.js
|
||||
| |-- plugin.json
|
||||
| |-- simple-json-plugin_linux_amd64
|
||||
| |-- simple-json-plugin_darwin_amd64
|
||||
| |-- simple-json-plugin_windows_amd64.exe
|
||||
...
|
||||
```
|
||||
|
||||
### Plugin code
|
||||
|
||||
A `pkg/` directory contains three `.go` files:
|
||||
|
||||
- `plugin.go` - an entry point of the plugin. This file would be very similar for your data source - you just need to change some details like the plugin name etc.
|
||||
- `datasource.go` - contains `Query()` method implementation and other plugin logic.
|
||||
- `models.go` - types for request and response specific to your data source.
|
||||
|
||||
The data source type is declared in [`datasource.go`](https://github.com/grafana/simple-json-backend-datasource/blob/7927ff0db60c3402dbf954a454f19d7230e18deb/pkg/datasource.go#L21-L24):
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
plugin "github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
type JsonDatasource struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
}
|
||||
```
|
||||
|
||||
The only requirement for the plugin type is that it should extend `plugin.NetRPCUnsupportedPlugin`. You can include more fields into your struct if you want to add some data source-specific features, like logging, cache etc:
|
||||
|
||||
```go
|
||||
type JsonDatasource struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
logger hclog.Logger
|
||||
}
|
||||
```
|
||||
|
||||
The main method you should implement is the [`Query()`](https://github.com/grafana/simple-json-backend-datasource/blob/7927ff0db60c3402dbf954a454f19d7230e18deb/pkg/datasource.go#L26):
|
||||
|
||||
```go
|
||||
func (t *JsonDatasource) Query(ctx context.Context, tsdbReq *datasource.DatasourceRequest) (*datasource.DatasourceResponse, error) {
|
||||
...
|
||||
```
|
||||
|
||||
#### Request format
|
||||
|
||||
In order to call this method from the [frontend part of your data source](https://github.com/grafana/simple-json-backend-datasource/blob/7927ff0db60c3402dbf954a454f19d7230e18deb/src/datasource.ts#L116), use the `/api/tsdb/query` endpoint:
|
||||
|
||||
```js
|
||||
class SimpleJSONDatasource {
|
||||
...
|
||||
|
||||
doTsdbRequest(options) {
|
||||
const tsdbRequest = {
|
||||
from: options.range.from.valueOf().toString(),
|
||||
to: options.range.to.valueOf().toString(),
|
||||
queries: options.targets,
|
||||
};
|
||||
|
||||
return this.backendSrv.datasourceRequest({
|
||||
url: '/api/tsdb/query',
|
||||
method: 'POST',
|
||||
data: tsdbRequest
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This endpoint gets data in the following format (see [pkg/api/metrics.go](https://github.com/grafana/grafana/blob/7b63913dc1d79da07f0329cf19dc4c2704ec488f/pkg/api/metrics.go#L16) and [pkg/api/dtos/models.go](https://github.com/grafana/grafana/blob/7b63913dc1d79da07f0329cf19dc4c2704ec488f/pkg/api/dtos/models.go#L43-L47)):
|
||||
|
||||
```js
|
||||
{
|
||||
from: "1555324640782", // Optional, time range from
|
||||
to: "1555328240782", // Optional, time range to
|
||||
queries: [
|
||||
{
|
||||
datasourceId: 42, // Required
|
||||
refId: "A", // Optional, default is "A"
|
||||
maxDataPoints: 100, // Optional, default is 100
|
||||
intervalMs: 1000, // Optional, default is 1000
|
||||
|
||||
myFieldFoo: "bar", // Any other fields,
|
||||
myFieldBar: "baz", // defined by user
|
||||
...
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
There is only one query function but it is possible to move all your queries to the backend. In order to achieve this, you could add a kind of `queryType` field to your query model and check this type in the backend code. The Stackdriver and Cloudwatch core plugins have examples of supporting multiple types of queries if you need/want to do this:
|
||||
|
||||
- Stackdriver: [pkg/tsdb/stackdriver/stackdriver.go](https://github.com/grafana/grafana/blob/6724aaeff9a332dc73b4ee0f8abe0621f7253142/pkg/tsdb/stackdriver/stackdriver.go#L75-L88)
|
||||
- Cloudwatch: [pkg/tsdb/cloudwatch/cloudwatch.go](https://github.com/grafana/grafana/blob/7b63913dc1d79da07f0329cf19dc4c2704ec488f/pkg/tsdb/cloudwatch/cloudwatch.go#L62-L74)
|
||||
|
||||
#### Response format
|
||||
|
||||
Go types for the query response can be found in Grafana tsdb models ([pkg/tsdb/models.go](https://github.com/grafana/grafana/blob/7b63913dc1d79da07f0329cf19dc4c2704ec488f/pkg/tsdb/models.go#L22-L34)) or in the corresponding protocol buffer file ([datasource.proto](https://github.com/grafana/grafana-plugin-model/blob/84176c64269d8060f99e750ee8aba6f062753336/datasource.proto#L26-L36))
|
||||
|
||||
```protobuf
|
||||
// datasource.proto
|
||||
|
||||
message DatasourceResponse {
|
||||
repeated QueryResult results = 1;
|
||||
}
|
||||
|
||||
message QueryResult {
|
||||
string error = 1;
|
||||
string refId = 2;
|
||||
string metaJson = 3;
|
||||
repeated TimeSeries series = 4;
|
||||
repeated Table tables = 5;
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// pkg/tsdb/models.go
|
||||
|
||||
type Response struct {
|
||||
Results map[string]*QueryResult `json:"results"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type QueryResult struct {
|
||||
Error error `json:"-"`
|
||||
ErrorString string `json:"error,omitempty"`
|
||||
RefId string `json:"refId"`
|
||||
Meta *simplejson.Json `json:"meta,omitempty"`
|
||||
Series TimeSeriesSlice `json:"series"`
|
||||
Tables []*Table `json:"tables"`
|
||||
}
|
||||
```
|
||||
|
||||
The resulting JSON response which the frontend will receive looks like this:
|
||||
|
||||
```js
|
||||
results: {
|
||||
A: {
|
||||
refId: "A",
|
||||
series: [
|
||||
{ name: "series_1", points: [...] },
|
||||
{ name: "series_2", points: [...] },
|
||||
...
|
||||
],
|
||||
tables: null,
|
||||
// Request metadata (any arbitrary JSON).
|
||||
// Optional, empty field will be omitted.
|
||||
meta: {},
|
||||
// Error message. Optional, empty field will be omitted.
|
||||
error: "Request failed",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
Logs from the plugin will be automatically sent to the Grafana server and will appear in its log flow. Grafana server reads logs from the plugin's `stderr` stream, so with the standard `log` package you have to set output to `os.Stderr` first:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
log.SetOutput(os.Stderr)
|
||||
log.Println("from plugin!")
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Another option for logging - using [go-hclog](https://github.com/hashicorp/go-hclog) package:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
)
|
||||
|
||||
var pluginLogger = hclog.New(&hclog.LoggerOptions{
|
||||
Name: "simple-json-backend-datasource",
|
||||
Level: hclog.LevelFromString("DEBUG"),
|
||||
})
|
||||
|
||||
func main() {
|
||||
pluginLogger.Debug("Running Simple JSON backend datasource")
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Building the backend binary
|
||||
|
||||
Building the binary depends on which OS you are using.
|
||||
|
||||
For a Linux distro, the build command would be:
|
||||
|
||||
```sh
|
||||
go build -o ./dist/simple-json-plugin_linux_amd64 ./pkg
|
||||
```
|
||||
|
||||
On Windows, the command would be:
|
||||
|
||||
```sh
|
||||
go build -o ./dist/simple-json-plugin_windows_amd64.exe ./pkg
|
||||
```
|
||||
|
||||
Restart your Grafana server and then check the Grafana logs to make sure your plugin is loaded properly.
|
||||
@@ -1,181 +0,0 @@
|
||||
+++
|
||||
title = "Data frames"
|
||||
type = "docs"
|
||||
+++
|
||||
|
||||
# Data frames
|
||||
|
||||
Grafana supports a variety of different data sources, each with its own data model. To make this possible, Grafana consolidates the query results from each of these data sources into one unified data structure called a _data frame_.
|
||||
|
||||
The data frame structure is a concept that's borrowed from data analysis tools like the [R programming language](https://www.r-project.org), and [Pandas](https://pandas.pydata.org/).
|
||||
|
||||
> Data frames are available in Grafana 7.0+, and replaced the Time series and Table structures with a more generic data structure that can support a wider range of data types.
|
||||
|
||||
This document gives an overview of the data frame structure, and of how data is handled within Grafana.
|
||||
|
||||
## The data frame
|
||||
|
||||
A data frame is a columnar-oriented table structure, which means it stores data by column and not by row. To understand what this means, let’s look at the TypeScript definition used by Grafana:
|
||||
|
||||
```ts
|
||||
interface DataFrame {
|
||||
name?: string;
|
||||
// reference to query that create the frame
|
||||
refId?: string;
|
||||
|
||||
fields: []Field;
|
||||
}
|
||||
```
|
||||
|
||||
In essence, a data frame is a collection of _fields_, where each field corresponds to a column. Each field, in turn, consists of a collection of values, along with meta information, such as the data type of those values.
|
||||
|
||||
```ts
|
||||
interface Field {
|
||||
name: string;
|
||||
// Prometheus like Labels / Tags
|
||||
labels?: Record<string, string>;
|
||||
|
||||
// For example string, number, time (or more specific primitives in the backend)
|
||||
type: FieldType;
|
||||
// Array of values all of the same type
|
||||
values: Vector<T>;
|
||||
|
||||
// Optional display data for the field (e.g. unit, name over-ride, etc)
|
||||
config: FieldConfig;
|
||||
}
|
||||
```
|
||||
|
||||
Let's look an example. The table below demonstrates a data frame with two fields, _time_ and _temperature_.
|
||||
|
||||
| time | temperature |
|
||||
|---------------------|-------------|
|
||||
| 2020-01-02 03:04:00 | 45.0 |
|
||||
| 2020-01-02 03:05:00 | 47.0 |
|
||||
| 2020-01-02 03:06:00 | 48.0 |
|
||||
|
||||
Each field has three values, and each value in a field must share the same type. In this case, all values in the time field are timestamps, and all values in the temperature field are numbers.
|
||||
|
||||
One restriction on data frames is that all fields in the frame must be of the same length to be a valid data frame.
|
||||
|
||||
### Field configuration
|
||||
|
||||
Each field in a data frame contains optional information about the values in the field, such as units, scaling, and so on.
|
||||
|
||||
By adding field configurations to a data frame, Grafana can configure visualizations automatically. For example, you could configure Grafana to automatically set the unit provided by the data source.
|
||||
|
||||
## Transformations
|
||||
|
||||
Along with the type information, field configs enables _data transformations_ within Grafana.
|
||||
|
||||
A data transformation is any function that accepts a data frame as input, and returns another data frame as output. By using data frames in your plugin, you get a range of transformations for free.
|
||||
|
||||
## Data frames as time series
|
||||
|
||||
A data frame with at least one time field is considered a _time series_.
|
||||
|
||||
For more information on time series, refer to our [Introduction to time series](https://grafana.com/docs/grafana/latest/guides/timeseries/).
|
||||
|
||||
### Wide format
|
||||
|
||||
When a collection of time series share the same _time index_—the time fields in each time series are identical—they can be stored together, in a _wide_ format. By reusing the time field, we can reduce the amount of data being sent to the browser.
|
||||
|
||||
In this example, the `cpu` usage from each host share the time index, so we can store them in the same data frame.
|
||||
|
||||
```text
|
||||
Name: Wide
|
||||
Dimensions: 3 fields by 2 rows
|
||||
+---------------------+-----------------+-----------------+
|
||||
| Name: time | Name: cpu | Name: cpu |
|
||||
| Labels: | Labels: host=a | Labels: host=b |
|
||||
| Type: []time.Time | Type: []float64 | Type: []float64 |
|
||||
+---------------------+-----------------+-----------------+
|
||||
| 2020-01-02 03:04:00 | 3 | 4 |
|
||||
| 2020-01-02 03:05:00 | 6 | 7 |
|
||||
+---------------------+-----------------+-----------------+
|
||||
```
|
||||
|
||||
However, if the two time series don't share the same time values, they are represented as two distinct data frames.
|
||||
|
||||
```text
|
||||
Name: cpu
|
||||
Dimensions: 2 fields by 2 rows
|
||||
+---------------------+-----------------+
|
||||
| Name: time | Name: cpu |
|
||||
| Labels: | Labels: host=a |
|
||||
| Type: []time.Time | Type: []float64 |
|
||||
+---------------------+-----------------+
|
||||
| 2020-01-02 03:04:00 | 3 |
|
||||
| 2020-01-02 03:05:00 | 6 |
|
||||
+---------------------+-----------------+
|
||||
|
||||
Name: cpu
|
||||
Dimensions: 2 fields by 2 rows
|
||||
+---------------------+-----------------+
|
||||
| Name: time | Name: cpu |
|
||||
| Labels: | Labels: host=b |
|
||||
| Type: []time.Time | Type: []float64 |
|
||||
+---------------------+-----------------+
|
||||
| 2020-01-02 03:04:01 | 4 |
|
||||
| 2020-01-02 03:05:01 | 7 |
|
||||
+---------------------+-----------------+
|
||||
```
|
||||
|
||||
The wide format can typically be used when multiple time series are collected by the same process. In this case, every measurement is made at the same interval and will therefore share the same time values.
|
||||
|
||||
### Long format
|
||||
|
||||
Some data sources return data in a _long_ format (also called _narrow_ format). This is common format returned by, for example, SQL databases.
|
||||
|
||||
In long format, string values are represented as separate fields rather than as labels. As a result, a data form in long form may have duplicated time values.
|
||||
|
||||
Grafana can detect and convert data frames in long format into wide format.
|
||||
|
||||
> Note: Long format is currently only supported in the backend: [Grafana Issue #22219](https://github.com/grafana/grafana/issues/22219).
|
||||
|
||||
For example, the following data frame in long format:
|
||||
|
||||
```text
|
||||
Name: Long
|
||||
Dimensions: 4 fields by 4 rows
|
||||
+---------------------+-----------------+-----------------+----------------+
|
||||
| Name: time | Name: aMetric | Name: bMetric | Name: host |
|
||||
| Labels: | Labels: | Labels: | Labels: |
|
||||
| Type: []time.Time | Type: []float64 | Type: []float64 | Type: []string |
|
||||
+---------------------+-----------------+-----------------+----------------+
|
||||
| 2020-01-02 03:04:00 | 2 | 10 | foo |
|
||||
| 2020-01-02 03:04:00 | 5 | 15 | bar |
|
||||
| 2020-01-02 03:05:00 | 3 | 11 | foo |
|
||||
| 2020-01-02 03:05:00 | 6 | 16 | bar |
|
||||
+---------------------+-----------------+-----------------+----------------+
|
||||
```
|
||||
|
||||
can be converted into a data frame in wide format:
|
||||
|
||||
```text
|
||||
Name: Wide
|
||||
Dimensions: 5 fields by 2 rows
|
||||
+---------------------+------------------+------------------+------------------+------------------+
|
||||
| Name: time | Name: aMetric | Name: bMetric | Name: aMetric | Name: bMetric |
|
||||
| Labels: | Labels: host=foo | Labels: host=foo | Labels: host=bar | Labels: host=bar |
|
||||
| Type: []time.Time | Type: []float64 | Type: []float64 | Type: []float64 | Type: []float64 |
|
||||
+---------------------+------------------+------------------+------------------+------------------+
|
||||
| 2020-01-02 03:04:00 | 2 | 10 | 5 | 15 |
|
||||
| 2020-01-02 03:05:00 | 3 | 11 | 6 | 16 |
|
||||
+---------------------+------------------+------------------+------------------+------------------+
|
||||
```
|
||||
|
||||
## Technical references
|
||||
|
||||
This section contains links to technical reference and implementations of data frames.
|
||||
|
||||
### Apache Arrow
|
||||
|
||||
The data frame structure is inspired by, and uses the [Apache Arrow Project](https://arrow.apache.org/). Javascript Data frames use Arrow Tables as the underlying structure, and the backend Go code serializes its Frames in Arrow Tables for transmission.
|
||||
|
||||
### Javascript
|
||||
|
||||
The Javascript implementation of data frames is in the [`/src/dataframe` folder](https://github.com/grafana/grafana/tree/master/packages/grafana-data/src/dataframe) and [`/src/types/dataframe.ts`](https://github.com/grafana/grafana/blob/master/packages/grafana-data/src/types/dataFrame.ts) of the [`@grafana/data` package](https://github.com/grafana/grafana/tree/master/packages/grafana-data).
|
||||
|
||||
### Go
|
||||
|
||||
For documentation on the Go implementation of data frames, refer to the [github.com/grafana/grafana-plugin-sdk-go/data package](https://pkg.go.dev/github.com/grafana/grafana-plugin-sdk-go/data?tab=doc).
|
||||
@@ -1,132 +0,0 @@
|
||||
+++
|
||||
title = "Legacy plugins"
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/development/", "/docs/grafana/latest/plugins/datasources/", "/docs/grafana/latest/plugins/apps/", "/docs/grafana/latest/plugins/panels/", "/docs/grafana/latest/plugins/developing/development/"]
|
||||
+++
|
||||
|
||||
# Legacy plugins
|
||||
|
||||
> **Note**: Since Grafana 7.0, writing plugins using Angular is no longer recommended. If you're looking to build a new plugin, refer to [Plugins]({{< relref "../_index.md" >}}).
|
||||
|
||||
You can extend Grafana by writing your own plugins and then share them with other users in [our plugin repository](https://grafana.com/plugins).
|
||||
|
||||
Grafana already has a strong community of contributors and plugin developers. By making it easier to develop and install plugins with resources such as this guide, we hope that the community can grow even stronger and develop new plugins that we would never think about.
|
||||
|
||||
## Short version
|
||||
|
||||
1. [Set up Grafana](https://github.com/grafana/grafana/blob/master/contribute/developer-guide.md)
|
||||
2. Clone an example plugin into ```/var/lib/grafana/plugins``` or `data/plugins` (relative to grafana git repo if you're running development version from source dir)
|
||||
3. Use one of our example plugins as a starting point
|
||||
|
||||
Example plugins
|
||||
|
||||
- ["Hello World" panel using Angular](https://github.com/grafana/simple-angular-panel)
|
||||
- ["Hello World" panel using React](https://github.com/grafana/simple-react-panel)
|
||||
- [Simple json data source](https://github.com/grafana/simple-json-datasource)
|
||||
- [Clock panel](https://github.com/grafana/clock-panel)
|
||||
- [Pie chart panel](https://github.com/grafana/piechart-panel)
|
||||
|
||||
You might also be interested in the available tutorials around authoring a plugin.
|
||||
|
||||
- [Grafana Tutorials](https://grafana.com/tutorials/)
|
||||
|
||||
## What languages?
|
||||
|
||||
Since everything turns into JavaScript, it's up to you to choose which language you want. That said, it's probably a good idea to choose es6 or TypeScript, because we use es6 classes in Grafana. So it's easier to get inspiration from the Grafana repo if you choose one of those languages.
|
||||
|
||||
## Buildscript
|
||||
|
||||
You can use any build system that supports systemjs. All the built content should end up in a folder named ```dist``` and be committed to the repository. By committing the dist folder, the person who installs your plugin does not have to run any build script. All of our example plugins have a build script configured.
|
||||
|
||||
## Keep your plugin up to date
|
||||
|
||||
New versions of Grafana can sometimes cause plugins to break. Check out our [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) doc for changes in
|
||||
Grafana that can impact your plugin.
|
||||
|
||||
## Metadata
|
||||
|
||||
See the [coding styleguide]({{< relref "style-guide.md" >}}) for details on the metadata.
|
||||
|
||||
## module.(js|ts)
|
||||
|
||||
This is the entry point for every plugin. This is the place where you should export
|
||||
your plugin implementation. Depending on what kind of plugin you are developing you
|
||||
will be expected to export different things. You can find what's expected for [datasource]({{< relref "data-sources.md" >}}), [panels]({{< relref "panels.md" >}})
|
||||
and [apps]({{< relref "apps.md" >}}) plugins in the documentation.
|
||||
|
||||
The Grafana SDK is quite small so far and can be found here:
|
||||
|
||||
- [SDK file in Grafana](https://github.com/grafana/grafana/blob/master/public/app/plugins/sdk.ts)
|
||||
|
||||
The SDK contains three different plugin classes: PanelCtrl, MetricsPanelCtrl and QueryCtrl. For plugins of the panel type, the module.js file should export one of these. There are some extra classes for [data sources]({{< relref "data-sources.md" >}}).
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
import {ClockCtrl} from './clock_ctrl';
|
||||
|
||||
export {
|
||||
ClockCtrl as PanelCtrl
|
||||
};
|
||||
```
|
||||
|
||||
The module class is also where css for the dark and light themes is imported:
|
||||
|
||||
```javascript
|
||||
import {loadPluginCss} from 'app/plugins/sdk';
|
||||
import WorldmapCtrl from './worldmap_ctrl';
|
||||
|
||||
loadPluginCss({
|
||||
dark: 'plugins/grafana-worldmap-panel/css/worldmap.dark.css',
|
||||
light: 'plugins/grafana-worldmap-panel/css/worldmap.light.css'
|
||||
});
|
||||
|
||||
export {
|
||||
WorldmapCtrl as PanelCtrl
|
||||
};
|
||||
```
|
||||
|
||||
## Start developing your plugin
|
||||
|
||||
There are three ways that you can start developing a Grafana plugin.
|
||||
|
||||
1. Set up a Grafana development environment. [(described here)](https://github.com/grafana/grafana/blob/master/contribute/developer-guide.md) and place your plugin in the ```data/plugins``` folder.
|
||||
2. Install Grafana and place your plugin in the plugins directory which is set in your [config file](/installation/configuration). By default this is `/var/lib/grafana/plugins` on Linux systems.
|
||||
3. Place your plugin directory anywhere you like and specify it grafana.ini.
|
||||
|
||||
We encourage people to set up the full Grafana environment so that you can get inspiration from the rest of the Grafana code base.
|
||||
|
||||
When Grafana starts, it scans the plugin folders and mounts every folder that contains a plugin.json file unless
|
||||
the folder contains a subfolder named dist. In that case, Grafana mounts the dist folder instead.
|
||||
This makes it possible to have both built and src content in the same plugin Git repo.
|
||||
|
||||
## Grafana Events
|
||||
|
||||
There are a number of Grafana events that a plugin can hook into:
|
||||
|
||||
- `init-edit-mode` can be used to add tabs when editing a panel
|
||||
- `panel-teardown` can be used for clean up
|
||||
- `data-received` is an event in that is triggered on data refresh and can be hooked into
|
||||
- `data-snapshot-load` is an event triggered to load data when in snapshot mode.
|
||||
- `data-error` is used to handle errors on dashboard refresh.
|
||||
|
||||
If a panel receives data and hooks into the `data-received` event then it should handle snapshot mode too. Otherwise the panel will not work if saved as a snapshot. [Getting Plugins to work in Snapshot Mode]({{< relref "snapshot-mode.md" >}}) describes how to add support for this.
|
||||
|
||||
## Examples
|
||||
|
||||
We have three different examples that you can fork/download to get started developing your Grafana plugin.
|
||||
|
||||
- [simple-json-datasource](https://github.com/grafana/simple-json-datasource) (small data source plugin for querying json data from backends)
|
||||
- [simple-app-plugin](https://github.com/grafana/simple-app-plugin)
|
||||
- [clock-panel](https://github.com/grafana/clock-panel)
|
||||
- [singlestat-panel](https://github.com/grafana/grafana/tree/master/public/app/plugins/panel/singlestat)
|
||||
- [piechart-panel](https://github.com/grafana/piechart-panel)
|
||||
|
||||
## Other Articles
|
||||
|
||||
- [Getting Plugins to work in Snapshot Mode]({{< relref "snapshot-mode.md" >}})
|
||||
- [Plugin Defaults and Editor Mode]({{< relref "defaults-and-editor-mode.md" >}})
|
||||
- [Grafana Plugin Code Styleguide]({{< relref "style-guide.md" >}})
|
||||
- [Grafana Apps]({{< relref "apps.md" >}})
|
||||
- [Grafana Data Sources]({{< relref "data-sources.md" >}})
|
||||
- [plugin.json Schema]({{< relref "metadata.md" >}})
|
||||
@@ -1,189 +0,0 @@
|
||||
+++
|
||||
title = "Legacy data source plugins"
|
||||
keywords = ["grafana", "plugins", "documentation"]
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/datasources/"]
|
||||
+++
|
||||
|
||||
# Legacy data source plugins
|
||||
|
||||
Data source plugins enable people to develop plugins for any database that
|
||||
communicates over HTTP. Its up to the plugin to transform the data into
|
||||
time series data so that any grafana panel can then show it.
|
||||
|
||||
## Data source development
|
||||
|
||||
> Our goal is not to have a very extensive documentation but rather have actual
|
||||
> code that people can look at. Example implementations of a data source can be
|
||||
> found in these repos:
|
||||
|
||||
> - [simple-json-datasource](https://github.com/grafana/simple-json-datasource)
|
||||
> - [simple-datasource](https://github.com/grafana/simple-datasource)
|
||||
> - [simple-json-backend-datasource](https://github.com/grafana/simple-json-backend-datasource)
|
||||
|
||||
To interact with the rest of grafana the plugins module file can export 4 different components.
|
||||
|
||||
- Datasource (Required)
|
||||
- QueryCtrl (Required)
|
||||
- ConfigCtrl (Required)
|
||||
- AnnotationsQueryCtrl
|
||||
|
||||
## Plugin json
|
||||
|
||||
There are two data source specific settings for the plugin.json
|
||||
|
||||
```json
|
||||
"metrics": true,
|
||||
"annotations": false,
|
||||
```
|
||||
|
||||
These settings indicate what kind of data the plugin can deliver. At least one of them has to be true.
|
||||
|
||||
## Data source
|
||||
|
||||
The javascript object that communicates with the database and transforms data to times series.
|
||||
|
||||
The Data source should contain the following functions:
|
||||
|
||||
```javascript
|
||||
query(options) // used by panels to get data
|
||||
testDatasource() // used by data source configuration page to make sure the connection is working
|
||||
annotationQuery(options) // used by dashboards to get annotations
|
||||
metricFindQuery(options) // used by query editor to get metric suggestions.
|
||||
```
|
||||
|
||||
### testDatasource
|
||||
|
||||
When a user clicks on the *Save & Test* button when adding a new data source, the details are first saved to the database and then the `testDatasource` function that is defined in your data source plugin will be called. It is recommended that this function makes a query to the data source that will also test that the authentication details are correct. This is so the data source is correctly configured when the user tries to write a query in a new dashboard.
|
||||
|
||||
### Query
|
||||
|
||||
Request object passed to datasource.query function:
|
||||
|
||||
```json
|
||||
{
|
||||
"range": { "from": "2015-12-22T03:06:13.851Z", "to": "2015-12-22T06:48:24.137Z" },
|
||||
"interval": "5s",
|
||||
"targets": [
|
||||
{ "refId": "B", "target": "upper_75" },
|
||||
{ "refId": "A", "target": "upper_90" }
|
||||
],
|
||||
"format": "json",
|
||||
"maxDataPoints": 2495 // decided by the panel
|
||||
}
|
||||
```
|
||||
|
||||
There are two different kinds of results for data sources:
|
||||
time series and table. Time series is the most common format and is supported by all data sources and panels. Table format is only supported by the InfluxDB data source and table panel. But we might see more of this in the future.
|
||||
|
||||
Time series response from datasource.query.
|
||||
An array of:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"target":"upper_75",
|
||||
"datapoints":[
|
||||
[622, 1450754160000],
|
||||
[365, 1450754220000]
|
||||
]
|
||||
},
|
||||
{
|
||||
"target":"upper_90",
|
||||
"datapoints":[
|
||||
[861, 1450754160000],
|
||||
[767, 1450754220000]
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Table response from datasource.query.
|
||||
An array of:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"columns": [
|
||||
{
|
||||
"text": "Time",
|
||||
"type": "time",
|
||||
"sort": true,
|
||||
"desc": true,
|
||||
},
|
||||
{
|
||||
"text": "mean",
|
||||
},
|
||||
{
|
||||
"text": "sum",
|
||||
}
|
||||
],
|
||||
"rows": [
|
||||
[
|
||||
1457425380000,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
1457425370000,
|
||||
1002.76215352,
|
||||
1002.76215352
|
||||
],
|
||||
],
|
||||
"type": "table"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Annotation Query
|
||||
|
||||
Request object passed to datasource.annotationQuery function:
|
||||
|
||||
```json
|
||||
{
|
||||
"range": { "from": "2016-03-04T04:07:55.144Z", "to": "2016-03-04T07:07:55.144Z" },
|
||||
"rangeRaw": { "from": "now-3h", to: "now" },
|
||||
"annotation": {
|
||||
"datasource": "generic datasource",
|
||||
"enable": true,
|
||||
"name": "annotation name"
|
||||
},
|
||||
"dashboard": DashboardModel
|
||||
}
|
||||
```
|
||||
|
||||
Expected result from datasource.annotationQuery:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"annotation": {
|
||||
"name": "annotation name", //should match the annotation name in grafana
|
||||
"enabled": true,
|
||||
"datasource": "generic datasource"
|
||||
},
|
||||
"title": "Cluster outage",
|
||||
"time": 1457075272576,
|
||||
"text": "Joe causes brain split",
|
||||
"tags": ["joe", "cluster", "failure"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## QueryCtrl
|
||||
|
||||
A JavaScript class that will be instantiated and treated as an Angular controller when the user edits metrics in a panel. This class has to inherit from the `app/plugins/sdk.QueryCtrl` class.
|
||||
|
||||
Requires a static template or `templateUrl` variable which will be rendered as the view for this controller.
|
||||
|
||||
## ConfigCtrl
|
||||
|
||||
A JavaScript class that will be instantiated and treated as an Angular controller when a user tries to edit or create a new data source of this type.
|
||||
|
||||
Requires a static template or `templateUrl` variable which will be rendered as the view for this controller.
|
||||
|
||||
## AnnotationsQueryCtrl
|
||||
|
||||
A JavaScript class that will be instantiated and treated as an Angular controller when the user chooses this type of data source in the templating menu in the dashboard.
|
||||
|
||||
Requires a static template or `templateUrl` variable which will be rendered as the view for this controller. The fields that are bound to this controller are then sent to the Database objects annotationQuery function.
|
||||
@@ -1,28 +0,0 @@
|
||||
+++
|
||||
title = "Legacy panel plugins"
|
||||
keywords = ["grafana", "plugins", "panel", "documentation"]
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/panels/"]
|
||||
+++
|
||||
|
||||
# Legacy panel plugins
|
||||
|
||||
Panels are the main building blocks of dashboards.
|
||||
|
||||
## Panel development
|
||||
|
||||
### Scrolling
|
||||
The grafana dashboard framework controls the panel height. To enable a scrollbar within the panel the PanelCtrl needs to set the scrollable static variable:
|
||||
|
||||
```javascript
|
||||
export class MyPanelCtrl extends PanelCtrl {
|
||||
static scrollable = true;
|
||||
...
|
||||
```
|
||||
|
||||
In this case, make sure the template has a single `<div>...</div>` root. The plugin loader will modify that element adding a scrollbar.
|
||||
|
||||
### Examples
|
||||
|
||||
- [clock-panel](https://github.com/grafana/clock-panel)
|
||||
- [singlestat-panel](https://github.com/grafana/grafana/tree/master/public/app/plugins/panel/singlestat)
|
||||
@@ -1,175 +0,0 @@
|
||||
+++
|
||||
title = "Legacy review guidelines"
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/plugin-review-guidelines/"]
|
||||
+++
|
||||
|
||||
# Legacy review guidelines
|
||||
|
||||
The Grafana team reviews all plugins that are published on Grafana.com. There are two areas we review, the metadata for the plugin and the plugin functionality.
|
||||
|
||||
## Metadata
|
||||
|
||||
The plugin metadata consists of a `plugin.json` file and the README.md file. The `plugin.json` file is used by Grafana to load the plugin, and the README.md file is shown in the plugins section of Grafana and the plugins section of https://grafana.com.
|
||||
|
||||
### README.md
|
||||
|
||||
The README.md file is shown on the plugins page in Grafana and the plugin page on Grafana.com. There are some differences between the GitHub markdown and the markdown allowed in Grafana/Grafana.com:
|
||||
|
||||
- Cannot contain inline HTML.
|
||||
- Any image links should be absolute links. For example: https://raw.githubusercontent.com/grafana/azure-monitor-datasource/master/dist/img/grafana_cloud_install.png
|
||||
|
||||
The README should:
|
||||
|
||||
- describe the purpose of the plugin.
|
||||
- contain steps on how to get started.
|
||||
|
||||
### Plugin.json
|
||||
|
||||
The `plugin.json` file is the same concept as the `package.json` file for an npm package. When the Grafana server starts it will scan the plugin folders (all folders in the data/plugins subfolder) and load every folder that contains a `plugin.json` file unless the folder contains a subfolder named `dist`. In that case, the Grafana server will load the `dist` folder instead.
|
||||
|
||||
A minimal `plugin.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "panel",
|
||||
"name": "Clock",
|
||||
"id": "yourorg-clock-panel",
|
||||
|
||||
"info": {
|
||||
"description": "Clock panel for grafana",
|
||||
"author": {
|
||||
"name": "Author Name",
|
||||
"url": "http://yourwebsite.com"
|
||||
},
|
||||
"keywords": ["clock", "panel"],
|
||||
"version": "1.0.0",
|
||||
"updated": "2018-03-24"
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"grafanaVersion": "3.x.x",
|
||||
"plugins": [ ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- The convention for the plugin id is **[grafana.com username/org]-[plugin name]-[datasource|app|panel]** and it has to be unique. The org **cannot** be `grafana` unless it is a plugin created by the Grafana core team.
|
||||
|
||||
Examples:
|
||||
|
||||
- raintank-worldping-app
|
||||
- ryantxu-ajax-panel
|
||||
- alexanderzobnin-zabbix-app
|
||||
- hawkular-datasource
|
||||
|
||||
|
||||
- The `type` field should be either `datasource` `app` or `panel`.
|
||||
- The `version` field should be in the form: x.x.x e.g. `1.0.0` or `0.4.1`.
|
||||
|
||||
The full file format for the `plugin.json` file is described [here](http://docs.grafana.org/plugins/developing/plugin.json/).
|
||||
|
||||
## Plugin Language
|
||||
|
||||
JavaScript, TypeScript, ES6 (or any other language) are all fine as long as the contents of the `dist` subdirectory are transpiled to JavaScript (ES5).
|
||||
|
||||
## File and Directory Structure Conventions
|
||||
|
||||
Here is a typical directory structure for a plugin.
|
||||
|
||||
```bash
|
||||
johnnyb-awesome-datasource
|
||||
|-- dist
|
||||
|-- src
|
||||
| |-- img
|
||||
| | |-- logo.svg
|
||||
| |-- partials
|
||||
| | |-- annotations.editor.html
|
||||
| | |-- config.html
|
||||
| | |-- query.editor.html
|
||||
| |-- datasource.js
|
||||
| |-- module.js
|
||||
| |-- plugin.json
|
||||
| |-- query_ctrl.js
|
||||
|-- Gruntfile.js
|
||||
|-- LICENSE
|
||||
|-- package.json
|
||||
|-- README.md
|
||||
```
|
||||
|
||||
Most JavaScript projects have a build step. The generated JavaScript should be placed in the `dist` directory and the source code in the `src` directory. We recommend that the plugin.json file be placed in the src directory and then copied over to the dist directory when building. The `README.md` can be placed in the root or in the dist directory.
|
||||
|
||||
Directories:
|
||||
|
||||
- `src/` contains plugin source files.
|
||||
- `src/partials` contains html templates.
|
||||
- `src/img` contains plugin logos and other images.
|
||||
- `dist/` contains built content.
|
||||
|
||||
## HTML and CSS
|
||||
|
||||
For the HTML on editor tabs, we recommend using the inbuilt Grafana styles rather than defining your own. This makes plugins feel like a more natural part of Grafana. If done correctly, the html will also be responsive and adapt to smaller screens. The `gf-form` css classes should be used for labels and inputs.
|
||||
|
||||
Below is a minimal example of an editor row with one form group and two fields, a dropdown and a text input:
|
||||
|
||||
```html
|
||||
<div class="editor-row">
|
||||
<div class="section gf-form-group">
|
||||
<h5 class="section-heading">My Plugin Options</h5>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Label1</label>
|
||||
<div class="gf-form-select-wrapper max-width-10">
|
||||
<select class="input-small gf-form-input" ng-model="ctrl.panel.mySelectProperty" ng-options="t for t in ['option1', 'option2', 'option3']" ng-change="ctrl.onSelectChange()"></select>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Label2</label>
|
||||
<input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.myProperty" ng-change="ctrl.onFieldChange()" placeholder="suggestion for user" ng-model-onblur />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Use the `width-x` and `max-width-x` classes to control the width of your labels and input fields. Try to get labels and input fields to line up neatly by having the same width for all the labels in a group and the same width for all inputs in a group if possible.
|
||||
|
||||
## Data Sources
|
||||
|
||||
A basic guide for data sources can be found [here](http://docs.grafana.org/plugins/developing/datasources/).
|
||||
|
||||
### Config Page Guidelines
|
||||
|
||||
- It should be as easy as possible for a user to configure a URL. If the data source is using the `datasource-http-settings` component, it should use the `suggest-url` attribute to suggest the default URL or a URL that is similar to what it should be (especially important if the URL refers to a REST endpoint that is not common knowledge for most users e.g. `https://yourserver:4000/api/custom-endpoint`).
|
||||
|
||||
```html
|
||||
<datasource-http-settings
|
||||
current="ctrl.current"
|
||||
suggest-url="http://localhost:8080">
|
||||
</datasource-http-settings>
|
||||
```
|
||||
|
||||
- The `testDatasource` function should make a query to the data source that will also test that the authentication details are correct. This is so the data source is correctly configured when the user tries to write a query in a new dashboard.
|
||||
|
||||
|
||||
#### Password Security
|
||||
|
||||
If possible, any passwords or secrets should be be saved in the `secureJsonData` blob. To encrypt sensitive data, the Grafana server's proxy feature must be used. The Grafana server has support for token authentication (OAuth) and HTTP Header authentication. If the calls have to be sent directly from the browser to a third-party API, this will not be possible and sensitive data will not be encrypted.
|
||||
|
||||
Read more here about how [authentication for data sources]({{< relref "../authentication.md" >}}) works.
|
||||
|
||||
If using the proxy feature, the Config page should use the `secureJsonData` blob like this:
|
||||
|
||||
- good: `<input type="password" class="gf-form-input" ng-model='ctrl.current.secureJsonData.password' placeholder="password"></input>`
|
||||
- bad: `<input type="password" class="gf-form-input" ng-model='ctrl.current.password' placeholder="password"></input>`
|
||||
|
||||
|
||||
### Query Editor
|
||||
|
||||
Each query editor is unique and can have a unique style. It should be adapted to what the users of the data source are used to.
|
||||
|
||||
- Should use the Grafana CSS `gf-form` classes.
|
||||
- Should be neat and tidy. Labels and fields in columns should be aligned and should be the same width if possible.
|
||||
- The data source should be able to handle when a user toggles a query (by clicking on the eye icon) and not execute the query. This is done by checking the `hide` property - an [example](https://github.com/grafana/grafana/blob/e75840737e81f70b6d169df21eca86a624d4bdc4/public/app/plugins/datasource/postgres/datasource.ts#L73).
|
||||
- Should not execute queries if fields in the Query Editor are empty and the query will throw an exception (defensive programming).
|
||||
- Should handle errors. There are two main ways to do this:
|
||||
- use the notification system in Grafana to show a toaster popup with the error message. Example [here](https://github.com/alexanderzobnin/grafana-zabbix/blob/fdbbba2fb03f5f2a4b3b0715415e09d5a4cf6cde/src/panel-triggers/triggers_panel_ctrl.js#L467-L471).
|
||||
- provide an error notification in the query editor like the MySQL/Postgres data sources do. Example code in the `query_ctrl` [here](https://github.com/grafana/azure-monitor-datasource/blob/b184d077f082a69f962120ef0d1f8296a0d46f03/src/query_ctrl.ts#L36-L51) and in the [html](https://github.com/grafana/azure-monitor-datasource/blob/b184d077f082a69f962120ef0d1f8296a0d46f03/src/partials/query.editor.html#L190-L193).
|
||||
@@ -1,179 +0,0 @@
|
||||
+++
|
||||
title = "Legacy code style guide"
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/code-styleguide/"]
|
||||
+++
|
||||
|
||||
# Legacy code style guide
|
||||
|
||||
This guide has two parts. The first part describes the metadata and the second part is a styleguide for HTML/CSS and JavaScript in Grafana plugins and applies if you are using ES6 in your plugin. If using TypeScript then the [Angular TypeScript styleguide](https://angular.io/styleguide) is recommended.
|
||||
|
||||
## Metadata
|
||||
|
||||
The plugin metadata consists of a plugin.json file and the README.md file. These two files are used by Grafana and Grafana.com.
|
||||
|
||||
### Plugin.json (mandatory)
|
||||
|
||||
The plugin.json file is the same concept as the package.json file for an npm package. When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless the folder contains a subfolder named `dist`. In that case grafana will mount the `dist` folder instead.
|
||||
|
||||
The most important fields are the first three, especially the id. The convention for the plugin id is **[github username/org]-[plugin name]-[datasource|app|panel]** and it has to be unique.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
raintank-worldping-app
|
||||
grafana-simple-json-datasource
|
||||
grafana-piechart-panel
|
||||
mtanda-histogram-panel
|
||||
```
|
||||
|
||||
The full file format for plugin.json is described [here]({{< relref "metadata.md" >}}).
|
||||
|
||||
Minimal plugin.json:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"type": "panel",
|
||||
"name": "Clock",
|
||||
"id": "yourorg-clock-panel",
|
||||
|
||||
"info": {
|
||||
"description": "Clock panel for grafana",
|
||||
"author": {
|
||||
"name": "Grafana Labs",
|
||||
"url": "https://grafana.com"
|
||||
},
|
||||
"keywords": ["clock", "panel"],
|
||||
"version": "1.0.0",
|
||||
"updated": "2015-03-24"
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"grafanaVersion": "3.x.x",
|
||||
"plugins": [ ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### README.md
|
||||
|
||||
The README.md file is rendered both in the grafana.com plugins page, and within the Grafana application. The only difference from how GitHub renders markdown is that html is not allowed.
|
||||
|
||||
## File and Directory Structure Conventions
|
||||
|
||||
Here is a typical directory structure for a plugin.
|
||||
|
||||
```bash
|
||||
johnnyb-awesome-datasource
|
||||
|-- dist
|
||||
|-- spec
|
||||
| |-- datasource_spec.js
|
||||
| |-- query_ctrl_spec.js
|
||||
| |-- test-main.js
|
||||
|-- src
|
||||
| |-- img
|
||||
| | |-- logo.svg
|
||||
| |-- partials
|
||||
| | |-- annotations.editor.html
|
||||
| | |-- config.html
|
||||
| | |-- query.editor.html
|
||||
| |-- datasource.js
|
||||
| |-- module.js
|
||||
| |-- plugin.json
|
||||
| |-- query_ctrl.js
|
||||
|-- Gruntfile.js
|
||||
|-- LICENSE
|
||||
|-- package.json
|
||||
|-- README.md
|
||||
```
|
||||
|
||||
Most JavaScript projects have a build step and most Grafana plugins are built using Babel and ES6. The generated JavaScript should be placed in the `dist` directory and the source code in the `src` directory. We recommend that the plugin.json file be placed in the src directory and then copied over to the dist directory when building. The `README.md` can be placed in the root or in the dist directory.
|
||||
|
||||
Directories:
|
||||
|
||||
- `src/` contains plugin source files.
|
||||
- `src/partials` contains html templates.
|
||||
- `src/img` contains plugin logos and other images.
|
||||
- `spec/` contains tests (optional).
|
||||
- `dist/` contains built content.
|
||||
|
||||
## HTML and CSS
|
||||
|
||||
For the HTML on editor tabs, we recommend using the inbuilt Grafana styles rather than defining your own. This makes plugins feel like a more natural part of Grafana. If done correctly, the html will also be responsive and adapt to smaller screens. The `gf-form` css classes should be used for labels and inputs.
|
||||
|
||||
Below is a minimal example of an editor row with one form group and two fields, a dropdown and a text input:
|
||||
|
||||
```html
|
||||
<div class="editor-row">
|
||||
<div class="section gf-form-group">
|
||||
<h5 class="section-heading">My Plugin Options</h5>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Label1</label>
|
||||
<div class="gf-form-select-wrapper max-width-10">
|
||||
<select class="input-small gf-form-input" ng-model="ctrl.panel.mySelectProperty" ng-options="t for t in ['option1', 'option2', 'option3']" ng-change="ctrl.onSelectChange()"></select>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-10">Label2</label>
|
||||
<input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.myProperty" ng-change="ctrl.onFieldChange()" placeholder="suggestion for user" ng-model-onblur />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Use the `width-x` and `max-width-x` classes to control the width of your labels and input fields. Try to get labels and input fields to line up neatly by having the same width for all the labels in a group and the same width for all inputs in a group if possible.
|
||||
|
||||
## Build Scripts
|
||||
|
||||
Our recommendation is to use whatever you usually use - Grunt, Gulp or npm scripts. Most plugins seems to use Grunt so that is probably the easiest to get started with if you do not have a preferred build system. The only requirement is that it supports systemjs which is required by Grafana to load plugins.
|
||||
|
||||
## Linting
|
||||
|
||||
We recommend that you use a linter for your JavaScript. For ES6, the standard linter is [eslint](http://eslint.org/). Rules for linting are described in an .eslintrc that is placed in the root directory. [Here is an example](https://github.com/grafana/worldmap-panel/blob/master/.eslintrc) of linting rules in a plugin.
|
||||
|
||||
### ES6 features
|
||||
|
||||
1. Use `const` if a variable is not going to be reassigned.
|
||||
2. Prefer to use `let` instead `var` ([Exploring ES6](http://exploringjs.com/es6/ch_core-features.html#_from-var-to-letconst))
|
||||
3. Use arrow functions, which don’t shadow `this` ([Exploring ES6](http://exploringjs.com/es6/ch_core-features.html#_from-function-expressions-to-arrow-functions)):
|
||||
|
||||
```js
|
||||
testDatasource() {
|
||||
return this.getServerStatus()
|
||||
.then(status => {
|
||||
return this.doSomething(status);
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
better than
|
||||
|
||||
```js
|
||||
testDatasource() {
|
||||
var self = this;
|
||||
return this.getServerStatus()
|
||||
.then(function(status) {
|
||||
return self.doSomething(status);
|
||||
})
|
||||
}
|
||||
```
|
||||
4. Use native _Promise_ object:
|
||||
|
||||
```js
|
||||
metricFindQuery(query) {
|
||||
if (!query) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
better than
|
||||
|
||||
```js
|
||||
metricFindQuery(query) {
|
||||
if (!query) {
|
||||
return this.$q.when([]);
|
||||
}
|
||||
}
|
||||
```
|
||||
5. If using Lodash, then be consistent and prefer that to the native ES6 array functions.
|
||||
@@ -1,36 +0,0 @@
|
||||
+++
|
||||
title = "plugin.json"
|
||||
keywords = ["grafana", "plugins", "documentation"]
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/plugins/developing/plugin.json/"]
|
||||
+++
|
||||
|
||||
# plugin.json
|
||||
|
||||
The plugin.json file is mandatory for all plugins. When Grafana starts it will scan the plugin folders and mount every folder that contains a plugin.json file unless the folder contains a subfolder named `dist`. In that case grafana will mount the `dist` folder instead.
|
||||
|
||||
## Schema
|
||||
|
||||
| Property | Description |
|
||||
|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------|
|
||||
| id | Unique name of the plugin. |
|
||||
| type | One of `app`, `datasource`, `panel` |
|
||||
| name | Human-readable name of the plugin |
|
||||
| dependencies.grafanaVersion | Required Grafana version for this plugin |
|
||||
| dependencies.plugins | An array of required plugins on which this plugin depends |
|
||||
| info.author.name | Author's name |
|
||||
| info.author.url | Link to author's website |
|
||||
| info.description | Description of plugin. Used for search on grafana.com |
|
||||
| info.keywords | Array of plugin keywords. Used for search on grafana.com |
|
||||
| info.links | An array of link objects to be displayed on this plugin's project page in the form `{name: 'foo', url: 'http://example.com'}` |
|
||||
| info.logos.small | Link to the "small" version of the plugin logo, which must be an SVG image. "Large" and "small" logos can be the same image. |
|
||||
| info.logos.large | Link to the "large" version of the plugin logo, which must be an SVG image. "Large" and "small" logos can be the same image. |
|
||||
| info.screenshots | An array of screenshot objects in the form `{name: 'bar', path: 'img/screenshot.png'}` |
|
||||
| info.updated | Date when this plugin was built. Use `%TODAY%` for Grafana to autopopulate this value. |
|
||||
| info.version | Project version of this commit. Use `%VERSION%` for Grafana to autopopulate this value. |
|
||||
|
||||
## Plugin.json Example
|
||||
|
||||
Here's an example of an up-to-date plugin.json file:
|
||||
|
||||
https://github.com/grafana/clock-panel/blob/master/src/plugin.json
|
||||
@@ -1,7 +1,7 @@
|
||||
+++
|
||||
title = "Grafana Enterprise"
|
||||
description = "Grafana Enterprise overview"
|
||||
keywords = ["grafana", "documentation", "datasource", "permissions", "ldap", "licensing", "enterprise", "insights", "reporting"]
|
||||
keywords = ["grafana", "documentation", "datasource", "permissions", "ldap", "licensing", "enterprise"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Grafana Enterprise"
|
||||
@@ -50,18 +50,10 @@ Supported auth providers:
|
||||
|
||||
[Reporting]({{< relref "reporting.md" >}}) allows you to take any dashboard, generate a PDF report, and set up a schedule to have it emailed to whoever you choose.
|
||||
|
||||
## Export dashboard as PDF
|
||||
|
||||
[Export dashboard as PDF]({{< relref "export-pdf.md" >}}) allows you to export a dashboard as a PDF document.
|
||||
|
||||
## White labeling
|
||||
|
||||
[White labeling]({{< relref "white-labeling.md" >}}) allows you to replace the Grafana brand and logo with your own corporate brand and logo. You can also change footer links to point to your custom resources.
|
||||
|
||||
## Usage insights
|
||||
|
||||
[Usage insights]({{< relref "usage-insights.md" >}}) allow you to understand how your Grafana instance is used. You can see who is looking at a dashboard, how often a dashboard is seen, and which dashboards are prone to errors. You'll also be able to discover what are the least and the most used dashboards.
|
||||
|
||||
## Enterprise plugins
|
||||
|
||||
With a Grafana Enterprise license, you get access to premium plugins, including:
|
||||
@@ -72,7 +64,6 @@ With a Grafana Enterprise license, you get access to premium plugins, including:
|
||||
* [Dynatrace](https://grafana.com/plugins/grafana-dynatrace-datasource)
|
||||
* [New Relic](https://grafana.com/plugins/grafana-newrelic-datasource)
|
||||
* [Oracle Database](https://grafana.com/plugins/grafana-oracle-datasource)
|
||||
* [ServiceNow](https://grafana.com/grafana/plugins/grafana-servicenow-datasource)
|
||||
* [Splunk](https://grafana.com/plugins/grafana-splunk-datasource)
|
||||
|
||||
## Try Grafana Enterprise
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
+++
|
||||
title = "Export dashboard as PDF"
|
||||
description = ""
|
||||
keywords = ["grafana", "export", "pdf", "share"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
parent = "enterprise"
|
||||
weight = 900
|
||||
+++
|
||||
|
||||
# Export dashboard as PDF
|
||||
|
||||
You can generate PDFs from any of your dashboards and save it to file.
|
||||
|
||||
> Only available in Grafana Enterprise v6.7+.
|
||||
|
||||
1. In the upper right corner of the dashboard that you want to export as PDF, click the **Share dashboard** icon.
|
||||
1. On the PDF tab, select the layout option for exported dashboard: **Portrait** or **Landscape**.
|
||||
1. Click **Save as PDF** to render dashboard as a PDF document.
|
||||
Grafana opens the PDF in a new window or browser tab.
|
||||
@@ -28,104 +28,36 @@ Any changes you make to a dashboard used in a report are reflected the next time
|
||||
|
||||
Currently only Organization Admins can create reports.
|
||||
|
||||
1. Click on the reports icon in the side menu. The Reports tab allows you to view, create, and update your reports.
|
||||
1. Click on the reports icon in the side menu. The Reports tab allow you to view, create, and update your reports.
|
||||
1. Enter report information. All fields are required unless otherwise indicated.
|
||||
* **Name -** Name of the report as you want it to appear in the Reports list.
|
||||
* **Choose dashboard -** Select the dashboard to generate the report from.
|
||||
* **Recipients -** Enter the emails of the people or teams that you want to receive the report.
|
||||
* **Reply to -** (optional) The address that will appear in the **Reply to** field of the email.
|
||||
* **Custom message -** (optional) Message body in the email with the report.
|
||||
1. **Preview** the report to make sure it appears as you expect. Update if necessary
|
||||
1. Select the layout option for generated report: **Portrait** or **Landscape**.
|
||||
1. **Preview** the report to make sure it appears as you expect. Update if necessary.
|
||||
1. Enter scheduling information. Options vary depending on the frequency you select.
|
||||
1. **Save** the report.
|
||||
1. **Send test mail** after saving the report to verify that the whole configuration is working as expected.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/enterprise/reports_create_new.png" max-width="500px" class="docs-image--no-shadow" >}}
|
||||
|
||||
### Scheduling
|
||||
|
||||
Scheduled reports can be sent on a weekly, daily, or hourly basis. You may also disable scheduling for when you either want to pause a report or send it via the API.
|
||||
|
||||
All scheduling indicates when the reporting service will start rendering the dashboard. It can take a few minutes to render a dashboard with a lot of panels.
|
||||
|
||||
#### Hourly
|
||||
|
||||
Hourly reports are generated once per hour. All fields are required.
|
||||
|
||||
* **At minute -** The number of minutes after full hour when the report should be generated.
|
||||
* **Time zone -** Time zone to determine the offset of the full hour. Does not currently change the time in the rendered report.
|
||||
|
||||
#### Daily
|
||||
|
||||
Daily reports are generated once per day. All fields are required.
|
||||
|
||||
* **Time -** Time of day in 24 hours format when the report should be sent.
|
||||
* **Time zone -** Time zone for the **Time** field.
|
||||
|
||||
#### Weekly
|
||||
|
||||
Weekly reports are generated once per week. All fields are required.
|
||||
|
||||
* **Day -** Weekday which the report should be sent on.
|
||||
* **Time -** Time of day in 24 hours format when the report should be sent.
|
||||
* **Time zone -** Time zone for the **Time** field.
|
||||
|
||||
#### Never
|
||||
|
||||
> Only available in Grafana Enterprise v7.0+.
|
||||
|
||||
Reports which are scheduled to never be sent have no parameter and will not be sent to the scheduler. They may be manually generated from the **Send test email** prompt or via the API.
|
||||
|
||||
### Send test mail
|
||||
|
||||
> Only available in Grafana Enterprise v7.0+.
|
||||
|
||||
1. In the report, click **Send test mail**.
|
||||
1. In the Email field, enter the email address or addresses that you want to test, separated by semicolon.
|
||||
If you want to use email addresses from the report, then select the **Use emails from report** check box.
|
||||
1. Click **Send**.
|
||||
|
||||
The last saved version of the report will be sent to selected emails. You can use this to verify emails are working and to make sure the report is generated and displayed as you expect.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/enterprise/reports_send_test_mail.png" max-width="500px" class="docs-image--no-shadow" >}}
|
||||
|
||||
## Send report via the API
|
||||
|
||||
You can send reports programmatically with the [send report]({{< relref "../http_api/reporting.md#send-report" >}}) endpoint in the [HTTP APIs]({{< relref "../http_api" >}}).
|
||||
|
||||
## Rendering configuration
|
||||
|
||||
When generating reports, each panel renders separately before being collected in a PDF. The per panel rendering timeout and number of concurrently rendered panels can be configured.
|
||||
|
||||
To modify the panels' clarity you can set a scale factor for the rendered images. A higher scale factor is more legible but will increase the file size of the generated PDF.
|
||||
|
||||
These options are available in the [configuration]({{< relref "../installation/configuration.md">}}) file.
|
||||
When Grafana generates a report, it will render each panel separately and then put them together in a PDF file. You can configure the per-panel rendering request timeout and the maximum number of concurrent calls to the rendering service. These options are available in the [configuration]({{< relref "../installation/configuration.md">}}) file.
|
||||
|
||||
```ini
|
||||
[reporting]
|
||||
# Set timeout for each panel rendering request
|
||||
rendering_timeout = 10s
|
||||
# Set maximum number of concurrent calls to the rendering service
|
||||
concurrent_render_limit = 4
|
||||
# Set the scale factor for rendering images. 2 is enough for monitor resolutions
|
||||
# 4 would be better for printed material. Setting a higher value affects performance and memory
|
||||
image_scale_factor = 2
|
||||
concurrent_render_limit = 10
|
||||
```
|
||||
|
||||
## Report time range
|
||||
|
||||
Reports use the saved time range of the dashboard. Changing the time range of the report is done by saving a modified time range to the dashboard.
|
||||
|
||||
The page header of the report displays the time range for the dashboard's data queries. Dashboards set to use the browser's time zone will use the time zone on the Grafana server.
|
||||
|
||||
If the time zone is set differently between your Grafana server and its remote image renderer, then the time ranges in the report might be different between the page header and the time axes in the panels. We advise always setting the time zone to UTC for dashboards when using a remote renderer to avoid this.
|
||||
|
||||
## Troubleshoot reporting
|
||||
|
||||
To troubleshoot and get more log information, enable debug logging in the configuration file. Refer to [Configuration]({{< relref "../installation/configuration.md#filters" >}}) for more information.
|
||||
|
||||
```bash
|
||||
[log]
|
||||
filters = report:debug
|
||||
filters = saml.auth:debug
|
||||
```
|
||||
|
||||
@@ -12,7 +12,7 @@ weight = 500
|
||||
|
||||
# SAML authentication
|
||||
|
||||
SAML authentication integration allows your Grafana users to log in by using an external SAML 2.0 Identity Provider (IdP). To enable this, Grafana becomes a Service Provider (SP) in the authentication flow, interacting with the IdP to exchange user information.
|
||||
SAML authentication integration allows your Grafana users to log in by using an external SAML Identity Provider (IdP). To enable this, Grafana becomes a Service Provider (SP) in the authentication flow, interacting with the IdP to exchange user information.
|
||||
|
||||
The SAML single-sign-on (SSO) standard is varied and flexible. Our implementation contains the subset of features needed to provide a smooth authentication experience into Grafana.
|
||||
|
||||
@@ -20,7 +20,7 @@ The SAML single-sign-on (SSO) standard is varied and flexible. Our implementatio
|
||||
|
||||
## Supported SAML
|
||||
|
||||
Grafana supports the following SAML 2.0 bindings:
|
||||
Grafana supports the following SAML integrations.
|
||||
|
||||
* From the Service Provider (SP) to the Identity Provider (IdP):
|
||||
- `HTTP-POST` binding
|
||||
@@ -65,7 +65,7 @@ The SAML SSO standard uses asymmetric encryption to exchange information between
|
||||
|
||||
Grafana supports two ways of specifying both the `certificate` and `private_key`.
|
||||
* Without a suffix (`certificate` or `private_key`), the configuration assumes you've supplied the base64-encoded file contents.
|
||||
* With the `_path` suffix (`certificate_path` or `private_key_path`), then Grafana treats the value entered as a file path and attempts to read the file from the file system.
|
||||
* With the `_path` suffix (`certificate_path` or `private_key_path`), then Grafana treats the value entered as a file path and attempt to read the file from the file system.
|
||||
|
||||
You can only use one form of each configuration option. Using multiple forms, such as both `certificate` and `certificate_path`, results in an error.
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ If you have already grouped some users into a team, then you can synchronize tha
|
||||
## Supported providers
|
||||
|
||||
* [Auth Proxy]({{< relref "../auth/auth-proxy.md#team-sync-enterprise-only">}})
|
||||
* [Azure AD]({{< relref "../auth/azuread.md#team-sync-enterprise-only" >}})
|
||||
* [GitHub OAuth]({{< relref "../auth/github.md#team-sync-enterprise-only" >}})
|
||||
* [GitLab OAuth]({{< relref "../auth/gitlab.md#team-sync-enterprise-only" >}})
|
||||
* [LDAP]({{< relref "enhanced_ldap.md#ldap-group-synchronization-for-teams" >}})
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
+++
|
||||
title = "Usage-insights"
|
||||
description = "Usage-insights"
|
||||
keywords = ["grafana", "usage-insights", "enterprise"]
|
||||
aliases = ["/docs/grafana/latest/enterprise/usage-insights/"]
|
||||
type = "docs"
|
||||
[menu.docs]
|
||||
name = "Usage-insights"
|
||||
parent = "enterprise"
|
||||
weight = 700
|
||||
+++
|
||||
|
||||
# Usage insights
|
||||
|
||||
Usage insights allow you to have a better understanding of how your Grafana instance is used. The collected data are the number of:
|
||||
|
||||
- Dashboard views (aggregated and per user)
|
||||
- Data source errors
|
||||
- Data source queries
|
||||
|
||||
> Only available in Grafana Enterprise v7.0+.
|
||||
|
||||
## Presence indicator
|
||||
|
||||
The presence indicator is visible to all signed-in users on all dashboards. It shows the avatars of users who interacted with the dashboard recently (last 10 minutes by default). You can see the user's name by hovering your cursor over the user's avatar. The avatars come from [Gravatar](https://gravatar.com) based on the user's email.
|
||||
|
||||
When more users are active on a dashboard than can fit in the presence indicator section, click on the `+X` icon that opens [dashboard insights]({{< relref "#dashboard-insights" >}}) to see more details about recent user activity.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/enterprise/presence_indicators.png" max-width="400px" class="docs-image--no-shadow" >}}
|
||||
|
||||
You can choose your own definition of "recent" by setting it in the [configuration]({{< relref "../installation/configuration.md">}}) file.
|
||||
|
||||
```ini
|
||||
[analytics.views]
|
||||
# Set age for recent active users
|
||||
recent_users_age = 10m
|
||||
```
|
||||
|
||||
## Dashboard insights
|
||||
|
||||
You can see dashboard usage information by clicking on the `Dashboard insights` button in the top bar.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/enterprise/dashboard_insights_button.png" max-width="400px" class="docs-image--no-shadow" >}}
|
||||
|
||||
It shows two kinds of information:
|
||||
|
||||
- **Stats:** Shows the daily query count and error count for the last 30 days.
|
||||
- **Users & activity:** Shows the daily view count for the last 30 days; last activities on the dashboard and recent users (with a limit of 20).
|
||||
|
||||
{{< docs-imagebox img="/img/docs/enterprise/dashboard_insights_stats.png" max-width="400px" class="docs-image--no-shadow" >}}{{< docs-imagebox img="/img/docs/enterprise/dashboard_insights_users.png" max-width="400px" class="docs-image--no-shadow" >}}
|
||||
|
||||
|
||||
## Improved dashboard search
|
||||
|
||||
In the search view, you can sort dashboards using these insights data. It helps you find unused or broken dashboards or discover most viewed ones.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/enterprise/improved_search.png" max-width="650px" class="docs-image--no-shadow" >}}
|
||||
@@ -16,7 +16,7 @@ White labeling allows you to replace the Grafana brand and logo with your own co
|
||||
|
||||
> Only available in Grafana Enterprise v6.6+.
|
||||
|
||||
Grafana Enterprise has white labeling options in the `grafana.ini` file. As with all configuration options, you can also set them with environment variables.
|
||||
Grafana Enterprise has white labeling options in the `grafana.ini` file. As with all configuration options, you can also be set set them with environment variables.
|
||||
|
||||
You can change the following elements:
|
||||
|
||||
@@ -26,9 +26,6 @@ You can change the following elements:
|
||||
- Side menu top logo
|
||||
- Footer and help menu links
|
||||
- Fav icon (shown in browser tab)
|
||||
- Login title (will not appear if a login logo is set, Grafana v7.0+)
|
||||
- Login subtitle (will not appear if a login logo is set, Grafana v7.0+)
|
||||
- Login box background (Grafana v7.0+)
|
||||
|
||||
> You will have to host your logo and other images used by the white labeling feature separately. Make sure Grafana can access the URL where the assets are stored.
|
||||
|
||||
@@ -42,22 +39,13 @@ The configuration file in Grafana Enterprise contains the following options. Eac
|
||||
# Set to your company name to override application title
|
||||
;app_title =
|
||||
|
||||
# Set to main title on the login page (Will not appear if a login logo is set)
|
||||
;login_title =
|
||||
|
||||
# Set to login subtitle (Will not appear if a login logo is set)
|
||||
;login_subtitle =
|
||||
|
||||
# Set to complete URL to override login logo
|
||||
;login_logo =
|
||||
|
||||
# Set to complete CSS background expression to override login background
|
||||
# Set to complete css background expression to override login background
|
||||
# example: login_background = url(http://www.bhmpics.com/wallpapers/starfield-1920x1080.jpg)
|
||||
;login_background =
|
||||
|
||||
# Set to complete CSS background expression to override login box background
|
||||
;login_box_background =
|
||||
|
||||
# Set to complete URL to override menu logo
|
||||
;menu_logo =
|
||||
|
||||
@@ -85,5 +73,5 @@ GF_WHITE_LABELING_FOOTER_LINKS=support guides
|
||||
GF_WHITE_LABELING_FOOTER_LINKS_SUPPORT_TEXT=Support
|
||||
GF_WHITE_LABELING_FOOTER_LINKS_SUPPORT_URL=http://your.support.site
|
||||
GF_WHITE_LABELING_FOOTER_LINKS_GUIDES_TEXT=Guides
|
||||
GF_WHITE_LABELING_FOOTER_LINKS_GUIDES_URL=http://your.guides.site
|
||||
GF_WHITE_LABELING_FOOTER_LINKS_GUIDES_URL=http://your.guides.site
|
||||
```
|
||||
|
||||
@@ -18,7 +18,7 @@ A *dashboard* is a set of one or more panels organized and arranged into one or
|
||||
1. Zoom out time range
|
||||
2. Time picker dropdown. Here you can access relative time range options, auto refresh options and set custom absolute time ranges.
|
||||
3. Manual refresh button. Will cause all panels to refresh (fetch new data).
|
||||
4. Dashboard panel. Click the panel title to edit panels.
|
||||
4. Dashboard panel. You edit panels by clicking the panel title.
|
||||
5. Graph legend. You can change series colors, y-axis and series visibility directly from the legend.
|
||||
|
||||
## Dashboard header
|
||||
@@ -30,7 +30,7 @@ Click the new Dashboard link on the right side of the Dashboard picker. You now
|
||||
The image above shows you the top header for a Dashboard.
|
||||
|
||||
1. Side menubar toggle: This toggles the side menu, allowing you to focus on the data presented in the dashboard. The side menu provides access to features unrelated to a Dashboard such as Users, Organizations, and Data Sources.
|
||||
2. Dashboard dropdown: This dropdown shows you which Dashboard you are currently viewing, and allows you to easily switch to a new Dashboard. From here you can also create a new Dashboard or folder, import existing Dashboards, and manage Dashboard playlists.
|
||||
2. Dashboard dropdown: This dropdown shows you which Dashboard you are currently viewing, and allows you to easily switch to a new Dashboard. From here you can also create a new Dashboard or folder, Import existing Dashboards, and manage Dashboard playlists.
|
||||
3. Add Panel: Adds a new panel to the current Dashboard
|
||||
4. Star Dashboard: Star (or unstar) the current Dashboard. Starred Dashboards will show up on your own Home Dashboard by default, and are a convenient way to mark Dashboards that you're interested in.
|
||||
5. Share Dashboard: Share the current dashboard by creating a link or create a static Snapshot of it. Make sure the Dashboard is saved before sharing.
|
||||
@@ -41,7 +41,7 @@ The image above shows you the top header for a Dashboard.
|
||||
|
||||
The time period for the dashboard can be controlled by the [Time range controls]({{< relref "../../reference/timerange.md" >}}) in the upper right of the dashboard.
|
||||
|
||||
Dashboards can use [templating]({{< relref "../../variables/templates-and-variables.md" >}}) to make them more dynamic and interactive.
|
||||
Dashboards can use [templating]({{< relref "../../reference/templating.md" >}}) to make them more dynamic and interactive.
|
||||
|
||||
Dashboards can use [annotations]({{< relref "../../reference/annotations.md" >}}) to display event data across panels. This can help correlate the time series data in the panel with other events.
|
||||
|
||||
@@ -61,4 +61,4 @@ We use a unit abstraction so that Grafana looks great on all screens sizes.
|
||||
|
||||
Collapse a row by clicking on the row title. If you save a dashboard with a row collapsed, then it saves in that state and does not load those graphs until you expand the row.
|
||||
|
||||
Use the [repeating rows]({{< relref "../../variables/templates-and-variables.md#repeating-rows" >}}) functionality to dynamically create or remove entire rows, which can be filled with panels, based on the template variables selected.
|
||||
Use the [repeating rows]({{< relref "../../reference/templating.md#repeating-rows" >}}) functionality to dynamically create or remove entire rows, which can be filled with panels, based on the template variables selected.
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
+++
|
||||
title = "Add navigation links"
|
||||
description = ""
|
||||
keywords = ["grafana", "linking", "create links", "link panels", "link dashboards", "navigate"]
|
||||
type = "docs"
|
||||
aliases = ["/docs/grafana/latest/features/navigation-links/"]
|
||||
[menu.docs]
|
||||
identifier = "dashboards"
|
||||
parent = "features"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
# Add navigation links
|
||||
|
||||
You can use links to navigate between commonly-used dashboards or to connect others to your visualizations. Links let you create shortcuts to other dashboards, panels, and even external websites.
|
||||
|
||||
Grafana supports three types of links: Dashboard Links, Panel Links, and Data Links. They are all available from your dashboard.
|
||||
|
||||
{{< docs-imagebox img="/assets/img/blog/dashboard_links.png" max-width="800px" caption="Links Supported in Grafana" >}}
|
||||
|
||||
## Which link should you use?
|
||||
|
||||
Start by figuring out how you're currently navigating between dashboards. If you're often jumping between a set of dashboards and struggling to find the same context in each, links can help optimize your workflow.
|
||||
|
||||
The next step is to figure out which link type is right for your workflow. Even though all the link types in Grafana are used to create shortcuts to other dashboards or external websites, they work in different contexts.
|
||||
|
||||
- If the link relates to most if not all of the panels in the dashboard, use a _dashboard link_.
|
||||
- If you want to drill down into specific panels, use a _panel link_.
|
||||
- If you want to drill down into a specific series, or even a single measurement, use a _data link_.
|
||||
|
||||
## Dashboard links
|
||||
|
||||
When you create a dashboard link, you can include the time range and current template variables to directly jump to the same context in another dashboard. This way, you don’t have to worry whether the person you send the link to is looking at the right data.
|
||||
|
||||
Dashboard links can also be used as shortcuts to external systems, such as submitting [a GitHub issue with the current dashboard name](https://github.com/grafana/grafana/issues/new?title=Dashboard%3A%20HTTP%20Requests).
|
||||
|
||||
To see an example of dashboard links in action, check out [this demo](https://play.grafana.org/d/rUpVRdamz/dashboard-links-with-variables?orgId=1).
|
||||
|
||||
Once you've added a dashboard link, it appears in the upper right corner of your dashboard.
|
||||
|
||||
### Add links to dashboards
|
||||
|
||||
Add links to other dashboards at the top of your current dashboard.
|
||||
|
||||
1. While viewing the dashboard you want to link, click the gear at the top of the screen to open **Dashboard settings**.
|
||||
1. Click **Links** and then click **Add Dashboard Link** or **New**.
|
||||
1. In **Type**, select **dashboards**.
|
||||
1. Select link options:
|
||||
- **With tags** – Enter tags to limit the linked dashboards to only the ones with the tags you enter. Otherwise, Grafana includes links to all other dashboards.
|
||||
- **As dropdown** – If you are linking to lots of dashboards, then you probably want to select this option and add an optional title to the dropdown. Otherwise, Grafana displays the dashboard links side by side across the top of your dashboard.
|
||||
- **Time range** – Select this option to include the dashboard time range in the link. When the user clicks the link, the linked dashboard opens with the indicated time range already set. **Example:** https://play.grafana.org/d/000000010/annotations?orgId=1&from=now-3h&to=now
|
||||
- **Variable values** – Select this option to include template variables currently used as query parameters in the link. When the user clicks the link, any matching templates in the linked dashboard are set to the values from the link. **Example:** https://play.grafana.org/d/000000074/alerting?var-app=backend&var-server=backend_01&var-server=backend_03&var-interval=1h
|
||||
- **Open in new tab** – Select this option if you want the dashboard link to open in a new tab or window.
|
||||
1. Click **Add**.
|
||||
|
||||
### Add a link to a URL
|
||||
|
||||
Add a link to a URL at the top of your current dashboard. You can link to any available URL, including dashboards, panels, or external sites. You can even [control the time range](https://grafana.com/docs/grafana/latest/reference/timerange/#controlling-time-range-using-url) to ensure the user is zoomed in on the right data in Grafana.
|
||||
|
||||
1. While viewing the dashboard you want to link, click the gear at the top of the screen to open **Dashboard settings**.
|
||||
1. Click **Links** and then click **Add Dashboard Link** or **New**.
|
||||
1. In **Type**, select **link**.
|
||||
1. Select link options:
|
||||
- **Url** – Enter the URL you want to link to. Depending on the target, you might want to include field values. **Example:** https://github.com/grafana/grafana/issues/new?title=Dashboard%3A%20HTTP%20Requests
|
||||
- **Title** – Enter the title you want the link to display.
|
||||
- **Tooltip** – Enter the tooltip you want the link to display when the user hovers their mouse over it.
|
||||
- **Icon** – Choose the icon you want displayed with the link.
|
||||
- **Time range** – Select this option to include the dashboard time range in the link. When the user clicks the link, the linked dashboard opens with the indicated time range already set. **Example:** https://play.grafana.org/d/000000010/annotations?orgId=1&from=now-3h&to=now
|
||||
- **Variable values** – Select this option to include template variables currently used as query parameters in the link. When the user clicks the link, any matching templates in the linked dashboard are set to the values from the link. **Example:** https://play.grafana.org/d/000000074/alerting?var-app=backend&var-server=backend_01&var-server=backend_03&var-interval=1h
|
||||
- **Open in new tab** – Select this option if you want the dashboard link to open in a new tab or window.
|
||||
1. Click **Add**.
|
||||
|
||||
### Update a dashboard link
|
||||
|
||||
To change or update an existing dashboard link, follow this procedure.
|
||||
|
||||
1. In Dashboard Settings, on the Links tab, click the existing link that you want to edit.
|
||||
1. Change the settings and then click **Update**.
|
||||
|
||||
### Delete a dashboard link
|
||||
|
||||
To delete an existing dashboard link, click the red **X** next to the existing link that you want to delete.
|
||||
|
||||
## Panel links
|
||||
|
||||
Each panel can have its own set of links that are shown in the upper left corner of the panel. You can link to any available URL, including dashboards, panels, or external sites. You can even [control the time range](https://grafana.com/docs/grafana/latest/reference/timerange/#controlling-time-range-using-url) to ensure the user is zoomed in on the right data in Grafana.
|
||||
|
||||
Click the icon on the top left corner of a panel to see available panel links. To see an example of panel links in action, check out [this demo](https://play.grafana.org/d/000000156/dashboard-with-panel-link?orgId=1).
|
||||
|
||||
### Add a panel link
|
||||
|
||||
1. Hover your cursor over the panel that you want to add a link to and then press `e`. Or click the dropdown arrow next to the panel title and then click **Edit**.
|
||||
2. Open the **General** tab in the panel settings and then scroll down to the Panel links section.
|
||||
3. Click **Add link**.
|
||||
4. Enter a **Title**.
|
||||
5. If you want the link to open in a new tab, then select **Open in a new tab**.
|
||||
6. Enter the **URL** you want to link to.
|
||||
You can even add one of the template variables that are available. Press Ctrl+Space in the **URL** field to see the available variables. By adding template variables to your panel ink, the link sends the user to the right context, with the relevant variables already set.
|
||||
|
||||
### Update or delete a panel link
|
||||
|
||||
On the panel settings General tab, in the Panel links section, find the panel link that you want to make changes to or delete. Make any necessary changes, or click the **X** to the right of the title to delete the link.
|
||||
|
||||
## Data links
|
||||
|
||||
Data links allow you to provide more granular context to your links. You can create links that include the series name or even the value under the cursor. For example, if your visualization showed four servers, you could add a data link to one or two of them.
|
||||
|
||||
Click directly on the panel to see the data link. It appears on the context menu under **Add annotation**.
|
||||
|
||||
To see an example of data links in action, check out [this demo](https://play.grafana.org/d/ZvPm55mWk/new-features-in-v6-3?orgId=1&fullscreen&panelId=27).
|
||||
|
||||
## Add a data link to a panel
|
||||
|
||||
Currently, data links are only supported in the Graph, Stat, Gauge, and Bar Gauge visualizations.
|
||||
|
||||
1. Hover your cursor over the panel that you want to add a link to and then press `e`. Or click the dropdown arrow next to the panel title and then click **Edit**.
|
||||
1. Open the **Visualization** tab in the panel settings and then scroll down to the Data links section.
|
||||
1. Click **Add link**.
|
||||
1. Enter a **Title**.
|
||||
1. If you want the link to open in a new tab, then select **Open in a new tab**.
|
||||
1. Enter the **URL** you want to link to.
|
||||
You can even add one of the template variables that are available. Press Ctrl+Space in the **URL** field to see the available variables. By adding template variables to your panel ink, the link sends the user to the right context, with the relevant variables already set.
|
||||
|
||||
### Update or delete a panel link
|
||||
|
||||
On the panel settings General tab, in the Panel links section, find the panel link that you want to make changes to or delete. Make any necessary changes, or click the **X** to the right of the title to delete the link.
|
||||
@@ -38,4 +38,4 @@ The following data sources are officially supported:
|
||||
|
||||
## Data source plugins
|
||||
|
||||
Since Grafana 3.0 you can install data sources as plugins. Check out [Grafana.com/plugins](https://grafana.com/plugins) for more data sources.
|
||||
Since Grafana 3.0 you can install data sources as plugins. Check out [Grafana.net](https://grafana.com/plugins) for more data sources.
|
||||
|
||||
@@ -12,10 +12,8 @@ weight = 2
|
||||
|
||||
Before you create your first dashboard, you need to add your data source. Following are the list of instructions to create one.
|
||||
|
||||
> Only users with the Admin role can add data sources.
|
||||
|
||||
1. Move your cursor to the cog on the side menu which will show you the configuration menu. If the side menu is not visible click the Grafana icon in the upper left corner. Click on **Configuration** > **Data Sources** in the side menu and you'll be taken to the data sources page
|
||||
where you can add and edit data sources. You can also click the cog.
|
||||
where you can add add and edit data sources. You can also click the cog.
|
||||
{{< docs-imagebox img="/img/docs/v52/sidemenu-datasource.png" max-width="250px" class="docs-image--no-shadow">}}
|
||||
|
||||
1. Click **Add data source** and you will come to the settings page of your new data source.
|
||||
@@ -26,6 +24,6 @@ Before you create your first dashboard, you need to add your data source. Follow
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v52/datasource-settings.png" max-width="700px" class="docs-image--no-shadow">}}
|
||||
|
||||
1. In the **Type**, select the type of data source. See [Supported data sources]({{< relref "../../features/datasources/#supported-data-sources/" >}}) for more information and how to configure your data source settings.
|
||||
1. In the **Type**, select the type of data source. See [Supported data sources]({{< relref "../../features/datasources/#supported-data-sources/" >}}) for more information and how to configure your data source.
|
||||
|
||||
1. Click **Save & Test**.
|
||||
1. Click **Save & Test**.
|
||||
@@ -79,7 +79,7 @@ In the query editor for a panel, after choosing your Azure Monitor data source,
|
||||
|
||||
The query editor will change depending on which one you pick. Azure Monitor is the default.
|
||||
|
||||
## Querying the Azure Monitor service
|
||||
## Querying the Azure Monitor Service
|
||||
|
||||
The Azure Monitor service provides metrics for all the Azure services that you have running. It helps you understand how your applications on Azure are performing and to proactively find issues affecting your applications.
|
||||
|
||||
@@ -93,7 +93,7 @@ Examples of metrics that you can get from the service are:
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/azuremonitor-service-query-editor.png" class="docs-image--no-shadow" caption="Azure Monitor Query Editor" >}}
|
||||
|
||||
### Formatting legend keys with aliases for Azure Monitor
|
||||
### Formatting Legend Keys with Aliases for the Azure Monitor Service
|
||||
|
||||
The default legend formatting for the Azure Monitor API is:
|
||||
|
||||
@@ -106,7 +106,7 @@ Azure Monitor Examples:
|
||||
- `dimension: {{dimensionvalue}}`
|
||||
- `{{resourcegroup}} - {{resourcename}}`
|
||||
|
||||
### Alias patterns for Azure Monitor
|
||||
### Alias Patterns for Azure Monitor
|
||||
|
||||
- `{{resourcegroup}}` = replaced with the value of the Resource Group
|
||||
- `{{namespace}}` = replaced with the value of the Namespace (e.g. Microsoft.Compute/virtualMachines)
|
||||
@@ -115,9 +115,9 @@ Azure Monitor Examples:
|
||||
- `{{dimensionname}}` = replaced with dimension key/label (e.g. blobtype)
|
||||
- `{{dimensionvalue}}` = replaced with dimension value (e.g. BlockBlob)
|
||||
|
||||
### Templating with variables for Azure Monitor
|
||||
### Templating with Variables for the Azure Monitor Service
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data being displayed in your dashboard.
|
||||
|
||||
Note that the Azure Monitor service does not support multiple values yet. If you want to visualize multiple time series (for example, metrics for server1 and server2) then you have to add multiple queries to able to view them on the same graph or in the same table.
|
||||
|
||||
@@ -146,14 +146,14 @@ Examples:
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/azuremonitor-service-variables.png" class="docs-image--no-shadow" caption="Nested Azure Monitor Template Variables" >}}
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
types of template variables.
|
||||
|
||||
### Azure Monitor metrics whitelist
|
||||
### Azure Monitor Metrics Whitelist
|
||||
|
||||
Not all metrics returned by the Azure Monitor API have values. The Grafana data source has a whitelist to only return metric names if it is possible they might have values. This whitelist is updated regularly as new services and metrics are added to the Azure cloud. You can find the current whitelist [here](https://github.com/grafana/grafana/blob/master/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/supported_namespaces.ts).
|
||||
|
||||
### Azure Monitor alerting
|
||||
### Azure Monitor Alerting
|
||||
|
||||
Grafana alerting is supported for the Azure Monitor service. This is not Azure Alerts support. Read more about how alerting in Grafana works [here]({{< relref "../../alerting/rules.md" >}}).
|
||||
|
||||
@@ -163,7 +163,7 @@ Grafana alerting is supported for the Azure Monitor service. This is not Azure A
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/appinsights-service-query-editor.png" class="docs-image--no-shadow" caption="Application Insights Query Editor" >}}
|
||||
|
||||
### Formatting legend keys with aliases for Application Insights
|
||||
### Formatting Legend Keys with Aliases for the Application Insights Service
|
||||
|
||||
The default legend formatting is:
|
||||
|
||||
@@ -177,13 +177,13 @@ Application Insights Examples:
|
||||
- `city: {{groupbyvalue}}`
|
||||
- `{{groupbyname}}: {{groupbyvalue}}`
|
||||
|
||||
### Alias patterns for Application Insights
|
||||
### Alias Patterns for Application Insights
|
||||
|
||||
- `{{groupbyvalue}}` = replaced with the value of the group by
|
||||
- `{{groupbyname}}` = replaced with the name/label of the group by
|
||||
- `{{metric}}` = replaced with metric name (e.g. requests/count)
|
||||
|
||||
### Filter expressions for Application Insights
|
||||
### Filter Expressions for Application Insights
|
||||
|
||||
The filter field takes an OData filter expression.
|
||||
|
||||
@@ -194,11 +194,11 @@ Examples:
|
||||
- `client/city ne 'Boydton' and client/city ne 'Dublin'`
|
||||
- `client/city eq 'Boydton' or client/city eq 'Dublin'`
|
||||
|
||||
### Templating with variables for Application Insights
|
||||
### Templating with Variables for Application Insights
|
||||
|
||||
Use the one of the following queries in the `Query` field in the Variable edit view.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
types of template variables.
|
||||
|
||||
| Name | Description |
|
||||
@@ -214,13 +214,13 @@ Examples:
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/appinsights-service-variables.png" class="docs-image--no-shadow" caption="Nested Application Insights Template Variables" >}}
|
||||
|
||||
### Application Insights alerting
|
||||
### Application Insights Alerting
|
||||
|
||||
Grafana alerting is supported for Application Insights. This is not Azure Alerts support. Read more about how alerting in Grafana works [here]({{< relref "../../alerting/rules.md" >}}).
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/azuremonitor-alerting.png" class="docs-image--no-shadow" caption="Azure Monitor Alerting" >}}
|
||||
|
||||
## Querying the Azure Log Analytics service
|
||||
## Querying the Azure Log Analytics Service
|
||||
|
||||
Queries are written in the new [Azure Log Analytics (or KustoDB) Query Language](https://docs.loganalytics.io/index). A Log Analytics Query can be formatted as Time Series data or as Table data.
|
||||
|
||||
@@ -246,7 +246,7 @@ If your credentials give you access to multiple subscriptions then choose the ap
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v60/azureloganalytics-service-query-editor.png" class="docs-image--no-shadow" caption="Azure Log Analytics Query Editor" >}}
|
||||
|
||||
### Azure Log Analytics macros
|
||||
### Azure Log Analytics Macros
|
||||
|
||||
To make writing queries easier there are several Grafana macros that can be used in the where clause of a query:
|
||||
|
||||
@@ -268,17 +268,17 @@ To make writing queries easier there are several Grafana macros that can be used
|
||||
|
||||
If using the `All` option, then check the `Include All Option` checkbox and in the `Custom all value` field type in the following value: `all`. If `$myVar` has value `all` then the macro will instead expand to `1 == 1`. For template variables with a lot of options, this will increase the query performance by not building a large where..in clause.
|
||||
|
||||
### Azure Log Analytics builtin variables
|
||||
### Azure Log Analytics Builtin Variables
|
||||
|
||||
There are also some Grafana variables that can be used in Azure Log Analytics queries:
|
||||
|
||||
- `$__interval` - Grafana calculates the minimum time grain that can be used to group by time in queries. More details on how it works [here]({{< relref "../../variables/templates-and-variables.md#interval-variables" >}}). It returns a time grain like `5m` or `1h` that can be used in the bin function. E.g. `summarize count() by bin(TimeGenerated, $__interval)`
|
||||
- `$__interval` - Grafana calculates the minimum time grain that can be used to group by time in queries. More details on how it works [here]({{< relref "../../reference/templating.md#interval-variables" >}}). It returns a time grain like `5m` or `1h` that can be used in the bin function. E.g. `summarize count() by bin(TimeGenerated, $__interval)`
|
||||
|
||||
### Templating with variables for Azure Log Analytics
|
||||
### Templating with Variables for Azure Log Analytics
|
||||
|
||||
Any Log Analytics query that returns a list of values can be used in the `Query` field in the Variable edit view. There is also one Grafana function for Log Analytics that returns a list of workspaces.
|
||||
|
||||
Refer to the [Variables]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
Refer to the [Variables]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
types of template variables.
|
||||
|
||||
| Name | Description |
|
||||
@@ -313,25 +313,11 @@ Perf
|
||||
| order by TimeGenerated asc
|
||||
```
|
||||
|
||||
### Deep linking from Grafana panels to the Log Analytics query editor in Azure Portal
|
||||
### Azure Log Analytics Alerting
|
||||
|
||||
> Only available in Grafana v7.0+.
|
||||
Not implemented yet.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v70/azure-log-analytics-deep-linking.png" max-width="500px" class="docs-image--right" caption="Azure Log Analytics deep linking" >}}
|
||||
|
||||
Click on a time series in the panel to see a context menu with a link to `View in Azure Portal`. Clicking that link opens the Azure Log Analytics query editor in the Azure Portal and runs the query from the Grafana panel there.
|
||||
|
||||
If you're not currently logged in to the Azure Portal, then the link opens the login page. The provided link is valid for any account, but it only displays the query if your account has access to the Azure Log Analytics workspace specified in the query.
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
### Azure Log Analytics alerting
|
||||
|
||||
> Only available in Grafana v7.0+.
|
||||
|
||||
Grafana alerting is supported for Application Insights. This is not Azure Alerts support. Read more about how alerting in Grafana works in [Alerting rules]({{< relref "../../alerting/rules.md" >}}).
|
||||
|
||||
### Writing analytics queries For the Application Insights service
|
||||
### Writing Analytics Queries For the Application Insights Service
|
||||
|
||||
If you change the service type to "Application Insights", the menu icon to the right adds another option, "Toggle Edit Mode". Once clicked, the query edit mode changes to give you a full text area in which to write log analytics queries. (This is identical to how the InfluxDB data source lets you write raw queries.)
|
||||
|
||||
@@ -346,34 +332,3 @@ There are some important caveats to remember:
|
||||
- Currently, four default dashboard variables are supported: `$__timeFilter()`, `$__from`, `$__to`, and `$__interval`. If you're searching in timestamped data, replace the beginning of your where clause to `where $__timeFilter()`. Dashboard changes by time region are handled as you'd expect, as long as you leave the name of the `timestamp` column alone. Likewise, `$__interval` will automatically change based on the dashboard's time region _and_ the width of the chart being displayed. Use it in bins, so `bin(timestamp,$__interval)` changes into something like `bin(timestamp,1s)`. Use `$__from` and `$__to` if you just want the formatted dates to be inserted.
|
||||
|
||||
- Templated dashboard variables are not yet supported! They will come in a future version.
|
||||
|
||||
## Configure the data source with provisioning
|
||||
|
||||
It's now possible to configure data sources using config files with Grafana's provisioning system. You can read more about how it works and all the settings you can set for data sources on the [provisioning docs page]({{< relref "../../administration/provisioning/#datasources" >}})
|
||||
|
||||
Here are some provisioning examples for this data source.
|
||||
|
||||
```yaml
|
||||
# config file version
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Azure Monitor
|
||||
type: grafana-azure-monitor-datasource
|
||||
access: proxy
|
||||
jsonData:
|
||||
appInsightsAppId: <app-insights-app-id>
|
||||
clientId: <client-id>
|
||||
cloudName: azuremonitor
|
||||
subscriptionId: <subscription-id>
|
||||
tenantId: <tenant-id>
|
||||
logAnalyticsClientId: <log-analytics-client-id>
|
||||
logAnalyticsDefaultWorkspace: <log-analytics-default-workspace>
|
||||
logAnalyticsSubscriptionId: <log-analytics-subscription-id>
|
||||
logAnalyticsTenantId: <log-analytics-tenant-id>
|
||||
secureJsonData:
|
||||
clientSecret: <client-secret>
|
||||
appInsightsApiKey: <app-insights-api-key>
|
||||
logAnalyticsClientSecret: <log-analytics-client-secret>
|
||||
version: 1
|
||||
```
|
||||
|
||||
@@ -43,7 +43,7 @@ server is running on AWS you can use IAM Roles and authentication will be handle
|
||||
|
||||
See the AWS documentation on [IAM Roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)
|
||||
|
||||
> NOTE: AWS Role Switching as described [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html) is not supported at the moment.
|
||||
> NOTE: AWS Role Switching as described [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-cli.html) it not supported at the moment.
|
||||
|
||||
## IAM Policies
|
||||
|
||||
@@ -62,8 +62,6 @@ Here is a minimal policy example:
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"cloudwatch:DescribeAlarmsForMetric",
|
||||
"cloudwatch:DescribeAlarmHistory",
|
||||
"cloudwatch:DescribeAlarms",
|
||||
"cloudwatch:ListMetrics",
|
||||
"cloudwatch:GetMetricStatistics",
|
||||
"cloudwatch:GetMetricData"
|
||||
@@ -182,9 +180,9 @@ To import the pre-configured dashboards, go to the configuration page of your Cl
|
||||
|
||||
## Templated queries
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data being displayed in your dashboard.
|
||||
|
||||
See the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
See the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
|
||||
### Query variable
|
||||
|
||||
|
||||
@@ -17,6 +17,6 @@ Each data source has a specific query editor that is customized for the features
|
||||
|
||||
Use the query editor to build one or more queries in your time series database. The panel instantly updates, allowing you to effectively explore your data in real time and build a perfect query for that particular panel.
|
||||
|
||||
You can use [template variables]({{< relref "../../variables/templates-and-variables.md" >}}) in the query editor within the queries themselves. This provides a powerful way to explore data dynamically based on the templating variables selected on the dashboard.
|
||||
You can use [template variables]({{< relref "../../reference/templating.md" >}}) in the query editor within the queries themselves. This provides a powerful way to explore data dynamically based on the templating variables selected on the dashboard.
|
||||
|
||||
Grafana allows you to reference queries in the query editor by the row that they’re on. If you add a second query to graph, you can reference the first query by typing in #A. This provides an easy and convenient way to build compound queries.
|
||||
@@ -116,11 +116,11 @@ Some metric aggregations are called Pipeline aggregations, for example, *Moving
|
||||
|
||||
## Templating
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place.
|
||||
Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place.
|
||||
Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data
|
||||
being displayed in your dashboard.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
types of template variables.
|
||||
|
||||
### Query variable
|
||||
@@ -172,7 +172,7 @@ Example dashboard:
|
||||
|
||||
## Annotations
|
||||
|
||||
[Annotations]({{< relref "../../reference/annotations.md" >}}) allow you to overlay rich event information on top of graphs. You add annotation
|
||||
[Annotations]({{< relref "../../reference/annotations.md" >}}) allows you to overlay rich event information on top of graphs. You add annotation
|
||||
queries via the Dashboard menu / Annotations view. Grafana can query any Elasticsearch index
|
||||
for annotation events.
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ All requests will be made from the browser directly to the data source and may b
|
||||
|
||||
### Navigate metric segments
|
||||
|
||||
Click the ``Select metric`` link to start navigating the metric space. Once you start you can continue using the mouse
|
||||
Click the ``Select metric`` link to start navigating the metric space. One you start you can continue using the mouse
|
||||
or keyboard arrow keys. You can select a wildcard and still continue.
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v45/graphite_query1_still.png"
|
||||
@@ -87,11 +87,11 @@ this consolidation is done using `avg` function. You can control how Graphite co
|
||||
|
||||
## Templating
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place.
|
||||
Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place.
|
||||
Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data
|
||||
being displayed in your dashboard.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
types of template variables.
|
||||
|
||||
Graphite 1.1 introduced tags and Grafana added support for Graphite queries with tags in version 5.0. To create a variable using tag values, then you need to use the Grafana functions `tags` and `tag_values`.
|
||||
@@ -132,6 +132,7 @@ TagValues
|
||||
tag_values(server, server=~${__searchFilter:regex})
|
||||
```
|
||||
|
||||
|
||||
### Variable Usage
|
||||
|
||||
You can use a variable in a metric node path or as a parameter to a function.
|
||||
@@ -158,20 +159,16 @@ Example of a tag expression with regex formatting and using the Equal Tilde oper
|
||||
server=~${servers:regex}
|
||||
```
|
||||
|
||||
Check out the [Advanced Formatting Options section in the Variables]({{< relref "../../variables/templates-and-variables.md#advanced-formatting-options" >}}) documentation for examples and details.
|
||||
Check out the [Advanced Formatting Options section in the Variables]({{< relref "../../reference/templating.md#advanced-formatting-options" >}}) documentation for examples and details.
|
||||
|
||||
## Annotations
|
||||
|
||||
[Annotations]({{< relref "../../reference/annotations.md" >}}) allow you to overlay rich event information on top of graphs. You add annotation
|
||||
[Annotations]({{< relref "../../reference/annotations.md" >}}) allows you to overlay rich event information on top of graphs. You add annotation
|
||||
queries via the Dashboard menu / Annotations view.
|
||||
|
||||
Graphite supports two ways to query annotations. A regular metric query, for this you use the `Graphite query` textbox. A Graphite events query, use the `Graphite event tags` textbox,
|
||||
specify a tag or wildcard (leave empty should also work)
|
||||
|
||||
## Getting Grafana metrics into Graphite
|
||||
|
||||
Grafana exposes metrics for Graphite on the `/metrics` endpoint. For detailed instructions, refer to [Internal Grafana metrics]({{< relref "../../administration/metrics.md">}}).
|
||||
|
||||
## Configure the data source with provisioning
|
||||
|
||||
It's now possible to configure data sources using config files with Grafana's provisioning system. You can read more about how it works and all the settings you can set for data sources on the [provisioning docs page]({{< relref "../../administration/provisioning/#datasources" >}})
|
||||
|
||||
@@ -140,11 +140,11 @@ To add a filter click the plus icon to the right of the `Measurements/Fields` bu
|
||||
|
||||
## Templating
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place.
|
||||
Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place.
|
||||
Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data
|
||||
being displayed in your dashboard.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different
|
||||
types of template variables.
|
||||
|
||||
### Query variable
|
||||
|
||||
@@ -39,16 +39,14 @@ Just add it as a data source and you are ready to query your log data in [Explor
|
||||
### Derived fields
|
||||
|
||||
The Derived Fields configuration allows you to:
|
||||
|
||||
* Add fields parsed from the log message.
|
||||
* Add a link that uses the value of the field.
|
||||
|
||||
You can use this functionality to link to your tracing backend directly from your logs, or link to a user profile page if a userId is present in the log line. These links appear in the [log details](/features/explore/#labels-and-parsed-fields).
|
||||
You can use this functionality to link to your tracing backend directly from your logs, or link to a user profile page if a userId is present in the log line. These links will be shown in the [log details](/features/explore/#labels-and-parsed-fields).
|
||||
{{< docs-imagebox img="/img/docs/v65/loki_derived_fields.png" class="docs-image--no-shadow" caption="Screenshot of the derived fields configuration" >}}
|
||||
Each derived field consists of:
|
||||
|
||||
- **Name:** Shown in the log details as a label.
|
||||
- **Regex:** A Regex pattern that runs on the log message and captures part of it as the value of the new field. Can only contain a single capture group.
|
||||
- **Regex:** A Regex pattern that runs on the log message and captures part of it to as the value of the new field. Can only contain capture a single group.
|
||||
- **URL**: A URL template used to construct a link next to the field value in log details. Use special `${__value.raw}` value in your template to interpolate the real field value into your URL template.
|
||||
|
||||
You can use a debug section to see what your fields extract and how the URL is interpolated. Click **Show example log message** to show the text area where you can enter a log message.
|
||||
@@ -71,7 +69,7 @@ Once the result is returned, the log panel shows a list of log rows and a bar ch
|
||||
|
||||
<div class="medium-6 columns">
|
||||
<video width="800" height="500" controls>
|
||||
<source src="/assets/videos/explore_loki.mp4" type="video/mp4">
|
||||
<source src="https://grafana.com/static/assets/videos/explore_loki.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
@@ -98,7 +96,7 @@ Examples:
|
||||
|
||||
The [same rules that apply for Prometheus Label Selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#instant-vector-selectors) apply for Loki Log Stream Selectors.
|
||||
|
||||
Another way to add a label selector is in the table section. Click **Filter** beside a label to add the label to the query expression. This even works for multiple queries and will add the label selector to each query.
|
||||
Another way to add a label selector, is in the table section, clicking on the **Filter** button beside a label will add the label to the query expression. This even works for multiple queries and will the label selector to each query.
|
||||
|
||||
### Search Expression
|
||||
|
||||
@@ -127,7 +125,7 @@ The following filter types are currently supported:
|
||||
|
||||
## Live tailing
|
||||
|
||||
Loki supports Live tailing which displays logs in real-time. This feature is supported in [Explore]({{< relref "../explore/#loki-specific-features" >}}).
|
||||
Loki supports Live tailing which displays logs in real-time. This feature is supported in [Explore]({{< relref "../explore/#loki-specific-features" >}}) and in dashboards with a Live toggle in the query editor.
|
||||
|
||||
Note that Live Tailing relies on two Websocket connections: one between the browser and the Grafana server, and another between the Grafana server and the Loki server. If you run any reverse proxies, please configure them accordingly.
|
||||
|
||||
@@ -146,7 +144,7 @@ log message you're interested in.
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries, you can use variables in their place. Variables are shown as drop-down select boxes at the top of the dashboard. These drop-down boxes make it easy to change the data being displayed in your dashboard.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
Check out the [Templating]({{< relref "../../reference/templating" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
|
||||
## Annotations
|
||||
|
||||
@@ -189,16 +187,8 @@ datasources:
|
||||
jsonData:
|
||||
maxLines: 1000
|
||||
derivedFields:
|
||||
# Field with internal link pointing to data source in Grafana.
|
||||
# Right now, Grafana supports only Jaeger and Zipkin data sources as link targets.
|
||||
- datasourceUid: my_jaeger_uid
|
||||
- datasourceName: Jaeger
|
||||
matcherRegex: "traceID=(\\w+)"
|
||||
name: TraceID
|
||||
# url will be interpreted as query for the datasource
|
||||
url: "$${__value.raw}"
|
||||
|
||||
# Field with external link.
|
||||
- matcherRegex: "traceID=(\\w+)"
|
||||
name: TraceID
|
||||
url: "http://localhost:16686/trace/$${__value.raw}"
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ Name | Description
|
||||
|
||||
### Min time interval
|
||||
|
||||
A lower limit for the [$__interval]({{< relref "../../variables/templates-and-variables/#the-interval-variable" >}}) and [$__interval_ms]({{< relref "../../variables/templates-and-variables/#the-interval-ms-variable" >}}) variables.
|
||||
A lower limit for the [$__interval]({{< relref "../../reference/templating/#the-interval-variable" >}}) and [$__interval_ms]({{< relref "../../reference/templating/#the-interval-ms-variable" >}}) variables.
|
||||
Recommended to be set to write frequency, for example `1m` if your data is written every minute.
|
||||
This option can also be overridden/configured in a dashboard panel under data source options. It's important to note that this value **needs** to be formatted as a
|
||||
number followed by a valid time identifier, e.g. `1m` (1 minute) or `30s` (30 seconds). The following time identifiers are supported:
|
||||
@@ -80,7 +80,7 @@ If possible, we recommend you to use the latest service pack available for optim
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v51/mssql_query_editor.png" class="docs-image--no-shadow" >}}
|
||||
|
||||
You will find the MSSQL query editor in the metrics tab in Graph, Singlestat or Table panel's edit mode. You enter edit mode by clicking the
|
||||
You find the MSSQL query editor in the metrics tab in Graph, Singlestat or Table panel's edit mode. You enter edit mode by clicking the
|
||||
panel title, then edit. The editor allows you to define a SQL query to select data to be visualized.
|
||||
|
||||
1. Select *Format as* `Time series` (for use in Graph or Singlestat panel's among others) or `Table` (for use in Table panel among others).
|
||||
@@ -97,24 +97,24 @@ To simplify syntax and to allow for dynamic parts, like date range filters, the
|
||||
|
||||
Macro example | Description
|
||||
------------ | -------------
|
||||
*`$__time(dateColumn)`* | Will be replaced by an expression to rename the column to *time*. For example, *dateColumn as time*
|
||||
*`$__timeEpoch(dateColumn)`* | Will be replaced by an expression to convert a DATETIME column type to Unix timestamp and rename it to *time*. <br/>For example, *DATEDIFF(second, '1970-01-01', dateColumn) AS time*
|
||||
*`$__timeFilter(dateColumn)`* | Will be replaced by a time range filter using the specified column name. <br/>For example, *dateColumn BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:06:17Z'*
|
||||
*`$__timeFrom()`* | Will be replaced by the start of the currently active time selection. For example, *'2017-04-21T05:01:17Z'*
|
||||
*`$__timeTo()`* | Will be replaced by the end of the currently active time selection. For example, *'2017-04-21T05:06:17Z'*
|
||||
*`$__timeGroup(dateColumn,'5m'[, fillvalue])`* | Will be replaced by an expression usable in GROUP BY clause. Providing a *fillValue* of *NULL* or *floating value* will automatically fill empty series in timerange with that value. <br/>For example, *CAST(ROUND(DATEDIFF(second, '1970-01-01', time_column)/300.0, 0) as bigint)\*300*.
|
||||
*`$__timeGroup(dateColumn,'5m', 0)`* | Same as above but with a fill parameter so missing points in that series will be added by grafana and 0 will be used as value.
|
||||
*`$__timeGroup(dateColumn,'5m', NULL)`* | Same as above but NULL will be used as value for missing points.
|
||||
*`$__timeGroup(dateColumn,'5m', previous)`* | Same as above but the previous value in that series will be used as fill value if no value has been seen yet NULL will be used (only available in Grafana 5.3+).
|
||||
*`$__timeGroupAlias(dateColumn,'5m')`* | Will be replaced identical to $__timeGroup but with an added column alias (only available in Grafana 5.3+).
|
||||
*`$__unixEpochFilter(dateColumn)`* | Will be replaced by a time range filter using the specified column name with times represented as Unix timestamp. For example, *dateColumn > 1494410783 AND dateColumn < 1494497183*
|
||||
*`$__unixEpochFrom()`* | Will be replaced by the start of the currently active time selection as Unix timestamp. For example, *1494410783*
|
||||
*`$__unixEpochTo()`* | Will be replaced by the end of the currently active time selection as Unix timestamp. For example, *1494497183*
|
||||
*`$__unixEpochNanoFilter(dateColumn)`* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, *dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872*
|
||||
*`$__unixEpochNanoFrom()`* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214*
|
||||
*`$__unixEpochNanoTo()`* | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, *1494497183142514872*
|
||||
*`$__unixEpochGroup(dateColumn,'5m', [fillmode])`* | Same as $__timeGroup but for times stored as Unix timestamp (only available in Grafana 5.3+).
|
||||
*`$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])`* | Same as above but also adds a column alias (only available in Grafana 5.3+).
|
||||
*$__time(dateColumn)* | Will be replaced by an expression to rename the column to *time*. For example, *dateColumn as time*
|
||||
*$__timeEpoch(dateColumn)* | Will be replaced by an expression to convert a DATETIME column type to Unix timestamp and rename it to *time*. <br/>For example, *DATEDIFF(second, '1970-01-01', dateColumn) AS time*
|
||||
*$__timeFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name. <br/>For example, *dateColumn BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:06:17Z'*
|
||||
*$__timeFrom()* | Will be replaced by the start of the currently active time selection. For example, *'2017-04-21T05:01:17Z'*
|
||||
*$__timeTo()* | Will be replaced by the end of the currently active time selection. For example, *'2017-04-21T05:06:17Z'*
|
||||
*$__timeGroup(dateColumn,'5m'[, fillvalue])* | Will be replaced by an expression usable in GROUP BY clause. Providing a *fillValue* of *NULL* or *floating value* will automatically fill empty series in timerange with that value. <br/>For example, *CAST(ROUND(DATEDIFF(second, '1970-01-01', time_column)/300.0, 0) as bigint)\*300*.
|
||||
*$__timeGroup(dateColumn,'5m', 0)* | Same as above but with a fill parameter so missing points in that series will be added by grafana and 0 will be used as value.
|
||||
*$__timeGroup(dateColumn,'5m', NULL)* | Same as above but NULL will be used as value for missing points.
|
||||
*$__timeGroup(dateColumn,'5m', previous)* | Same as above but the previous value in that series will be used as fill value if no value has been seen yet NULL will be used (only available in Grafana 5.3+).
|
||||
*$__timeGroupAlias(dateColumn,'5m')* | Will be replaced identical to $__timeGroup but with an added column alias (only available in Grafana 5.3+).
|
||||
*$__unixEpochFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as Unix timestamp. For example, *dateColumn > 1494410783 AND dateColumn < 1494497183*
|
||||
*$__unixEpochFrom()* | Will be replaced by the start of the currently active time selection as Unix timestamp. For example, *1494410783*
|
||||
*$__unixEpochTo()* | Will be replaced by the end of the currently active time selection as Unix timestamp. For example, *1494497183*
|
||||
*$__unixEpochNanoFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, *dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872*
|
||||
*$__unixEpochNanoFrom()* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214*
|
||||
*$__unixEpochNanoTo()* | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, *1494497183142514872*
|
||||
*$__unixEpochGroup(dateColumn,'5m', [fillmode])* | Same as $__timeGroup but for times stored as Unix timestamp (only available in Grafana 5.3+).
|
||||
*$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])* | Same as above but also adds a column alias (only available in Grafana 5.3+).
|
||||
|
||||
We plan to add many more macros. If you have suggestions for what macros you would like to see, please [open an issue](https://github.com/grafana/grafana) in our GitHub repo.
|
||||
|
||||
@@ -293,14 +293,14 @@ GROUP BY
|
||||
ORDER BY 1
|
||||
```
|
||||
|
||||
When the above query is used in a graph panel, the result is two series named `Metric A` and `Metric B` with a sum of `valueTwo` plotted over `time`.
|
||||
When above query are used in a graph panel the result will be two series named `Metric A` and `Metric B` with a sum of `valueTwo` plotted over `time`.
|
||||
Any series lacking a value in a 3 minute window will have a value of zero which you'll see rendered in the graph to the right.
|
||||
|
||||
## Templating
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data being displayed in your dashboard.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
|
||||
### Query Variable
|
||||
|
||||
@@ -319,7 +319,7 @@ A query can return multiple columns and Grafana will automatically create a list
|
||||
SELECT [host].[hostname], [other_host].[hostname2] FROM host JOIN other_host ON [host].[city] = [other_host].[city]
|
||||
```
|
||||
|
||||
Another option is a query that can create a key/value variable. The query should return two columns that are named `__text` and `__value`. The `__text` column value should be unique (if it is not unique then the first value is used). The options in the dropdown will have a text and value that allow you to have a friendly name as text and an id as the value. An example query with `hostname` as the text and `id` as the value:
|
||||
Another option is a query that can create a key/value variable. The query should return two columns that are named `__text` and `__value`. The `__text` column value should be unique (if it is not unique then the first value is used). The options in the dropdown will have a text and value that allows you to have a friendly name as text and an id as the value. An example query with `hostname` as the text and `id` as the value:
|
||||
|
||||
```sql
|
||||
SELECT hostname __text, id __value FROM host
|
||||
@@ -370,18 +370,18 @@ Grafana automatically creates a quoted, comma-separated string for multi-value v
|
||||
|
||||
`${servers:csv}`
|
||||
|
||||
Read more about variable formatting options in the [Variables]({{< relref "../../variables/templates-and-variables.md#advanced-formatting-options" >}}) documentation.
|
||||
Read more about variable formatting options in the [Variables]({{< relref "../../reference/templating.md#advanced-formatting-options" >}}) documentation.
|
||||
|
||||
## Annotations
|
||||
|
||||
[Annotations]({{< relref "../../reference/annotations.md" >}}) allow you to overlay rich event information on top of graphs. You add annotation queries via the Dashboard menu / Annotations view.
|
||||
[Annotations]({{< relref "../../reference/annotations.md" >}}) allows you to overlay rich event information on top of graphs. You add annotation queries via the Dashboard menu / Annotations view.
|
||||
|
||||
**Columns:**
|
||||
|
||||
Name | Description
|
||||
------------ | -------------
|
||||
time | The name of the date/time field. Could be a column with a native SQL date/time data type or epoch value.
|
||||
timeend | Optional name of the end date/time field. Could be a column with a native SQL date/time data type or epoch value. (Grafana v6.6+)
|
||||
timeend | Optional name of the end date/time field. Could be a column with a native SQL date/time data type or epoch value.
|
||||
text | Event description field.
|
||||
tags | Optional field name to use for event tags as a comma separated string.
|
||||
|
||||
@@ -411,23 +411,6 @@ WHERE
|
||||
ORDER BY 1
|
||||
```
|
||||
|
||||
**Example region query using time and timeend columns with epoch values:**
|
||||
|
||||
> Only available in Grafana v6.6+.
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
time_sec as time,
|
||||
time_end_sec as timeend,
|
||||
description as [text],
|
||||
tags
|
||||
FROM
|
||||
[events]
|
||||
WHERE
|
||||
$__unixEpochFilter(time_sec)
|
||||
ORDER BY 1
|
||||
```
|
||||
|
||||
**Example query using time column of native SQL date/time data type:**
|
||||
|
||||
```sql
|
||||
@@ -444,7 +427,7 @@ ORDER BY 1
|
||||
|
||||
## Stored procedure support
|
||||
|
||||
Stored procedures have been verified to work. However, please note that we haven't done anything special to support this, so there might be edge cases where it won't work as you would expect.
|
||||
Stored procedures have been verified to work. However, please note that we haven't done anything special to support this why there may exist edge cases where it won't work as you would expect.
|
||||
Stored procedures should be supported in table, time series and annotation queries as long as you use the same naming of columns and return data in the same format as describe above under respective section.
|
||||
|
||||
Please note that any macro function will not work inside a stored procedure.
|
||||
@@ -452,7 +435,7 @@ Please note that any macro function will not work inside a stored procedure.
|
||||
### Examples
|
||||
|
||||
{{< docs-imagebox img="/img/docs/v51/mssql_metrics_graph.png" class="docs-image--no-shadow docs-image--right" >}}
|
||||
For the following examples the database table is defined in [Time series queries](#time-series-queries). Let's say that we want to visualize 4 series in a graph panel, i.e. all combinations of columns `valueOne`, `valueTwo` and `measurement`. Graph panel to the right visualizes what we want to achieve. To solve this we actually need to use two queries:
|
||||
For the following examples the database table defined in [Time series queries](#time-series-queries). Let's say that we want to visualize 4 series in a graph panel, i.e. all combinations of columns `valueOne`, `valueTwo` and `measurement`. Graph panel to the right visualizes what we want to achieve. To solve this we actually need to use two queries:
|
||||
|
||||
**First query:**
|
||||
|
||||
@@ -491,7 +474,7 @@ We can define a stored procedure that will return all data we need to render 4 s
|
||||
In this case the stored procedure accepts two parameters `@from` and `@to` of `int` data types which should be a timerange (from-to) in epoch format
|
||||
which will be used to filter the data to return from the stored procedure.
|
||||
|
||||
We're mimicking the `$__timeGroup(time, '5m')` in the select and group by expressions, and that's why there are a lot of lengthy expressions needed -
|
||||
We're mimicking the `$__timeGroup(time, '5m')` in the select and group by expressions and that's why there's a lot of lengthy expressions needed -
|
||||
these could be extracted to MSSQL functions, if wanted.
|
||||
|
||||
```sql
|
||||
|
||||
@@ -15,7 +15,7 @@ weight = 7
|
||||
>
|
||||
> Starting from Grafana v5.1 you can name the time column *time* in addition to earlier supported *time_sec*. Usage of *time_sec* will eventually be deprecated.
|
||||
|
||||
Grafana ships with a built-in MySQL data source plugin that allows you to query and visualize
|
||||
Grafana ships with a built-in MySQL data source plugin that allow you to query any visualize
|
||||
data from a MySQL compatible database.
|
||||
|
||||
## Adding the data source
|
||||
@@ -41,7 +41,7 @@ Name | Description
|
||||
|
||||
### Min time interval
|
||||
|
||||
A lower limit for the [$__interval]({{< relref "../../variables/templates-and-variables/#the-interval-variable" >}}) and [$__interval_ms]({{< relref "../../variables/templates-and-variables/#the-interval-ms-variable" >}}) variables.
|
||||
A lower limit for the [$__interval]({{< relref "../../reference/templating/#the-interval-variable" >}}) and [$__interval_ms]({{< relref "../../reference/templating/#the-interval-ms-variable" >}}) variables.
|
||||
Recommended to be set to write frequency, for example `1m` if your data is written every minute.
|
||||
This option can also be overridden/configured in a dashboard panel under data source options. It's important to note that this value **needs** to be formatted as a
|
||||
number followed by a valid time identifier, e.g. `1m` (1 minute) or `30s` (30 seconds). The following time identifiers are supported:
|
||||
@@ -131,28 +131,28 @@ To simplify syntax and to allow for dynamic parts, like date range filters, the
|
||||
|
||||
Macro example | Description
|
||||
------------ | -------------
|
||||
*`$__time(dateColumn)`* | Will be replaced by an expression to convert to a UNIX timestamp and rename the column to `time_sec`. For example, *UNIX_TIMESTAMP(dateColumn) as time_sec*
|
||||
*`$__timeEpoch(dateColumn)`* | Will be replaced by an expression to convert to a UNIX timestamp and rename the column to `time_sec`. For example, *UNIX_TIMESTAMP(dateColumn) as time_sec*
|
||||
*`$__timeFilter(dateColumn)`* | Will be replaced by a time range filter using the specified column name. For example, *dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)*
|
||||
*`$__timeFrom()`* | Will be replaced by the start of the currently active time selection. For example, *FROM_UNIXTIME(1494410783)*
|
||||
*`$__timeTo()`* | Will be replaced by the end of the currently active time selection. For example, *FROM_UNIXTIME(1494410983)*
|
||||
*`$__timeGroup(dateColumn,'5m')`* | Will be replaced by an expression usable in GROUP BY clause. For example, *cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) as signed)*300 as signed),*
|
||||
*`$__timeGroup(dateColumn,'5m', 0)`* | Same as above but with a fill parameter so missing points in that series will be added by grafana and 0 will be used as value.
|
||||
*`$__timeGroup(dateColumn,'5m', NULL)`* | Same as above but NULL will be used as value for missing points.
|
||||
*`$__timeGroup(dateColumn,'5m', previous)`* | Same as above but the previous value in that series will be used as fill value if no value has been seen yet NULL will be used (only available in Grafana 5.3+).
|
||||
*`$__timeGroupAlias(dateColumn,'5m')`* | Will be replaced identical to $__timeGroup but with an added column alias (only available in Grafana 5.3+).
|
||||
*`$__unixEpochFilter(dateColumn)`* | Will be replaced by a time range filter using the specified column name with times represented as Unix timestamp. For example, *dateColumn > 1494410783 AND dateColumn < 1494497183*
|
||||
*`$__unixEpochFrom()`* | Will be replaced by the start of the currently active time selection as Unix timestamp. For example, *1494410783*
|
||||
*`$__unixEpochTo()`* | Will be replaced by the end of the currently active time selection as Unix timestamp. For example, *1494497183*
|
||||
*`$__unixEpochNanoFilter(dateColumn)`* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, *dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872*
|
||||
*`$__unixEpochNanoFrom()`* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214*
|
||||
*`$__unixEpochNanoTo()`* | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, *1494497183142514872*
|
||||
*`$__unixEpochGroup(dateColumn,'5m', [fillmode])`* | Same as $__timeGroup but for times stored as Unix timestamp (only available in Grafana 5.3+).
|
||||
*`$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])`* | Same as above but also adds a column alias (only available in Grafana 5.3+).
|
||||
*$__time(dateColumn)* | Will be replaced by an expression to convert to a UNIX timestamp and rename the column to `time_sec`. For example, *UNIX_TIMESTAMP(dateColumn) as time_sec*
|
||||
*$__timeEpoch(dateColumn)* | Will be replaced by an expression to convert to a UNIX timestamp and rename the column to `time_sec`. For example, *UNIX_TIMESTAMP(dateColumn) as time_sec*
|
||||
*$__timeFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name. For example, *dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)*
|
||||
*$__timeFrom()* | Will be replaced by the start of the currently active time selection. For example, *FROM_UNIXTIME(1494410783)*
|
||||
*$__timeTo()* | Will be replaced by the end of the currently active time selection. For example, *FROM_UNIXTIME(1494410983)*
|
||||
*$__timeGroup(dateColumn,'5m')* | Will be replaced by an expression usable in GROUP BY clause. For example, *cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) as signed)*300 as signed),*
|
||||
*$__timeGroup(dateColumn,'5m', 0)* | Same as above but with a fill parameter so missing points in that series will be added by grafana and 0 will be used as value.
|
||||
*$__timeGroup(dateColumn,'5m', NULL)* | Same as above but NULL will be used as value for missing points.
|
||||
*$__timeGroup(dateColumn,'5m', previous)* | Same as above but the previous value in that series will be used as fill value if no value has been seen yet NULL will be used (only available in Grafana 5.3+).
|
||||
*$__timeGroupAlias(dateColumn,'5m')* | Will be replaced identical to $__timeGroup but with an added column alias (only available in Grafana 5.3+).
|
||||
*$__unixEpochFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as Unix timestamp. For example, *dateColumn > 1494410783 AND dateColumn < 1494497183*
|
||||
*$__unixEpochFrom()* | Will be replaced by the start of the currently active time selection as Unix timestamp. For example, *1494410783*
|
||||
*$__unixEpochTo()* | Will be replaced by the end of the currently active time selection as Unix timestamp. For example, *1494497183*
|
||||
*$__unixEpochNanoFilter(dateColumn)* | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, *dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872*
|
||||
*$__unixEpochNanoFrom()* | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, *1494410783152415214*
|
||||
*$__unixEpochNanoTo()* | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, *1494497183142514872*
|
||||
*$__unixEpochGroup(dateColumn,'5m', [fillmode])* | Same as $__timeGroup but for times stored as Unix timestamp (only available in Grafana 5.3+).
|
||||
*$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])* | Same as above but also adds a column alias (only available in Grafana 5.3+).
|
||||
|
||||
We plan to add many more macros. If you have suggestions for what macros you would like to see, please [open an issue](https://github.com/grafana/grafana) in our GitHub repo.
|
||||
|
||||
The query editor has a link named `Generated SQL` that shows up after a query has been executed, while in panel edit mode. Click on it and it will expand and show the raw interpolated SQL string that was executed.
|
||||
The query editor has a link named `Generated SQL` that show up after a query as been executed, while in panel edit mode. Click on it and it will expand and show the raw interpolated SQL string that was executed.
|
||||
|
||||
## Table queries
|
||||
|
||||
@@ -236,9 +236,9 @@ This is something we plan to add.
|
||||
|
||||
This feature is currently available in the nightly builds and will be included in the 5.0.0 release.
|
||||
|
||||
Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard.
|
||||
Instead of hard-coding things like server, application and sensor name in you metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns makes it easy to change the data being displayed in your dashboard.
|
||||
|
||||
Check out the [Templating]({{< relref "../../variables/templates-and-variables.md" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
Check out the [Templating]({{< relref "../../reference/templating.md" >}}) documentation for an introduction to the templating feature and the different types of template variables.
|
||||
|
||||
### Query Variable
|
||||
|
||||
@@ -251,7 +251,7 @@ For example, you can have a variable that contains all values for the `hostname`
|
||||
SELECT hostname FROM my_host
|
||||
```
|
||||
|
||||
A query can return multiple columns and Grafana will automatically create a list from them. For example, the query below will return a list with values from `hostname` and `hostname2`.
|
||||
A query can returns multiple columns and Grafana will automatically create a list from them. For example, the query below will return a list with values from `hostname` and `hostname2`.
|
||||
|
||||
```sql
|
||||
SELECT my_host.hostname, my_other_host.hostname2 FROM my_host JOIN my_other_host ON my_host.city = my_other_host.city
|
||||
@@ -331,7 +331,7 @@ Grafana automatically creates a quoted, comma-separated string for multi-value v
|
||||
|
||||
`${servers:csv}`
|
||||
|
||||
Read more about variable formatting options in the [Variables]({{< relref "../../variables/templates-and-variables.md#advanced-formatting-options" >}}) documentation.
|
||||
Read more about variable formatting options in the [Variables]({{< relref "../../reference/templating.md#advanced-formatting-options" >}}) documentation.
|
||||
|
||||
## Annotations
|
||||
|
||||
@@ -350,22 +350,6 @@ WHERE
|
||||
$__unixEpochFilter(epoch_time)
|
||||
```
|
||||
|
||||
**Example region query using time and timeend columns with epoch values:**
|
||||
|
||||
> Only available in Grafana v6.6+.
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
epoch_time as time,
|
||||
epoch_timeend as timeend,
|
||||
metric1 as text,
|
||||
CONCAT(tag1, ',', tag2) as tags
|
||||
FROM
|
||||
public.test_data
|
||||
WHERE
|
||||
$__unixEpochFilter(epoch_time)
|
||||
```
|
||||
|
||||
**Example query using time column of native SQL date/time data type:**
|
||||
|
||||
```sql
|
||||
@@ -382,13 +366,13 @@ WHERE
|
||||
Name | Description
|
||||
------------ | -------------
|
||||
time | The name of the date/time field. Could be a column with a native SQL date/time data type or epoch value.
|
||||
timeend | Optional name of the end date/time field. Could be a column with a native SQL date/time data type or epoch value. (Grafana v6.6+)
|
||||
timeend | Optional name of the end date/time field. Could be a column with a native SQL date/time data type or epoch value.
|
||||
text | Event description field.
|
||||
tags | Optional field name to use for event tags as a comma separated string.
|
||||
|
||||
## Alerting
|
||||
|
||||
Time series queries should work in alerting conditions. Table formatted queries are not yet supported in alert rule conditions.
|
||||
Time series queries should work in alerting conditions. Table formatted queries is not yet supported in alert rule conditions.
|
||||
|
||||
## Configure the data source with provisioning
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user