Compare commits
15 Commits
v8.2.0
...
v8.1.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
147704deb9 | ||
|
|
078d716be9 | ||
|
|
04cb471599 | ||
|
|
6564f22772 | ||
|
|
13cd3ea28b | ||
|
|
d5e0665081 | ||
|
|
909141592d | ||
|
|
fda235a862 | ||
|
|
154231a58d | ||
|
|
197e4344da | ||
|
|
64b008e28b | ||
|
|
bc9ac1199b | ||
|
|
2b15e1a962 | ||
|
|
4308a77e27 | ||
|
|
f18749927c |
12
.bingo/.gitignore
vendored
12
.bingo/.gitignore
vendored
@@ -1,12 +0,0 @@
|
||||
|
||||
# Ignore everything
|
||||
*
|
||||
|
||||
# But not these files:
|
||||
!.gitignore
|
||||
!*.mod
|
||||
!README.md
|
||||
!Variables.mk
|
||||
!variables.env
|
||||
|
||||
*tmp.mod
|
||||
@@ -1,14 +0,0 @@
|
||||
# Project Development Dependencies.
|
||||
|
||||
This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo.
|
||||
|
||||
- Run `bingo get` to install all tools having each own module file in this directory.
|
||||
- Run `bingo get <tool>` to install <tool> that have own module file in this directory.
|
||||
- For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $(<upper case tool name>) variable where <tool> is the .bingo/<tool>.mod.
|
||||
- For shell: Run `source .bingo/variables.env` to source all environment variable for each tool.
|
||||
- For go: Import `.bingo/variables.go` to for variable names.
|
||||
- See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.14+
|
||||
@@ -1,25 +0,0 @@
|
||||
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.4.3. DO NOT EDIT.
|
||||
# All tools are designed to be build inside $GOBIN.
|
||||
BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
GOPATH ?= $(shell go env GOPATH)
|
||||
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
|
||||
GO ?= $(shell which go)
|
||||
|
||||
# Below generated variables ensure that every time a tool under each variable is invoked, the correct version
|
||||
# will be used; reinstalling only if needed.
|
||||
# For example for wire variable:
|
||||
#
|
||||
# In your main Makefile (for non array binaries):
|
||||
#
|
||||
#include .bingo/Variables.mk # Assuming -dir was set to .bingo .
|
||||
#
|
||||
#command: $(WIRE)
|
||||
# @echo "Running wire"
|
||||
# @$(WIRE) <flags/args..>
|
||||
#
|
||||
WIRE := $(GOBIN)/wire-v0.5.0
|
||||
$(WIRE): $(BINGO_DIR)/wire.mod
|
||||
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
|
||||
@echo "(re)installing $(GOBIN)/wire-v0.5.0"
|
||||
@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=wire.mod -o=$(GOBIN)/wire-v0.5.0 "github.com/google/wire/cmd/wire"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files.
|
||||
@@ -1,12 +0,0 @@
|
||||
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.4.3. DO NOT EDIT.
|
||||
# All tools are designed to be build inside $GOBIN.
|
||||
# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.
|
||||
GOBIN=${GOBIN:=$(go env GOBIN)}
|
||||
|
||||
if [ -z "$GOBIN" ]; then
|
||||
GOBIN="$(go env GOPATH)/bin"
|
||||
fi
|
||||
|
||||
|
||||
WIRE="${GOBIN}/wire-v0.5.0"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/google/wire v0.5.0 // cmd/wire
|
||||
@@ -1,6 +1,5 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["make", "gen-go"],
|
||||
["go", "run", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
|
||||
12
.drone.star
12
.drone.star
@@ -4,12 +4,12 @@
|
||||
# 3. Run `make drone`
|
||||
# More information about this process here: https://github.com/grafana/deployment_tools/blob/master/docs/infrastructure/drone/signing.md
|
||||
|
||||
load('scripts/drone/pipelines/pr.star', 'pr_pipelines')
|
||||
load('scripts/drone/pipelines/main.star', 'main_pipelines')
|
||||
load('scripts/drone/pipelines/release.star', 'release_pipelines', 'test_release_pipelines')
|
||||
load('scripts/drone/version.star', 'version_branch_pipelines')
|
||||
load('scripts/drone/pipelines/cron.star', 'cronjobs')
|
||||
load('scripts/drone/vault.star', 'secrets')
|
||||
load('scripts/pr.star', 'pr_pipelines')
|
||||
load('scripts/main.star', 'main_pipelines')
|
||||
load('scripts/release.star', 'release_pipelines', 'test_release_pipelines')
|
||||
load('scripts/version.star', 'version_branch_pipelines')
|
||||
load('scripts/job.star', 'cronjobs')
|
||||
load('scripts/vault.star', 'secrets')
|
||||
|
||||
def main(ctx):
|
||||
edition = 'oss'
|
||||
|
||||
986
.drone.yml
986
.drone.yml
File diff suppressed because it is too large
Load Diff
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -22,10 +22,6 @@
|
||||
go.mod @grafana/backend-platform
|
||||
go.sum @grafana/backend-platform
|
||||
|
||||
# Continuous Integration
|
||||
.drone.yml @malcolmholmes @dsotirakis @zserge
|
||||
/scripts/drone/ @malcolmholmes @dsotirakis @zserge
|
||||
|
||||
# Cloud Datasources backend code
|
||||
/pkg/tsdb/cloudwatch @grafana/cloud-datasources @grafana/observability-squad
|
||||
/pkg/tsdb/azuremonitor @grafana/cloud-datasources
|
||||
|
||||
13
.github/pr-commands.json
vendored
13
.github/pr-commands.json
vendored
@@ -66,6 +66,9 @@
|
||||
"packaging/**/*",
|
||||
"scripts/build/**/*",
|
||||
"scripts/*.sh",
|
||||
"scripts/*.star",
|
||||
".drone.star",
|
||||
".drone.yml",
|
||||
"Makefile",
|
||||
"Dockerfile",
|
||||
"Dockerfile.ubuntu"
|
||||
@@ -73,16 +76,6 @@
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/build-packaging"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"scripts/*.star",
|
||||
".drone.star",
|
||||
".drone.yml"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/ci"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [ "public/app/plugins/datasource/grafana-azure-monitor-datasource/**/*", "pkg/tsdb/azuremonitor/**/*"],
|
||||
|
||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- run: git clone --single-branch --no-tags --depth 1 -b master https://grafanabot:${{ secrets.GH_BOT_ACCESS_TOKEN }}@github.com/grafana/website-sync ./.github/actions/website-sync
|
||||
- uses: actions/cache@v2.1.6
|
||||
- uses: actions/cache@v2.1.5
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -75,7 +75,6 @@ profile.cov
|
||||
/pkg/cmd/grafana-server/grafana-server
|
||||
/pkg/cmd/grafana-server/debug
|
||||
/pkg/extensions/*
|
||||
/pkg/server/wireexts_enterprise.go
|
||||
!/pkg/extensions/main.go
|
||||
/public/app/extensions
|
||||
debug.test
|
||||
@@ -123,15 +122,8 @@ compilation-stats.json
|
||||
!/e2e/**/screenshots/expected/*
|
||||
/e2e/**/videos/*
|
||||
|
||||
# a11y tests
|
||||
/pa11y-ci-results.json
|
||||
/pa11y-ci-report
|
||||
|
||||
# report dumping the whole system env
|
||||
/report.*.json
|
||||
|
||||
# auto generated frontend docs
|
||||
/docs/sources/packages_api
|
||||
|
||||
# auto generated Go files
|
||||
*_gen.go
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
var config = {
|
||||
defaults: {
|
||||
concurrency: 1,
|
||||
runners: ['axe'],
|
||||
chromeLaunchConfig: {
|
||||
args: ['--no-sandbox'],
|
||||
},
|
||||
},
|
||||
|
||||
urls: [
|
||||
{
|
||||
url: '${HOST}/login',
|
||||
actions: [
|
||||
"set field input[name='user'] to admin",
|
||||
"set field input[name='password'] to admin",
|
||||
"click element button[aria-label='Login button']",
|
||||
"wait for element [aria-label='Skip change password button'] to be visible",
|
||||
],
|
||||
threshold: 3,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1',
|
||||
threshold: 7,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge',
|
||||
hideElements: '.sidemenu',
|
||||
threshold: 2,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=settings',
|
||||
rootElement: '.dashboard-settings',
|
||||
threshold: 10,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1&search=open',
|
||||
rootElement: '.main-view',
|
||||
threshold: 15,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/alerting/list',
|
||||
rootElement: '.main-view',
|
||||
threshold: 7,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/datasources',
|
||||
rootElement: '.main-view',
|
||||
threshold: 36,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/users',
|
||||
rootElement: '.main-view',
|
||||
threshold: 4,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/teams',
|
||||
rootElement: '.main-view',
|
||||
threshold: 1,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/plugins',
|
||||
rootElement: '.main-view',
|
||||
threshold: 41,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org',
|
||||
rootElement: '.main-view',
|
||||
threshold: 2,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/apikeys',
|
||||
rootElement: '.main-view',
|
||||
threshold: 5,
|
||||
},
|
||||
{
|
||||
url: '${HOST}/dashboards',
|
||||
rootElement: '.main-view',
|
||||
threshold: 8,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function myPa11yCiConfiguration(urls, defaults) {
|
||||
const HOST_SERVER = process.env.HOST || 'localhost';
|
||||
const PORT_SERVER = process.env.PORT || '3000';
|
||||
for (var idx = 0; idx < urls.length; idx++) {
|
||||
urls[idx] = { ...urls[idx], url: urls[idx].url.replace('${HOST}', `${HOST_SERVER}:${PORT_SERVER}`) };
|
||||
}
|
||||
|
||||
return {
|
||||
defaults: defaults,
|
||||
urls: urls,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = myPa11yCiConfiguration(config.urls, config.defaults);
|
||||
@@ -1,83 +0,0 @@
|
||||
var config = {
|
||||
defaults: {
|
||||
concurrency: 1,
|
||||
runners: ['axe'],
|
||||
chromeLaunchConfig: {
|
||||
args: ['--no-sandbox'],
|
||||
},
|
||||
},
|
||||
|
||||
urls: [
|
||||
{
|
||||
url: '${HOST}/login',
|
||||
actions: [
|
||||
"set field input[name='user'] to admin",
|
||||
"set field input[name='password'] to admin",
|
||||
"click element button[aria-label='Login button']",
|
||||
"wait for element [aria-label='Skip change password button'] to be visible",
|
||||
],
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge',
|
||||
hideElements: '.sidemenu',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=settings',
|
||||
rootElement: '.dashboard-settings',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/?orgId=1&search=open',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/alerting/list',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/datasources',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/users',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/teams',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/plugins',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/org/apikeys',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
{
|
||||
url: '${HOST}/dashboards',
|
||||
rootElement: '.main-view',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
function myPa11yCiConfiguration(urls, defaults) {
|
||||
const HOST_SERVER = process.env.HOST || 'localhost';
|
||||
const PORT_SERVER = process.env.PORT || '3000';
|
||||
for (var idx = 0; idx < urls.length; idx++) {
|
||||
urls[idx] = { ...urls[idx], url: urls[idx].url.replace('${HOST}', `${HOST_SERVER}:${PORT_SERVER}`) };
|
||||
}
|
||||
|
||||
return {
|
||||
defaults: defaults,
|
||||
urls: urls,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = myPa11yCiConfiguration(config.urls, config.defaults);
|
||||
@@ -5,9 +5,8 @@ pkg/
|
||||
node_modules
|
||||
public/vendor/
|
||||
vendor/
|
||||
/data/
|
||||
data/
|
||||
e2e/tmp
|
||||
public/build/
|
||||
public/sass/*.generated.scss
|
||||
devenv/
|
||||
public/lib/monaco
|
||||
|
||||
1954
CHANGELOG.md
1954
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -26,12 +26,10 @@ Report a bug by submitting a [bug report](https://github.com/grafana/grafana/iss
|
||||
Follow the issue template and add additional information that will help us replicate the problem.
|
||||
|
||||
For data visualization issues:
|
||||
|
||||
- Query results from the inspect drawer (data tab & query inspector)
|
||||
- Panel settings can be extracted in the panel inspect drawer JSON tab
|
||||
|
||||
For a dashboard related issues:
|
||||
|
||||
- Dashboard JSON can be found in the dashboard settings JSON model view
|
||||
|
||||
For authentication and alerting Grafana server logs are useful.
|
||||
@@ -42,7 +40,7 @@ If you believe you've found a security vulnerability, please read our [security
|
||||
|
||||
### Suggest enhancements
|
||||
|
||||
If you have an idea of how to improve Grafana, submit an [enhancement request](https://github.com/grafana/grafana/discussions/new).
|
||||
If you have an idea of how to improve Grafana, submit an [enhancement request](https://github.com/grafana/grafana/issues/new?labels=type%3A+feature+request&template=2-feature_request.md).
|
||||
|
||||
We want to make Grafana accessible to even more people. Submit an [accessibility issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+accessibility&template=3-accessibility.md) to help us understand what we can improve.
|
||||
|
||||
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM node:16-alpine3.14 as js-builder
|
||||
FROM node:14.16.0-alpine3.13 as js-builder
|
||||
|
||||
WORKDIR /usr/src/app/
|
||||
|
||||
@@ -17,25 +17,25 @@ COPY emails emails
|
||||
ENV NODE_ENV production
|
||||
RUN yarn build
|
||||
|
||||
FROM golang:1.17.0-alpine3.14 as go-builder
|
||||
FROM golang:1.16.1-alpine3.13 as go-builder
|
||||
|
||||
RUN apk add --no-cache gcc g++
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/grafana/grafana
|
||||
|
||||
COPY go.mod go.sum embed.go ./
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
COPY cue cue
|
||||
COPY cue.mod cue.mod
|
||||
COPY packages/grafana-schema packages/grafana-schema
|
||||
COPY public/app/plugins public/app/plugins
|
||||
COPY pkg pkg
|
||||
COPY build.go package.json ./
|
||||
|
||||
RUN go mod verify
|
||||
RUN go run build.go build
|
||||
|
||||
# Final stage
|
||||
FROM alpine:3.14.2
|
||||
FROM alpine:3.13
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
|
||||
|
||||
@@ -17,19 +17,19 @@ COPY emails emails
|
||||
ENV NODE_ENV production
|
||||
RUN yarn build
|
||||
|
||||
FROM golang:1.17.0 AS go-builder
|
||||
FROM golang:1.16 AS go-builder
|
||||
|
||||
WORKDIR /src/grafana
|
||||
|
||||
COPY go.mod go.sum embed.go ./
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
COPY build.go package.json ./
|
||||
COPY pkg pkg/
|
||||
COPY cue cue/
|
||||
COPY cue.mod cue.mod/
|
||||
COPY packages/grafana-schema packages/grafana-schema/
|
||||
COPY public/app/plugins public/app/plugins/
|
||||
|
||||
RUN go mod verify
|
||||
RUN go run build.go build
|
||||
|
||||
FROM ubuntu:20.04
|
||||
|
||||
15
Makefile
15
Makefile
@@ -2,10 +2,7 @@
|
||||
##
|
||||
## For more information, refer to https://suva.sh/posts/well-documented-makefiles/
|
||||
|
||||
WIRE_TAGS = "oss"
|
||||
|
||||
-include local/Makefile
|
||||
include .bingo/Variables.mk
|
||||
|
||||
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go golangci-lint test-go test-js test run run-frontend clean devenv devenv-down protobuf drone help
|
||||
|
||||
@@ -30,11 +27,7 @@ node_modules: package.json yarn.lock ## Install node modules.
|
||||
|
||||
##@ Building
|
||||
|
||||
gen-go: $(WIRE)
|
||||
@echo "generate go files"
|
||||
$(WIRE) gen -tags $(WIRE_TAGS) ./pkg/server
|
||||
|
||||
build-go: gen-go ## Build all Go binaries.
|
||||
build-go: ## Build all Go binaries.
|
||||
@echo "build go files"
|
||||
$(GO) run build.go build
|
||||
|
||||
@@ -43,7 +36,7 @@ build-server: ## Build Grafana server.
|
||||
$(GO) run build.go build-server
|
||||
|
||||
build-cli: ## Build Grafana CLI application.
|
||||
@echo "build grafana-cli"
|
||||
@echo "build in CI environment"
|
||||
$(GO) run build.go build-cli
|
||||
|
||||
build-js: ## Build frontend assets.
|
||||
@@ -98,7 +91,7 @@ shellcheck: $(SH_FILES) ## Run checks for shell scripts.
|
||||
build-docker-dev: ## Build Docker image for development (fast).
|
||||
@echo "build development container"
|
||||
@echo "\033[92mInfo:\033[0m the frontend code is expected to be built already."
|
||||
$(GO) run build.go -goos linux -pkg-arch amd64 ${OPT} build latest
|
||||
$(GO) run build.go -goos linux -pkg-arch amd64 ${OPT} build pkg-archive latest
|
||||
cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
cd packaging/docker && docker build --tag grafana/grafana:dev .
|
||||
|
||||
@@ -148,7 +141,7 @@ clean: ## Clean up intermediate build artifacts.
|
||||
rm -rf public/build
|
||||
|
||||
# This repository's configuration is protected (https://readme.drone.io/signature/).
|
||||
# Use this make target to regenerate the configuration YAML files when
|
||||
# Use this make target to regenerate the configuration YAML files when
|
||||
# you modify starlark files.
|
||||
drone:
|
||||
drone starlark
|
||||
|
||||
466
build.go
466
build.go
@@ -3,14 +3,476 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
"github.com/grafana/grafana/pkg/build"
|
||||
const (
|
||||
windows = "windows"
|
||||
linux = "linux"
|
||||
)
|
||||
|
||||
var (
|
||||
//versionRe = regexp.MustCompile(`-[0-9]{1,3}-g[0-9a-f]{5,10}`)
|
||||
goarch string
|
||||
goos string
|
||||
gocc string
|
||||
cgo bool
|
||||
libc string
|
||||
pkgArch string
|
||||
version string = "v1"
|
||||
buildTags []string
|
||||
// deb & rpm does not support semver so have to handle their version a little differently
|
||||
linuxPackageVersion string = "v1"
|
||||
linuxPackageIteration string = ""
|
||||
race bool
|
||||
workingDir string
|
||||
includeBuildId bool = true
|
||||
buildId string = "0"
|
||||
serverBinary string = "grafana-server"
|
||||
cliBinary string = "grafana-cli"
|
||||
binaries []string = []string{serverBinary, cliBinary}
|
||||
isDev bool = false
|
||||
enterprise bool = false
|
||||
skipRpmGen bool = false
|
||||
skipDebGen bool = false
|
||||
printGenVersion bool = false
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(0)
|
||||
os.Exit(build.RunCmd())
|
||||
|
||||
var buildIdRaw string
|
||||
var buildTagsRaw string
|
||||
|
||||
flag.StringVar(&goarch, "goarch", runtime.GOARCH, "GOARCH")
|
||||
flag.StringVar(&goos, "goos", runtime.GOOS, "GOOS")
|
||||
flag.StringVar(&gocc, "cc", "", "CC")
|
||||
flag.StringVar(&libc, "libc", "", "LIBC")
|
||||
flag.StringVar(&buildTagsRaw, "build-tags", "", "Sets custom build tags")
|
||||
flag.BoolVar(&cgo, "cgo-enabled", cgo, "Enable cgo")
|
||||
flag.StringVar(&pkgArch, "pkg-arch", "", "PKG ARCH")
|
||||
flag.BoolVar(&race, "race", race, "Use race detector")
|
||||
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")
|
||||
flag.BoolVar(&isDev, "dev", isDev, "optimal for development, skips certain steps")
|
||||
flag.BoolVar(&skipRpmGen, "skipRpm", skipRpmGen, "skip rpm package generation (default: false)")
|
||||
flag.BoolVar(&skipDebGen, "skipDeb", skipDebGen, "skip deb package generation (default: false)")
|
||||
flag.BoolVar(&printGenVersion, "gen-version", printGenVersion, "generate Grafana version and output (default: false)")
|
||||
flag.Parse()
|
||||
|
||||
buildId = shortenBuildId(buildIdRaw)
|
||||
|
||||
readVersionFromPackageJson()
|
||||
|
||||
if pkgArch == "" {
|
||||
pkgArch = goarch
|
||||
}
|
||||
|
||||
if printGenVersion {
|
||||
printGeneratedVersion()
|
||||
return
|
||||
}
|
||||
|
||||
if len(buildTagsRaw) > 0 {
|
||||
buildTags = strings.Split(buildTagsRaw, ",")
|
||||
}
|
||||
|
||||
log.Printf("Version: %s, Linux Version: %s, Package Iteration: %s\n", version, linuxPackageVersion, linuxPackageIteration)
|
||||
|
||||
if flag.NArg() == 0 {
|
||||
log.Println("Usage: go run build.go build")
|
||||
return
|
||||
}
|
||||
|
||||
workingDir, _ = os.Getwd()
|
||||
|
||||
for _, cmd := range flag.Args() {
|
||||
switch cmd {
|
||||
case "setup":
|
||||
setup()
|
||||
|
||||
case "build-srv", "build-server":
|
||||
clean()
|
||||
doBuild("grafana-server", "./pkg/cmd/grafana-server", buildTags)
|
||||
|
||||
case "build-cli":
|
||||
clean()
|
||||
doBuild("grafana-cli", "./pkg/cmd/grafana-cli", buildTags)
|
||||
|
||||
case "build":
|
||||
//clean()
|
||||
for _, binary := range binaries {
|
||||
doBuild(binary, "./pkg/cmd/"+binary, buildTags)
|
||||
}
|
||||
|
||||
case "build-frontend":
|
||||
yarn("build")
|
||||
|
||||
case "sha-dist":
|
||||
shaFilesInDist()
|
||||
|
||||
case "latest":
|
||||
makeLatestDistCopies()
|
||||
|
||||
case "clean":
|
||||
clean()
|
||||
|
||||
default:
|
||||
log.Fatalf("Unknown command %q", cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeLatestDistCopies() {
|
||||
files, err := ioutil.ReadDir("dist")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create latest copies. Cannot read from /dist")
|
||||
}
|
||||
|
||||
latestMapping := map[string]string{
|
||||
"_amd64.deb": "dist/grafana_latest_amd64.deb",
|
||||
".x86_64.rpm": "dist/grafana-latest-1.x86_64.rpm",
|
||||
".linux-amd64.tar.gz": "dist/grafana-latest.linux-x64.tar.gz",
|
||||
".linux-amd64-musl.tar.gz": "dist/grafana-latest.linux-x64-musl.tar.gz",
|
||||
".linux-armv7.tar.gz": "dist/grafana-latest.linux-armv7.tar.gz",
|
||||
".linux-armv7-musl.tar.gz": "dist/grafana-latest.linux-armv7-musl.tar.gz",
|
||||
".linux-armv6.tar.gz": "dist/grafana-latest.linux-armv6.tar.gz",
|
||||
".linux-arm64.tar.gz": "dist/grafana-latest.linux-arm64.tar.gz",
|
||||
".linux-arm64-musl.tar.gz": "dist/grafana-latest.linux-arm64-musl.tar.gz",
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
for extension, fullName := range latestMapping {
|
||||
if strings.HasSuffix(file.Name(), extension) {
|
||||
runError("cp", path.Join("dist", file.Name()), fullName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readVersionFromPackageJson() {
|
||||
reader, err := os.Open("package.json")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to open package.json")
|
||||
return
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
jsonObj := map[string]interface{}{}
|
||||
jsonParser := json.NewDecoder(reader)
|
||||
|
||||
if err := jsonParser.Decode(&jsonObj); err != nil {
|
||||
log.Fatal("Failed to decode package.json")
|
||||
}
|
||||
|
||||
version = jsonObj["version"].(string)
|
||||
linuxPackageVersion = version
|
||||
linuxPackageIteration = ""
|
||||
|
||||
// handle pre version stuff (deb / rpm does not support semver)
|
||||
parts := strings.Split(version, "-")
|
||||
|
||||
if len(parts) > 1 {
|
||||
linuxPackageVersion = parts[0]
|
||||
linuxPackageIteration = parts[1]
|
||||
}
|
||||
|
||||
// add timestamp to iteration
|
||||
if includeBuildId {
|
||||
if buildId != "0" {
|
||||
linuxPackageIteration = fmt.Sprintf("%s%s", buildId, linuxPackageIteration)
|
||||
} else {
|
||||
linuxPackageIteration = fmt.Sprintf("%d%s", time.Now().Unix(), linuxPackageIteration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func yarn(params ...string) {
|
||||
runPrint(`yarn run`, params...)
|
||||
}
|
||||
|
||||
func genPackageVersion() string {
|
||||
if includeBuildId {
|
||||
return fmt.Sprintf("%v-%v", linuxPackageVersion, linuxPackageIteration)
|
||||
} else {
|
||||
return version
|
||||
}
|
||||
}
|
||||
|
||||
func setup() {
|
||||
args := []string{"install", "-v"}
|
||||
if goos == windows {
|
||||
args = append(args, "-buildmode=exe")
|
||||
}
|
||||
args = append(args, "./pkg/cmd/grafana-server")
|
||||
runPrint("go", args...)
|
||||
}
|
||||
|
||||
func printGeneratedVersion() {
|
||||
fmt.Print(genPackageVersion())
|
||||
}
|
||||
|
||||
func test(pkg string) {
|
||||
setBuildEnv()
|
||||
args := []string{"test", "-short", "-timeout", "60s"}
|
||||
if goos == windows {
|
||||
args = append(args, "-buildmode=exe")
|
||||
}
|
||||
args = append(args, pkg)
|
||||
runPrint("go", args...)
|
||||
}
|
||||
|
||||
func doBuild(binaryName, pkg string, tags []string) {
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("-%s", libc)
|
||||
}
|
||||
binary := fmt.Sprintf("./bin/%s-%s%s/%s", goos, goarch, libcPart, binaryName)
|
||||
if isDev {
|
||||
//don't include os/arch/libc in output path in dev environment
|
||||
binary = fmt.Sprintf("./bin/%s", binaryName)
|
||||
}
|
||||
|
||||
if goos == windows {
|
||||
binary += ".exe"
|
||||
}
|
||||
|
||||
if !isDev {
|
||||
rmr(binary, binary+".md5")
|
||||
}
|
||||
args := []string{"build", "-ldflags", ldflags()}
|
||||
if goos == windows {
|
||||
// Work around a linking error on Windows: "export ordinal too large"
|
||||
args = append(args, "-buildmode=exe")
|
||||
}
|
||||
if len(tags) > 0 {
|
||||
args = append(args, "-tags", strings.Join(tags, ","))
|
||||
}
|
||||
if race {
|
||||
args = append(args, "-race")
|
||||
}
|
||||
|
||||
args = append(args, "-o", binary)
|
||||
args = append(args, pkg)
|
||||
|
||||
if !isDev {
|
||||
setBuildEnv()
|
||||
runPrint("go", "version")
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("/%s", libc)
|
||||
}
|
||||
fmt.Printf("Targeting %s/%s%s\n", goos, goarch, libcPart)
|
||||
}
|
||||
|
||||
runPrint("go", args...)
|
||||
|
||||
if !isDev {
|
||||
// Create an md5 checksum of the binary, to be included in the archive for
|
||||
// automatic upgrades.
|
||||
err := md5File(binary)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ldflags() string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString("-w")
|
||||
b.WriteString(fmt.Sprintf(" -X main.version=%s", version))
|
||||
b.WriteString(fmt.Sprintf(" -X main.commit=%s", getGitSha()))
|
||||
b.WriteString(fmt.Sprintf(" -X main.buildstamp=%d", buildStamp()))
|
||||
b.WriteString(fmt.Sprintf(" -X main.buildBranch=%s", getGitBranch()))
|
||||
if v := os.Getenv("LDFLAGS"); v != "" {
|
||||
b.WriteString(fmt.Sprintf(" -extldflags \"%s\"", v))
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func rmr(paths ...string) {
|
||||
for _, path := range paths {
|
||||
log.Println("rm -r", path)
|
||||
os.RemoveAll(path)
|
||||
}
|
||||
}
|
||||
|
||||
func clean() {
|
||||
if isDev {
|
||||
return
|
||||
}
|
||||
|
||||
rmr("dist")
|
||||
rmr("tmp")
|
||||
rmr(filepath.Join(build.Default.GOPATH, fmt.Sprintf("pkg/%s_%s/github.com/grafana", goos, goarch)))
|
||||
}
|
||||
|
||||
func setBuildEnv() {
|
||||
os.Setenv("GOOS", goos)
|
||||
if goos == windows {
|
||||
// require windows >=7
|
||||
os.Setenv("CGO_CFLAGS", "-D_WIN32_WINNT=0x0601")
|
||||
}
|
||||
if goarch != "amd64" || goos != linux {
|
||||
// needed for all other archs
|
||||
cgo = true
|
||||
}
|
||||
if strings.HasPrefix(goarch, "armv") {
|
||||
os.Setenv("GOARCH", "arm")
|
||||
os.Setenv("GOARM", goarch[4:])
|
||||
} else {
|
||||
os.Setenv("GOARCH", goarch)
|
||||
}
|
||||
if cgo {
|
||||
os.Setenv("CGO_ENABLED", "1")
|
||||
}
|
||||
if gocc != "" {
|
||||
os.Setenv("CC", gocc)
|
||||
}
|
||||
}
|
||||
|
||||
func getGitBranch() string {
|
||||
v, err := runError("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
if err != nil {
|
||||
return "main"
|
||||
}
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func getGitSha() string {
|
||||
v, err := runError("git", "rev-parse", "--short", "HEAD")
|
||||
if err != nil {
|
||||
return "unknown-dev"
|
||||
}
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func buildStamp() int64 {
|
||||
// use SOURCE_DATE_EPOCH if set.
|
||||
if s, _ := strconv.ParseInt(os.Getenv("SOURCE_DATE_EPOCH"), 10, 64); s > 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
bs, err := runError("git", "show", "-s", "--format=%ct")
|
||||
if err != nil {
|
||||
return time.Now().Unix()
|
||||
}
|
||||
s, _ := strconv.ParseInt(string(bs), 10, 64)
|
||||
return s
|
||||
}
|
||||
|
||||
func runError(cmd string, args ...string) ([]byte, error) {
|
||||
ecmd := exec.Command(cmd, args...)
|
||||
bs, err := ecmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bytes.TrimSpace(bs), nil
|
||||
}
|
||||
|
||||
func runPrint(cmd string, args ...string) {
|
||||
log.Println(cmd, strings.Join(args, " "))
|
||||
ecmd := exec.Command(cmd, args...)
|
||||
ecmd.Stdout = os.Stdout
|
||||
ecmd.Stderr = os.Stderr
|
||||
err := ecmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func md5File(file string) error {
|
||||
fd, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
h := md5.New()
|
||||
_, err = io.Copy(h, fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := os.Create(file + ".md5")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(out, "%x\n", h.Sum(nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func shaFilesInDist() {
|
||||
filepath.Walk("./dist", func(path string, f os.FileInfo, err error) error {
|
||||
if path == "./dist" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !strings.Contains(path, ".sha256") {
|
||||
err := shaFile(path)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create sha file. error: %v\n", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func shaFile(file string) error {
|
||||
fd, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
h := sha256.New()
|
||||
_, err = io.Copy(h, fd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := os.Create(file + ".sha256")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(out, "%x\n", h.Sum(nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return out.Close()
|
||||
}
|
||||
|
||||
func shortenBuildId(buildId string) string {
|
||||
buildId = strings.Replace(buildId, "-", "", -1)
|
||||
if len(buildId) < 9 {
|
||||
return buildId
|
||||
}
|
||||
return buildId[0:8]
|
||||
}
|
||||
|
||||
@@ -172,12 +172,6 @@ idle_conn_timeout_seconds = 90
|
||||
# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request.
|
||||
send_user_header = false
|
||||
|
||||
# Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests.
|
||||
response_limit = 0
|
||||
|
||||
# Limits the number of rows that Grafana will process from SQL data sources.
|
||||
row_limit = 1000000
|
||||
|
||||
#################################### Analytics ###########################
|
||||
[analytics]
|
||||
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
|
||||
@@ -208,12 +202,6 @@ rudderstack_write_key =
|
||||
# Rudderstack data plane url, enabled only if rudderstack_write_key is also set
|
||||
rudderstack_data_plane_url =
|
||||
|
||||
# Application Insights connection string. Specify an URL string to enable this feature.
|
||||
application_insights_connection_string =
|
||||
|
||||
# Optional. Specifies an Application Insights endpoint URL where the endpoint string is wrapped in backticks ``.
|
||||
application_insights_endpoint_url =
|
||||
|
||||
#################################### Security ############################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
@@ -510,11 +498,9 @@ role_attribute_path =
|
||||
role_attribute_strict = false
|
||||
groups_attribute_path =
|
||||
id_token_attribute_name =
|
||||
team_ids_attribute_path =
|
||||
auth_url =
|
||||
token_url =
|
||||
api_url =
|
||||
teams_url =
|
||||
allowed_domains =
|
||||
team_ids =
|
||||
allowed_organizations =
|
||||
@@ -729,67 +715,11 @@ global_session = -1
|
||||
# global limit of alerts
|
||||
global_alert_rule = -1
|
||||
|
||||
#################################### Unified Alerting ####################
|
||||
[unified_alerting]
|
||||
# Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed.
|
||||
enabled = false
|
||||
|
||||
# Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
|
||||
disabled_orgs =
|
||||
|
||||
# Specify the frequency of polling for admin config changes.
|
||||
# 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.
|
||||
admin_config_poll_interval = 60s
|
||||
|
||||
# Specify the frequency of polling for Alertmanager config changes.
|
||||
# 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.
|
||||
alertmanager_config_poll_interval = 60s
|
||||
|
||||
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port.
|
||||
ha_listen_address = "0.0.0.0:9094"
|
||||
|
||||
# Explicit address/hostname and port to advertise other Grafana instances. The port is used for both TCP and UDP.
|
||||
ha_advertise_address = ""
|
||||
|
||||
# Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
|
||||
ha_peers = ""
|
||||
|
||||
# Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
|
||||
# be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
|
||||
# each instance wait before sending the notification to take into account replication lag.
|
||||
# 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.
|
||||
ha_peer_timeout = 15s
|
||||
|
||||
# The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
|
||||
# across cluster more quickly at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
ha_gossip_interval = 200ms
|
||||
|
||||
# The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
|
||||
# across larger clusters at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
ha_push_pull_interval = 60s
|
||||
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
execute_alerts = true
|
||||
|
||||
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
evaluation_timeout = 30s
|
||||
|
||||
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
max_attempts = 3
|
||||
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# 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_interval = 10s
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Disable legacy alerting engine & UI features
|
||||
# Disable alerting engine & UI features
|
||||
enabled = true
|
||||
|
||||
# Makes it possible to turn off alert execution but alerting UI is visible
|
||||
# Makes it possible to turn off alert rule execution but alerting UI is visible
|
||||
execute_alerts = true
|
||||
|
||||
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
@@ -965,7 +895,7 @@ app_tls_skip_verify_insecure = false
|
||||
# Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded.
|
||||
allow_loading_unsigned_plugins =
|
||||
# Enable or disable installing plugins directly from within Grafana.
|
||||
plugin_admin_enabled = true
|
||||
plugin_admin_enabled = false
|
||||
plugin_admin_external_manage_enabled = false
|
||||
plugin_catalog_url = https://grafana.com/grafana/plugins/
|
||||
|
||||
|
||||
@@ -178,12 +178,6 @@
|
||||
# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false.
|
||||
;send_user_header = false
|
||||
|
||||
# Limit the amount of bytes that will be read/accepted from responses of outgoing HTTP requests.
|
||||
;response_limit = 0
|
||||
|
||||
# Limits the number of rows that Grafana will process from SQL data sources.
|
||||
;row_limit = 1000000
|
||||
|
||||
#################################### Analytics ####################################
|
||||
[analytics]
|
||||
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
|
||||
@@ -489,14 +483,12 @@
|
||||
;auth_url = https://foo.bar/login/oauth/authorize
|
||||
;token_url = https://foo.bar/login/oauth/access_token
|
||||
;api_url = https://foo.bar/user
|
||||
;teams_url =
|
||||
;allowed_domains =
|
||||
;team_ids =
|
||||
;allowed_organizations =
|
||||
;role_attribute_path =
|
||||
;role_attribute_strict = false
|
||||
;groups_attribute_path =
|
||||
;team_ids_attribute_path =
|
||||
;tls_skip_verify_insecure = false
|
||||
;tls_client_cert =
|
||||
;tls_client_key =
|
||||
@@ -706,67 +698,11 @@
|
||||
# global limit of alerts
|
||||
;global_alert_rule = -1
|
||||
|
||||
#################################### Unified Alerting ####################
|
||||
[unified_alerting]
|
||||
#Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed.```
|
||||
;enabled = false
|
||||
|
||||
# Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
|
||||
;disabled_orgs =
|
||||
|
||||
# Specify the frequency of polling for admin config changes.
|
||||
# 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.
|
||||
;admin_config_poll_interval = 60s
|
||||
|
||||
# Specify the frequency of polling for Alertmanager config changes.
|
||||
# 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.
|
||||
;alertmanager_config_poll_interval = 60s
|
||||
|
||||
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
|
||||
;ha_listen_address = "0.0.0.0:9094"
|
||||
|
||||
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
|
||||
;ha_advertise_address = ""
|
||||
|
||||
# Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
|
||||
;ha_peers = ""
|
||||
|
||||
# Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
|
||||
# be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
|
||||
# each instance wait before sending the notification to take into account replication lag.
|
||||
# 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.
|
||||
;ha_peer_timeout = "15s"
|
||||
|
||||
# The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
|
||||
# across cluster more quickly at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
;ha_gossip_interval = "200ms"
|
||||
|
||||
# The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
|
||||
# across larger clusters at the expense of increased bandwidth usage.
|
||||
# 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.
|
||||
;ha_push_pull_interval = "60s"
|
||||
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
;execute_alerts = true
|
||||
|
||||
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;evaluation_timeout = 30s
|
||||
|
||||
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
;max_attempts = 3
|
||||
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# 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_interval = 10s
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Disable legacy alerting engine & UI features
|
||||
# Disable alerting engine & UI features
|
||||
;enabled = true
|
||||
|
||||
# Makes it possible to turn off alert execution but alerting UI is visible
|
||||
# Makes it possible to turn off alert rule execution but alerting UI is visible
|
||||
;execute_alerts = true
|
||||
|
||||
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
@@ -779,6 +715,7 @@
|
||||
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
|
||||
;concurrent_render_limit = 5
|
||||
|
||||
|
||||
# Default setting for alert calculation timeout. Default value is 30
|
||||
;evaluation_timeout_seconds = 30
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ This directory contains guides for contributors to the Grafana project.
|
||||
- [Contributing documentation](documentation.md)
|
||||
- [Developer guide](developer-guide.md)
|
||||
- [Triage issues](triage-issues.md)
|
||||
- [Merge a pull request](merge-pull-request.md)
|
||||
|
||||
The `style-guides` directory contains style guides for the Grafana software project and documentation.
|
||||
|
||||
|
||||
@@ -2,136 +2,71 @@
|
||||
|
||||
A Grafana _service_ encapsulates and exposes application logic to the rest of the application, through a set of related operations.
|
||||
|
||||
Grafana uses [Wire](https://github.com/google/wire), which is a code generation tool that automates connecting components using [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection). Dependencies between components are represented in Wire as function parameters, encouraging explicit initialization instead of global variables.
|
||||
Before a service can start communicating with the rest of Grafana, it needs to be registered in the _service registry_.
|
||||
|
||||
The service registry keeps track of all available services during runtime. On start-up, Grafana uses the registry to build a dependency graph of services, a _service graph_.
|
||||
|
||||
Even though the services in Grafana do different things, they share a number of patterns. To better understand how a service works, let's build one from scratch!
|
||||
|
||||
Before a service can start communicating with the rest of Grafana, it needs to be registered with Wire, see `ProvideService` factory function/method in the service example below and how it's being referenced in the wire.go example below.
|
||||
## Create a service
|
||||
|
||||
When Wire is run it will inspect the parameters of `ProvideService` and make sure that all it's dependencies has been wired up and initialized properly.
|
||||
To start building a service:
|
||||
|
||||
**Service example:**
|
||||
- Create a new Go package `mysvc` in the [pkg/services](/pkg/services) directory.
|
||||
- Create a `service.go` file inside your new directory.
|
||||
|
||||
All services need to implement the [Service](https://godoc.org/github.com/grafana/grafana/pkg/registry#Service) interface:
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
// Service service is the service responsible for X, Y and Z.
|
||||
type Service struct {
|
||||
logger log.Logger
|
||||
cfg *setting.Cfg
|
||||
sqlStore *sqlstore.SQLStore
|
||||
type MyService struct {
|
||||
}
|
||||
|
||||
// ProvideService provides Service as dependency for other services.
|
||||
func ProvideService(cfg *setting.Cfg, sqlStore *sqlstore.SQLStore) (*Service, error) {
|
||||
s := &Service{
|
||||
logger: log.New("service"),
|
||||
cfg: cfg,
|
||||
sqlStore: sqlStore,
|
||||
}
|
||||
|
||||
if s.IsDisabled() {
|
||||
// skip certain initialization logic
|
||||
return s, nil
|
||||
}
|
||||
|
||||
if err := s.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Service) init() error {
|
||||
// additional initialization logic...
|
||||
func (s *MyService) Init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsDisabled returns true if the service is disabled.
|
||||
//
|
||||
// Satisfies the registry.CanBeDisabled interface which will guarantee
|
||||
// that Run() is not called if the service is disabled.
|
||||
func (s *Service) IsDisabled() bool {
|
||||
return !s.cfg.IsServiceEnabled()
|
||||
}
|
||||
|
||||
// Run runs the service in the background.
|
||||
//
|
||||
// Satisfies the registry.BackgroundService interface which will
|
||||
// guarantee that the service can be registered as a background service.
|
||||
func (s *Service) Run(ctx context.Context) error {
|
||||
// background service logic...
|
||||
<-ctx.Done()
|
||||
return ctx.Err()
|
||||
}
|
||||
```
|
||||
|
||||
[wire.go](/pkg/server/wire.go)
|
||||
The `Init` method is used to initialize and configure the service to make it ready to use. Services that return an error halt Grafana's startup process and cause the error to be logged as it exits.
|
||||
|
||||
## Register a service
|
||||
|
||||
Every service needs to be registered with the application for it to be included in the service graph.
|
||||
|
||||
To register a service, call the `registry.RegisterService` function in an `init` function within your package.
|
||||
|
||||
```go
|
||||
// +build wireinject
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/google/wire"
|
||||
"github.com/grafana/grafana/pkg/example"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
)
|
||||
|
||||
var wireBasicSet = wire.NewSet(
|
||||
example.ProvideService,
|
||||
|
||||
)
|
||||
|
||||
var wireSet = wire.NewSet(
|
||||
wireBasicSet,
|
||||
sqlstore.ProvideService,
|
||||
)
|
||||
|
||||
var wireTestSet = wire.NewSet(
|
||||
wireBasicSet,
|
||||
)
|
||||
|
||||
func Initialize(cla setting.CommandLineArgs, opts Options, apiOpts api.ServerOptions) (*Server, error) {
|
||||
wire.Build(wireExtsSet)
|
||||
return &Server{}, nil
|
||||
func init() {
|
||||
registry.RegisterService(&MyService{})
|
||||
}
|
||||
|
||||
func InitializeForTest(cla setting.CommandLineArgs, opts Options, apiOpts api.ServerOptions, sqlStore *sqlstore.SQLStore) (*Server, error) {
|
||||
wire.Build(wireExtsTestSet)
|
||||
return &Server{}, nil
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Background services
|
||||
`init` functions are only run whenever a package is imported, so we also need to import the package in the application. In the `server.go` file under `pkg/server`, import the package we just created:
|
||||
|
||||
A background service is a service that runs in the background of the lifecycle between Grafana starts up and shutdown. If you want a service to be run in the background your Service should satisfy the `registry.BackgroundService` interface and add it as argument to the [ProvideBackgroundServiceRegistry](/pkg/server/backgroundsvcs/background_services.go) function and add it as argument to `NewBackgroundServiceRegistry` to register it as a background service.
|
||||
```go
|
||||
import _ "github.com/grafana/grafana/pkg/services/mysvc"
|
||||
```
|
||||
|
||||
You can see an example implementation above of the Run method.
|
||||
## Dependencies
|
||||
|
||||
## Disabled services
|
||||
Grafana uses the [inject](https://github.com/facebookgo/inject) package to inject dependencies during runtime.
|
||||
|
||||
If you want to guarantee that a background service is not run by Grafana when certain criteria is met/service is disabled your service should satisfy the `registry.CanBeDisabled` interface. When the service.IsDisabled method return false Grafana would not call the service.Run method.
|
||||
For example, to access the [bus](communication.md), add it to the `MyService` struct:
|
||||
|
||||
If you want to run certain initialization code if service is disabled or not, you need to handle this in the service factory method.
|
||||
```go
|
||||
type MyService struct {
|
||||
Bus bus.Bus `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
You can see an example implementation above of the IsDisabled method and custom initialization code when service is disabled.
|
||||
You can also inject other services in the same way:
|
||||
|
||||
## Run Wire / generate code
|
||||
```go
|
||||
type MyService struct {
|
||||
Service other.Service `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
When running `make run` it will call `make gen-go` on the first run. `gen-go` in turn will call the wire binary and generate the code in [wire_gen.go](/pkg/server/wire_gen.go). The wire binary is installed using [bingo](https://github.com/bwplotka/bingo) which will make sure to download and install all the tools needed, including the Wire binary at using a specific version.
|
||||
|
||||
## OSS vs Enterprise
|
||||
|
||||
Grafana OSS and Grafana Enterprise shares code and dependencies. Grafana Enterprise might need to override/extend certain OSS services.
|
||||
|
||||
There's a [wireexts_oss.go](/pkg/server/wireexts_oss.go) that has the `wireinject` and `oss` build tags as requirements. Here services that might have other implementations, e.g. Grafana Enterprise, can be registered.
|
||||
|
||||
Similarly, there's a wireexts_enterprise.go file in the Enterprise source code repository where other service implementations can be overridden/be registered.
|
||||
|
||||
To extend oss background service create a specific background interface for that type and inject that type to [ProvideBackgroundServiceRegistry](/pkg/server/backgroundsvcs/background_services.go) instead of the concrete type. Then add a wire binding for that interface in [wireexts_oss.go](/pkg/server/wireexts_oss.go) and in the enterprise wireexts file.
|
||||
> **Note:** Any injected dependency needs to be an exported field. Any unexported fields result in a runtime error.
|
||||
|
||||
## Methods
|
||||
|
||||
|
||||
@@ -55,17 +55,6 @@ Pull requests that create new UI components or modify existing ones must adhere
|
||||
- Use the [Grafana theme palette](/contribute/style-guides/themes.md) for styling. It contains colors with good contrast which aids accessibility.
|
||||
- Use [RTL](https://testing-library.com/docs/dom-testing-library/api-accessibility/) for writing unit tests. It helps to create accessible components.
|
||||
|
||||
Pull requests that introduce accessibility(a11y) errors:
|
||||
|
||||
We use [pa11y-ci](https://github.com/pa11y/pa11y-ci) to collect accessibility errors on [some URLs on the project](https://github.com/grafana/grafana/issues/36555), threshold errors are specified per URL.
|
||||
|
||||
If the contribution introduces new a11y errors, our continuous integration will fail, preventing you to merge on the main branch. In those cases there are two alternatives for moving forward:
|
||||
|
||||
- Check the error log on the pipeline step `test-a11y-frontend-pr`, identify what was the error, and fix it.
|
||||
- Locally run the command `yarn test:accessibility-report` that generates an HTML accessibility report, then go to the URL that contains your change, identify the error, and fix it. Keep in mind, a local Grafana instance needs to be running on `http://localhost:3000`.
|
||||
|
||||
You can also prevent introducing a11y errors by installing an a11y plugin in your browser, for example, axe DevTools, Accessibility Insights for Web among others.
|
||||
|
||||
### Backend-specific guidelines
|
||||
|
||||
Please refer to the [backend style guidelines](/contribute/style-guides/backend.md).
|
||||
@@ -113,8 +102,6 @@ For changes to panels, the area should be the name of the panel, suffixed with P
|
||||
- `GraphPanel: Fix legend sorting issues`
|
||||
- `Docs: Changed url to URL in all documentation files`
|
||||
|
||||
If you're unsure, please have a look at the existing [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md) for inspiration/guidance.
|
||||
|
||||
### Pull request titles
|
||||
|
||||
The Grafana team _squashes_ all commits into one when we accept a pull request. The title of the pull request becomes the subject line of the squashed commit message. We still encourage contributors to write informative commit messages, as they becomes a part of the Git commit body.
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# Merge a pull request
|
||||
|
||||
When a pull request has been reviewed and approved by at least one person and all checks have passed it's time to merge the pull request.
|
||||
|
||||
## Who is expected to merge a pull request?
|
||||
|
||||
Maintainers are responsible for merging all pull requests. If a maintainer has opened a pull request the general rule is that the same maintainer merges the pull request. If a non-maintainer has opened a pull request it's suggested that one of the maintainers reviewing the pull request merges the pull request.
|
||||
|
||||
## Checklist/summary
|
||||
|
||||
The following checklist/summary should give you a quick overview of what to ask/consider before merging a pull request.
|
||||
|
||||
- Reviewed and approved?
|
||||
- All checks passed?
|
||||
- Proper pull request title?
|
||||
- Milestone assigned?
|
||||
- Add to changelog/release notes?
|
||||
- Needs backporting?
|
||||
|
||||
## Before merge
|
||||
|
||||
Before actually merging a pull request there's a couple of things to take into consideration.
|
||||
|
||||
### Format the pull request title
|
||||
|
||||
Make sure that the pull request title is properly formatted according to `<Area>: <Summary>` and try to make the summary short and understandable for the community as a whole.
|
||||
|
||||
All commits in a pull request are squashed when merged and the pull request title will be the default subject line of the squashed commit message. It's also used for [changelog/release notes](#include-in-changelog-and-release-notes).
|
||||
|
||||
See [formatting guidelines](create-pull-request.md#formatting-guidelines) for more information.
|
||||
|
||||
### Assign a milestone
|
||||
|
||||
It's recommended to add a milestone to every pull request. This makes it easier to track what changes did go into a certain release. Without this you're basically left with going through git commits which could be a lot harder.
|
||||
|
||||
There's also various tooling built that in some cases requires a pull request to be assigned a milestone, for example [generating changelog/release notes](#include-in-changelog-and-release-notes).
|
||||
|
||||
### Include in changelog and release notes?
|
||||
|
||||
At Grafana we generate the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md) and [release notes](https://grafana.com/docs/grafana/latest/release-notes/) based on merged pull requests. Including changes in the changelog/release notes is very important to provide a somewhat complete picture of what changes a Grafana release actually includes.
|
||||
|
||||
Exactly what changes should be added to the changelog is hard to answer but some general guidance would be any change that you think would be interesting for the community as a whole. Use your best judgement and/or ask other maintainers for advice.
|
||||
|
||||
There's a GitHub action available in the repository named [Update changelog](https://github.com/grafana/grafana/blob/main/.github/workflows/update-changelog.yml) that can manually be triggered to re-generate the changelog and release notes for any release.
|
||||
|
||||
To include a pull request in the changelog/release notes the general rule of thumb is that a milestone should be assigned and labeled with `add to changelog`.
|
||||
|
||||
The changelog/release notes are divided into sections and here's a description of how you make a pull request show up in a certain section.
|
||||
|
||||
**Features and enhancements:**
|
||||
|
||||
Milestone assigned and labeled with `add to changelog` and any of the other section rules don't apply.
|
||||
|
||||
**Bug fixes:**
|
||||
|
||||
Milestone assigned and labeled with `add to changelog` and either labeled with `type/bug` or the pull request title contains `fix` or `fixes`.
|
||||
|
||||
**Plugin development fixes & changes:**
|
||||
|
||||
Milestone assigned and labeled with `area/grafana/toolkit`, `area/grafana/ui` or `area/grafana/runtime`.
|
||||
|
||||
**Deprecations:**
|
||||
|
||||
In case the pull request introduces a deprecation you should document this. Label the pull request with `add to changelog` and use the following template at the end of the pull request description describing the deprecation change.
|
||||
|
||||
```md
|
||||
# Deprecation notice
|
||||
|
||||
<Deprecation description>
|
||||
```
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
In case the pull request introduces a breaking change you should document this. Label the pull request with `add to changelog` and `breaking change` and use the following template at the end of the pull request description describing the breaking change.
|
||||
|
||||
```md
|
||||
# Release notice breaking change
|
||||
|
||||
<Breaking change description>
|
||||
```
|
||||
|
||||
### Should the pull request be backported?
|
||||
|
||||
If your pull request has changes that need to go into one or several existing release branches you need to backport the changes. Please refer to [Backport PR](.github/bot.md#backport-pr) for detailed instructions.
|
||||
|
||||
Some examples when backport is required:
|
||||
|
||||
- The change needs to be released in the next upcoming patch release, e.g. v8.1.3, so you have to backport it, e.g. into the v8.1.x release branch.
|
||||
- You have a change to be released in the next major/minor release, e.g. v8.0.0, and there's already a release branch, e.g. v8.0.x, you have to backport it, e.g. into the v8.0.x release branch.
|
||||
- The change includes documentation changes that needs to be updated for one or multiple older versions, then you have to backport it to each release branch.
|
||||
|
||||
Some examples when backport is not required:
|
||||
|
||||
- The change is supposed to be released in the next major/minor release, e.g. v8.0.0, but the release branch, e.g. v8.0.x, has not yet been created.
|
||||
|
||||
> **Note:** You can still backport a pull request after it's been merged.
|
||||
|
||||
## Doing the actual merge
|
||||
|
||||
Time to actually merge the pull request changes. All commits in a pull request are squashed, hence the GitHub `Squash and merge` button is used to initialize the merge.
|
||||
|
||||
This will present you with options allowing you to optionally change the commit message before merging. Please remember that developers might use the commit information when reviewing changes of files, doing git blame and resolving merge conflicts etc., trying to quickly figure out what the actual change was. But there's not really any best practices around this, the following is an attempt to bring some guidance.
|
||||
|
||||
Do:
|
||||
|
||||
- Make sure the pull request title is formatted properly before merging, this will automatically give you a good and short summary of the commit/change.
|
||||
- Leave `Co-authored-by:` lines as is so that co-authors will be accounted for the contribution.
|
||||
- Remove any commit information that doesn't bring any context to the change.
|
||||
|
||||
Consider:
|
||||
|
||||
- Add any references to issues that the pull request fixes/closes/references to ease giving quick context to things. Doing this allows cross-reference between the commit and referenced issue(s).
|
||||
|
||||
Finalize the merge by clicking on the `Confirm squash and merge` button.
|
||||
|
||||
## After the merge
|
||||
|
||||
Make sure to close any referenced/related issues. It's recommended to assign the same milestone on the issues that the pull request fixes/closes, but not required.
|
||||
@@ -4,13 +4,13 @@ This style guide applies to all documentation created for Grafana products.
|
||||
|
||||
For information about how to write technical documentation, refer to the following resources:
|
||||
|
||||
- [Google Technical Writing courses](https://developers.google.com/tech-writing)
|
||||
- [Divio documentation system](https://documentation.divio.com/)
|
||||
- [Vue writing principles](https://v3.vuejs.org/guide/contributing/writing-guide.html#principles)
|
||||
* [Google Technical Writing courses](https://developers.google.com/tech-writing)
|
||||
* [Divio documentation system](https://documentation.divio.com/)
|
||||
* [Vue writing principles](https://v3.vuejs.org/guide/contributing/writing-guide.html#principles)
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
## Published guides
|
||||
|
||||
@@ -46,14 +46,10 @@ Avoid _master_ or _slave_.
|
||||
|
||||
## Grafana-specific style
|
||||
|
||||
The following guidelines are specific to Grafana documentation. For the most part, these are _guidelines_ are not rigid rules. If you have questions, then please ask in the #docs channel of Grafana Slack.
|
||||
The following guidelines are specific to Grafana documentation. For the most part, these are *guidelines* are not rigid rules. If you have questions, then please ask in the #docs channel of Grafana Slack.
|
||||
|
||||
### General
|
||||
|
||||
Per the [Voice and tone](https://developers.google.com/style/tone) section of the Google developer documentation style guide:
|
||||
|
||||
> In your documents, aim for a voice and tone that's conversational, friendly, and respectful without being overly colloquial or frivolous; a voice that's casual and natural and approachable, not pedantic or pushy. Try to sound like a knowledgeable friend who understands what the developer wants to do.
|
||||
|
||||
- Use active voice:
|
||||
- Active: Grafana displays the heatmap visualization.
|
||||
- Passive: The heatmap visualization is displayed.
|
||||
@@ -108,7 +104,6 @@ However, sometimes we need to use headings as numbered steps. This is mostly in
|
||||
If that is the case, then use the following format for headings:
|
||||
|
||||
##### Step 1. Install the software
|
||||
|
||||
##### Step 2. Run the software
|
||||
|
||||
### Images
|
||||
@@ -154,7 +149,6 @@ In general, "integration" is not capitalized. Only capitalize it if it is capita
|
||||
The first letter of the name of an integration is always capitalized, even if the original named source is lowercase.
|
||||
|
||||
**Examples:**
|
||||
|
||||
- MySQL Integration
|
||||
- CockroachDB Integration
|
||||
- Etcd Integration
|
||||
@@ -218,20 +212,16 @@ Warnings tell the user not to do something. For example:
|
||||
- Do not assume everyone is using Linux. Make sure instructions include enough information for Windows and Mac users to successfully complete procedures.
|
||||
|
||||
- Do not add `$` before commands. Make it easy for users to copy and paste commands.
|
||||
|
||||
- **Right:** `sudo yum install grafana`
|
||||
- **Wrong:** `$ sudo yum install grafana`
|
||||
|
||||
- Include `sudo` before commands that require `sudo` to work.
|
||||
|
||||
For terminal examples and Grafana configuration, use a `bash` code block:
|
||||
|
||||
```bash
|
||||
sudo yum install grafana
|
||||
```
|
||||
|
||||
For HTTP request/response, use an `http` code block:
|
||||
|
||||
```http
|
||||
GET /api/dashboards/id/1/permissions HTTP/1.1
|
||||
Accept: application/json
|
||||
@@ -269,7 +259,6 @@ Two words if used as a verb, one word if used as a noun.
|
||||
Two words, not one.
|
||||
|
||||
**Exceptions:**
|
||||
|
||||
- "datasource" used as an identifier
|
||||
- "datasource" in a URL
|
||||
- Use "data source" instead of "datasource" unless used as an identifier, in code, or as part of a URL.
|
||||
@@ -278,8 +267,7 @@ Two words, not one.
|
||||
|
||||
#### display (verb)
|
||||
|
||||
_Display_ is a transitive verb, which means it always needs a direct object.
|
||||
|
||||
*Display* is a transitive verb, which means it always needs a direct object.
|
||||
- Correct, active voice: Grafana displays your list of active alarms.
|
||||
- Correct, but passive voice: Your list of active alarms is displayed.
|
||||
- Incorrect: The list of active alarms displays.
|
||||
@@ -339,7 +327,6 @@ Two words, not one.
|
||||
**Incorrect:** webserver
|
||||
|
||||
### MS SQL Server
|
||||
|
||||
Always use "MS SQL" when referring to MS SQL Server application.
|
||||
|
||||
Incorrect UI spellings will be corrected in a later version of Grafana.
|
||||
|
||||
@@ -23,13 +23,20 @@ Inspired by https://martinfowler.com/bliki/PageObject.html
|
||||
Let's start with a simple [JSX](https://reactjs.org/docs/introducing-jsx.html) example containing a single input field that we want to populate during our E2E test:
|
||||
|
||||
```jsx
|
||||
<input className="gf-form-input login-form-input" type="text" />
|
||||
<input
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
```
|
||||
|
||||
We _could_ target the field with a CSS selector like `.gf-form-input.login-form-input` but that would be brittle as style changes occur frequently. Furthermore there is nothing that signals to future developers that this input is part of an E2E test. At Grafana, we use `aria-label` attributes as our preferred way of defining selectors instead of [`data-*`](https://mdn.io/docs/Web/HTML/Global_attributes/data-*) as they also aid in [accessibility](https://mdn.io/docs/Learn/Accessibility/What_is_accessibility):
|
||||
|
||||
```jsx
|
||||
<input aria-label="Username input field" className="gf-form-input login-form-input" type="text" />
|
||||
<input
|
||||
aria-label="Username input field"
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
```
|
||||
|
||||
The next step is to create a `Page` representation in our E2E 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:
|
||||
@@ -38,6 +45,7 @@ The next step is to create a `Page` representation in our E2E framework to glue
|
||||
export const Login = {
|
||||
// Called via `Login.visit()`
|
||||
url: '/login',
|
||||
|
||||
// Called via `Login.username()`
|
||||
username: 'Username input field',
|
||||
};
|
||||
@@ -59,7 +67,11 @@ Now that we have a `Page` called `Login` in our `Pages` const we can use that to
|
||||
```jsx
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
<input aria-label={selectors.pages.Login.username} className="gf-form-input login-form-input" type="text" />;
|
||||
<input
|
||||
aria-label={selectors.pages.Login.username}
|
||||
className="gf-form-input login-form-input"
|
||||
type="text"
|
||||
/>
|
||||
```
|
||||
|
||||
The last step in our example is to use our `Login` page as part of a test.
|
||||
@@ -74,7 +86,9 @@ describe('Login test', () => {
|
||||
e2e.pages.Login.visit();
|
||||
// To prevent flaky tests, always do a `.should` on any selector that you expect to be in the DOM.
|
||||
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
|
||||
e2e.pages.Login.username().should('be.visible').type('admin');
|
||||
e2e.pages.Login.username()
|
||||
.should('be.visible')
|
||||
.type('admin');
|
||||
});
|
||||
});
|
||||
```
|
||||
@@ -140,28 +154,25 @@ describe('List test', () => {
|
||||
e2e.pages.DataSources.visit();
|
||||
// To prevent flaky tests, always do a .should on any selector that you expect to be in the DOM.
|
||||
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
|
||||
e2e.pages.DataSources.dataSources('B').should('be.visible').click();
|
||||
e2e.pages.DataSources.dataSources('B')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Aria-Labels vs data-testid
|
||||
|
||||
Our selectors are set up to work with both aria-labels and data-testid attributes. Aria-labels help assistive technologies such as screenreaders identify interactive elements of a page for our users.
|
||||
Our selectors are set up to work with both aria-labels and data-testid attributes. Aria-labels help assistive technologies such as screenreaders identify interactive elements of a page for our users.
|
||||
|
||||
A good example of a time to use an aria-label might be if you have a button with an X to close:
|
||||
|
||||
```
|
||||
<button aria-label="close">X<button>
|
||||
```
|
||||
|
||||
It might be clear visually that the X closes the modal, but audibly it would not be clear for example.
|
||||
|
||||
```
|
||||
<button aria-label="close">Close<button>
|
||||
```
|
||||
|
||||
The example might read aloud to a user as "Close, Close" or something similar.
|
||||
The above example for example might read aloud to a user "Close, Close" or something similar.
|
||||
|
||||
However adding aria-labels to elements that are already clearly labeled or not interactive can be confusing and redundant for users with assistive technologies.
|
||||
|
||||
@@ -174,18 +185,16 @@ In such cases rather than adding unnecessary aria-labels to components so as to
|
||||
We have added support for this in our selectors, to use:
|
||||
|
||||
Prefix your selector string with "data-testid":
|
||||
|
||||
```typescript
|
||||
export const Components = {
|
||||
Login: {
|
||||
openButton: 'open-button', // this would look for an aria-label
|
||||
closeButton: 'data-testid modal-close-button', // this would look for a data-testid
|
||||
openButton: "data-testid-open", // this would look for a data-testid
|
||||
closeButton: "close-button" // this would look for an aria-label
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
and in your component, import the selectors and add the data test id:
|
||||
|
||||
```
|
||||
<button data-testid={Selectors.Components.Login.closeButton}>
|
||||
```
|
||||
<button data-testid={Selectors.Components.Login.openButton}>
|
||||
```
|
||||
@@ -5,7 +5,6 @@ Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/jav
|
||||
## Table of Contents
|
||||
|
||||
- [Frontend Style Guide](#frontend-style-guide)
|
||||
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Basic rules](#basic-rules)
|
||||
- [Naming conventions](#naming-conventions)
|
||||
@@ -29,12 +28,12 @@ Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/jav
|
||||
- [Linting](#linting)
|
||||
- [React](#react)
|
||||
- [Props](#props)
|
||||
- [Name callback props and handlers with an "on" prefix.](#name-callback-props-and-handlers-with-an-on-prefix)
|
||||
- [React Component definitions](#react-component-definitions)
|
||||
- [React Component constructor](#react-component-constructor)
|
||||
- [React Component defaultProps](#react-component-defaultprops)
|
||||
- [Name callback props and handlers with an "on" prefix.](#name-callback-props-and-handlers-with-an-on-prefix)
|
||||
- [React Component definitions](#react-component-definitions)
|
||||
- [React Component constructor](#react-component-constructor)
|
||||
- [React Component defaultProps](#react-component-defaultprops)
|
||||
- [State management](#state-management)
|
||||
|
||||
|
||||
- [Proposal for removing or replacing Angular dependencies](https://github.com/grafana/grafana/pull/23048)
|
||||
|
||||
## Basic rules
|
||||
@@ -195,12 +194,12 @@ _SASS styles are deprecated. Please migrate to Emotion whenever you need to modi
|
||||
|
||||
### Typing
|
||||
|
||||
In general, you should let Typescript infer the types so that there's no need to explicitly define type for each variable.
|
||||
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
|
||||
// Typescript needs to know type of arrays or objects otherwise it would infer it as array of any
|
||||
|
||||
// bad
|
||||
const stringArray = [];
|
||||
@@ -209,7 +208,7 @@ const stringArray = [];
|
||||
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.
|
||||
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.
|
||||
|
||||
@@ -217,18 +216,18 @@ Specify function return types explicitly in new code. This improves readability
|
||||
// bad
|
||||
function transform(value?: string) {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
return applyTransform(value);
|
||||
}
|
||||
return applyTransform(value)
|
||||
};
|
||||
|
||||
// good
|
||||
function transform(value?: string): TransformedValue | undefined {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
return undefined
|
||||
}
|
||||
return applyTransform(value);
|
||||
}
|
||||
return applyTransform(value)
|
||||
};
|
||||
```
|
||||
|
||||
### File and directory naming conventions
|
||||
@@ -245,8 +244,6 @@ For files exporting multiple utility functions, use the name that describes the
|
||||
- Use `reducers.ts` Redux reducers.
|
||||
- Use `*.test.ts(x)` for test files.
|
||||
|
||||
- Use kebab case for directory names: lowercase, words delimited by hyphen ( `-` ). For example, `features/new-important-feature/utils.ts`.
|
||||
|
||||
### Code organization
|
||||
|
||||
Organize your code in a directory that encloses feature code:
|
||||
|
||||
@@ -120,7 +120,7 @@ Example use cases:
|
||||
|
||||
### Typography
|
||||
|
||||
For font family, font sizes and line heights use the variables under `theme.typography`.
|
||||
For font family, font sizes and line heights use the variables under `theme.typography`.
|
||||
|
||||
#### Using `ThemeContext` directly
|
||||
|
||||
|
||||
212
cue/data/gen.cue
Normal file
212
cue/data/gen.cue
Normal file
@@ -0,0 +1,212 @@
|
||||
package grafanaschema
|
||||
|
||||
import "github.com/grafana/grafana/cue/scuemata"
|
||||
|
||||
Family: scuemata.#Family & {
|
||||
lineages: [
|
||||
[
|
||||
{ // 0.0
|
||||
// Unique numeric identifier for the dashboard.
|
||||
// TODO must isolate or remove identifiers local to a Grafana instance...?
|
||||
id?: number
|
||||
// Unique dashboard identifier that can be generated by anyone. string (8-40)
|
||||
uid?: string
|
||||
// Title of dashboard.
|
||||
title?: string
|
||||
// Description of dashboard.
|
||||
description?: string
|
||||
|
||||
gnetId?: string
|
||||
// Tags associated with dashboard.
|
||||
tags?: [...string]
|
||||
// Theme of dashboard.
|
||||
style: *"light" | "dark"
|
||||
// Timezone of dashboard,
|
||||
timezone?: *"browser" | "utc"
|
||||
// Whether a dashboard is editable or not.
|
||||
editable: bool | *true
|
||||
// 0 for no shared crosshair or tooltip (default).
|
||||
// 1 for shared crosshair.
|
||||
// 2 for shared crosshair AND shared tooltip.
|
||||
graphTooltip: >=0 & <=2 | *0
|
||||
// Time range for dashboard, e.g. last 6 hours, last 7 days, etc
|
||||
time?: {
|
||||
from: string | *"now-6h"
|
||||
to: string | *"now"
|
||||
}
|
||||
// Timepicker metadata.
|
||||
timepicker?: {
|
||||
// Whether timepicker is collapsed or not.
|
||||
collapse: bool | *false
|
||||
// Whether timepicker is enabled or not.
|
||||
enable: bool | *true
|
||||
// Whether timepicker is visible or not.
|
||||
hidden: bool | *false
|
||||
// Selectable intervals for auto-refresh.
|
||||
refresh_intervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
|
||||
}
|
||||
// Templating.
|
||||
templating?: list: [...{...}]
|
||||
// Annotations.
|
||||
annotations?: list: [...{
|
||||
builtIn: number | *0
|
||||
// Datasource to use for annotation.
|
||||
datasource: string
|
||||
// Whether annotation is enabled.
|
||||
enable?: bool | *true
|
||||
// Whether to hide annotation.
|
||||
hide?: bool | *false
|
||||
// Annotation icon color.
|
||||
iconColor?: string
|
||||
// Name of annotation.
|
||||
name?: string
|
||||
type: string | *"dashboard"
|
||||
// Query for annotation data.
|
||||
rawQuery?: string
|
||||
showIn: number | *0
|
||||
}]
|
||||
// Auto-refresh interval.
|
||||
refresh?: string
|
||||
// Version of the JSON schema, incremented each time a Grafana update brings
|
||||
// changes to said schema.
|
||||
schemaVersion: number | *25
|
||||
// Version of the dashboard, incremented each time the dashboard is updated.
|
||||
version?: number
|
||||
panels?: [...#Panel]
|
||||
|
||||
// Dashboard panels. Panels are canonically defined inline
|
||||
// because they share a version timeline with the dashboard
|
||||
// schema; they do not vary independently. We create a separate,
|
||||
// synthetic Family to represent them in Go, for ease of generating
|
||||
// e.g. JSON Schema.
|
||||
#Panel: {
|
||||
// The panel plugin type id.
|
||||
type: !=""
|
||||
|
||||
// Internal - the exact major and minor versions of the panel plugin
|
||||
// schema. Hidden and therefore not a part of the data model, but
|
||||
// expected to be filled with panel plugin schema versions so that it's
|
||||
// possible to figure out which schema version matched on a successful
|
||||
// unification.
|
||||
// _pv: { maj: int, min: int }
|
||||
// The major and minor versions of the panel plugin for this schema.
|
||||
// TODO 2-tuple list instead of struct?
|
||||
panelSchema?: { maj: number, min: number }
|
||||
|
||||
// Panel title.
|
||||
title?: string
|
||||
// Description.
|
||||
description?: string
|
||||
// Whether to display the panel without a background.
|
||||
transparent: bool | *false
|
||||
// Name of default datasource.
|
||||
datasource?: string
|
||||
// Grid position.
|
||||
gridPos?: {
|
||||
// Panel
|
||||
h: number & >0 | *9
|
||||
// Panel
|
||||
w: number & >0 & <=24 | *12
|
||||
// Panel x
|
||||
x: number & >=0 & <24 | *0
|
||||
// Panel y
|
||||
y: number & >=0 | *0
|
||||
// true if fixed
|
||||
static?: bool
|
||||
}
|
||||
// Panel links.
|
||||
// links?: [..._panelLink]
|
||||
// Name of template variable to repeat for.
|
||||
repeat?: string
|
||||
// Direction to repeat in if 'repeat' is set.
|
||||
// "h" for horizontal, "v" for vertical.
|
||||
repeatDirection: *"h" | "v"
|
||||
// Schema for panel targets is specified by datasource
|
||||
// plugins. We use a placeholder definition, which the Go
|
||||
// schema loader either left open/as-is with the Base
|
||||
// variant of the Dashboard and Panel families, or filled
|
||||
// with types derived from plugins in the Instance variant.
|
||||
// When working directly from CUE, importers can extend this
|
||||
// type directly to achieve the same effect.
|
||||
targets?: [...{...}]
|
||||
|
||||
// The values depend on panel type
|
||||
options: {...}
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
// The display value for this field. This supports template variables blank is auto
|
||||
displayName?: string
|
||||
|
||||
// This can be used by data sources that return and explicit naming structure for values and labels
|
||||
// When this property is configured, this value is used rather than the default naming strategy.
|
||||
displayNameFromDS?: string
|
||||
|
||||
// Human readable field metadata
|
||||
description?: string
|
||||
|
||||
// An explict path to the field in the datasource. When the frame meta includes a path,
|
||||
// This will default to `${frame.meta.path}/${field.name}
|
||||
//
|
||||
// When defined, this value can be used as an identifier within the datasource scope, and
|
||||
// may be used to update the results
|
||||
path?: string
|
||||
|
||||
// True if data source can write a value to the path. Auth/authz are supported separately
|
||||
writeable?: bool
|
||||
|
||||
// True if data source field supports ad-hoc filters
|
||||
filterable?: bool
|
||||
|
||||
// Numeric Options
|
||||
unit?: string
|
||||
|
||||
// Significant digits (for display)
|
||||
decimals?: number
|
||||
|
||||
min?: number
|
||||
max?: number
|
||||
|
||||
// // Convert input values into a display string
|
||||
// mappings?: ValueMapping[];
|
||||
|
||||
// // Map numeric values to states
|
||||
// thresholds?: ThresholdsConfig;
|
||||
|
||||
// // Map values to a display color
|
||||
// color?: FieldColor;
|
||||
|
||||
// // Used when reducing field values
|
||||
// nullValueMode?: NullValueMode;
|
||||
|
||||
// // The behavior when clicking on a result
|
||||
links?: [...]
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string
|
||||
|
||||
// Can always exist. Valid fields within this are
|
||||
// defined by the panel plugin - that's the
|
||||
// PanelFieldConfig that comes from the plugin.
|
||||
custom?: {}
|
||||
}
|
||||
overrides: [...{
|
||||
matcher: {
|
||||
id: string | *""
|
||||
options?: _
|
||||
}
|
||||
properties: [...{
|
||||
id: string | *""
|
||||
value?: _
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
#Latest: {
|
||||
#Dashboard: Family.latest
|
||||
#Panel: Family.latest._Panel
|
||||
}
|
||||
@@ -8,10 +8,10 @@ package scuemata
|
||||
// the larger Dashboard schema.
|
||||
#PanelSchema: {
|
||||
// Defines plugin specific options for a panel
|
||||
PanelOptions: {...} @cuetsy(kind="interface")
|
||||
PanelOptions: {...}
|
||||
|
||||
// Define the custom properties that exist within standard field config
|
||||
PanelFieldConfig?: {...} @cuetsy(kind="interface")
|
||||
PanelFieldConfig?: {...}
|
||||
|
||||
// Panels may define their own types
|
||||
...
|
||||
|
||||
@@ -14,7 +14,6 @@ package scuemata
|
||||
// its position in the list of lineages - e.g., 0.0 corresponds to the first
|
||||
// schema in the first lineage.
|
||||
#Family: {
|
||||
compose?: {...}
|
||||
lineages: [#Lineage, ...#Lineage]
|
||||
migrations: [...#Migration]
|
||||
let lseq = lineages[len(lineages)-1]
|
||||
|
||||
93
cue/ui/gen.cue
Normal file
93
cue/ui/gen.cue
Normal file
@@ -0,0 +1,93 @@
|
||||
package grafanaschema
|
||||
|
||||
TableCellDisplayMode: {
|
||||
Auto: "auto",
|
||||
ColorText: "color-text",
|
||||
ColorBackground: "color-background",
|
||||
GradientGauge: "gradient-gauge",
|
||||
LcdGauge: "lcd-gauge",
|
||||
JSONView: "json-view",
|
||||
BasicGauge: "basic",
|
||||
Image: "image",
|
||||
} @cuetsy(targetType="enum")
|
||||
|
||||
TableFieldOptions: {
|
||||
width?: number
|
||||
align: FieldTextAlignment | *"auto"
|
||||
displayMode: TableCellDisplayMode | *"auto"
|
||||
hidden?: bool // ?? default is missing or false ??
|
||||
} @cuetsy(targetType="interface")
|
||||
|
||||
TableSortByFieldState: {
|
||||
displayName: string
|
||||
desc?: bool
|
||||
} @cuetsy(targetType="interface")
|
||||
|
||||
TooltipDisplayMode: "single" | "multi" | "none" @cuetsy(targetType="enum")
|
||||
FieldTextAlignment: "auto" | "left" | "right" | "center" @cuetsy(targetType="type")
|
||||
AxisPlacement: "auto" | "top" | "right" | "bottom" | "left" | "hidden" @cuetsy(targetType="enum")
|
||||
PointVisibility: "auto" | "never" | "always" @cuetsy(targetType="enum")
|
||||
DrawStyle: "line" | "bars" | "points" @cuetsy(targetType="enum")
|
||||
LineInterpolation: "linear" | "smooth" | "stepBefore" | "stepAfter" @cuetsy(targetType="enum")
|
||||
ScaleDistribution: "linear" | "log" @cuetsy(targetType="enum")
|
||||
GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(targetType="enum")
|
||||
LineStyle: {
|
||||
fill?: "solid" | "dash" | "dot" | "square"
|
||||
dash?: [number]
|
||||
} @cuetsy(targetType="interface")
|
||||
LineConfig: {
|
||||
lineColor?: string
|
||||
lineWidth?: number
|
||||
lineInterpolation?: LineInterpolation
|
||||
lineStyle?: LineStyle
|
||||
spanNulls?: bool
|
||||
} @cuetsy(targetType="interface")
|
||||
FillConfig: {
|
||||
fillColor?: string
|
||||
fillOpacity?: number
|
||||
fillBelowTo?: string
|
||||
} @cuetsy(targetType="interface")
|
||||
PointsConfig: {
|
||||
showPoints?: PointVisibility
|
||||
pointSize?: number
|
||||
pointColor?: string
|
||||
pointSymbol?: string
|
||||
} @cuetsy(targetType="interface")
|
||||
ScaleDistributionConfig: {
|
||||
type: ScaleDistribution
|
||||
log?: number
|
||||
} @cuetsy(targetType="interface")
|
||||
AxisConfig: {
|
||||
axisPlacement?: AxisPlacement
|
||||
axisLabel?: string
|
||||
axisWidth?: number
|
||||
axisSoftMin?: number
|
||||
axisSoftMax?: number
|
||||
scaleDistribution?: ScaleDistributionConfig
|
||||
} @cuetsy(targetType="interface")
|
||||
HideSeriesConfig: {
|
||||
tooltip: bool
|
||||
legend: bool
|
||||
graph: bool
|
||||
} @cuetsy(targetType="interface")
|
||||
LegendPlacement: "bottom" | "right" @cuetsy(targetType="type")
|
||||
LegendDisplayMode: "list" | "table" | "hidden" @cuetsy(targetType="enum")
|
||||
TableFieldOptions: {
|
||||
width?: number
|
||||
align: FieldTextAlignment | *"auto"
|
||||
displayMode: TableCellDisplayMode | *"auto"
|
||||
hidden?: bool
|
||||
} @cuetsy(targetType="interface")
|
||||
GraphFieldConfig: LineConfig & FillConfig & PointsConfig & AxisConfig & {
|
||||
drawStyle?: DrawStyle
|
||||
gradientMode?: GraphGradientMode
|
||||
hideFrom?: HideSeriesConfig
|
||||
} @cuetsy(targetType="interface")
|
||||
VizLegendOptions: {
|
||||
displayMode: LegendDisplayMode
|
||||
placement: LegendPlacement
|
||||
calcs: [string]
|
||||
} @cuetsy(targetType="interface")
|
||||
VizTooltipOptions: {
|
||||
mode: TooltipDisplayMode
|
||||
} @cuetsy(targetType="interface")
|
||||
@@ -55,9 +55,6 @@ Jaeger block runs both Jaeger and Loki container. Loki container sends traces to
|
||||
| 1.0 | graphite1 | 8280 | 2203 | 2203 |
|
||||
| 0.9 | graphite09 | 8380 | 2303 | 2303 |
|
||||
|
||||
## Debugging setup in VS Code
|
||||
An example of launch.json is provided in `devenv/vscode/launch.json`. It basically does what Makefile and .bra.toml do. The 'program' field is set to the folder name so VS Code loads all *.go files in it instead of just main.go.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Containers that read from log files fail to start (Mac OS)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 3151,
|
||||
"links": [],
|
||||
@@ -89,7 +90,9 @@
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "CPU per host",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
@@ -98,24 +101,33 @@
|
||||
},
|
||||
"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
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -187,7 +199,9 @@
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Login Count per host",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
@@ -196,24 +210,33 @@
|
||||
},
|
||||
"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
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -232,4 +255,4 @@
|
||||
"title": "Datasource tests - OpenTSDB v2.3",
|
||||
"uid": "rZRUGik7k",
|
||||
"version": 3
|
||||
}
|
||||
}
|
||||
@@ -511,6 +511,7 @@
|
||||
},
|
||||
"id": 41,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -612,6 +613,7 @@
|
||||
},
|
||||
"id": 42,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -714,6 +716,7 @@
|
||||
},
|
||||
"id": 32,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -816,6 +819,7 @@
|
||||
},
|
||||
"id": 44,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -2066,6 +2070,7 @@
|
||||
"id": 29,
|
||||
"maxDataPoints": 500,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [
|
||||
"last"
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 625,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 24,
|
||||
@@ -36,10 +38,13 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"transparent": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
@@ -102,7 +107,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -160,6 +166,7 @@
|
||||
"type": "state-timeline"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 15,
|
||||
@@ -200,7 +207,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue"
|
||||
"color": "blue",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
@@ -259,9 +267,10 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
@@ -284,7 +293,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue"
|
||||
"color": "blue",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
@@ -333,6 +343,7 @@
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 13,
|
||||
@@ -375,7 +386,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue"
|
||||
"color": "blue",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "#EAB839",
|
||||
@@ -461,7 +473,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue"
|
||||
"color": "blue",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "#EAB839",
|
||||
@@ -509,6 +522,7 @@
|
||||
"type": "status-history"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
@@ -548,7 +562,7 @@
|
||||
"fillOpacity": 74,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -559,7 +573,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -664,7 +679,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -698,7 +713,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "blue"
|
||||
"color": "blue",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -741,6 +757,7 @@
|
||||
"type": "barchart"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
@@ -766,6 +783,7 @@
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
@@ -805,7 +823,7 @@
|
||||
"fillOpacity": 50,
|
||||
"gradientMode": "hue",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -830,7 +848,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -905,6 +924,8 @@
|
||||
"stringInput": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Interpolation mode: smooth",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -923,7 +944,7 @@
|
||||
"fillOpacity": 40,
|
||||
"gradientMode": "hue",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -948,7 +969,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1023,6 +1045,8 @@
|
||||
"stringInput": "1,20,90,30,5,0"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Interpolation mode: Step before",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -1041,7 +1065,7 @@
|
||||
"fillOpacity": 40,
|
||||
"gradientMode": "hue",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -1066,7 +1090,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1141,10 +1166,13 @@
|
||||
"stringInput": "1,20,90,30,5,0"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Interpolation mode: Step after",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
@@ -1182,9 +1210,12 @@
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"gradientMode": {
|
||||
"label": "None",
|
||||
"value": "none"
|
||||
},
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -1209,7 +1240,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1229,6 +1261,7 @@
|
||||
},
|
||||
"id": 41,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -1267,6 +1300,8 @@
|
||||
"stringInput": "10,11,12,11,10,11,12,12,11,10,9,10,11,12,10,10,11,12,13,11,10,9,10,11,12,13,14,10,10"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Auto min max",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -1284,9 +1319,12 @@
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"gradientMode": {
|
||||
"label": "None",
|
||||
"value": "none"
|
||||
},
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -1313,7 +1351,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1333,6 +1372,7 @@
|
||||
},
|
||||
"id": 32,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -1371,6 +1411,8 @@
|
||||
"stringInput": "10,11,12,11,10,11,12,12,11,10,9,10,11,12,200,10,11,12,13,11,10,9,10,11,12,13,14,10,10"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Hard min 0, max 30",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -1390,9 +1432,12 @@
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"gradientMode": {
|
||||
"label": "None",
|
||||
"value": "none"
|
||||
},
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -1417,7 +1462,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1437,6 +1483,7 @@
|
||||
},
|
||||
"id": 44,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -1475,10 +1522,13 @@
|
||||
"stringInput": "10,11,12,11,10,11,12,12,11,10,9,10,11,12,200,10,11,12,13,11,10,9,10,11,12,13,14,10,10"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Soft min 0, soft max 30",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 5,
|
||||
@@ -1520,7 +1570,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "opacity",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -1545,7 +1595,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1718,6 +1769,7 @@
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 5,
|
||||
@@ -1755,9 +1807,12 @@
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"gradientMode": {
|
||||
"label": "None",
|
||||
"value": "none"
|
||||
},
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -1789,7 +1844,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -2077,9 +2133,12 @@
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"gradientMode": {
|
||||
"label": "None",
|
||||
"value": "none"
|
||||
},
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -2111,7 +2170,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -2401,7 +2461,7 @@
|
||||
"fillOpacity": 82,
|
||||
"gradientMode": "hue",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -2433,7 +2493,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -2512,6 +2573,7 @@
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"datasource": "gdev-testdata",
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
@@ -2547,7 +2609,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "hue",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -2558,7 +2620,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -2592,6 +2655,7 @@
|
||||
"y": 83
|
||||
},
|
||||
"id": 49,
|
||||
"maxDataPoints": null,
|
||||
"options": {
|
||||
"bucketOffset": 0,
|
||||
"bucketSize": 10,
|
||||
@@ -2655,7 +2719,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -2689,6 +2754,7 @@
|
||||
"y": 83
|
||||
},
|
||||
"id": 77,
|
||||
"maxDataPoints": null,
|
||||
"options": {
|
||||
"showHeader": true
|
||||
},
|
||||
@@ -2772,4 +2838,4 @@
|
||||
"title": "New Features in v8.0",
|
||||
"uid": "8mux8PqGz",
|
||||
"version": 17
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,12 @@
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 26,
|
||||
"w": 6,
|
||||
@@ -32,6 +34,7 @@
|
||||
"id": 7,
|
||||
"links": [],
|
||||
"options": {
|
||||
"folderId": null,
|
||||
"maxItems": 100,
|
||||
"query": "",
|
||||
"showHeadings": true,
|
||||
@@ -42,10 +45,13 @@
|
||||
},
|
||||
"pluginVersion": "8.1.0-pre",
|
||||
"tags": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Starred",
|
||||
"type": "dashlist"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 13,
|
||||
"w": 6,
|
||||
@@ -69,10 +75,13 @@
|
||||
"tags": [
|
||||
"panel-tests"
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "tag: panel-tests",
|
||||
"type": "dashlist"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 13,
|
||||
"w": 6,
|
||||
@@ -82,6 +91,7 @@
|
||||
"id": 3,
|
||||
"links": [],
|
||||
"options": {
|
||||
"folderId": null,
|
||||
"maxItems": 1000,
|
||||
"query": "",
|
||||
"showHeadings": false,
|
||||
@@ -98,10 +108,13 @@
|
||||
"gdev",
|
||||
"demo"
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "tag: dashboard-demo",
|
||||
"type": "dashlist"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 26,
|
||||
"w": 6,
|
||||
@@ -111,6 +124,7 @@
|
||||
"id": 5,
|
||||
"links": [],
|
||||
"options": {
|
||||
"folderId": null,
|
||||
"maxItems": 1000,
|
||||
"query": "",
|
||||
"showHeadings": false,
|
||||
@@ -127,10 +141,13 @@
|
||||
"gdev",
|
||||
"datasource-test"
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Data source tests",
|
||||
"type": "dashlist"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 13,
|
||||
"w": 6,
|
||||
@@ -156,10 +173,13 @@
|
||||
"templating",
|
||||
"gdev"
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "tag: templating ",
|
||||
"type": "dashlist"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 13,
|
||||
"w": 6,
|
||||
@@ -185,6 +205,8 @@
|
||||
"gdev",
|
||||
"demo"
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "tag: transforms",
|
||||
"type": "dashlist"
|
||||
}
|
||||
@@ -228,4 +250,4 @@
|
||||
"title": "Grafana Dev Overview & Home",
|
||||
"uid": "j6T00KRZz",
|
||||
"version": 2
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,12 @@
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -35,6 +37,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -46,7 +49,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -76,7 +80,6 @@
|
||||
},
|
||||
"orientation": "auto",
|
||||
"showValue": "auto",
|
||||
"stacking": "none",
|
||||
"text": {},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
@@ -84,7 +87,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"csvContent": "Time,Name,Stat1,Stat2\n2020-01-01T00:00:00Z,Stockholm, 10, 15\n2020-01-01T00:00:00Z,New York, 19, 5\n2020-01-01T00:00:00Z,London, 10, 1\n2020-01-01T00:00:00Z,Negative, 15, -5\n2020-01-01T00:00:00Z,Long value, 15,10",
|
||||
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, 5\nLondon, 10, 1\nNegative, 15, -5\nLong value, 15,10",
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_content"
|
||||
}
|
||||
@@ -93,6 +96,7 @@
|
||||
"type": "barchart"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"description": "Should be smaller given the longer value",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
@@ -106,6 +110,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -118,7 +123,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -148,7 +154,6 @@
|
||||
},
|
||||
"orientation": "auto",
|
||||
"showValue": "auto",
|
||||
"stacking": "none",
|
||||
"text": {},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
@@ -165,6 +170,7 @@
|
||||
"type": "barchart"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -177,6 +183,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -188,7 +195,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -218,7 +226,6 @@
|
||||
},
|
||||
"orientation": "auto",
|
||||
"showValue": "auto",
|
||||
"stacking": "none",
|
||||
"text": {},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
@@ -235,6 +242,7 @@
|
||||
"type": "barchart"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -247,6 +255,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -258,7 +267,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -288,7 +298,6 @@
|
||||
},
|
||||
"orientation": "auto",
|
||||
"showValue": "always",
|
||||
"stacking": "none",
|
||||
"text": {},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
@@ -318,6 +327,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -329,7 +339,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -357,9 +368,8 @@
|
||||
},
|
||||
"orientation": "auto",
|
||||
"showValue": "auto",
|
||||
"stacking": "none",
|
||||
"text": {
|
||||
"titleSize": 10,
|
||||
"size": 10,
|
||||
"valueSize": 25
|
||||
},
|
||||
"tooltip": {
|
||||
@@ -376,6 +386,7 @@
|
||||
"type": "barchart"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -388,6 +399,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -400,7 +412,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -430,7 +443,6 @@
|
||||
},
|
||||
"orientation": "horizontal",
|
||||
"showValue": "auto",
|
||||
"stacking": "none",
|
||||
"text": {},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
@@ -447,6 +459,7 @@
|
||||
"type": "barchart"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
@@ -460,6 +473,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -471,7 +485,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -501,7 +516,6 @@
|
||||
},
|
||||
"orientation": "horizontal",
|
||||
"showValue": "auto",
|
||||
"stacking": "none",
|
||||
"text": {},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
@@ -538,4 +552,4 @@
|
||||
"title": "BarChart - Panel Tests - Value sizing",
|
||||
"uid": "WFlOM-jM1",
|
||||
"version": 9
|
||||
}
|
||||
}
|
||||
@@ -1,395 +0,0 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "continuous-GrYlRd"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 11,
|
||||
"w": 9,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 62,
|
||||
"options": {
|
||||
"basemap": {
|
||||
"config": {},
|
||||
"type": "default"
|
||||
},
|
||||
"controls": {
|
||||
"mouseWheelZoom": true,
|
||||
"showAttribution": true,
|
||||
"showDebug": false,
|
||||
"showScale": false,
|
||||
"showZoom": true
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"config": {
|
||||
"color": {
|
||||
"field": "Price",
|
||||
"fixed": "dark-green"
|
||||
},
|
||||
"fillOpacity": 0.4,
|
||||
"shape": "circle",
|
||||
"showLegend": true,
|
||||
"size": {
|
||||
"field": "Count",
|
||||
"fixed": 5,
|
||||
"max": 15,
|
||||
"min": 2
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"gazetteer": "public/gazetteer/usa-states.json",
|
||||
"lookup": "State",
|
||||
"mode": "auto"
|
||||
},
|
||||
"type": "markers"
|
||||
}
|
||||
],
|
||||
"view": {
|
||||
"id": "coords",
|
||||
"lat": 38.297683,
|
||||
"lon": -99.228359,
|
||||
"shared": true,
|
||||
"zoom": 3.98
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"csvFileName": "flight_info_by_state.csv",
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_file"
|
||||
}
|
||||
],
|
||||
"title": "Size, color mapped to different fields + share view",
|
||||
"type": "geomap"
|
||||
},
|
||||
{
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
},
|
||||
{
|
||||
"color": "#EAB839",
|
||||
"value": 90
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 11,
|
||||
"w": 9,
|
||||
"x": 9,
|
||||
"y": 0
|
||||
},
|
||||
"id": 66,
|
||||
"options": {
|
||||
"basemap": {
|
||||
"config": {},
|
||||
"type": "default"
|
||||
},
|
||||
"controls": {
|
||||
"mouseWheelZoom": true,
|
||||
"showAttribution": true,
|
||||
"showDebug": false,
|
||||
"showScale": false,
|
||||
"showZoom": true
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"config": {
|
||||
"color": {
|
||||
"field": "Price",
|
||||
"fixed": "dark-green"
|
||||
},
|
||||
"fillOpacity": 0.4,
|
||||
"shape": "circle",
|
||||
"showLegend": true,
|
||||
"size": {
|
||||
"field": "Count",
|
||||
"fixed": 5,
|
||||
"max": 15,
|
||||
"min": 2
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"gazetteer": "public/gazetteer/usa-states.json",
|
||||
"lookup": "State",
|
||||
"mode": "auto"
|
||||
},
|
||||
"type": "markers"
|
||||
}
|
||||
],
|
||||
"view": {
|
||||
"id": "coords",
|
||||
"lat": 38.297683,
|
||||
"lon": -99.228359,
|
||||
"shared": true,
|
||||
"zoom": 3.98
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"csvFileName": "flight_info_by_state.csv",
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_file"
|
||||
}
|
||||
],
|
||||
"title": "Thresholds legend",
|
||||
"type": "geomap"
|
||||
},
|
||||
{
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "continuous-BlYlRd"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 11,
|
||||
"w": 9,
|
||||
"x": 0,
|
||||
"y": 11
|
||||
},
|
||||
"id": 63,
|
||||
"options": {
|
||||
"basemap": {
|
||||
"config": {},
|
||||
"type": "default"
|
||||
},
|
||||
"controls": {
|
||||
"mouseWheelZoom": true,
|
||||
"showAttribution": true,
|
||||
"showDebug": false,
|
||||
"showScale": false,
|
||||
"showZoom": true
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"config": {
|
||||
"blur": 27,
|
||||
"radius": 25,
|
||||
"weight": {
|
||||
"field": "Count",
|
||||
"fixed": 1,
|
||||
"max": 1,
|
||||
"min": 0
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"gazetteer": "public/gazetteer/usa-states.json",
|
||||
"lookup": "State",
|
||||
"mode": "auto"
|
||||
},
|
||||
"type": "heatmap"
|
||||
}
|
||||
],
|
||||
"view": {
|
||||
"id": "coords",
|
||||
"lat": 38.251497,
|
||||
"lon": -100.932144,
|
||||
"shared": false,
|
||||
"zoom": 4.15
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"csvFileName": "flight_info_by_state.csv",
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_file"
|
||||
}
|
||||
],
|
||||
"title": "Heatmap data layer",
|
||||
"transformations": [],
|
||||
"type": "geomap"
|
||||
},
|
||||
{
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "continuous-GrYlRd"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 11,
|
||||
"w": 9,
|
||||
"x": 9,
|
||||
"y": 11
|
||||
},
|
||||
"id": 65,
|
||||
"options": {
|
||||
"basemap": {
|
||||
"config": {
|
||||
"server": "world-imagery"
|
||||
},
|
||||
"type": "esri-xyz"
|
||||
},
|
||||
"controls": {
|
||||
"mouseWheelZoom": true,
|
||||
"showAttribution": true,
|
||||
"showDebug": false,
|
||||
"showScale": false,
|
||||
"showZoom": true
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"config": {
|
||||
"color": {
|
||||
"fixed": "#ff001e"
|
||||
},
|
||||
"fillOpacity": 0.4,
|
||||
"shape": "star",
|
||||
"showLegend": true,
|
||||
"size": {
|
||||
"field": "Count",
|
||||
"fixed": 5,
|
||||
"max": 15,
|
||||
"min": 2
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"gazetteer": "public/gazetteer/usa-states.json",
|
||||
"lookup": "State",
|
||||
"mode": "auto"
|
||||
},
|
||||
"type": "markers"
|
||||
}
|
||||
],
|
||||
"view": {
|
||||
"id": "coords",
|
||||
"lat": 40.159084,
|
||||
"lon": -96.508021,
|
||||
"shared": true,
|
||||
"zoom": 3.83
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"csvFileName": "flight_info_by_state.csv",
|
||||
"refId": "A",
|
||||
"scenarioId": "csv_file"
|
||||
}
|
||||
],
|
||||
"title": "Base layer ArcGIS wold imagery + star shape + share view",
|
||||
"type": "geomap"
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"schemaVersion": 30,
|
||||
"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 - Geomap",
|
||||
"uid": "2xuwrgV7z",
|
||||
"version": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -92,6 +92,7 @@
|
||||
"interval": "1m",
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
@@ -180,6 +181,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
@@ -268,6 +270,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
@@ -355,6 +358,7 @@
|
||||
"interval": "1m",
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
@@ -443,6 +447,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 80,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
@@ -531,6 +536,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 9,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -193,6 +194,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 9,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -287,6 +289,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 9,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -381,6 +384,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 9,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -475,6 +479,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 9,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -569,6 +574,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 9,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -663,6 +669,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -757,6 +764,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -851,6 +859,7 @@
|
||||
"links": [],
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
|
||||
@@ -8,17 +8,12 @@
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [
|
||||
{
|
||||
@@ -48,6 +43,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -73,7 +69,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -94,6 +91,7 @@
|
||||
"id": 3,
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -134,6 +132,8 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Show gaps",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -153,6 +153,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -179,7 +180,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -200,6 +202,7 @@
|
||||
"id": 2,
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -248,6 +251,8 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Gaps & null between every point for series B",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -267,6 +272,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -293,7 +299,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -314,6 +321,7 @@
|
||||
"id": 6,
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -382,6 +390,8 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "No nulls but unaligned series",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -400,6 +410,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -425,7 +436,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -446,6 +458,7 @@
|
||||
"id": 4,
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -486,6 +499,8 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Connected",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -505,6 +520,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -531,7 +547,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -552,6 +569,7 @@
|
||||
"id": 5,
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -600,6 +618,8 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Same as above but connected",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -619,6 +639,7 @@
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -645,7 +666,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -666,6 +688,7 @@
|
||||
"id": 7,
|
||||
"links": [],
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -734,6 +757,8 @@
|
||||
"target": ""
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Same as above but connected",
|
||||
"type": "timeseries"
|
||||
},
|
||||
@@ -752,6 +777,7 @@
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -777,7 +803,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -828,6 +855,9 @@
|
||||
},
|
||||
"id": 11,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"calcs": [],
|
||||
@@ -873,6 +903,8 @@
|
||||
"stringInput": "1,20,90,30,5,0"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Null values in first series & show gaps ",
|
||||
"transformations": [],
|
||||
"type": "timeseries"
|
||||
@@ -892,6 +924,7 @@
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -917,7 +950,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -968,6 +1002,9 @@
|
||||
},
|
||||
"id": 9,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"calcs": [],
|
||||
@@ -1013,11 +1050,14 @@
|
||||
"stringInput": "10,25,null,null,50,10"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Null values in second series show gaps (bugged)",
|
||||
"transformations": [],
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1031,6 +1071,7 @@
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
@@ -1056,7 +1097,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1076,6 +1118,7 @@
|
||||
},
|
||||
"id": 13,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
@@ -1114,10 +1157,13 @@
|
||||
"stringInput": "1,20,90,null,30,5,0"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Span nulls below 1hr",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1159,7 +1205,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -1216,5 +1263,5 @@
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - Graph NG - Gaps and Connected",
|
||||
"uid": "8mmCAF1Mz",
|
||||
"version": 2
|
||||
}
|
||||
"version": 12
|
||||
}
|
||||
@@ -80,6 +80,7 @@
|
||||
"id": 2,
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -150,6 +151,7 @@
|
||||
"id": 3,
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -220,6 +222,7 @@
|
||||
"id": 4,
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -290,6 +293,7 @@
|
||||
"id": 5,
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -360,6 +364,7 @@
|
||||
"id": 6,
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
@@ -430,6 +435,7 @@
|
||||
"id": 7,
|
||||
"maxDataPoints": 50,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "hidden",
|
||||
|
||||
@@ -113,6 +113,9 @@
|
||||
"id": 47,
|
||||
"maxDataPoints": 500,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -234,6 +237,9 @@
|
||||
"id": 48,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -355,6 +361,9 @@
|
||||
"id": 55,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -476,6 +485,9 @@
|
||||
"id": 56,
|
||||
"maxDataPoints": 90,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -597,6 +609,9 @@
|
||||
"id": 52,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -718,6 +733,9 @@
|
||||
"id": 53,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -839,6 +857,9 @@
|
||||
"id": 54,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -960,6 +981,9 @@
|
||||
"id": 57,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -1160,6 +1184,9 @@
|
||||
},
|
||||
"id": 60,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -1441,6 +1468,7 @@
|
||||
"interval": null,
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"placement": "right"
|
||||
@@ -1571,6 +1599,9 @@
|
||||
"id": 63,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -1706,6 +1737,9 @@
|
||||
"id": 64,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -1841,6 +1875,9 @@
|
||||
"id": 65,
|
||||
"maxDataPoints": 10,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -1976,6 +2013,9 @@
|
||||
"id": 66,
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -2139,6 +2179,9 @@
|
||||
"id": 32,
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "list",
|
||||
@@ -2276,6 +2319,9 @@
|
||||
"id": 35,
|
||||
"maxDataPoints": 100,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "list",
|
||||
@@ -2427,6 +2473,9 @@
|
||||
"id": 31,
|
||||
"maxDataPoints": 200,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": true,
|
||||
"displayMode": "table",
|
||||
@@ -2577,6 +2626,9 @@
|
||||
"id": 51,
|
||||
"maxDataPoints": 200,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": true,
|
||||
"displayMode": "table",
|
||||
@@ -2716,6 +2768,9 @@
|
||||
},
|
||||
"id": 19,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -2821,6 +2876,9 @@
|
||||
},
|
||||
"id": 20,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -2925,6 +2983,9 @@
|
||||
},
|
||||
"id": 21,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -3030,6 +3091,9 @@
|
||||
},
|
||||
"id": 9,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "hidden",
|
||||
@@ -3151,6 +3215,9 @@
|
||||
},
|
||||
"id": 46,
|
||||
"options": {
|
||||
"graph": {
|
||||
"realTimeUpdates": false
|
||||
},
|
||||
"legend": {
|
||||
"asTable": false,
|
||||
"displayMode": "list",
|
||||
@@ -3291,6 +3358,7 @@
|
||||
},
|
||||
"id": 68,
|
||||
"options": {
|
||||
"graph": {},
|
||||
"legend": {
|
||||
"displayMode": "hidden",
|
||||
"placement": "bottom"
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 632,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -27,7 +29,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -38,7 +40,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -86,7 +89,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -97,7 +100,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -135,6 +139,7 @@
|
||||
"type": "histogram"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -144,7 +149,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -155,7 +160,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -206,6 +212,7 @@
|
||||
"type": "histogram"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -215,7 +222,7 @@
|
||||
"fillOpacity": 80,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"viz": false,
|
||||
"graph": false,
|
||||
"legend": false,
|
||||
"tooltip": false
|
||||
},
|
||||
@@ -226,7 +233,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -277,6 +285,7 @@
|
||||
"type": "histogram"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -291,7 +300,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -343,6 +353,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -357,7 +368,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -427,4 +439,4 @@
|
||||
"title": "Panel Tests - Histogram",
|
||||
"uid": "UTv--wqMk",
|
||||
"version": 4
|
||||
}
|
||||
}
|
||||
@@ -8,21 +8,17 @@
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -59,7 +55,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -85,12 +82,9 @@
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"mergeValues": true,
|
||||
"mode": "changes",
|
||||
"rowHeight": 0.98,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"pluginVersion": "7.5.0-pre",
|
||||
"targets": [
|
||||
@@ -119,6 +113,7 @@
|
||||
"type": "state-timeline"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -156,7 +151,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -177,17 +173,9 @@
|
||||
"options": {
|
||||
"alignValue": "center",
|
||||
"colWidth": 1,
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"mergeValues": true,
|
||||
"mode": "changes",
|
||||
"rowHeight": 0.98,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
@@ -219,6 +207,7 @@
|
||||
"type": "state-timeline"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"description": "Should show gaps",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
@@ -257,7 +246,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -278,17 +268,9 @@
|
||||
"options": {
|
||||
"alignValue": "center",
|
||||
"colWidth": 1,
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"mergeValues": true,
|
||||
"mode": "changes",
|
||||
"rowHeight": 0.98,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
@@ -319,6 +301,7 @@
|
||||
"type": "state-timeline"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -336,7 +319,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -355,6 +339,7 @@
|
||||
"y": 19
|
||||
},
|
||||
"id": 4,
|
||||
"interval": null,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"alignValue": "center",
|
||||
@@ -364,11 +349,9 @@
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"mode": "samples",
|
||||
"rowHeight": 0.98,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"pluginVersion": "7.5.0-pre",
|
||||
"targets": [
|
||||
@@ -427,5 +410,5 @@
|
||||
"timezone": "utc",
|
||||
"title": "Timeline Demo",
|
||||
"uid": "mIJjFy8Kz",
|
||||
"version": 3
|
||||
}
|
||||
"version": 13
|
||||
}
|
||||
@@ -8,22 +8,18 @@
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 329,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -38,7 +34,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -66,10 +63,7 @@
|
||||
},
|
||||
"mergeValues": true,
|
||||
"rowHeight": 0.9,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"pluginVersion": "7.5.0-pre",
|
||||
"targets": [
|
||||
@@ -171,6 +165,7 @@
|
||||
1616557148000
|
||||
],
|
||||
[
|
||||
null,
|
||||
1616558756000
|
||||
],
|
||||
[
|
||||
@@ -178,6 +173,7 @@
|
||||
1616561658000
|
||||
],
|
||||
[
|
||||
null,
|
||||
1616562446000
|
||||
],
|
||||
[
|
||||
@@ -185,6 +181,7 @@
|
||||
1616564104000
|
||||
],
|
||||
[
|
||||
null,
|
||||
1616564548000
|
||||
],
|
||||
[
|
||||
@@ -200,6 +197,7 @@
|
||||
"type": "state-timeline"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -214,7 +212,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -242,10 +241,7 @@
|
||||
},
|
||||
"mergeValues": true,
|
||||
"rowHeight": 0.9,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"pluginVersion": "7.5.0-pre",
|
||||
"targets": [
|
||||
@@ -271,6 +267,7 @@
|
||||
"type": "state-timeline"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -285,7 +282,8 @@
|
||||
"mode": "percentage",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "#EAB839",
|
||||
@@ -308,6 +306,7 @@
|
||||
"y": 21
|
||||
},
|
||||
"id": 4,
|
||||
"interval": null,
|
||||
"maxDataPoints": 20,
|
||||
"options": {
|
||||
"colWidth": 0.9,
|
||||
@@ -317,10 +316,7 @@
|
||||
"placement": "bottom"
|
||||
},
|
||||
"rowHeight": 0.9,
|
||||
"showValue": "always",
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
"showValue": "always"
|
||||
},
|
||||
"pluginVersion": "7.5.0-pre",
|
||||
"targets": [
|
||||
@@ -375,5 +371,5 @@
|
||||
"timezone": "utc",
|
||||
"title": "Timeline Modes",
|
||||
"uid": "mIJjFy8Gz",
|
||||
"version": 13
|
||||
"version": 12
|
||||
}
|
||||
|
||||
@@ -20,10 +20,12 @@
|
||||
},
|
||||
"description": "",
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -49,6 +51,10 @@
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "line"
|
||||
}
|
||||
@@ -58,7 +64,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -115,6 +122,7 @@
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -129,7 +137,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -200,6 +209,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -214,7 +224,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -280,6 +291,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -294,7 +306,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -364,6 +377,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -378,7 +392,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -431,6 +446,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -454,7 +470,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -548,4 +565,4 @@
|
||||
"title": "Transforms - Config from query",
|
||||
"uid": "Juj4_7ink",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"panels": [
|
||||
@@ -38,7 +39,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -85,7 +87,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -143,6 +146,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -153,7 +157,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -204,6 +209,7 @@
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -215,7 +221,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -279,7 +286,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -326,7 +334,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -384,6 +393,7 @@
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -394,7 +404,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -443,6 +454,7 @@
|
||||
"type": "bargauge"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -454,7 +466,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -517,6 +530,7 @@
|
||||
"type": "gauge"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -527,7 +541,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -597,4 +612,4 @@
|
||||
"title": "Transforms - Rows to fields",
|
||||
"uid": "PMtIInink",
|
||||
"version": 1
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,12 @@
|
||||
- influxdb
|
||||
|
||||
telegraf:
|
||||
image: telegraf:latest
|
||||
image: telegraf:1.19.1
|
||||
links:
|
||||
- influxdb
|
||||
depends_on:
|
||||
- influxdb_cli
|
||||
volumes:
|
||||
- ./docker/blocks/influxdb/telegraf.conf:/etc/telegraf/telegraf.conf:ro
|
||||
- /var/log:/var/log/host
|
||||
- /var/log:/var/log
|
||||
- ../data/log:/var/log/grafana
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
[[inputs.logparser]]
|
||||
files = [
|
||||
"/var/log/host/*.log",
|
||||
"/var/log/*.log",
|
||||
"/var/log/grafana/*.log"
|
||||
]
|
||||
[inputs.logparser.grok]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
influxdb1:
|
||||
image: influxdb:1.8
|
||||
image: influxdb:1.8.6
|
||||
container_name: influxdb1
|
||||
ports:
|
||||
- '2004:2004'
|
||||
@@ -22,11 +22,11 @@
|
||||
FD_PORT: 8086
|
||||
|
||||
telegraf-influxdb1:
|
||||
image: telegraf:latest
|
||||
image: telegraf:1.19.1
|
||||
links:
|
||||
- influxdb1
|
||||
volumes:
|
||||
- ./docker/blocks/influxdb1/telegraf.conf:/etc/telegraf/telegraf.conf:ro
|
||||
- /var/log:/var/log/host
|
||||
- /var/log:/var/log
|
||||
- ../data/log:/var/log/grafana
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
[[inputs.logparser]]
|
||||
files = [
|
||||
"/var/log/host/*.log",
|
||||
"/var/log/*.log",
|
||||
"/var/log/grafana/*.log"
|
||||
]
|
||||
[inputs.logparser.grok]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# datasource URL: http://localhost:3100/
|
||||
loki:
|
||||
image: grafana/loki:latest
|
||||
image: grafana/loki:master
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
promtail:
|
||||
image: grafana/promtail:latest
|
||||
image: grafana/promtail:master
|
||||
volumes:
|
||||
- ./docker/blocks/loki/config.yaml:/etc/promtail/docker-config.yaml
|
||||
- /var/log:/var/log
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
# This Dockerfile builds an image for a client_golang example.
|
||||
|
||||
# Builder image, where we build the example.
|
||||
FROM golang:1.17 AS builder
|
||||
FROM golang:1.15.1 AS builder
|
||||
# Download prometheus/client_golang/examples/random first
|
||||
RUN CGO_ENABLED=0 GOOS=linux go install -tags netgo -ldflags '-w' github.com/prometheus/client_golang/examples/random@latest
|
||||
RUN go get github.com/prometheus/client_golang/examples/random
|
||||
WORKDIR /go/src/github.com/prometheus/client_golang
|
||||
WORKDIR /go/src/github.com/prometheus/client_golang/prometheus
|
||||
RUN go get -d
|
||||
WORKDIR /go/src/github.com/prometheus/client_golang/examples/random
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w'
|
||||
|
||||
# Final image.
|
||||
FROM scratch
|
||||
LABEL maintainer "The Prometheus Authors <prometheus-developers@googlegroups.com>"
|
||||
COPY --from=builder /go/bin/random .
|
||||
COPY --from=builder /go/src/github.com/prometheus/client_golang/examples/random .
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/random"]
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
grafana/provisioning/dashboards/alerts/alert-*
|
||||
@@ -1,66 +0,0 @@
|
||||
# Grafana Unified Alerting High Availability (HA) test setup
|
||||
|
||||
A set of docker compose services which together creates a Grafana HA test setup for unified alerting.
|
||||
|
||||
Included services
|
||||
|
||||
- Grafana
|
||||
- Mysql - Grafana configuration database, exporter for metrics and session storage
|
||||
- Prometheus - Monitoring of Grafana and used as data source
|
||||
- Nginx - Reverse proxy for Grafana and Prometheus. Enables browsing Grafana/Prometheus UI using a hostname
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Build grafana docker container
|
||||
|
||||
Build a Grafana docker container from current branch and commit and tag it as grafana/grafana:dev.
|
||||
|
||||
```bash
|
||||
$ cd <grafana repo>
|
||||
$ make build-docker-full
|
||||
```
|
||||
|
||||
### Virtual host names
|
||||
|
||||
#### Alternative 1 - Use dnsmasq
|
||||
|
||||
```bash
|
||||
$ sudo apt-get install dnsmasq
|
||||
$ echo 'address=/loc/127.0.0.1' | sudo tee /etc/dnsmasq.d/dnsmasq-loc.conf > /dev/null
|
||||
$ sudo /etc/init.d/dnsmasq restart
|
||||
$ ping whatever.loc
|
||||
PING whatever.loc (127.0.0.1) 56(84) bytes of data.
|
||||
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.076 ms
|
||||
--- whatever.loc ping statistics ---
|
||||
1 packet transmitted, 1 received, 0% packet loss, time 1998ms
|
||||
```
|
||||
|
||||
#### Alternative 2 - Manually update /etc/hosts
|
||||
|
||||
Update your `/etc/hosts` to be able to access Grafana and/or Prometheus UI using a hostname.
|
||||
|
||||
```bash
|
||||
$ cat /etc/hosts
|
||||
127.0.0.1 grafana.loc
|
||||
127.0.0.1 prometheus.loc
|
||||
```
|
||||
|
||||
## Start services
|
||||
|
||||
```bash
|
||||
$ docker-compose up -d
|
||||
```
|
||||
|
||||
Browse
|
||||
- http://grafana.loc/
|
||||
- http://prometheus.loc/
|
||||
|
||||
|
||||
## Test alerting
|
||||
|
||||
### Create contact points
|
||||
TBD
|
||||
### Create alerts
|
||||
TBD
|
||||
### Create silences
|
||||
TBD
|
||||
@@ -1,90 +0,0 @@
|
||||
version: "2.1"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mysql:5.6
|
||||
platform: linux/x86_64
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpass
|
||||
MYSQL_DATABASE: grafana
|
||||
MYSQL_USER: grafana
|
||||
MYSQL_PASSWORD: password
|
||||
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --innodb_monitor_enable=all, --max-connections=1001]
|
||||
ports:
|
||||
- 3306
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
mysqld-exporter:
|
||||
image: prom/mysqld-exporter
|
||||
environment:
|
||||
- DATA_SOURCE_NAME=root:rootpass@(db:3306)/
|
||||
ports:
|
||||
- 9104
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
prometheus:
|
||||
image: prom/prometheus:v2.4.2
|
||||
volumes:
|
||||
- ./prometheus/:/etc/prometheus/
|
||||
environment:
|
||||
- VIRTUAL_HOST=prometheus.loc
|
||||
ports:
|
||||
- 909
|
||||
nginx-proxy:
|
||||
image: jwilder/nginx-proxy
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
grafana1:
|
||||
image: grafana/grafana:dev
|
||||
volumes:
|
||||
- ./grafana/provisioning/:/etc/grafana/provisioning/
|
||||
environment:
|
||||
- VIRTUAL_HOST=grafana.loc
|
||||
- GF_FEATURE_TOGGLES_ENABLE=ngalert
|
||||
- GF_UNIFIED_ALERTING_HA_PEERS=ha-test-unified-alerting_grafana2_1:9094,ha-test-unified-alerting_grafana1_1:9094
|
||||
- GF_SERVER_ROOT_URL=http://grafana.loc
|
||||
- GF_DATABASE_NAME=grafana
|
||||
- GF_DATABASE_USER=grafana
|
||||
- GF_DATABASE_PASSWORD=password
|
||||
- GF_DATABASE_TYPE=mysql
|
||||
- GF_DATABASE_HOST=db:3306
|
||||
- GF_DATABASE_MAX_OPEN_CONN=300
|
||||
- GF_SESSION_PROVIDER=mysql
|
||||
- GF_SESSION_PROVIDER_CONFIG=grafana:password@tcp(db:3306)/grafana?allowNativePasswords=true
|
||||
ports:
|
||||
- 3010:3000
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
grafana2:
|
||||
image: grafana/grafana:dev
|
||||
volumes:
|
||||
- ./grafana/provisioning/:/etc/grafana/provisioning/
|
||||
environment:
|
||||
- VIRTUAL_HOST=grafana.loc
|
||||
- GF_FEATURE_TOGGLES_ENABLE=ngalert
|
||||
- GF_UNIFIED_ALERTING_HA_PEERS=ha-test-unified-alerting_grafana2_1:9094,ha-test-unified-alerting_grafana1_1:9094
|
||||
- GF_SERVER_ROOT_URL=http://grafana.loc
|
||||
- GF_DATABASE_NAME=grafana
|
||||
- GF_DATABASE_USER=grafana
|
||||
- GF_DATABASE_PASSWORD=password
|
||||
- GF_DATABASE_TYPE=mysql
|
||||
- GF_DATABASE_HOST=db:3306
|
||||
- GF_DATABASE_MAX_OPEN_CONN=300
|
||||
- GF_SESSION_PROVIDER=mysql
|
||||
- GF_SESSION_PROVIDER_CONFIG=grafana:password@tcp(db:3306)/grafana?allowNativePasswords=true
|
||||
ports:
|
||||
- 3020:3000
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
local numAlerts = std.extVar('alerts');
|
||||
local condition = std.extVar('condition');
|
||||
local arr = std.range(1, numAlerts);
|
||||
|
||||
local alertDashboardTemplate = {
|
||||
"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,
|
||||
"for": "1m",
|
||||
"name": "bulk alerting",
|
||||
"noDataState": "no_data",
|
||||
"notifications": [
|
||||
{
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "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
|
||||
};
|
||||
|
||||
|
||||
{
|
||||
['alert-' + std.toString(x) + '.json']:
|
||||
alertDashboardTemplate + {
|
||||
panels: [
|
||||
alertDashboardTemplate.panels[0] +
|
||||
{
|
||||
alert+: {
|
||||
name: 'Alert rule ' + x,
|
||||
conditions: [
|
||||
alertDashboardTemplate.panels[0].alert.conditions[0] +
|
||||
{
|
||||
evaluator+: {
|
||||
params: [condition]
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
uid: 'alert-' + x,
|
||||
title: 'Alert ' + x
|
||||
},
|
||||
for x in arr
|
||||
}
|
||||
@@ -1,172 +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": [
|
||||
{
|
||||
"aliasColors": {
|
||||
"Active alerts": "#bf1b00"
|
||||
},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "Prometheus",
|
||||
"fill": 1,
|
||||
"gridPos": {
|
||||
"h": 12,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"interval": "",
|
||||
"legend": {
|
||||
"alignAsTable": true,
|
||||
"avg": false,
|
||||
"current": true,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": true,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": true
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "Active grafana instances",
|
||||
"dashes": true,
|
||||
"fill": 0
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(increase(grafana_alerting_notification_sent_total[1m])) by(job)",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"interval": "1m",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Notifications sent",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "min(grafana_alerting_active_alerts) without(instance)",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Active alerts",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "count(up{job=\"grafana\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "Active grafana instances",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Notifications sent vs active alerts",
|
||||
"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": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": 3
|
||||
}
|
||||
}
|
||||
],
|
||||
"schemaVersion": 16,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"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": "Overview",
|
||||
"uid": "xHy7-hAik",
|
||||
"version": 6
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: 'Alerts'
|
||||
folder: 'Alerts'
|
||||
type: file
|
||||
options:
|
||||
path: /etc/grafana/provisioning/dashboards/alerts
|
||||
|
||||
- name: 'MySQL'
|
||||
folder: 'MySQL'
|
||||
type: file
|
||||
options:
|
||||
path: /etc/grafana/provisioning/dashboards/mysql
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:9090
|
||||
jsonData:
|
||||
timeInterval: 10s
|
||||
queryTimeout: 30s
|
||||
httpMethod: POST
|
||||
|
||||
- name: Loki
|
||||
type: loki
|
||||
access: proxy
|
||||
url: http://loki:3100
|
||||
@@ -1,47 +0,0 @@
|
||||
# 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:
|
||||
# - "127.0.0.1:9093"
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'prometheus'
|
||||
static_configs:
|
||||
- targets: ['localhost:9090']
|
||||
|
||||
- job_name: 'grafana'
|
||||
dns_sd_configs:
|
||||
- names:
|
||||
- 'grafana'
|
||||
type: 'A'
|
||||
port: 3000
|
||||
refresh_interval: 10s
|
||||
|
||||
- job_name: 'mysql'
|
||||
dns_sd_configs:
|
||||
- names:
|
||||
- 'mysqld-exporter'
|
||||
type: 'A'
|
||||
port: 9104
|
||||
refresh_interval: 10s
|
||||
|
||||
- job_name: 'loki'
|
||||
dns_sd_configs:
|
||||
- names:
|
||||
- 'loki'
|
||||
type: 'A'
|
||||
port: 3100
|
||||
refresh_interval: 10s
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "grafana-server",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/pkg/cmd/grafana-server",
|
||||
"env": {},
|
||||
"args": [
|
||||
"--homepath=${workspaceFolder}",
|
||||
"--packaging=dev",
|
||||
"cfg:app_mode=development",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -25,29 +25,17 @@ Edit content in the `sources` directory.
|
||||
Use the Hugo shortcode [relref](https://gohugo.io/content-management/cross-references/#use-ref-and-relref) any time you are linking to other internal docs pages.
|
||||
|
||||
Syntax is:
|
||||
|
||||
```
|
||||
{{< relref "example.md" >}}
|
||||
```
|
||||
|
||||
You might need to add more context for the link (containing folders and so on, `folder/example.md`) if Hugo says the relref is ambiguous.
|
||||
You might need to add more context for the link (containing folders and so on, `folder/example.md`) if Hugo says the relref is ambiguous.
|
||||
|
||||
### Managing redirects
|
||||
|
||||
When moving content around or removing pages it's important that users following old links are properly redirected to the new location. We do this using the [aliases](https://gohugo.io/content-management/urls/#aliases) feature in Hugo.
|
||||
|
||||
If you are moving a page, add an `aliases` entry in the front matter referencing the old location of the page which will redirect the old url to the new location.
|
||||
|
||||
If you are removing a page, add an `aliases` entry in the front matter of the most-applicable page referencing the location of the page being removed.
|
||||
|
||||
If you are copying an existing page as the basis for a new one, be sure to remove any `aliases` entries in the front matter in your copy to avoid conflicting redirects.
|
||||
|
||||
### Edit the side menu
|
||||
|
||||
The side menu is automatically build from the file structure. Use the [weight](https://gohugo.io/templates/lists/#by-weight) front matter parameter to order pages.
|
||||
|
||||
To specify different menu text from the page title, use the front matter parameter `menuTitle`.
|
||||
|
||||
### Add images
|
||||
|
||||
Images are currently hosted in the grafana/website repo.
|
||||
@@ -56,9 +44,6 @@ Images are currently hosted in the grafana/website repo.
|
||||
|
||||
## Deploy changes to grafana.com
|
||||
|
||||
When a PR is merged with changes in the `docs/sources` directory, those changes are automatically synced by a GitHub action (`.github/workflows/publish.yml`) to the grafana/website repo.
|
||||
When a PR is merged to main with changes in the `docs/sources` directory, those changes are automatically synced to the grafana/website repo and published to the staging site.
|
||||
|
||||
- A PR that targets the `main` branch syncs to the `content/docs/grafana/next` directory in the `website` repository, and publishes to `https://grafana.com/docs/grafana/next/`.
|
||||
- A PR targeting the `latest/current` release branch syncs to the `content/docs/grafana/latest` directory in the `website` repository, and publishes to `https://grafana.com/docs/grafana/latest/`.
|
||||
|
||||
Once the sync is complete, the website will automatically publish to production - no further action is needed.
|
||||
Generally, someone from marketing will publish to production each day: so as long as the sync is successful your docs edits will be published. Alternatively, you can refer to [publishing to production](https://github.com/grafana/website#publishing-to-production-grafanacom) if you'd like to do it yourself.
|
||||
|
||||
@@ -94,7 +94,7 @@ aliases = ["/docs/grafana/v1.1", "/docs/grafana/latest/guides/reference/admin",
|
||||
<img src="/static/img/docs/logos/icon_cloudmonitoring.svg">
|
||||
<h5>Google Cloud Monitoring</h5>
|
||||
</a>
|
||||
<a href="{{< relref "datasources/aws-cloudwatch/_index.md" >}}" class="nav-cards__item nav-cards__item--ds">
|
||||
<a href="{{< relref "datasources/cloudwatch.md" >}}" class="nav-cards__item nav-cards__item--ds">
|
||||
<img src="/static/img/docs/logos/icon_cloudwatch.svg">
|
||||
<h5>AWS CloudWatch</h5>
|
||||
</a>
|
||||
|
||||
@@ -10,21 +10,18 @@ weight = 400
|
||||
Grafana CLI is a small executable that is bundled with Grafana server. It can be executed on the same machine Grafana server is running on. Grafana CLI has `plugins` and `admin` commands, as well as global options.
|
||||
|
||||
To list all commands and options:
|
||||
|
||||
```
|
||||
grafana-cli -h
|
||||
```
|
||||
|
||||
## Invoking Grafana CLI
|
||||
|
||||
To invoke Grafana CLI, add the path to the grafana binaries in your `PATH` environment variable. Alternately, if your current directory is the `bin` directory, use `./grafana-cli`. Otherwise, you can specify full path to the CLI. For example, on Linux `/usr/share/grafana/bin/grafana-cli` and on Windows `C:\Program Files\GrafanaLabs\grafana\bin\grafana-cli.exe`.
|
||||
|
||||
> **Note:** Some commands, such as installing or removing plugins, require `sudo` on Linux. If you are on Windows, run Windows PowerShell as Administrator.
|
||||
>**Note:** Some commands, such as installing or removing plugins, require `sudo` on Linux. If you are on Windows, run Windows PowerShell as Administrator.
|
||||
|
||||
## Grafana CLI command syntax
|
||||
|
||||
The general syntax for commands in Grafana CLI is:
|
||||
|
||||
```bash
|
||||
grafana-cli [global options] command [command options] [arguments...]
|
||||
```
|
||||
@@ -40,7 +37,6 @@ Each global option applies only to the command in which it is used. For example,
|
||||
`--help` or `-h` displays the help, including default paths and Docker configuration information.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli -h
|
||||
```
|
||||
@@ -50,7 +46,6 @@ grafana-cli -h
|
||||
`--version` or `-v` prints the version of Grafana CLI currently running.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli -v
|
||||
```
|
||||
@@ -60,7 +55,6 @@ grafana-cli -v
|
||||
`--pluginsDir value` overrides the path to where your local Grafana instance stores plugins. Use this option if you want to install, update, or remove a plugin somewhere other than the default directory ("/var/lib/grafana/plugins") [$GF_PLUGIN_DIR].
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --pluginsDir "/var/lib/grafana/devplugins" plugins install <plugin-id>
|
||||
```
|
||||
@@ -70,7 +64,6 @@ grafana-cli --pluginsDir "/var/lib/grafana/devplugins" plugins install <plugin-i
|
||||
`--repo value` allows you to download and install or update plugins from a repository other than the default Grafana repo.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --repo "https://example.com/plugins" plugins install <plugin-id>
|
||||
```
|
||||
@@ -80,7 +73,6 @@ grafana-cli --repo "https://example.com/plugins" plugins install <plugin-id>
|
||||
`--pluginUrl value` allows you to download a .zip file containing a plugin from a local URL instead of downloading it from the default Grafana source.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --pluginUrl https://company.com/grafana/plugins/<plugin-id>-<plugin-version>.zip plugins install <plugin-id>
|
||||
```
|
||||
@@ -92,7 +84,6 @@ grafana-cli --pluginUrl https://company.com/grafana/plugins/<plugin-id>-<plugin-
|
||||
`--insecure` allows you to turn off Transport Layer Security (TLS) verification (insecure). You might want to do this if you are downloading a plugin from a non-default source.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --insecure --pluginUrl https://company.com/grafana/plugins/<plugin-id>-<plugin-version>.zip plugins install <plugin-id>
|
||||
```
|
||||
@@ -102,7 +93,6 @@ grafana-cli --insecure --pluginUrl https://company.com/grafana/plugins/<plugin-i
|
||||
`--debug` or `-d` enables debug logging. Debug output is returned and shown in the terminal.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --debug plugins install <plugin-id>
|
||||
```
|
||||
@@ -114,7 +104,6 @@ grafana-cli --debug plugins install <plugin-id>
|
||||
For example, you can use it to redirect logging to another file (maybe to log plugin installations in Grafana Cloud) or when resetting the admin password and you have non-default values for some important configuration value (like where the database is located).
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --configOverrides cfg:default.paths.log=/dev/null plugins install <plugin-id>
|
||||
```
|
||||
@@ -124,7 +113,6 @@ grafana-cli --configOverrides cfg:default.paths.log=/dev/null plugins install <p
|
||||
Sets the path for the Grafana install/home path, defaults to working directory. You do not need to use this if you are in the Grafana installation directory when using the CLI.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --homepath "/usr/share/grafana" admin reset-admin-password <new password>
|
||||
```
|
||||
@@ -134,7 +122,6 @@ grafana-cli --homepath "/usr/share/grafana" admin reset-admin-password <new pass
|
||||
`--config value` overrides the default location where Grafana expects the configuration file. Refer to [Configuration]({{< relref "../administration/configuration.md" >}}) for more information about configuring Grafana and default configuration file locations.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli --config "/etc/configuration/" admin reset-admin-password mynewpassword
|
||||
```
|
||||
@@ -170,7 +157,6 @@ grafana-cli plugins ls
|
||||
```
|
||||
|
||||
### Update all installed plugins
|
||||
|
||||
```bash
|
||||
grafana-cli plugins update-all
|
||||
```
|
||||
@@ -222,7 +208,6 @@ If you need to set the password in a script, then you can use the [Grafana User
|
||||
`encrypt-datasource-passwords` migrates passwords from unsecured fields to secure_json_data field. Returns `ok` unless there is an error. Safe to execute multiple times.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
grafana-cli admin data-migration encrypt-datasource-passwords
|
||||
```
|
||||
|
||||
@@ -16,8 +16,6 @@ To see all settings currently applied to the Grafana server, refer to [View serv
|
||||
|
||||
## Config file locations
|
||||
|
||||
The default settings for a Grafana instance are stored in the `$WORKING_DIR/conf/defaults.ini` file. _Do not_ change the location in this file.
|
||||
|
||||
_Do not_ change `defaults.ini`! Grafana defaults are stored in this file. Depending on your OS, make all configuration changes in either `custom.ini` or `grafana.ini`.
|
||||
|
||||
- Default configuration from `$WORKING_DIR/conf/defaults.ini`
|
||||
@@ -208,6 +206,7 @@ Another way is to put a web server like Nginx or Apache in front of Grafana and
|
||||
|
||||
### domain
|
||||
|
||||
|
||||
### enforce_domain
|
||||
|
||||
Redirect to correct domain if the host header does not match the domain. Prevents DNS rebinding attacks. Default is `false`.
|
||||
@@ -424,7 +423,6 @@ For more details check the [Transport.MaxConnsPerHost](https://golang.org/pkg/ne
|
||||
The maximum number of idle connections that Grafana will maintain. Default is `100`. For more details check the [Transport.MaxIdleConns](https://golang.org/pkg/net/http/#Transport.MaxIdleConns) documentation.
|
||||
|
||||
### max_idle_connections_per_host
|
||||
|
||||
[Deprecated - use max_idle_connections instead]
|
||||
|
||||
The maximum number of idle connections per host that Grafana will maintain. Default is `2`. For more details check the [Transport.MaxIdleConnsPerHost](https://golang.org/pkg/net/http/#Transport.MaxIdleConnsPerHost) documentation.
|
||||
@@ -437,14 +435,6 @@ The length of time that Grafana maintains idle connections before closing them.
|
||||
|
||||
If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request. Default is `false`.
|
||||
|
||||
### response_limit
|
||||
|
||||
Limits the amount of bytes that will be read/accepted from responses of outgoing HTTP requests. Default is `0` which means disabled.
|
||||
|
||||
### row_limit
|
||||
|
||||
Limits the number of rows that Grafana will process from SQL (relational) data sources. Default is `1000000`.
|
||||
|
||||
<hr />
|
||||
|
||||
## [analytics]
|
||||
@@ -470,14 +460,6 @@ Analytics ID here. By default this feature is disabled.
|
||||
|
||||
Google Tag Manager ID, only enabled if you enter an ID here.
|
||||
|
||||
### application_insights_connection_string
|
||||
|
||||
If you want to track Grafana usage via Azure Application Insights, then specify _your_ Application Insights connection string. Since the connection string contains semicolons, you need to wrap it in backticks (`). By default, tracking usage is disabled.
|
||||
|
||||
### application_insights_endpoint_url
|
||||
|
||||
Optionally, use this option to override the default endpoint address for Application Insights data collecting. For details, refer to the [Azure documentation](https://docs.microsoft.com/en-us/azure/azure-monitor/app/custom-endpoints?tabs=js).
|
||||
|
||||
<hr />
|
||||
|
||||
## [security]
|
||||
@@ -606,7 +588,7 @@ As of Grafana v7.3, this also limits the refresh interval options in Explore.
|
||||
|
||||
Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json".
|
||||
|
||||
> **Note:** On Linux, Grafana uses `/usr/share/grafana/public/dashboards/home.json` as the default home dashboard location.
|
||||
>**Note:** On Linux, Grafana uses `/usr/share/grafana/public/dashboards/home.json` as the default home dashboard location.
|
||||
|
||||
<hr />
|
||||
|
||||
@@ -846,7 +828,7 @@ Azure cloud environment where Grafana is hosted:
|
||||
|
||||
| Azure Cloud | Value |
|
||||
| ------------------------------------------------ | ---------------------- |
|
||||
| Microsoft Azure public cloud | AzureCloud (_default_) |
|
||||
| Microsoft Azure public cloud | AzureCloud (*default*) |
|
||||
| Microsoft Chinese national cloud | AzureChinaCloud |
|
||||
| US Government cloud | AzureUSGovernment |
|
||||
| Microsoft German national cloud ("Black Forest") | AzureGermanCloud |
|
||||
@@ -1117,97 +1099,13 @@ Sets a global limit on number of alert rules that can be created. Default is -1
|
||||
|
||||
<hr>
|
||||
|
||||
## [unified_alerting]
|
||||
|
||||
For more information about the Grafana 8 alerts, refer to [Unified Alerting]({{< relref "../alerting/unified-alerting/_index.md" >}}).
|
||||
|
||||
### enabled
|
||||
|
||||
Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed. The default value is `false`.
|
||||
|
||||
Alerting Rules migrated from dashboards and panels will include a link back via the `annotations`.
|
||||
|
||||
### disabled_orgs
|
||||
|
||||
Comma-separated list of organization IDs for which to disable Grafana 8 Unified Alerting.
|
||||
|
||||
### admin_config_poll_interval
|
||||
|
||||
Specify the frequency of polling for admin config changes. The default value is `60s`.
|
||||
|
||||
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.
|
||||
|
||||
### alertmanager_config_poll_interval
|
||||
|
||||
Specify the frequency of polling for Alertmanager config changes. The default value is `60s`.
|
||||
|
||||
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.
|
||||
|
||||
### ha_listen_address
|
||||
|
||||
Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
|
||||
|
||||
### ha_advertise_address
|
||||
|
||||
Explicit address/hostname and port to advertise other Grafana instances. The port is used for both TCP and UDP.
|
||||
|
||||
### ha_peers
|
||||
|
||||
Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
|
||||
|
||||
### ha_peer_timeout
|
||||
|
||||
Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
|
||||
be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
|
||||
each instance wait before sending the notification to take into account replication lag. The default value is `15s`.
|
||||
|
||||
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.
|
||||
|
||||
### ha_gossip_interval
|
||||
|
||||
The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
|
||||
across cluster more quickly at the expense of increased bandwidth usage. The default value is `200ms`.
|
||||
|
||||
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.
|
||||
|
||||
### ha_push_pull_interval
|
||||
|
||||
The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
|
||||
across larger clusters at the expense of increased bandwidth usage. The default value is `60s`.
|
||||
|
||||
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.
|
||||
|
||||
### execute_alerts
|
||||
|
||||
Enable or disable alerting rule execution. The default value is `true`. The alerting UI remains visible. This option has a [legacy version in the alerting section]({{< relref "#execute_alerts-1">}}) that takes precedence.
|
||||
|
||||
### evaluation_timeout
|
||||
|
||||
Sets the alert evaluation timeout when fetching data from the datasource. The default value is `30s`. This option has a [legacy version in the alerting section]({{< relref "#evaluation_timeout_seconds">}}) that takes precedence.
|
||||
|
||||
The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
|
||||
### max_attempts
|
||||
|
||||
Sets a maximum number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is `3`. This option has a [legacy version in the alerting section]({{< relref "#max_attempts-1">}}) that takes precedence.
|
||||
|
||||
### min_interval
|
||||
|
||||
Sets the minimum interval to enforce between rule evaluations. The default value is `10s` which equals the scheduler interval. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has [a legacy version in the alerting section]({{< relref "#min_interval_seconds">}}) that takes precedence.
|
||||
|
||||
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.
|
||||
|
||||
> **Note.** This setting has precedence over each individual rule frequency. If a rule frequency is lower than this value, then this value is enforced.
|
||||
|
||||
<hr>
|
||||
|
||||
## [alerting]
|
||||
|
||||
For more information about the Alerting feature in Grafana, refer to [Alerts overview]({{< relref "../alerting/_index.md" >}}).
|
||||
|
||||
### enabled
|
||||
|
||||
Set to `false` to [enable Grafana 8 alerting]({{<relref "#unified_alerting">}}) and to disable legacy alerting engine. Default is `true`.
|
||||
Set to `false` to disable alerting engine and hide Alerting in the Grafana UI. Default is `true`.
|
||||
|
||||
### execute_alerts
|
||||
|
||||
@@ -1518,7 +1416,7 @@ Optional extra path inside bucket.
|
||||
|
||||
### enable_signed_urls
|
||||
|
||||
If set to true, Grafana creates a [signed URL](https://cloud.google.com/storage/docs/access-control/signed-urls) for
|
||||
If set to true, Grafana creates a [signed URL](https://cloud.google.com/storage/docs/access-control/signed-urls] for
|
||||
the image uploaded to Google Cloud Storage.
|
||||
|
||||
### signed_url_expiration
|
||||
@@ -1622,7 +1520,7 @@ The `allowed_origins` option is a comma-separated list of additional origins (`O
|
||||
|
||||
If not set (default), then the origin is matched over [root_url]({{< relref "#root_url" >}}) which should be sufficient for most scenarios.
|
||||
|
||||
Origin patterns support wildcard symbol "\*".
|
||||
Origin patterns support wildcard symbol "*".
|
||||
|
||||
For example:
|
||||
|
||||
@@ -1631,35 +1529,11 @@ For example:
|
||||
allowed_origins = "https://*.example.com"
|
||||
```
|
||||
|
||||
### ha_engine
|
||||
|
||||
> **Note**: Available in Grafana v8.1 and later versions.
|
||||
|
||||
**Experimental**
|
||||
|
||||
The high availability (HA) engine name for Grafana Live. By default, it's not set. The only possible value is "redis".
|
||||
|
||||
For more information, refer to [Configure Grafana Live HA setup]({{< relref "../live/live-ha-setup.md" >}}).
|
||||
|
||||
### ha_engine_address
|
||||
|
||||
> **Note**: Available in Grafana v8.1 and later versions.
|
||||
|
||||
**Experimental**
|
||||
|
||||
Address string of selected the high availability (HA) Live engine. For Redis, it's a `host:port` string. Example:
|
||||
|
||||
```ini
|
||||
[live]
|
||||
ha_engine = redis
|
||||
ha_engine_address = 127.0.0.1:6379
|
||||
```
|
||||
|
||||
<hr>
|
||||
|
||||
## [plugin.grafana-image-renderer]
|
||||
|
||||
For more information, refer to [Image rendering]({{< relref "../image-rendering/" >}}).
|
||||
For more information, refer to [Image rendering]({{< relref "image_rendering.md" >}}).
|
||||
|
||||
### rendering_timezone
|
||||
|
||||
@@ -1695,7 +1569,7 @@ It can be useful to set this to `true` when troubleshooting.
|
||||
|
||||
### rendering_args
|
||||
|
||||
Additional arguments to pass to the headless browser instance. Defaults are `--no-sandbox,--disable-gpu`. The list of Chromium flags can be found at (https://peter.sh/experiments/chromium-command-line-switches/). Separate multiple arguments with commas.
|
||||
Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found at (https://peter.sh/experiments/chromium-command-line-switches/). Separate multiple arguments with commas.
|
||||
|
||||
### rendering_chrome_bin
|
||||
|
||||
@@ -1753,7 +1627,7 @@ For more information about Grafana Enterprise, refer to [Grafana Enterprise]({{<
|
||||
|
||||
### enable
|
||||
|
||||
Keys of alpha features to enable, separated by space.
|
||||
Keys of alpha features to enable, separated by space. Available alpha features are: `ngalert`
|
||||
|
||||
## [date_formats]
|
||||
|
||||
@@ -1820,4 +1694,4 @@ default_baselayer_config = `{
|
||||
|
||||
### enable_custom_baselayers
|
||||
|
||||
Set this to `true` to disable loading other custom base maps and hide them in the Grafana UI. Default is `false`.
|
||||
Set this to `true` to disable loading other custom base maps and hide them in the Grafana UI. Default is `false`.
|
||||
@@ -40,14 +40,14 @@ docker run -d --user $ID --volume "$PWD/data:/var/lib/grafana" -p 3000:3000 graf
|
||||
|
||||
The following settings are hard-coded when launching the Grafana Docker container and can only be overridden using environment variables, not in `conf/grafana.ini`.
|
||||
|
||||
| Setting | Default value |
|
||||
| --------------------- | ------------------------- |
|
||||
| GF_PATHS_CONFIG | /etc/grafana/grafana.ini |
|
||||
| GF_PATHS_DATA | /var/lib/grafana |
|
||||
| GF_PATHS_HOME | /usr/share/grafana |
|
||||
| GF_PATHS_LOGS | /var/log/grafana |
|
||||
| GF_PATHS_PLUGINS | /var/lib/grafana/plugins |
|
||||
| GF_PATHS_PROVISIONING | /etc/grafana/provisioning |
|
||||
Setting | Default value
|
||||
----------------------|---------------------------
|
||||
GF_PATHS_CONFIG | /etc/grafana/grafana.ini
|
||||
GF_PATHS_DATA | /var/lib/grafana
|
||||
GF_PATHS_HOME | /usr/share/grafana
|
||||
GF_PATHS_LOGS | /var/log/grafana
|
||||
GF_PATHS_PLUGINS | /var/lib/grafana/plugins
|
||||
GF_PATHS_PROVISIONING | /etc/grafana/provisioning
|
||||
|
||||
## Logging
|
||||
|
||||
@@ -92,5 +92,5 @@ You may also specify multiple profiles to `GF_AWS_PROFILES` (e.g.
|
||||
Supported variables:
|
||||
|
||||
- `GF_AWS_${profile}_ACCESS_KEY_ID`: AWS access key ID (required).
|
||||
- `GF_AWS_${profile}_SECRET_ACCESS_KEY`: AWS secret access key (required).
|
||||
- `GF_AWS_${profile}_SECRET_ACCESS_KEY`: AWS secret access key (required).
|
||||
- `GF_AWS_${profile}_REGION`: AWS region (optional).
|
||||
|
||||
212
docs/sources/administration/image_rendering.md
Executable file
212
docs/sources/administration/image_rendering.md
Executable file
@@ -0,0 +1,212 @@
|
||||
+++
|
||||
title = "Image rendering"
|
||||
description = ""
|
||||
keywords = ["grafana", "image", "rendering", "plugin"]
|
||||
weight = 300
|
||||
+++
|
||||
|
||||
# Image rendering
|
||||
|
||||
Grafana supports automatic rendering of panels as PNG images. This allows Grafana to automatically generate images of your panels to include in [alert notifications]({{< relref "../alerting/old-alerting/notifications.md" >}}).
|
||||
|
||||
>**Note:** Image rendering of dashboards is not supported at this time.
|
||||
|
||||
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.
|
||||
|
||||
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 "../administration/configuration/#temp-data-lifetime" >}}) setting.
|
||||
|
||||
You can also render a PNG by clicking the dropdown arrow next to a panel title, then clicking **Share > Direct link rendered image**.
|
||||
|
||||
## Memory requirements
|
||||
|
||||
Minimum free memory recommendation is 16GB on the system doing the rendering.
|
||||
|
||||
Rendering images can require a lot of memory, mainly because Grafana creates browser instances in the background for the actual rendering. If multiple images are rendered in parallel, then the rendering has a bigger memory footprint. One advantage of using the remote rendering service is that the rendering will be done on the remote system, so your local system resources will not be affected by rendering.
|
||||
|
||||
## Alerting and render limits
|
||||
|
||||
Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see [concurrent_render_limit]({{< relref "../administration/configuration/#concurrent_render_limit" >}}).
|
||||
|
||||
## Install Grafana Image Renderer plugin
|
||||
|
||||
The [Grafana image renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) is a plugin that runs on the backend and handles rendering panels and dashboards as PNG images using headless Chrome.
|
||||
|
||||
To install the plugin, refer to the [Grafana Image Renderer Installation instructions](https://grafana.com/grafana/plugins/grafana-image-renderer/?tab=installation).
|
||||
|
||||
## Run in custom Grafana Docker image
|
||||
|
||||
We recommend setting up another Docker container for rendering and using remote rendering. Refer to [Remote rendering service]({{< relref "#remote-rendering-service" >}}) for instructions.
|
||||
|
||||
If you still want to install the plugin in the Grafana Docker image, refer to [Build with Grafana Image Renderer plugin pre-installed]({{< relref "../installation/docker/#build-with-grafana-image-renderer-plugin-pre-installed" >}}).
|
||||
|
||||
## Remote rendering service
|
||||
|
||||
> Requires an internet connection.
|
||||
|
||||
The [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) can also be run as a remote HTTP rendering service. In this setup, Grafana renders an image by making a HTTP request to the remote rendering service, which in turn renders the image and returns it back in the HTTP response to Grafana.
|
||||
|
||||
You can run the remote HTTP rendering service using Docker or as a standalone Node.js application.
|
||||
|
||||
### Run in Docker
|
||||
|
||||
The following example shows how to run Grafana and the remote HTTP rendering service in two separate Docker containers using Docker Compose.
|
||||
|
||||
Create a `docker-compose.yml` with the following content:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
grafana:
|
||||
image: grafana/grafana:main
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
GF_RENDERING_SERVER_URL: http://renderer:8081/render
|
||||
GF_RENDERING_CALLBACK_URL: http://grafana:3000/
|
||||
GF_LOG_FILTERS: rendering:debug
|
||||
renderer:
|
||||
image: grafana/grafana-image-renderer:latest
|
||||
ports:
|
||||
- 8081
|
||||
```
|
||||
|
||||
And then run:
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
## Run as standalone Node.js application
|
||||
|
||||
The following example describes how to build and run the remote HTTP rendering service as a standalone Node.js application and configure Grafana appropriately.
|
||||
|
||||
1. Clone the [Grafana image renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) Git repository.
|
||||
1. Install dependencies and build:
|
||||
|
||||
```bash
|
||||
yarn install --pure-lockfile
|
||||
yarn run build
|
||||
```
|
||||
|
||||
1. Run the server:
|
||||
|
||||
```bash
|
||||
node build/app.js server --port=8081
|
||||
```
|
||||
|
||||
1. Update Grafana configuration:
|
||||
|
||||
```
|
||||
[rendering]
|
||||
server_url = http://localhost:8081/render
|
||||
callback_url = http://localhost:3000/
|
||||
```
|
||||
|
||||
1. Restart Grafana.
|
||||
|
||||
## PhantomJS
|
||||
|
||||
> Starting from Grafana v7.0.0, all PhantomJS support has been removed. Please use the Grafana Image Renderer plugin or remote rendering service.
|
||||
|
||||
## Troubleshoot image rendering
|
||||
|
||||
Enable debug log messages for rendering in the Grafana configuration file and inspect the Grafana server log.
|
||||
|
||||
```bash
|
||||
[log]
|
||||
filters = rendering:debug
|
||||
```
|
||||
|
||||
### Grafana image renderer plugin and remote rendering service
|
||||
|
||||
The plugin and rendering service uses [Chromium browser](https://www.chromium.org/) which depends on certain libraries.
|
||||
If you don't have all of those libraries installed in your system you may encounter errors when trying to render an image, e.g.
|
||||
|
||||
```bash
|
||||
Rendering failed: Error: Failed to launch chrome!/var/lib/grafana/plugins/grafana-image-renderer/chrome-linux/chrome:
|
||||
error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory\n\n\nTROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
|
||||
```
|
||||
|
||||
In general you can use the [`ldd`](https://en.wikipedia.org/wiki/Ldd_(Unix)) utility to figure out what shared libraries
|
||||
are not installed in your system:
|
||||
|
||||
```bash
|
||||
cd <grafana-image-render plugin directory>
|
||||
ldd chrome-linux/chrome
|
||||
linux-vdso.so.1 (0x00007fff1bf65000)
|
||||
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2047945000)
|
||||
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2047924000)
|
||||
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f204791a000)
|
||||
libX11.so.6 => not found
|
||||
libX11-xcb.so.1 => not found
|
||||
libxcb.so.1 => not found
|
||||
libXcomposite.so.1 => not found
|
||||
...
|
||||
```
|
||||
|
||||
**Ubuntu:**
|
||||
|
||||
On Ubuntu 18.10 the following dependencies have been confirmed as needed for the image rendering to function.
|
||||
|
||||
```bash
|
||||
libx11-6 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrender1 libxtst6 libglib2.0-0 libnss3 libcups2 libdbus-1-3 libxss1 libxrandr2 libgtk-3-0 libgtk-3-0 libasound2 libxcb-dri3-0 libgbm1
|
||||
```
|
||||
|
||||
**Debian:**
|
||||
|
||||
On Debian 9 (Stretch) the following dependencies have been confirmed as needed for the image rendering to function.
|
||||
|
||||
```bash
|
||||
libx11 libcairo bcairo2 libcairo2 libxtst6 libxcomposite1 libx11-xcb1 libxcursor1 libxdamage1 libnss3 libcups libcups2 libXss libXss1 libxss1 libxrandr2 libasound2 libatk1.0-0 libatk-bridge2.0-0 libpangocairo-1.0-0 libgtk-3-0 libgbm1
|
||||
```
|
||||
|
||||
On Debian 10 (Buster) the following dependencies have been confirmed as needed for the image rendering to function.
|
||||
|
||||
```bash
|
||||
libxdamage1 libxext6 libxi6 libxtst6 libnss3 libnss3 libcups2 libxss1 libxrandr2 libasound2 libatk1.0-0 libatk-bridge2.0-0 libpangocairo-1.0-0 libpango-1.0-0 libcairo2 libatspi2.0-0 libgtk3.0-cil libgdk3.0-cil libx11-xcb-dev libgbm1
|
||||
```
|
||||
|
||||
**Centos:**
|
||||
|
||||
On a minimal Centos installation, 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 alsa-lib
|
||||
```
|
||||
|
||||
### 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 cryptographic 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:
|
||||
|
||||
```
|
||||
t=2019-12-04T12:39:22+0000 lvl=error msg="Render request failed" logger=rendering error=map[] url="https://192.168.106.101:3443/d-solo/zxDJxNaZk/graphite-metrics?orgId=1&refresh=1m&from=1575438321300&to=1575459921300&var-Host=master1&panelId=4&width=1000&height=500&tz=Europe%2FBerlin&render=1" timestamp=0001-01-01T00:00:00.000Z
|
||||
t=2019-12-04T12:39:22+0000 lvl=error msg="Rendering failed." logger=context userId=1 orgId=1 uname=admin error="Rendering failed: Error: net::ERR_CERT_AUTHORITY_INVALID at https://192.168.106.101:3443/d-solo/zxDJxNaZk/graphite-metrics?orgId=1&refresh=1m&from=1575438321300&to=1575459921300&var-Host=master1&panelId=4&width=1000&height=500&tz=Europe%2FBerlin&render=1"
|
||||
t=2019-12-04T12:39:22+0000 lvl=error msg="Request Completed" logger=context userId=1 orgId=1 uname=admin method=GET path=/render/d-solo/zxDJxNaZk/graphite-metrics status=500 remote_addr=192.168.106.101 time_ms=310 size=1722 referer="https://grafana.xxx-xxx/d/zxDJxNaZk/graphite-metrics?orgId=1&refresh=1m"
|
||||
```
|
||||
|
||||
(The severity-level `error` in the above messages might be misspelled with a single `r`)
|
||||
|
||||
If this happens, then you have to add the certificate to the trust store. If you have the certificate file for the internal root CA in the file `internal-root-ca.crt.pem`, then use these commands to create a user specific NSS trust store for the Grafana user (`grafana` for the purpose of this example) and execute the following steps:
|
||||
|
||||
```[root@server ~]# [ -d /usr/share/grafana/.pki/nssdb ] || mkdir -p /usr/share/grafana/.pki/nssdb
|
||||
[root@merver ~]# certutil -d sql:/usr/share/grafana/.pki/nssdb -A -n internal-root-ca -t C -i /etc/pki/tls/certs/internal-root-ca.crt.pem
|
||||
[root@server ~]# chown -R grafana: /usr/share/grafana/.pki/nssdb
|
||||
```
|
||||
|
||||
### Custom Chrome/Chromium
|
||||
|
||||
As a last resort, if you already have [Chrome](https://www.google.com/chrome/) or [Chromium](https://www.chromium.org/)
|
||||
installed on your system, then you can configure [Grafana Image renderer plugin](#grafana-image-renderer-plugin) to use this
|
||||
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 [Grafana Image renderer plugin](#grafana-image-renderer-plugin).
|
||||
|
||||
To override the path to the Chrome/Chromium executable, set an environment variable and make sure that it's available for the Grafana process. For example:
|
||||
|
||||
```bash
|
||||
export GF_PLUGIN_RENDERING_CHROME_BIN="/usr/bin/chromium-browser"
|
||||
```
|
||||
@@ -11,6 +11,6 @@ Grafana supports [Jaeger tracing](https://www.jaegertracing.io/).
|
||||
|
||||
Grafana can emit Jaeger traces for its HTTP API endpoints and propagate Jaeger trace information to data sources.
|
||||
All HTTP endpoints are logged evenly (annotations, dashboard, tags, and so on).
|
||||
When a trace ID is propagated, it is reported with operation 'HTTP /datasources/proxy/:id/\*'.
|
||||
When a trace ID is propagated, it is reported with operation 'HTTP /datasources/proxy/:id/*'.
|
||||
|
||||
Refer to [Configuration]({{< relref "configuration.md#tracing-jaeger" >}}) for information about enabling Jaeger tracing.
|
||||
|
||||
@@ -20,11 +20,10 @@ Follow these instructions if you are a Grafana Server Admin.
|
||||
|
||||
{{< docs/list >}}
|
||||
{{< docs/shared "manage-users/view-server-org-list.md" >}}
|
||||
|
||||
1. In the organization list, click the name of the organization that you want to change.
|
||||
1. In **Name**, enter the new organization name.
|
||||
1. Click **Update**.
|
||||
{{< /docs/list >}}
|
||||
{{< /docs/list >}}
|
||||
|
||||
### Organization Admin change organization name
|
||||
|
||||
@@ -32,16 +31,14 @@ If you are an Organization Admin, follow these steps:
|
||||
|
||||
{{< docs/list >}}
|
||||
{{< docs/shared "preferences/org-preferences-list.md" >}}
|
||||
|
||||
1. In **Organization name**, enter the new name.
|
||||
1. Click **Update organization name**.
|
||||
{{< /docs/list >}}
|
||||
{{< /docs/list >}}
|
||||
|
||||
## Change team name or email
|
||||
|
||||
Organization administrators and team administrators can change team names and email addresses.
|
||||
To change the team name or email, follow these steps:
|
||||
|
||||
1. Hover your cursor over the **Configuration** (gear) icon in the side menu.
|
||||
1. Click **Teams**. Grafana displays the team list.
|
||||
1. In the team list, click the name of the team that you want to change.
|
||||
|
||||
@@ -52,10 +52,9 @@ Organization and team administrators can change the UI theme for all users in a
|
||||
|
||||
{{< docs/list >}}
|
||||
{{< docs/shared "manage-users/view-team-list.md" >}}
|
||||
|
||||
1. Click on the team that you want to change the UI theme for and then navigate to the **Settings** tab.
|
||||
{{< docs/shared "preferences/select-ui-theme-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
{{< docs/shared "preferences/select-ui-theme-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
|
||||
## Change your personal UI theme
|
||||
|
||||
|
||||
@@ -30,10 +30,9 @@ Organization administrators and team administrators can choose a default timezon
|
||||
|
||||
{{< docs/list >}}
|
||||
{{< docs/shared "manage-users/view-team-list.md" >}}
|
||||
|
||||
1. Click on the team you that you want to change the timezone for and then navigate to the **Settings** tab.
|
||||
{{< docs/shared "preferences/select-timezone-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
{{< docs/shared "preferences/select-timezone-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
|
||||
## Set your personal timezone
|
||||
|
||||
@@ -42,4 +41,4 @@ You can change the timezone for your user account. This setting overrides timezo
|
||||
{{< docs/list >}}
|
||||
{{< docs/shared "preferences/navigate-user-preferences-list.md" >}}
|
||||
{{< docs/shared "preferences/select-timezone-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
{{< /docs/list >}}
|
||||
@@ -40,7 +40,7 @@ Users with the Grafana Server Admin flag on their account or access to the confi
|
||||
default_home_dashboard_path = data/main-dashboard.json
|
||||
```
|
||||
|
||||
> **Note:** On Linux, Grafana uses `/usr/share/grafana/public/dashboards/home.json` as the default home dashboard location.
|
||||
>**Note:** On Linux, Grafana uses `/usr/share/grafana/public/dashboards/home.json` as the default home dashboard location.
|
||||
|
||||
## Set the home dashboard for your organization
|
||||
|
||||
@@ -59,10 +59,9 @@ Organization administrators and Team Admins can choose a home dashboard for a te
|
||||
{{< docs/list >}}
|
||||
{{< docs/shared "preferences/navigate-to-the-dashboard-list.md" >}}
|
||||
{{< docs/shared "manage-users/view-team-list.md" >}}
|
||||
|
||||
1. Click on the team that you want to change the home dashboard for and then navigate to the **Settings** tab.
|
||||
{{< docs/shared "preferences/select-home-dashboard-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
{{< docs/shared "preferences/select-home-dashboard-list.md" >}}
|
||||
{{< /docs/list >}}
|
||||
|
||||
## Set your personal home dashboard
|
||||
|
||||
|
||||
@@ -141,50 +141,49 @@ Please refer to each datasource documentation for specific provisioning examples
|
||||
|
||||
Since not all datasources have the same configuration settings we only have the most common ones as fields. The rest should be stored as a json blob in the `jsonData` field. Here are the most common settings that the core datasources use.
|
||||
|
||||
| Name | Type | Datasource | Description |
|
||||
| ----------------------- | ------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| tlsAuth | boolean | _All_ | Enable TLS authentication using client cert configured in secure json data |
|
||||
| tlsAuthWithCACert | boolean | _All_ | Enable TLS authentication using CA cert |
|
||||
| tlsSkipVerify | boolean | _All_ | Controls whether a client verifies the server's certificate chain and host name. |
|
||||
| Name | Type | Datasource | Description |
|
||||
| ----------------------- | ------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| tlsAuth | boolean | _All_ | Enable TLS authentication using client cert configured in secure json data |
|
||||
| tlsAuthWithCACert | boolean | _All_ | Enable TLS authentication using CA cert |
|
||||
| tlsSkipVerify | boolean | _All_ | Controls whether a client verifies the server's certificate chain and host name. |
|
||||
| serverName | string | _All_ | Optional. Controls the server name used for certificate common name/subject alternative name verification. Defaults to using the data source URL. |
|
||||
| timeout | string | _All_ | Request timeout in seconds. Overrides dataproxy.timeout option |
|
||||
| graphiteVersion | string | Graphite | Graphite version |
|
||||
| timeInterval | string | Prometheus, Elasticsearch, InfluxDB, MySQL, PostgreSQL and MSSQL | Lowest interval/step value that should be used for this data source. |
|
||||
| httpMode | string | Influxdb | HTTP Method. 'GET', 'POST', defaults to GET |
|
||||
| maxSeries | number | Influxdb | Max number of series/tables that Grafana processes |
|
||||
| httpMethod | string | Prometheus | HTTP Method. 'GET', 'POST', defaults to POST |
|
||||
| customQueryParameters | string | Prometheus | Query parameters to add, as a URL-encoded string. |
|
||||
| manageAlerts | boolean | Prometheus and Loki | Manage alerts via Alerting UI |
|
||||
| esVersion | string | Elasticsearch | Elasticsearch version (E.g. `7.0.0`, `7.6.1`) |
|
||||
| timeField | string | Elasticsearch | Which field that should be used as timestamp |
|
||||
| interval | string | Elasticsearch | Index date time format. nil(No Pattern), 'Hourly', 'Daily', 'Weekly', 'Monthly' or 'Yearly' |
|
||||
| logMessageField | string | Elasticsearch | Which field should be used as the log message |
|
||||
| logLevelField | string | Elasticsearch | Which field should be used to indicate the priority of the log message |
|
||||
| sigV4Auth | boolean | Elasticsearch and Prometheus | Enable usage of SigV4 |
|
||||
| sigV4AuthType | string | Elasticsearch and Prometheus | SigV4 auth provider. default/credentials/keys |
|
||||
| sigV4ExternalId | string | Elasticsearch and Prometheus | Optional SigV4 External ID |
|
||||
| sigV4AssumeRoleArn | string | Elasticsearch and Prometheus | Optional SigV4 ARN role to assume |
|
||||
| sigV4Region | string | Elasticsearch and Prometheus | SigV4 AWS region |
|
||||
| sigV4Profile | string | Elasticsearch and Prometheus | Optional SigV4 credentials profile |
|
||||
| authType | string | Cloudwatch | Auth provider. default/credentials/keys |
|
||||
| externalId | string | Cloudwatch | Optional External ID |
|
||||
| assumeRoleArn | string | Cloudwatch | Optional ARN role to assume |
|
||||
| defaultRegion | string | Cloudwatch | Optional default AWS region |
|
||||
| customMetricsNamespaces | string | Cloudwatch | Namespaces of Custom Metrics |
|
||||
| profile | string | Cloudwatch | Optional credentials profile |
|
||||
| tsdbVersion | string | OpenTSDB | Version |
|
||||
| tsdbResolution | string | OpenTSDB | Resolution |
|
||||
| sslmode | string | PostgreSQL | SSLmode. 'disable', 'require', 'verify-ca' or 'verify-full' |
|
||||
| tlsConfigurationMethod | string | PostgreSQL | SSL Certificate configuration, either by 'file-path' or 'file-content' |
|
||||
| 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 |
|
||||
| maxOpenConns | number | MySQL, PostgreSQL and MSSQL | Maximum number of open connections to the database (Grafana v5.4+) |
|
||||
| maxIdleConns | number | MySQL, PostgreSQL and MSSQL | Maximum number of connections in the idle connection pool (Grafana v5.4+) |
|
||||
| connMaxLifetime | number | MySQL, PostgreSQL and MSSQL | Maximum amount of time in seconds a connection may be reused (Grafana v5.4+) |
|
||||
| timeout | string | _All_ | Request timeout in seconds. Overrides dataproxy.timeout option |
|
||||
| graphiteVersion | string | Graphite | Graphite version |
|
||||
| timeInterval | string | Prometheus, Elasticsearch, InfluxDB, MySQL, PostgreSQL and MSSQL | Lowest interval/step value that should be used for this data source. |
|
||||
| httpMode | string | Influxdb | HTTP Method. 'GET', 'POST', defaults to GET |
|
||||
| maxSeries | number | Influxdb | Max number of series/tables that Grafana processes |
|
||||
| httpMethod | string | Prometheus | HTTP Method. 'GET', 'POST', defaults to POST |
|
||||
| customQueryParameters | string | Prometheus | Query parameters to add, as a URL-encoded string. |
|
||||
| esVersion | string | Elasticsearch | Elasticsearch version (E.g. `7.0.0`, `7.6.1`) |
|
||||
| timeField | string | Elasticsearch | Which field that should be used as timestamp |
|
||||
| interval | string | Elasticsearch | Index date time format. nil(No Pattern), 'Hourly', 'Daily', 'Weekly', 'Monthly' or 'Yearly' |
|
||||
| logMessageField | string | Elasticsearch | Which field should be used as the log message |
|
||||
| logLevelField | string | Elasticsearch | Which field should be used to indicate the priority of the log message |
|
||||
| sigV4Auth | boolean | Elasticsearch and Prometheus | Enable usage of SigV4 |
|
||||
| sigV4AuthType | string | Elasticsearch and Prometheus | SigV4 auth provider. default/credentials/keys |
|
||||
| sigV4ExternalId | string | Elasticsearch and Prometheus | Optional SigV4 External ID |
|
||||
| sigV4AssumeRoleArn | string | Elasticsearch and Prometheus | Optional SigV4 ARN role to assume |
|
||||
| sigV4Region | string | Elasticsearch and Prometheus | SigV4 AWS region |
|
||||
| sigV4Profile | string | Elasticsearch and Prometheus | Optional SigV4 credentials profile |
|
||||
| authType | string | Cloudwatch | Auth provider. default/credentials/keys |
|
||||
| externalId | string | Cloudwatch | Optional External ID |
|
||||
| assumeRoleArn | string | Cloudwatch | Optional ARN role to assume |
|
||||
| defaultRegion | string | Cloudwatch | Optional default AWS region |
|
||||
| customMetricsNamespaces | string | Cloudwatch | Namespaces of Custom Metrics |
|
||||
| profile | string | Cloudwatch | Optional credentials profile |
|
||||
| tsdbVersion | string | OpenTSDB | Version |
|
||||
| tsdbResolution | string | OpenTSDB | Resolution |
|
||||
| sslmode | string | PostgreSQL | SSLmode. 'disable', 'require', 'verify-ca' or 'verify-full' |
|
||||
| tlsConfigurationMethod | string | PostgreSQL | SSL Certificate configuration, either by 'file-path' or 'file-content' |
|
||||
| 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 |
|
||||
| maxOpenConns | number | MySQL, PostgreSQL and MSSQL | Maximum number of open connections to the database (Grafana v5.4+) |
|
||||
| maxIdleConns | number | MySQL, PostgreSQL and MSSQL | Maximum number of connections in the idle connection pool (Grafana v5.4+) |
|
||||
| connMaxLifetime | number | MySQL, PostgreSQL and MSSQL | Maximum amount of time in seconds a connection may be reused (Grafana v5.4+) |
|
||||
|
||||
#### Secure Json Data
|
||||
|
||||
@@ -192,15 +191,15 @@ Since not all datasources have the same configuration settings we only have the
|
||||
|
||||
Secure json data is a map of settings that will be encrypted with [secret key]({{< relref "configuration.md#secret-key" >}}) from the Grafana config. The purpose of this is only to hide content from the users of the application. This should be used for storing TLS Cert and password that Grafana will append to the request on the server side. All of these settings are optional.
|
||||
|
||||
| Name | Type | Datasource | Description |
|
||||
| ----------------- | ------ | ---------------------------- | -------------------------------------------------------- |
|
||||
| tlsCACert | string | _All_ | CA cert for out going requests |
|
||||
| tlsClientCert | string | _All_ | TLS Client cert for outgoing requests |
|
||||
| tlsClientKey | string | _All_ | TLS Client key for outgoing requests |
|
||||
| password | string | _All_ | password |
|
||||
| basicAuthPassword | string | _All_ | password for basic authentication |
|
||||
| accessKey | string | Cloudwatch | Access key for connecting to Cloudwatch |
|
||||
| secretKey | string | Cloudwatch | Secret key for connecting to Cloudwatch |
|
||||
| Name | Type | Datasource | Description |
|
||||
| ----------------- | ------ | ---------- | --------------------------------------- |
|
||||
| tlsCACert | string | _All_ | CA cert for out going requests |
|
||||
| tlsClientCert | string | _All_ | TLS Client cert for outgoing requests |
|
||||
| tlsClientKey | string | _All_ | TLS Client key for outgoing requests |
|
||||
| password | string | _All_ | password |
|
||||
| basicAuthPassword | string | _All_ | password for basic authentication |
|
||||
| accessKey | string | Cloudwatch | Access key for connecting to Cloudwatch |
|
||||
| secretKey | string | Cloudwatch | Secret key for connecting to Cloudwatch |
|
||||
| sigV4AccessKey | string | Elasticsearch and Prometheus | SigV4 access key. Required when using keys auth provider |
|
||||
| sigV4SecretKey | string | Elasticsearch and Prometheus | SigV4 secret key. Required when using keys auth provider |
|
||||
|
||||
@@ -320,11 +319,9 @@ By default, Grafana deletes dashboards in the database if the file is removed. Y
|
||||
> or `uid` within the same installation as this will cause weird behaviors.
|
||||
|
||||
### Provision folders structure from filesystem to Grafana
|
||||
|
||||
If you already store your dashboards using folders in a git repo or on a filesystem, and also you want to have the same folder names in the Grafana menu, you can use `foldersFromFilesStructure` option.
|
||||
|
||||
For example, to replicate these dashboards structure from the filesystem to Grafana,
|
||||
|
||||
```
|
||||
/etc/dashboards
|
||||
├── /server
|
||||
@@ -334,21 +331,18 @@ For example, to replicate these dashboards structure from the filesystem to Graf
|
||||
├── /requests_dashboard.json
|
||||
└── /resources_dashboard.json
|
||||
```
|
||||
|
||||
you need to specify just this short provision configuration file.
|
||||
|
||||
```yaml
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: dashboards
|
||||
type: file
|
||||
updateIntervalSeconds: 30
|
||||
options:
|
||||
path: /etc/dashboards
|
||||
foldersFromFilesStructure: true
|
||||
- name: dashboards
|
||||
type: file
|
||||
updateIntervalSeconds: 30
|
||||
options:
|
||||
path: /etc/dashboards
|
||||
foldersFromFilesStructure: true
|
||||
```
|
||||
|
||||
`server` and `application` will become new folders in Grafana menu.
|
||||
|
||||
> **Note:** `folder` and `folderUid` options should be empty or missing to make `foldersFromFilesStructure` work.
|
||||
@@ -432,7 +426,7 @@ The following sections detail the supported settings and secure settings for eac
|
||||
#### Alert notification `pushover`
|
||||
|
||||
| Name | Secure setting |
|
||||
| ---------- | -------------- |
|
||||
| -------- | -------------- |
|
||||
| apiToken | yes |
|
||||
| userKey | yes |
|
||||
| device | |
|
||||
@@ -445,11 +439,11 @@ The following sections detail the supported settings and secure settings for eac
|
||||
|
||||
#### Alert notification `discord`
|
||||
|
||||
| Name | Secure setting |
|
||||
| ---------- | -------------- |
|
||||
| url | yes |
|
||||
| avatar_url | |
|
||||
| content | |
|
||||
| Name | Secure setting |
|
||||
| -------------- | -------------- |
|
||||
| url | yes |
|
||||
| avatar_url | |
|
||||
| message | |
|
||||
|
||||
#### Alert notification `slack`
|
||||
|
||||
@@ -506,7 +500,7 @@ The following sections detail the supported settings and secure settings for eac
|
||||
#### Alert notification `sensugo`
|
||||
|
||||
| Name | Secure setting |
|
||||
| --------- | -------------- |
|
||||
| -------- | -------------- |
|
||||
| url | |
|
||||
| apikey | yes |
|
||||
| entity | |
|
||||
|
||||
@@ -16,12 +16,6 @@ To prevent this type of exploitation from happening, we recommend that you apply
|
||||
|
||||
You can configure Grafana to only allow certain IP addresses or hostnames to be used as data source URLs and proxied through the Grafana data source proxy. Refer to [data_source_proxy_whitelist]({{< relref "../administration/configuration/#data-source-proxy-whitelist" >}}) for usage instructions.
|
||||
|
||||
## Request security
|
||||
|
||||
The request security configuration option allows users to limit requests from the Grafana server. It targets requests that are generated by users. For more information, refer to [Request security]({{< relref "../enterprise/request-security.md" >}}) in [Grafana Enterprise]({{< relref "../enterprise" >}}).
|
||||
|
||||
> **Note:** Request security is available in Grafana Enterprise v7.4 and later versions.
|
||||
|
||||
## Firewall rules
|
||||
|
||||
Configure a firewall to restrict Grafana from making network requests to sensitive internal web services.
|
||||
@@ -34,7 +28,7 @@ Require all network requests being made by Grafana to go through a proxy server.
|
||||
|
||||
## Limit Viewer query permissions
|
||||
|
||||
Users with the Viewer role can enter _any possible query_ in _any_ of the data sources available in the **organization**, not just the queries that are defined on the dashboards for which the user has Viewer permissions.
|
||||
Users with the Viewer role can enter *any possible query* in *any* of the data sources available in the **organization**, not just the queries that are defined on the dashboards for which the user has Viewer permissions.
|
||||
|
||||
**For example:** In a Grafana instance with one data source, one dashboard, and one panel that has one query defined, you might assume that a Viewer can only see the result of the query defined in that panel. Actually, the Viewer has access to send any query to the data source. With a command-line tool like curl (there are lots of tools for this), the Viewer can make their own query to the data source and potentially access sensitive data.
|
||||
|
||||
@@ -47,6 +41,6 @@ To address this vulnerability, you can restrict data source query access in the
|
||||
|
||||
When you enable anonymous access to a dashboard, it is publicly available. This section lists the security implications of enabling Anonymous access.
|
||||
|
||||
- Anyone with the URL can access the dashboard.
|
||||
- Anyone with the URL can access the dashboard.
|
||||
- Anyone can make view calls to the API and list all folders, dashboards, and data sources.
|
||||
- Anyone can make arbitrary queries to any data source that the Grafana instance is configured with.
|
||||
|
||||
@@ -18,7 +18,7 @@ and other persistent data. So the default embedded SQLite database will not work
|
||||
|
||||
First, you need to set up MySQL or Postgres on another server and configure Grafana to use that database.
|
||||
You can find the configuration for doing that in the [[database]]({{< relref "../administration/configuration.md#database" >}}) section in the Grafana config.
|
||||
Grafana will now persist all long term data in the database. How to configure the database for high availability is out of scope for this guide. We recommend finding an expert on the database you're using.
|
||||
Grafana will now persist all long term data in the database. How to configure the database for high availability is out of scope for this guide. We recommend finding an expert on for the database you're using.
|
||||
|
||||
## Alerting
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ These instructions assume you have already added Prometheus as a data source in
|
||||
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.
|
||||
@@ -82,7 +81,6 @@ These instructions assume you have already added Graphite as a data source in Gr
|
||||
```
|
||||
|
||||
1. Enable [metrics.graphite] options:
|
||||
|
||||
```
|
||||
# Send internal metrics to Graphite
|
||||
[metrics.graphite]
|
||||
|
||||
@@ -8,8 +8,6 @@ weight = 300
|
||||
|
||||
# View Grafana server settings
|
||||
|
||||
> Refer to [Fine-grained access control]({{< relref "../../enterprise/access-control/_index.md" >}}) in Grafana Enterprise to understand how you can control access with fine-grained permissions.
|
||||
|
||||
If you are a Grafana server administrator, use the Settings tab to view the settings that are applied to your Grafana server via the [Configuration]({{< relref "../configuration.md#config-file-locations" >}}) file and any environmental variables.
|
||||
|
||||
> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Grafana server admin]({{< relref "../../permissions/_index.md" >}}).
|
||||
|
||||
@@ -7,16 +7,14 @@ weight = 400
|
||||
|
||||
# View Grafana server stats
|
||||
|
||||
> Refer to [Fine-grained access control]({{< relref "../../enterprise/access-control/_index.md" >}}) in Grafana Enterprise to understand how you can control access with fine-grained permissions.
|
||||
|
||||
If you are a Grafana server admin, then you can view useful statistics about your Grafana server in the Stats & Licensing tab.
|
||||
If you are a Grafana server admin, then you can view useful statistics about your Grafana server in the Stats tab.
|
||||
|
||||
> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Grafana server admin]({{< relref "../../permissions/_index.md" >}}).
|
||||
|
||||
## View server stats
|
||||
|
||||
1. Log in to your Grafana server with an account that has the Grafana Admin flag set.
|
||||
1. Hover your cursor over the **Server Admin** (shield) icon in the side menu and then click the **Stats & Licensing** tab.
|
||||
1. Hover your cursor over the **Server Admin** (shield) icon in the side menu and then click the **Stats** tab.
|
||||
|
||||
## Available stats
|
||||
|
||||
@@ -47,5 +45,5 @@ If a user belongs to several organizations, then that user is counted once as a
|
||||
|
||||
For example, if Sofia is a Viewer in two organizations, an Editor in two organizations, and Admin in three organizations, then she would be reflected in the stats as:
|
||||
|
||||
- Total users 1
|
||||
- Total admins 1
|
||||
- Total users 1
|
||||
- Total admins 1
|
||||
|
||||
@@ -7,9 +7,7 @@ weight = 110
|
||||
|
||||
Alerts allow you to know about problems in your systems moments after they occur. Robust and actionable alerts help you identify and resolve issues quickly, minimizing disruption to your services.
|
||||
|
||||
Grafana 8.0 has new and improved alerts that centralizes alerting information for Grafana managed alerts as well as alerts from Prometheus-compatible data sources into one user interface and API.
|
||||
|
||||
> **Note:** Grafana 8 alerts is an [opt-in]({{< relref "./unified-alerting/opt-in.md" >}}) feature. Out of the box, Grafana still supports old [legacy dashboard alerts]({{< relref "./old-alerting/_index.md" >}}). We encourage you to create issues in the Grafana GitHub repository for bugs found while testing Grafana 8 alerts.
|
||||
Grafana 8.0 has new and improved alerts. The new alerting system are an [opt-in]({{< relref "./unified-alerting/opt-in.md" >}}) feature that centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible data sources in one UI and API.
|
||||
|
||||
Alerts have four main components:
|
||||
|
||||
@@ -28,4 +26,4 @@ As part of the new alert changes, we have introduced a new data source, Alertman
|
||||
|
||||
> **Note:** Out of the box, Grafana still supports old Grafana alerts. They are legacy alerts at this time, and will be deprecated in a future release. For more information, refer to [Legacy Grafana alerts]({{< relref "./old-alerting/_index.md" >}}).
|
||||
|
||||
To learn more about the differences between new alerts and the legacy alerts, refer to [What's New with Grafana 8 Alerts]({{< relref "../alerting/difference-old-new.md" >}}).
|
||||
To learn more about the differences between new alerts and the legacy alerts, refer to [What's New with Grafana 8 Alerts]({{< relref "../alerting/difference-old-new.md" >}}).
|
||||
@@ -1,26 +1,21 @@
|
||||
+++
|
||||
title = "What's New with Grafana 8 alerts"
|
||||
title = "What's New with Grafana 8 Alerts"
|
||||
description = "What's New with Grafana 8 Alerts"
|
||||
keywords = ["grafana", "alerting", "guide"]
|
||||
weight = 112
|
||||
+++
|
||||
|
||||
# What's New with Grafana 8 alerts
|
||||
|
||||
The alerts released with Grafana 8.0 centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible datasources in one UI and API. You can create and edit alerting rules for Grafana managed alerts, Cortex alerts, and Loki alerts as well as see alerting information from prometheus-compatible datasources in a single, searchable view.
|
||||
# What's New with Grafana 8 Alerts
|
||||
The Alerts released with Grafana 8.0 are an opt-in feature that centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible datasources in one UI and API. You are able to create and edit alerting rules for Grafana managed alerts, Cortex alerts, and Loki alerts as well as see alerting information from prometheus-compatible datasources in a single, searchable view.
|
||||
|
||||
## Multi-dimensional alerting
|
||||
|
||||
Create alerts that will give you system-wide visibility with a single alerting rule. With Grafana 8 alerts, you are able to generate multiple alert instances from a single rule eg. creating a rule to monitor disk usage for multiple mount points on a single host. The evaluation engine is able to return multiple time series from a single query. Each time series is identified by its label set.
|
||||
Create alerts that will give you system-wide visibility with a single alerting rule. With Grafana 8 alerts, you are able to generate multiple alert instances from a single rule eg. creating a rule to monitor disk usage for multiple mount points on a single host. The evaluation engine is able to return multiple time series from a single query. Each time series is identified by its label set.
|
||||
|
||||
## Create alerts outside of Dashboards
|
||||
|
||||
Grafana legacy alerts were tied to a dashboard. Grafana 8 Alerts allow you to create queries and expressions that can combine data from multiple sources, in unique ways. You are still able to link dashboards and panels to alerting rules, allowing you to quickly troubleshoot the system under observation, by linking a dashboard and/or panel ID to the alerting rule.
|
||||
Grafana legacy alerts were tied to a dashboard. Grafana 8 Alerts allow you to create queries and expressions that can combine data from multiple sources, in unique ways. You are still able to link dashboards and panels to alerting rules, allowing you to quickly troubleshoot the system under observation, by linking a dashboard and/or panel ID to the alerting rule.
|
||||
|
||||
## Create Loki and Cortex alerting rules
|
||||
|
||||
With Grafana 8 Alerts you are able to manage your Loki and Cortex alerting rules using the same UI and API as your Grafana managed alerts.
|
||||
With Grafana 8 Alerts you are able to manage your Loki and Cortex alerting rules using the same UI and API as your Grafana managed alerts.
|
||||
|
||||
## View and search for alerts from Prometheus
|
||||
|
||||
You can now display all of your alerting information in one, searchable UI. Alerts for Prometheus compatible datasources are listed below Grafana managed alerts. Search for labels across multiple datasources to quickly find all of the relevant alerts.
|
||||
|
||||
@@ -17,7 +17,7 @@ Currently only the graph panel visualization supports alerts.
|
||||
Legacy alerts have two main components:
|
||||
|
||||
- Alert rule - When the alert is triggered. Alert rules are defined by one or more conditions that are regularly evaluated by Grafana.
|
||||
- Notification channel - How the alert is delivered. When the conditions of an alert rule are met, the Grafana notifies the channels configured for that alert.
|
||||
- Notification channel - How the alert is delivered. When the conditions of an alert rule are met, the Grafana notifies the channels configured for that alert.
|
||||
|
||||
## Alert tasks
|
||||
|
||||
@@ -37,21 +37,20 @@ Currently alerting supports a limited form of high availability. Since v4.2.0 of
|
||||
Grafana managed alerts are evaluated by the Grafana backend. Rule evaluations are scheduled, according to the alert rule configuration, and queries are evaluated by an engine that is part of core Grafana.
|
||||
|
||||
Alert rules can only query backend data sources with alerting enabled:
|
||||
|
||||
- builtin or developed and maintained by grafana: `Graphite`, `Prometheus`, `Loki`, `InfluxDB`, `Elasticsearch`,
|
||||
`Google Cloud Monitoring`, `Cloudwatch`, `Azure Monitor`, `MySQL`, `PostgreSQL`, `MSSQL`, `OpenTSDB`, `Oracle`, and `Azure Data Explorer`
|
||||
`Google Cloud Monitoring`, `Cloudwatch`, `Azure Monitor`, `MySQL`, `PostgreSQL`, `MSSQL`, `OpenTSDB`, `Oracle`, and `Azure Data Explorer`
|
||||
- any community backend data sources with alerting enabled (`backend` and `alerting` properties are set in the [plugin.json]({{< relref "../../developers/plugins/metadata.md" >}}))
|
||||
|
||||
## Metrics from the alert engine
|
||||
|
||||
The alert engine publishes some internal metrics about itself. You can read more about how Grafana publishes [internal metrics]({{< relref "../../administration/view-server/internal-metrics.md" >}}).
|
||||
|
||||
| Metric Name | Type | Description |
|
||||
| ------------------------------------------- | --------- | ---------------------------------------------------------------------------------------- |
|
||||
| `alerting.alerts` | gauge | How many alerts by state |
|
||||
| `alerting.request_duration_seconds` | histogram | Histogram of requests to the Alerting API |
|
||||
| `alerting.active_configurations` | gauge | The number of active, non default alertmanager configurations for grafana managed alerts |
|
||||
| `alerting.rule_evaluations_total` | counter | The total number of rule evaluations |
|
||||
| `alerting.rule_evaluation_failures_total` | counter | The total number of rule evaluation failures |
|
||||
| `alerting.rule_evaluation_duration_seconds` | summary | The duration for a rule to execute |
|
||||
| `alerting.rule_group_rules` | gauge | The number of rules |
|
||||
Metric Name | Type | Description
|
||||
---------- | ----------- | ----------
|
||||
`alerting.alerts` | gauge | How many alerts by state
|
||||
`alerting.request_duration_seconds` | histogram | Histogram of requests to the Alerting API
|
||||
`alerting.active_configurations` | gauge | The number of active, non default alertmanager configurations for grafana managed alerts
|
||||
`alerting.rule_evaluations_total` | counter | The total number of rule evaluations
|
||||
`alerting.rule_evaluation_failures_total` | counter | The total number of rule evaluation failures
|
||||
`alerting.rule_evaluation_duration_seconds` | summary | The duration for a rule to execute
|
||||
`alerting.rule_group_rules` | gauge | The number of rules
|
||||
|
||||
@@ -96,16 +96,16 @@ Below are conditions you can configure how the rule evaluation engine should han
|
||||
| --------------- | ------------------------------------------------------------------------------------------ |
|
||||
| No Data | Set alert rule state to `NoData` |
|
||||
| Alerting | Set alert rule state to `Alerting` |
|
||||
| Keep Last State | Keep the current alert rule state, whatever it is. |
|
||||
| Keep Last State | Keep the current alert rule state, whatever it is. |
|
||||
| Ok | Not sure why you would want to send yourself an alert when things are okay, but you could. |
|
||||
|
||||
### Execution errors or timeouts
|
||||
|
||||
Tell Grafana how to handle execution or timeout errors.
|
||||
|
||||
| Error or timeout option | Description |
|
||||
| ----------------------- | -------------------------------------------------- |
|
||||
| Alerting | Set alert rule state to `Alerting` |
|
||||
| Error or timeout option | Description |
|
||||
| ----------------------- | --------------------------------------------------- |
|
||||
| Alerting | Set alert rule state to `Alerting` |
|
||||
| Keep Last State | Keep the current alert rule state, whatever it is. |
|
||||
|
||||
If you have an unreliable time series store from which queries sometime timeout or fail randomly you can set this option to `Keep Last State` in order to basically ignore them.
|
||||
@@ -124,3 +124,4 @@ The actual notifications are configured and shared between multiple alerts. Read
|
||||
## Alert state history and annotations
|
||||
|
||||
Alert state changes are recorded in the internal annotation table in Grafana's database. The state changes are visualized as annotations in the alert rule's graph panel. You can also go into the `State history` submenu in the alert tab to view and clear state history.
|
||||
|
||||
|
||||
@@ -37,40 +37,41 @@ This is done from the Notification channels page.
|
||||
|
||||
These examples show how often and when reminders are sent for a triggered alert.
|
||||
|
||||
| Alert rule evaluation interval | Send reminders every | Reminder sent every (after last alert notification) |
|
||||
| ------------------------------ | -------------------- | --------------------------------------------------- |
|
||||
| `30s` | `15s` | ~30 seconds |
|
||||
| `1m` | `5m` | ~5 minutes |
|
||||
| `5m` | `15m` | ~15 minutes |
|
||||
| `6m` | `20m` | ~24 minutes |
|
||||
| `1h` | `15m` | ~1 hour |
|
||||
| `1h` | `2h` | ~2 hours |
|
||||
Alert rule evaluation interval | Send reminders every | Reminder sent every (after last alert notification)
|
||||
---------- | ----------- | -----------
|
||||
`30s` | `15s` | ~30 seconds
|
||||
`1m` | `5m` | ~5 minutes
|
||||
`5m` | `15m` | ~15 minutes
|
||||
`6m` | `20m` | ~24 minutes
|
||||
`1h` | `15m` | ~1 hour
|
||||
`1h` | `2h` | ~2 hours
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
## List of supported notifiers
|
||||
|
||||
| Name | Type | Supports images | Supports alert rule tags |
|
||||
| --------------------------------------------- | ------------------------- | ------------------ | ----------------------- |
|
||||
| [DingDing](#dingdingdingtalk) | `dingding` | yes, external only | no |
|
||||
| [Discord](#discord) | `discord` | yes | no |
|
||||
| [Email](#email) | `email` | yes | no |
|
||||
| [Google Hangouts Chat](#google-hangouts-chat) | `googlechat` | yes, external only | no |
|
||||
| Hipchat | `hipchat` | yes, external only | no |
|
||||
| [Kafka](#kafka) | `kafka` | yes, external only | no |
|
||||
| Line | `line` | yes, external only | no |
|
||||
| Microsoft Teams | `teams` | yes, external only | no |
|
||||
| [Opsgenie](#opsgenie) | `opsgenie` | yes, external only | yes |
|
||||
| [Pagerduty](#pagerduty) | `pagerduty` | yes, external only | yes |
|
||||
| Prometheus Alertmanager | `prometheus-alertmanager` | yes, external only | yes |
|
||||
| [Pushover](#pushover) | `pushover` | yes | no |
|
||||
| Sensu | `sensu` | yes, external only | no |
|
||||
| [Sensu Go](#sensu-go) | `sensugo` | yes, external only | no |
|
||||
| [Slack](#slack) | `slack` | yes | no |
|
||||
| Telegram | `telegram` | yes | no |
|
||||
| Threema | `threema` | yes, external only | no |
|
||||
| VictorOps | `victorops` | yes, external only | yes |
|
||||
| [Webhook](#webhook) | `webhook` | yes, external only | yes |
|
||||
Name | Type | Supports images | Support alert rule tags
|
||||
-----|------|---------------- | -----------------------
|
||||
[DingDing](#dingdingdingtalk) | `dingding` | yes, external only | no
|
||||
[Discord](#discord) | `discord` | yes | no
|
||||
[Email](#email) | `email` | yes | no
|
||||
[Google Hangouts Chat](#google-hangouts-chat) | `googlechat` | yes, external only | no
|
||||
Hipchat | `hipchat` | yes, external only | no
|
||||
[Kafka](#kafka) | `kafka` | yes, external only | no
|
||||
Line | `line` | yes, external only | no
|
||||
Microsoft Teams | `teams` | yes, external only | no
|
||||
[Opsgenie](#opsgenie) | `opsgenie` | yes, external only | yes
|
||||
[Pagerduty](#pagerduty) | `pagerduty` | yes, external only | yes
|
||||
Prometheus Alertmanager | `prometheus-alertmanager` | yes, external only | yes
|
||||
[Pushover](#pushover) | `pushover` | yes | no
|
||||
Sensu | `sensu` | yes, external only | no
|
||||
[Sensu Go](#sensu-go) | `sensugo` | yes, external only | no
|
||||
[Slack](#slack) | `slack` | yes | no
|
||||
Telegram | `telegram` | yes | no
|
||||
Threema | `threema` | yes, external only | no
|
||||
VictorOps | `victorops` | yes, external only | yes
|
||||
[Webhook](#webhook) | `webhook` | yes, external only | yes
|
||||
[Zenduty](#zenduty) | `webhook` | yes, external only | yes
|
||||
|
||||
### Email
|
||||
|
||||
@@ -82,10 +83,10 @@ able to access the image.
|
||||
|
||||
> **Note:** Template variables are not supported in email alerts.
|
||||
|
||||
| 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. |
|
||||
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
|
||||
|
||||
@@ -97,17 +98,17 @@ firing alerts in the Slack messages you have to configure either the [external i
|
||||
in Grafana or a bot integration via Slack Apps. [Follow Slack's guide to set up a bot integration](https://api.slack.com/bot-users) and use the token
|
||||
provided, which starts with "xoxb".
|
||||
|
||||
| Setting | Description |
|
||||
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Url | Slack incoming webhook URL, or eventually the [chat.postMessage](https://api.slack.com/methods/chat.postMessage) Slack API endpoint. |
|
||||
| Username | Set the username for the bot's message. |
|
||||
| Recipient | Allows you to override the Slack recipient. You must either provide a channel Slack ID, a user Slack ID, a username reference (@<user>, all lowercase, no whitespace), or a channel reference (#<channel>, all lowercase, no whitespace). If you use the `chat.postMessage` Slack API endpoint, this is required. |
|
||||
| Icon emoji | Provide an emoji to use as the icon for the bot's message. Ex :smile: |
|
||||
| Icon URL | Provide a URL to an image to use as the icon for the bot's message. |
|
||||
| Mention Users | Optionally mention one or more users in the Slack notification sent by Grafana. You have to refer to users, comma-separated, via their corresponding Slack IDs (which you can find by clicking the overflow button on each user's Slack profile). |
|
||||
| Mention Groups | Optionally mention one or more groups in the Slack notification sent by Grafana. You have to refer to groups, comma-separated, via their corresponding Slack IDs (which you can get from each group's Slack profile URL). |
|
||||
| Mention Channel | Optionally mention either all channel members or just active ones. |
|
||||
| Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination. If you use the `chat.postMessage` Slack API endpoint, this is required. |
|
||||
Setting | Description
|
||||
---------- | -----------
|
||||
Url | Slack incoming webhook URL, or eventually the [chat.postMessage](https://api.slack.com/methods/chat.postMessage) Slack API endpoint.
|
||||
Username | Set the username for the bot's message.
|
||||
Recipient | Allows you to override the Slack recipient. You must either provide a channel Slack ID, a user Slack ID, a username reference (@<user>, all lowercase, no whitespace), or a channel reference (#<channel>, all lowercase, no whitespace). If you use the `chat.postMessage` Slack API endpoint, this is required.
|
||||
Icon emoji | Provide an emoji to use as the icon for the bot's message. Ex :smile:
|
||||
Icon URL | Provide a URL to an image to use as the icon for the bot's message.
|
||||
Mention Users | Optionally mention one or more users in the Slack notification sent by Grafana. You have to refer to users, comma-separated, via their corresponding Slack IDs (which you can find by clicking the overflow button on each user's Slack profile).
|
||||
Mention Groups | Optionally mention one or more groups in the Slack notification sent by Grafana. You have to refer to groups, comma-separated, via their corresponding Slack IDs (which you can get from each group's Slack profile URL).
|
||||
Mention Channel | Optionally mention either all channel members or just active ones.
|
||||
Token | If provided, Grafana will upload the generated image via Slack's file.upload API method, not the external image destination. If you use the `chat.postMessage` Slack API endpoint, this is required.
|
||||
|
||||
If you are using the token for a slack bot, then you have to invite the bot to the channel you want to send notifications and add the channel to the recipient field.
|
||||
|
||||
@@ -115,12 +116,12 @@ If you are using the token for a slack bot, then you have to invite the bot to t
|
||||
|
||||
To setup Opsgenie you will need an API Key and the Alert API Url. These can be obtained by configuring a new [Grafana Integration](https://docs.opsgenie.com/docs/grafana-integration).
|
||||
|
||||
| Setting | Description |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Alert API URL | The API URL for your Opsgenie instance. This will normally be either `https://api.opsgenie.com` or, for EU customers, `https://api.eu.opsgenie.com`. |
|
||||
| API Key | The API Key as provided by Opsgenie for your configured Grafana integration. |
|
||||
| Override priority | Configures the alert priority using the `og_priority` tag. The `og_priority` tag must have one of the following values: `P1`, `P2`, `P3`, `P4`, or `P5`. Default is `False`. |
|
||||
| Send notification tags as | Specify how you would like [Notification Tags]({{< relref "create-alerts.md/#notifications" >}}) delivered to Opsgenie. They can be delivered as `Tags`, `Extra Properties` or both. Default is Tags. See note below for more information. |
|
||||
Setting | Description
|
||||
--------|------------
|
||||
Alert API URL | The API URL for your Opsgenie instance. This will normally be either `https://api.opsgenie.com` or, for EU customers, `https://api.eu.opsgenie.com`.
|
||||
API Key | The API Key as provided by Opsgenie for your configured Grafana integration.
|
||||
Override priority | Configures the alert priority using the `og_priority` tag. The `og_priority` tag must have one of the following values: `P1`, `P2`, `P3`, `P4`, or `P5`. Default is `False`.
|
||||
Send notification tags as | Specify how you would like [Notification Tags]({{< relref "create-alerts.md/#notifications" >}}) delivered to Opsgenie. They can be delivered as `Tags`, `Extra Properties` or both. Default is Tags. See note below for more information.
|
||||
|
||||
> **Note:** When notification tags are sent as `Tags` they are concatenated into a string with a `key:value` format. If you prefer to receive the notifications tags as key/values under Extra Properties in Opsgenie then change the `Send notification tags as` to either `Extra Properties` or `Tags & Extra Properties`.
|
||||
|
||||
@@ -128,47 +129,45 @@ To setup Opsgenie you will need an API Key and the Alert API Url. These can be o
|
||||
|
||||
To set up PagerDuty, all you have to do is to provide an integration key.
|
||||
|
||||
| Setting | Description |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| Integration Key | Integration key for PagerDuty. |
|
||||
| Severity | Level for dynamic notifications, default is `critical` (1) |
|
||||
| Auto resolve incidents | Resolve incidents in PagerDuty once the alert goes back to ok |
|
||||
| Message in details | Removes the Alert message from the PD summary field and puts it into custom details instead (2) |
|
||||
Setting | Description
|
||||
---------- | -----------
|
||||
Integration Key | Integration key for PagerDuty.
|
||||
Severity | Level for dynamic notifications, default is `critical` (1)
|
||||
Auto resolve incidents | Resolve incidents in PagerDuty once the alert goes back to ok
|
||||
Message in details | Removes the Alert message from the PD summary field and puts it into custom details instead (2)
|
||||
|
||||
> **Note:** The tags `Severity`, `Class`, `Group`, `dedup_key`, 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 `Severity`, `Class`, `Group`, `dedup_key`, 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.
|
||||
|
||||
> Using Message In Details will change the structure of the `custom_details` field in the PagerDuty Event.
|
||||
> This might break custom event rules in your PagerDuty rules if you rely on the fields in `payload.custom_details`.
|
||||
> Move any existing rules using `custom_details.myMetric` to `custom_details.queries.myMetric`.
|
||||
> This behavior will become the default in a future version of Grafana.
|
||||
>Using Message In Details will change the structure of the `custom_details` field in the PagerDuty Event.
|
||||
This might break custom event rules in your PagerDuty rules if you rely on the fields in `payload.custom_details`.
|
||||
Move any existing rules using `custom_details.myMetric` to `custom_details.queries.myMetric`.
|
||||
This behavior will become the default in a future version of Grafana.
|
||||
|
||||
> **Note:** The `dedup_key` tag overrides the Grafana-generated `dedup_key` with a custom key.
|
||||
|
||||
> **Note:** The `state` tag overrides the current alert state inside the `custom_details` payload.
|
||||
|
||||
> **Note:** Grafana uses the `Events API V2` integration. This can be configured for each service.
|
||||
|
||||
### VictorOps
|
||||
|
||||
To configure VictorOps, provide the URL from the Grafana Integration and substitute `$routing_key` with a valid key.
|
||||
|
||||
> **Note:** The tag `Severity` has special meaning in the [VictorOps Incident Fields](https://help.victorops.com/knowledge-base/incident-fields-glossary/). If an alert panel defines this key, then it replaces the `message_type` in the root of the event sent to VictorOps.
|
||||
|
||||
### Pushover
|
||||
|
||||
To set up Pushover, you must provide a user key and an API token. Refer to [What is Pushover and how do I use it](https://support.pushover.net/i7-what-is-pushover-and-how-do-i-use-it) for instructions on how to generate them.
|
||||
|
||||
| Setting | Description |
|
||||
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| API Token | Application token |
|
||||
| User key(s) | A comma-separated list of user keys |
|
||||
| Device(s) | A comma-separated list of devices |
|
||||
| Priority | The priority alerting nottifications are sent |
|
||||
| OK priority | The priority OK notifications are sent; if not set, then OK notifications are sent with the priority set for alerting notifications |
|
||||
| Retry | How often (in seconds) the Pushover servers send the same notification to the user. (minimum 30 seconds) |
|
||||
| Expire | How many seconds your notification will continue to be retried for (maximum 86400 seconds) |
|
||||
| Alerting sound | The sound for alerting notifications |
|
||||
| OK sound | The sound for OK notifications |
|
||||
|
||||
Setting | Description
|
||||
---------- | -----------
|
||||
API Token | Application token
|
||||
User key(s) | A comma-separated list of user keys
|
||||
Device(s) | A comma-separated list of devices
|
||||
Priority | The priority alerting nottifications are sent
|
||||
OK priority | The priority OK notifications are sent; if not set, then OK notifications are sent with the priority set for alerting notifications
|
||||
Retry | How often (in seconds) the Pushover servers send the same notification to the user. (minimum 30 seconds)
|
||||
Expire | How many seconds your notification will continue to be retried for (maximum 86400 seconds)
|
||||
Alerting sound | The sound for alerting notifications
|
||||
OK sound | The sound for OK notifications
|
||||
|
||||
### Webhook
|
||||
|
||||
@@ -179,26 +178,26 @@ Example json body:
|
||||
|
||||
```json
|
||||
{
|
||||
"dashboardId": 1,
|
||||
"evalMatches": [
|
||||
"dashboardId":1,
|
||||
"evalMatches":[
|
||||
{
|
||||
"value": 1,
|
||||
"metric": "Count",
|
||||
"tags": {}
|
||||
"value":1,
|
||||
"metric":"Count",
|
||||
"tags":{}
|
||||
}
|
||||
],
|
||||
"imageUrl": "https://grafana.com/assets/img/blog/mixed_styles.png",
|
||||
"message": "Notification Message",
|
||||
"orgId": 1,
|
||||
"panelId": 2,
|
||||
"ruleId": 1,
|
||||
"ruleName": "Panel Title alert",
|
||||
"ruleUrl": "http://localhost:3000/d/hZ7BuVbWz/test-dashboard?fullscreen\u0026edit\u0026tab=alert\u0026panelId=2\u0026orgId=1",
|
||||
"state": "alerting",
|
||||
"tags": {
|
||||
"tag name": "tag value"
|
||||
"imageUrl":"https://grafana.com/assets/img/blog/mixed_styles.png",
|
||||
"message":"Notification Message",
|
||||
"orgId":1,
|
||||
"panelId":2,
|
||||
"ruleId":1,
|
||||
"ruleName":"Panel Title alert",
|
||||
"ruleUrl":"http://localhost:3000/d/hZ7BuVbWz/test-dashboard?fullscreen\u0026edit\u0026tab=alert\u0026panelId=2\u0026orgId=1",
|
||||
"state":"alerting",
|
||||
"tags":{
|
||||
"tag name":"tag value"
|
||||
},
|
||||
"title": "[Alerting] Panel Title alert"
|
||||
"title":"[Alerting] Panel Title alert"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -214,7 +213,7 @@ In DingTalk PC Client:
|
||||
|
||||
2. Click "Robot Manage" item in the pop menu, there will be a new panel call "Robot Manage".
|
||||
|
||||
3. In the "Robot Manage" panel, select "customized: customized robot with Webhook".
|
||||
3. In the "Robot Manage" panel, select "customized: customized robot with Webhook".
|
||||
|
||||
4. In the next new panel named "robot detail", click "Add" button.
|
||||
|
||||
@@ -227,11 +226,11 @@ In DingTalk PC Client:
|
||||
To set up Discord, you must create a Discord channel webhook. For instructions on how to create the channel, refer to
|
||||
[Intro to Webhooks](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks).
|
||||
|
||||
| Setting | Description |
|
||||
| --------------- | --------------------------------------------------------------------------------- |
|
||||
| Webhook URL | Discord webhook URL. |
|
||||
| Message Content | Mention a group using @ or a user using <@ID> when notifying in a channel. |
|
||||
| Avatar URL | Optionally, provide a URL to an image to use as the avatar for the bot's message. |
|
||||
Setting | Description
|
||||
---------- | -----------
|
||||
Webhook URL | Discord webhook URL.
|
||||
Message Content | Mention a group using @ or a user using <@ID> when notifying in a channel.
|
||||
Avatar URL | Optionally, provide a URL to an image to use as the avatar for the bot's message.
|
||||
|
||||
Alternately, use the [Slack](#slack) notifier by appending `/slack` to a Discord webhook URL.
|
||||
|
||||
@@ -256,14 +255,18 @@ Alertmanager handles alerts sent by client applications such as Prometheus serve
|
||||
|
||||
> **Caution:** In case of a high-availability setup, do not load balance traffic between Grafana and Alertmanagers to keep coherence between all your Alertmanager instances. Instead, point Grafana to a list of all Alertmanagers, by listing their URLs comma-separated in the notification channel configuration.
|
||||
|
||||
### Zenduty
|
||||
|
||||
[Zenduty](https://www.zenduty.com) is an incident alerting and response orchestration platform that not alerts the right teams via SMS, Phone(Voice), Email, Slack, Microsoft Teams and Push notifications(Android/iOS) whenever a Grafana alert is triggered, but also helps you rapidly triage and remediate critical, user impacting incidents. Grafana alert are sent to Zenduty through Grafana's native webhook dispatcher. Refer the Zenduty-Grafana [integration documentation](https://docs.zenduty.com/docs/grafana) for configuring the integration.
|
||||
|
||||
### Sensu Go
|
||||
|
||||
Grafana alert notifications can be sent to [Sensu](<(https://sensu.io)>) Go as events via the API. This operation requires an API key. For information on creating this key, refer to [Sensu Go documentation](https://docs.sensu.io/sensu-go/latest/operations/control-access/use-apikeys/#api-key-authentication).
|
||||
[Sensu](https://sensu.io) is a complete solution for monitoring and observability at scale. Sensu Go is designed to give you visibility into everything you care about: traditional server closets, containers, applications, the cloud, and more. Grafana notifications can be sent to Sensu Go as events via the API. This operation requires an API Key. Refer to the [Sensu Go documentation](https://docs.sensu.io/sensu-go/latest/operations/control-access/use-apikeys/#api-key-authentication) for information on creating this key.
|
||||
|
||||
## 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
|
||||
[image rendering]({{< relref "../../image-rendering/" >}}).
|
||||
[image rendering]({{< relref "../../administration/image_rendering/" >}}).
|
||||
|
||||
You must configure an [external image storage provider]({{< relref "../../administration/configuration/#external-image-storage" >}}) in order to receive images in alert notifications. If your notification channel requires that the image be publicly accessible (e.g. Slack, PagerDuty), configure a provider which uploads the image to a remote image store like Amazon S3, Webdav, Google Cloud Storage, or Azure Blob Storage. Otherwise, the local provider can be used to serve the image directly from Grafana.
|
||||
|
||||
|
||||
@@ -12,4 +12,4 @@ Pausing the evaluation of an alert rule can sometimes be useful. For example, du
|
||||
|
||||
1. In the Grafana side bar, hover your cursor over the Alerting (bell) icon and then click **Alert Rules**. All configured alert rules are listed, along with their current state.
|
||||
1. Find your alert in the list, and click the **Pause** icon on the right. The **Pause** icon turns into a **Play** icon.
|
||||
1. Click the **Play** icon to resume evaluation of your alert.
|
||||
1. Click the **Play** icon to resume evaluation of your alert.
|
||||
@@ -17,4 +17,4 @@ You can do several things while viewing alerts.
|
||||
- **Filter alerts by name -** Type an alert name in the **Search alerts** field.
|
||||
- **Filter alerts by state -** In **States**, select which alert states you want to see. All others will be hidden.
|
||||
- **Pause or resume an alert -** Click the **Pause** or **Play** icon next to the alert to pause or resume evaluation. See [Pause an alert rule]({{< relref "pause-an-alert-rule.md" >}}) for more information.
|
||||
- **Access alert rule settings -** Click the alert name or the **Edit alert rule** (gear) icon. Grafana opens the Alert tab of the panel where the alert rule is defined. This is helpful when an alert is firing but you don't know which panel it is defined in.
|
||||
- **Access alert rule settings -** Click the alert name or the **Edit alert rule** (gear) icon. Grafana opens the Alert tab of the panel where the alert rule is defined. This is helpful when an alert is firing but you don't know which panel it is defined in.
|
||||
@@ -5,12 +5,11 @@ weight = 113
|
||||
+++
|
||||
|
||||
# Overview of Grafana 8 alerts
|
||||
Alerts allow you to know about problems in your systems moments after they occur. Robust and actionable alerts help you identify and resolve issues quickly, minimizing disruption to your services.
|
||||
|
||||
Grafana 8.0 has a new and improved alerting sub-system that centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible data sources into one user interface and API.
|
||||
>**Note:** This information is for the new, Grafana 8 Alerts. This is an [opt-in]({{< relref"./opt-in.md" >}}) feature released in Grafana 8.0. Grafana still supports [legacy dashboard alerts]({{< relref "../old-alerting/_index.md" >}}) out of the box
|
||||
|
||||
> **Note:** Grafana 8 alerts is an [opt-in]({{< relref "../unified-alerting/opt-in.md" >}}) feature. Out of the box, Grafana still supports old [legacy dashboard alerts]({{< relref "./old-alerting/_index.md" >}}). We encourage you to create issues in the Grafana GitHub repository for bugs found while testing Grafana 8 alerts.
|
||||
|
||||
Grafana 8 alerts have four main components:
|
||||
Alerts have four main components:
|
||||
|
||||
- Alerting rule - One or more query and/or expression, a condition, the frequency of evaluation, and the (optional) duration that a condition must be met before creating an alert.
|
||||
- Contact point - A channel for sending notifications when the conditions of an alerting rule are met.
|
||||
@@ -21,10 +20,11 @@ Grafana 8 alerts have four main components:
|
||||
|
||||
You can perform the following tasks for alerts:
|
||||
|
||||
|
||||
- [Create a Grafana managed alert rule]({{< relref "alerting-rules/create-grafana-managed-rule.md" >}})
|
||||
- [Create a Cortex or Loki managed alert rule]({{< relref "alerting-rules/create-cortex-loki-managed-rule.md" >}})
|
||||
- [View existing alert rules and their current state]({{< relref "alerting-rules/rule-list.md" >}})
|
||||
- [View state and health of alerting rules]({{< relref "alerting-rules/state-and-health.md" >}})
|
||||
- [Test alert rules and troubleshoot]({{< relref "./troubleshoot-alerts.md" >}})
|
||||
- [Add or edit an alert contact point]({{< relref "./contact-points.md" >}})
|
||||
- [Add or edit notification policies]({{< relref "./notification-policies.md" >}})
|
||||
- [Create and edit silences]({{< relref "./silences.md" >}})
|
||||
@@ -38,25 +38,23 @@ The current alerting system doesn't support high availability. Alert notificatio
|
||||
Grafana managed alerts are evaluated by the Grafana backend. Rule evaluations are scheduled, according to the alert rule configuration, and queries are evaluated by an engine that is part of core Grafana.
|
||||
|
||||
Alerting rules can only query backend data sources with alerting enabled:
|
||||
|
||||
- builtin or developed and maintained by grafana: `Graphite`, `Prometheus`, `Loki`, `InfluxDB`, `Elasticsearch`,
|
||||
`Google Cloud Monitoring`, `Cloudwatch`, `Azure Monitor`, `MySQL`, `PostgreSQL`, `MSSQL`, `OpenTSDB`, `Oracle`, and `Azure Data Explorer`
|
||||
- any community backend data sources with alerting enabled (`backend` and `alerting` properties are set in the [plugin.json]({{< relref "../../developers/plugins/metadata.md" >}}))
|
||||
|
||||
## Metrics from the alerting engine
|
||||
|
||||
The alerting engine publishes some internal metrics about itself. You can read more about how Grafana publishes [internal metrics]({{< relref "../../administration/view-server/internal-metrics.md" >}}). See also, [View alert rules and their current state]({{< relref "alerting-rules/rule-list.md" >}}).
|
||||
The alerting engine publishes some internal metrics about itself. You can read more about how Grafana publishes [internal metrics]({{< relref "../../administration/view-server/internal-metrics.md" >}}).
|
||||
|
||||
| Metric Name | Type | Description |
|
||||
| ------------------------------------------------- | --------- | ---------------------------------------------------------------------------------------- |
|
||||
| `grafana_alerting_alerts` | gauge | How many alerts by state |
|
||||
| `grafana_alerting_request_duration` | histogram | Histogram of requests to the Alerting API |
|
||||
| `grafana_alerting_active_configurations` | gauge | The number of active, non default Alertmanager configurations for grafana managed alerts |
|
||||
| `grafana_alerting_rule_evaluations_total` | counter | The total number of rule evaluations |
|
||||
| `grafana_alerting_rule_evaluation_failures_total` | counter | The total number of rule evaluation failures |
|
||||
| `grafana_alerting_rule_evaluation_duration` | summary | The duration for a rule to execute |
|
||||
| `grafana_alerting_rule_group_rules` | gauge | The number of rules |
|
||||
Metric Name | Type | Description
|
||||
---------- | ----------- | ----------
|
||||
`alerting.alerts` | gauge | How many alerts by state
|
||||
`alerting.request_duration_seconds` | histogram | Histogram of requests to the Alerting API
|
||||
`alerting.active_configurations` | gauge | The number of active, non default Alertmanager configurations for grafana managed alerts
|
||||
`alerting.rule_evaluations_total` | counter | The total number of rule evaluations
|
||||
`alerting.rule_evaluation_failures_total` | counter | The total number of rule evaluation failures
|
||||
`alerting.rule_evaluation_duration_seconds` | summary | The duration for a rule to execute
|
||||
`alerting.rule_group_rules` | gauge | The number of rules
|
||||
|
||||
## Limitation
|
||||
|
||||
Grafana 8 alerting system can retrieve rules from all available Prometheus, Loki, and Alertmanager data sources. It might not be able to fetch rules from all other supported data sources at this time.
|
||||
- [View alert rules and their current state]({{< relref "alerting-rules/rule-list.md" >}})
|
||||
|
||||
@@ -4,13 +4,10 @@ aliases = ["/docs/grafana/latest/alerting/rules/"]
|
||||
weight = 130
|
||||
+++
|
||||
|
||||
# Create and manage alerting rules
|
||||
|
||||
One or more queries and/or expressions, a condition, the frequency of evaluation, and the (optional) duration that a condition must be met before creating an alert. Alerting rules are how you express the criteria for creating an alert. Queries and expressions select and can operate on the data you wish to alert on. A condition sets the threshold that an alert must meet or exceed to create an alert. The interval specifies how frequently the rule should be evaluated. The duration, when configured, sets a period that a condition must be met or exceeded before an alert is created. Alerting rules also can contain settings for what to do when your query does not return any data, or there is an error attempting to execute the query.
|
||||
# Create and manage alerting Rules
|
||||
One or more queries and/or expressions, a condition, the frequency of evaluation, and the (optional) duration that a condition must be met before creating an alert. Alerting rules are how you express the criteria for creating an alert. Queries and expressions select and can operate on the data you wish to alert on. A condition sets the threshold that an alert must meet or exceed to create an alert. The interval specifies how frequently the rule should be evaluated. The duration, when configured, sets a period that a condition must be met or exceeded before an alert is created. Alerting rules also can contain settings for what to do when your query does not return any data, or there is an error attempting to execute the query.
|
||||
|
||||
- [Create Cortex or Loki managed alert rule]({{< relref "./create-cortex-loki-managed-rule.md" >}})
|
||||
- [Create Cortex or Loki managed recording rule]({{< relref "./create-cortex-loki-managed-recording-rule.md" >}})
|
||||
- [Edit Cortex or Loki rule groups and namespaces]({{< relref "./edit-cortex-loki-namespace-group.md" >}})
|
||||
- [Create Grafana managed alert rule]({{< relref "./create-grafana-managed-rule.md" >}})
|
||||
- [State and Health of alerting rules]({{< relref "./state-and-health.md" >}})
|
||||
- [View existing alert rules and their current state]({{< relref "./rule-list.md" >}})
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
+++
|
||||
title = "Create Cortex or Loki managed recording rule"
|
||||
description = "Create Cortex or Loki managed recording rule"
|
||||
keywords = ["grafana", "alerting", "guide", "rules", "recording rules", "create"]
|
||||
weight = 400
|
||||
+++
|
||||
|
||||
# Create a Cortex or Loki managed recording rule
|
||||
|
||||
You can create and manage recording rules for an external Cortex or Loki instance. Recording rules calculate frequently needed expressions or computationally expensive expressions in advance and save the result as a new set of time series. Querying this new time series is faster, especially for dashboards since they query the same expression every time the dashboards refresh.
|
||||
|
||||
For both Cortex and Loki data sources to work with Grafana 8.0 alerting, enable the ruler API by configuring their respective services. The `local` rule storage type (default for Loki data source), only supports viewing of rules. If you want to edit rules, then configure one of the other rule storage types.
|
||||
|
||||
When configuring a Grafana Prometheus data source to point to Cortex, use the legacy /api/prom prefix, not /prometheus. Only single-binary mode is currently supported, provide a separate URL for the ruler API.
|
||||
|
||||
## Add a Cortex or Loki managed recording rule
|
||||
|
||||
1. Hover your cursor over the Alerting (bell) icon.
|
||||
1. Click **New alert rule**.
|
||||
1. Click on the **Alert type** drop down and select **Cortex / Loki managed recording rule**.
|
||||
1. Enter the recording rule details using instructions in the [Recording rule fields](#recording-rule-fields) section.
|
||||
1. Click **Save** in the upper right corner to save the rule.
|
||||
|
||||
## Edit a Cortex or Loki managed recording rule
|
||||
|
||||
1. Hover your cursor over the Alerting (bell) icon in the side menu.
|
||||
1. Expand an existing recording rule in the **Cortex / Loki** section and click **Edit**.
|
||||
1. Update the recording rule details using instructions in the [Recording rule fields](#recording-rule-fields) section.
|
||||
1. Click **Save and exit** to save and exit rule editing.
|
||||
|
||||
## Recording rule fields
|
||||
|
||||
This section describes the fields you fill out to create a recording rule.
|
||||
|
||||
### Rule type
|
||||
|
||||
- **Rule name -** Enter a descriptive name. The name will get displayed in the alert rule list. It will also get added as an `alertname` label to every alert instance that is created from this rule. Recording rules names must be valid [metric names](https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels).
|
||||
- **Rule type -** Select **Cortex / Loki managed recording rule**.
|
||||
- **Data source -** Select a Prometheus or Loki data source. Only data sources that support Cortex ruler API are available.
|
||||
- **Namespace -** Select an existing rule namespace or click **Add new** and enter a name to create a new one. Namespaces can contain one or more rule groups and have only organizational purpose.
|
||||
- **Group -** Select an existing group within the selected namespace or click **Add new** to create a new group. Newly created rules are added to the end of this group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
|
||||
|
||||

|
||||
|
||||
### Query
|
||||
|
||||
Enter a PromQL or LogQL expression. The result of this expression will get recorded as the value for the new metric.
|
||||
|
||||

|
||||
|
||||
### Details
|
||||
|
||||
You can optionally define labels in the details section.
|
||||
|
||||

|
||||
@@ -7,29 +7,30 @@ weight = 400
|
||||
|
||||
# Create a Cortex or Loki managed alerting rule
|
||||
|
||||
Grafana allows you manage alerting rules for an external Cortex or Loki instance.
|
||||
Grafana allows you manage alerting rules for an external Cortex or Loki instance.
|
||||
|
||||
In order for both Cortex and Loki data sources to work with Grafana 8.0 alerting, enable the ruler API by configuring their respective services. The`local` rule storage type, default for Loki, only supports viewing of rules. If you want to edit rules, then configure one of the other rule storage types. When configuring a Grafana Prometheus data source to point to Cortex, use the legacy `/api/prom` prefix, not `/prometheus`. Only single-binary mode is currently supported, and it is not possible to provide a separate URL for the ruler API.
|
||||
|
||||
In order for both Cortex and Loki data sources to work with Grafana 8.0 alerting, enable the ruler API by configuring their respective services. The`local` rule storage type, default for Loki, only supports viewing of rules. If you want to edit rules, then configure one of the other rule storage types. When configuring a Grafana Prometheus data source to point to Cortex, use the legacy `/api/prom` prefix, not `/prometheus`. Only single-binary mode is currently supported, and it is not possible to provide a separate URL for the ruler API.
|
||||
|
||||
## Add or edit a Cortex or Loki managed alerting rule
|
||||
|
||||
1. In the Grafana menu hover your cursor over the Alerting (bell) icon.
|
||||
1. To create a new alert rule, click **New alert rule**. To edit an existing rule, expand one of the rules in the **Cortex / Loki** section and click **Edit**.
|
||||
1. Click on the **Rule type** drop down and select **Cortex / Loki managed alert**.
|
||||
1. Click on the **Alert type** drop down and select **Cortex / Loki managed alert**.
|
||||
1. Fill out the rest of the fields. Descriptions are listed below in [Alert rule fields](#alert-rule-fields).
|
||||
1. When you have finished writing your rule, click **Save** in the upper right corner to save the rule, or **Save and exit** to save and exit rule editing.
|
||||
1. When you have finished writing your rule, click **Save** in the upper right corner to save the rule,, or **Save and exit** to save and exit rule editing.
|
||||
|
||||
## Alert rule fields
|
||||
|
||||
This section describes the fields you fill out to create an alert.
|
||||
|
||||
### Rule type
|
||||
### Alert type
|
||||
|
||||
- **Rule name -** Enter a descriptive name. The name will be displayed in the alert rule list, as well as added as `alertname` label to every alert instance that is created from this rule.
|
||||
- **Rule type -** Select **Cortex / Loki managed alert**.
|
||||
- **Data source -** Select a Prometheus or Loki data source. Only Prometheus data sources that support Cortex ruler API will be available.
|
||||
- **Namespace -** Select an existing rule namespace or click **Add new** and enter a name to create a new one. Namespaces can contain one or more rule groups and have only organizational purpose.
|
||||
- **Group -** Select an existing group within the selected namespace or click **Add new** and enter a name to create a new one. Newly created rules will be added to the end of the rule group. Rules within a group are run sequentially at a regular interval, with the same evaluation time.
|
||||
- **Alert name -** Enter a descriptive name. The name will be displayed in the alert rule list, as well as added as `alertname` label to every alert instance that is created from this rule.
|
||||
- **Alert type -** Select **Cortex / Loki managed alert**.
|
||||
- **Data source -** Select a Prometheus or Loki data source. Only Prometheus data sources that support Cortex ruler API will be available.
|
||||
- **Namespace -** Select an existing rule namespace or click **Add new** to create a new one.
|
||||
- **Group -** Select an existing group within the selected namespace or click **Add new** to create a new one. Newly created rules will be added to the end of the rule group.
|
||||
|
||||

|
||||
|
||||
@@ -41,7 +42,7 @@ Enter a PromQL or LogQL expression. Rule will fire if evaluation result has at l
|
||||
|
||||
### Conditions
|
||||
|
||||
- **For -** For how long the selected condition should violated before an alert enters `Firing` state. When condition threshold is violated for the first time, an alert becomes `Pending`. If the **for** time elapses and the condition is still violated, it becomes `Firing`. Else it reverts back to `Normal`.
|
||||
- **For -** For how long the selected condition should violated before an alert enters `Firing` state. When condition threshold is violated for the first time, an alert becomes `Pending`. If the **for** time elapses and the condition is still violated, it becomes `Firing`. Else it reverts back to `Normal`.
|
||||
|
||||

|
||||
|
||||
@@ -51,11 +52,11 @@ Annotations and labels can be optionally added in the details section.
|
||||
|
||||
#### Annotations
|
||||
|
||||
Annotations are key and value pairs that provide additional meta information about the alert, for example description, summary, runbook URL. They are displayed in rule and alert details in the UI and can be used in contact type message templates. Annotations can also be templated, for example `Instance {{ $labels.instance }} down` will have the evaluated `instance` label value added for every alert this rule produces.
|
||||
Annotations are key and value pairs that provide additional meta information about the alert, for example description, summary, runbook URL. They are displayed in rule and alert details in the UI and can be used in contact type message templates. Annotations can also be templated, for example `Instance {{ $labels.instance }} down` will have the evaluated `instance` label value added for every alert this rule produces.
|
||||
|
||||
#### Labels
|
||||
|
||||
Labels are key value pairs that categorize or identify an alert. Labels are used to match alerts in silences or match and groups alerts in notification policies. Labels are also shown in rule or alert details in the UI and can be used in contact type message templates. For example, it is common to add a `severity` label and then configure a separate notification policy for each severity. Or one could add a `team` label and configure team specific notification policies, or silence all alerts for a particular team.
|
||||
Labels are key value pairs that categorize or identify an alert. Labels are used to match alerts in silences or match and groups alerts in notification policies. Labels are also shown in rule or alert details in the UI and can be used in contact type message templates. For example, it is common to add a `severity` label and then configure a separate notification policy for each severity. Or one could add a `team` label and configure team specific notification policies, or silence all alerts for a particular team.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ weight = 400
|
||||
|
||||
# Create a Grafana managed alerting rule
|
||||
|
||||
Grafana allows you to create alerting rules that query one or more data sources, reduce or transform the results and compare them to each other or to fix thresholds. These rules will be executed and notifications sent by Grafana itself.
|
||||
Grafana allows you to create alerting rules that query one or more data sources, reduce or transform the results and compare them to each other or to fix thresholds. These rules will be executed and notifications sent by Grafana itself.
|
||||
|
||||
## Add or edit a Grafana managed alerting rule
|
||||
|
||||
@@ -23,15 +23,15 @@ This section describes the fields you fill out to create an alert.
|
||||
|
||||
### Alert type
|
||||
|
||||
- **Alert name -** Enter a descriptive name. The name will be displayed in the alert rule list, as well as added as `alertname` label to every alert instance that is created from this rule.
|
||||
- **Alert type -** Select **Grafana managed alert**.
|
||||
- **Folder -** Select a folder this alert rule will belong to. To create a new folder, click on the drop down and type in a new folder name.
|
||||
- **Alert name -** Enter a descriptive name. The name will be displayed in the alert rule list, as well as added as `alertname` label to every alert instance that is created from this rule.
|
||||
- **Alert type -** Select **Grafana managed alert**.
|
||||
- **Folder -** Select a folder this alert rule will belong to. To create a new folder, click on the drop down and type in a new folder name.
|
||||
|
||||

|
||||
|
||||
### Query
|
||||
|
||||
Add one or more [queries]({{< relref "../../../panels/queries.md" >}}) or [expressions]({{< relref "../../../panels/expressions.md" >}}). You can use classic condition expression to create a rule that will trigger a single alert if it's threshold is met, or use reduce and math expressions to create a multi dimensional alert rule that can trigger multiple alerts, one per matching series in the query result.
|
||||
Add one or more [queries]({{< relref "../../../panels/queries.md" >}}) or [expressions]({{< relref "../../../panels/expressions.md" >}}). You can use classic condition expression to create a rule that will trigger a single alert if it's threshold is met, or use reduce and math expressions to create a multi dimensional alert rule that can trigger multiple alerts, one per matching series in the query result.
|
||||
|
||||
#### Rule with classic condition
|
||||
|
||||
@@ -41,7 +41,7 @@ You can use classic condition expression to create a rule that will trigger a si
|
||||
1. Add an expression. Click on **Operation** dropdown and select **Classic condition**.
|
||||
1. Add one or more conditions. For each condition you can specify operator (`AND` / `OR`), aggregation function, query letter and threshold value.
|
||||
|
||||
If a query returns multiple series, then the aggregation function and threshold check will be evaluated for each series.It will not track alert state **per series**. This has implications that are detailed in the scenario below.
|
||||
If a query returns multiple series, then the aggregation function and threshold check will be evaluated for each series.It will not track alert state **per series**. This has implications that are detailed in the scenario below.
|
||||
|
||||
- Alert condition with query that returns 2 series: **server1** and **server2**
|
||||
- **server1** series causes the alert rule to fire and switch to state `Firing`
|
||||
@@ -67,24 +67,25 @@ See or [expressions documentation]({{< relref "../../../panels/expressions.md" >
|
||||
|
||||
### Conditions
|
||||
|
||||
- **Condition -** Select the letter of the query or expression whose result will trigger the alert rule. You will likely want to select either a `classic condition` or a `math` expression.
|
||||
- **Evaluate every -** How often the rule should be evaluated, executing the defined queries and expressions. Must be no less than 10 seconds and a multiple of 10 seconds. Examples: `1m`, `30s`
|
||||
- **Evaluate for -** For how long the selected condition should violated before an alert enters `Alerting` state. When condition threshold is violated for the first time, an alert becomes `Pending`. If the **for** time elapses and the condition is still violated, it becomes `Alerting`. Else it reverts back to `Normal`.
|
||||
- **Condition -** Select the letter of the query or expression whose result will trigger the alert rule. You will likely want to select either a `classic condition` or a `math` expression.
|
||||
- **Evaluate every -** How often the rule should be evaluated, executing the defined queries and expressions. Must be no less than 10 seconds and a multiple of 10 seconds. Examples: `1m`, `30s`
|
||||
- **Evaluate for -** For how long the selected condition should violated before an alert enters `Alerting` state. When condition threshold is violated for the first time, an alert becomes `Pending`. If the **for** time elapses and the condition is still violated, it becomes `Alerting`. Else it reverts back to `Normal`.
|
||||
|
||||
#### No Data & Error handling
|
||||
|
||||
Toggle **Configure no data and error handling** switch to configure how the rule should handle cases where evaluation results in error or returns no data.
|
||||
|
||||
Toggle **Configure no data and error handling** switch to configure how the rule should handle cases where evaluation results in error or returns no data.
|
||||
| No Data Option | Description |
|
||||
| --------------- | ------------------------------------------------------------------------------------------ |
|
||||
| No Data | Set alert state to `NoData` and rule state to `Normal` |
|
||||
| Alerting | Set alert rule state to `Alerting` |
|
||||
| Ok | Set alert rule state to `Normal` |
|
||||
|
||||
| No Data Option | Description |
|
||||
| -------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| No Data | Set alert state to `NoData` and rule state to `Normal` (notifications are not sent on NoData states). |
|
||||
| Alerting | Set alert rule state to `Alerting`. |
|
||||
| Ok | Set alert rule state to `Normal`. |
|
||||
|
||||
| Error or timeout option | Description |
|
||||
| ----------------------- | ---------------------------------- |
|
||||
| Alerting | Set alert rule state to `Alerting` |
|
||||
| OK | Set alert rule state to `Normal` |
|
||||
| Error or timeout option | Description |
|
||||
| ----------------------- | --------------------------------------------------- |
|
||||
| Alerting | Set alert rule state to `Alerting` |
|
||||
| OK | Set alert rule state to `Normal` |
|
||||
|
||||

|
||||
|
||||
@@ -94,11 +95,11 @@ Annotations and labels can be optionally added in the details section.
|
||||
|
||||
#### Annotations
|
||||
|
||||
Annotations are key and value pairs that provide additional meta information about the alert, for example description, summary, runbook URL. They are displayed in rule and alert details in the UI and can be used in contact type message templates. Annotations can also be templated, for example `Instance {{ $labels.instance }} down` will have the evaluated `instance` label value added for every alert this rule produces.
|
||||
Annotations are key and value pairs that provide additional meta information about the alert, for example description, summary, runbook URL. They are displayed in rule and alert details in the UI and can be used in contact type message templates. Annotations can also be templated, for example `Instance {{ $labels.instance }} down` will have the evaluated `instance` label value added for every alert this rule produces.
|
||||
|
||||
#### Labels
|
||||
|
||||
Labels are key value pairs that categorize or identify an alert. Labels are used to match alerts in silences or match and groups alerts in notification policies. Labels are also shown in rule or alert details in the UI and can be used in contact type message templates. For example, it is common to add a `severity` label and then configure a separate notification policy for each severity. Or one could add a `team` label and configure team specific notification policies, or silence all alerts for a particular team. Labels can also be templated like annotations, for example `{{ $labels.namespace }}/{{ $labels.job }}` will produce a new rule label that will have the evaluated `namespace` and `job` label value added for every alert this rule produces. The rule labels take precedence over the labels produced by the query/condition.
|
||||
Labels are key value pairs that categorize or identify an alert. Labels are used to match alerts in silences or match and groups alerts in notification policies. Labels are also shown in rule or alert details in the UI and can be used in contact type message templates. For example, it is common to add a `severity` label and then configure a separate notification policy for each severity. Or one could add a `team` label and configure team specific notification policies, or silence all alerts for a particular team. Labels can also be templated like annotations, for example `{{ $labels.namespace }}/{{ $labels.job }}` will produce a new rule label that will have the evaluated `namespace` and `job` label value added for every alert this rule produces. The rule labels take precedence over the labels produced by the query/condition.
|
||||
|
||||

|
||||
|
||||
@@ -106,11 +107,11 @@ Labels are key value pairs that categorize or identify an alert. Labels are used
|
||||
|
||||
The following template variables are available when expanding annotations and labels.
|
||||
|
||||
| Name | Description |
|
||||
| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| $labels | The labels from the query or condition. For example, `{{ $labels.instance }}` and `{{ $labels.job }}`. This is unavailable when the rule uses a classic condition. |
|
||||
| $values | The values of all reduce and math expressions that were evaluated for this alert rule. For example, `{{ $values.A }}`, `{{ $values.A.Labels }}` and `{{ $values.A.Value }}` where `A` is the `refID` of the expression. This is unavailable when the rule uses a classic condition. |
|
||||
| $value | The value string of the alert instance. For example, `[ var='A' labels={instance=foo} value=10 ]`. |
|
||||
| Name | Description |
|
||||
| ------- | --------------- |
|
||||
| $labels | The labels from the query or condition. For example, `{{ $labels.instance }}` and `{{ $labels.job }}`. |
|
||||
| $values | The values of all reduce and math expressions that were evaluated for this alert rule. For example, `{{ $values.A }}`, `{{ $values.A.Labels }}` and `{{ $values.A.Value }}` where `A` is the `refID` of the expression. |
|
||||
| $value | The value string of the alert instance. For example, `[ var='A' labels={instance=foo} value=10 ]`. |
|
||||
|
||||
## Preview alerts
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user