Compare commits

..

15 Commits

Author SHA1 Message Date
Grot (@grafanabot)
147704deb9 "Release: Updated versions in package to 8.1.0-beta.2" (#37138) 2021-07-23 10:29:33 +02:00
Grot (@grafanabot)
078d716be9 IconButton: Put tooltip text as aria-label (#36760) (#37137)
* Make tooltip prop aria-label

* Add ariaLabel prop

(cherry picked from commit 8af83b8b78)

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
2021-07-23 10:12:16 +02:00
Grot (@grafanabot)
04cb471599 Expand the value string in annotations and labels of alerts (#37051) (#37105)
This commit makes it possible to use the value string in
annotations and labels for alerts with "{{ $value }}"

(cherry picked from commit 2f4c893cf3)

Co-authored-by: George Robinson <85952834+gerobinson@users.noreply.github.com>
2021-07-23 09:28:49 +02:00
Grot (@grafanabot)
6564f22772 Gazetteer: Update Countries Json (#37129) (#37132)
(cherry picked from commit 2b51e94537)

Co-authored-by: Bryan Uribe <buribe@hmc.edu>
2021-07-23 09:25:20 +02:00
Grot (@grafanabot)
13cd3ea28b Explore: Fix encoding of internal URLs (#36919) (#37100)
* Encode internal explore url

* Fix tests

* Fix comma

(cherry picked from commit 93b4cc7035)

Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
2021-07-23 09:19:25 +02:00
Grot (@grafanabot)
d5e0665081 Storybook: Add a11y addon (#36790) (#37110)
* Storybook: Add a11y addon

* Update lockfile

* Bump Storybook addon versions

* Put Icon at top

* addon-knobs 6.3.0

(cherry picked from commit 437424d5d6)

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
2021-07-23 09:17:59 +02:00
Grot (@grafanabot)
909141592d StatPanel: Disable selection on Sparkline (#37125) (#37128)
(cherry picked from commit a1bbe797df)

Co-authored-by: nikki-kiga <42276368+nikki-kiga@users.noreply.github.com>
2021-07-23 09:14:51 +02:00
Grot (@grafanabot)
fda235a862 Infra: Azure authentication in HttpClientProvider (#36932) (#37124)
* Azure middleware in HttpClientProxy

* Azure authentication under feature flag

* Minor fixes

* Add prefixes to not clash with JsonData

* Return error if JsonData cannot be parsed

* Return original string if URL invalid

* Tests for datasource_cache

(cherry picked from commit c1963024ec)

Co-authored-by: Sergey Kostrukov <sergey@kostrukov.com>
2021-07-22 23:12:31 +02:00
Grot (@grafanabot)
154231a58d Doc: first draft of 8.1 what's new (#37021) (#37115)
* Create whats-new-in-v8-1.md

* Updated index page.

* Fixed two relrefs.

* Added section for annotation panel

(cherry picked from commit 013218e075)

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
2021-07-22 15:28:48 -04:00
Grot (@grafanabot)
197e4344da Prometheus: Azure authentication in configuration UI (#35860) (#37116)
* Azure authentication settings

* Persisting credentials

* Azure settings

* Prometheus-specific settings component

* Azure Prometheus Resource ID configuration

* DataSourceHttpSettings with extensibility for Azure

* Feature toggle for Azure auth

* Fix snapshot

* Update format of persisted credentials

* AzureSettings renamed to AzureAuthSettings

(cherry picked from commit 4664cba935)

Co-authored-by: Sergey Kostrukov <sergey@kostrukov.com>
2021-07-22 21:22:31 +02:00
Grot (@grafanabot)
64b008e28b ReleaseNotes: Updated changelog and release notes for 8.1.0-beta1 (#37111) (#37112) 2021-07-22 18:38:49 +02:00
Grot (@grafanabot)
bc9ac1199b fix sample.ini (#37106) (#37107)
(cherry picked from commit 6b2d33dc14)

Co-authored-by: Alexander Emelin <frvzmb@gmail.com>
2021-07-22 17:25:47 +02:00
Grot (@grafanabot)
2b15e1a962 Folder API: optionally force deleting Grafana 8 alerts when deleting a folder (or error) (#36427) (#37094)
* Folder API: Add an optional query parameter for allowing deleting a  folder containing rules

* Update frontend

- Set forceDeleteRules=true when frontend deletes a folder
- Improve modal text

* Update docs

* Apply suggestions from code review

Co-authored-by: gotjosh <josue@grafana.com>
Co-authored-by: Nathan Rodman <nathanrodman@gmail.com>
Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
(cherry picked from commit b96dd1877c)

Co-authored-by: Sofia Papagiannaki <papagian@users.noreply.github.com>
2021-07-22 17:56:33 +03:00
Grot (@grafanabot)
4308a77e27 Auth: Pass user role to Grafana using auth proxy (#36729) (#37103)
* Pass role to Grafana using auth proxy

By default, the role will be applied to the default org of the user.
If the request uses the standard header "X-Grafana-Org-Id", the role will be applied to the specified org

Tested in both unit test and manually E2E

* Address comment: only allow the user role to be applied to the default org

Co-authored-by: Leonard Gram <leo@xlson.com>
(cherry picked from commit ad1f792b8b)

Co-authored-by: yuwaMSFT2 <yuwa@microsoft.com>
2021-07-22 16:25:51 +02:00
Grot (@grafanabot)
f18749927c "Release: Updated versions in package to 8.1.0-beta.1" (#37091) 2021-07-22 11:21:21 +02:00
2539 changed files with 42090 additions and 99750 deletions

12
.bingo/.gitignore vendored
View File

@@ -1,12 +0,0 @@
# Ignore everything
*
# But not these files:
!.gitignore
!*.mod
!README.md
!Variables.mk
!variables.env
*tmp.mod

View File

@@ -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+

View File

@@ -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"

View File

@@ -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.

View File

@@ -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"

View File

@@ -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

View File

@@ -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"]

View File

@@ -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'

File diff suppressed because it is too large Load Diff

4
.github/CODEOWNERS vendored
View File

@@ -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

View File

@@ -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/**/*"],

View File

@@ -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
View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -5,9 +5,8 @@ pkg/
node_modules
public/vendor/
vendor/
/data/
data/
e2e/tmp
public/build/
public/sass/*.generated.scss
devenv/
public/lib/monaco

File diff suppressed because it is too large Load Diff

View File

@@ -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.

View File

@@ -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>"

View File

@@ -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

View File

@@ -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
View File

@@ -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]
}

View File

@@ -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/

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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}>
```

View File

@@ -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:

View File

@@ -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
View 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
}

View File

@@ -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
...

View File

@@ -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
View 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")

View File

@@ -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)

View File

@@ -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
}
}

View File

@@ -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"

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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",

View File

@@ -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"

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -44,7 +44,7 @@
[[inputs.logparser]]
files = [
"/var/log/host/*.log",
"/var/log/*.log",
"/var/log/grafana/*.log"
]
[inputs.logparser.grok]

View File

@@ -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

View File

@@ -52,7 +52,7 @@
[[inputs.logparser]]
files = [
"/var/log/host/*.log",
"/var/log/*.log",
"/var/log/grafana/*.log"
]
[inputs.logparser.grok]

View File

@@ -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

View File

@@ -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"]

View File

@@ -1 +0,0 @@
grafana/provisioning/dashboards/alerts/alert-*

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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",
]
}
]
}

View File

@@ -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.

View File

@@ -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>

View File

@@ -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
```

View File

@@ -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`.

View File

@@ -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).

View 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"
```

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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 >}}

View File

@@ -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

View File

@@ -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 | |

View File

@@ -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.

View File

@@ -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

View File

@@ -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]

View File

@@ -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" >}}).

View File

@@ -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

View File

@@ -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" >}}).

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View File

@@ -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 (@&lt;user&gt;, all lowercase, no whitespace), or a channel reference (#&lt;channel&gt;, 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 (@&lt;user&gt;, all lowercase, no whitespace), or a channel reference (#&lt;channel&gt;, 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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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" >}})

View File

@@ -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" >}})

View File

@@ -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.
![Rule type section screenshot](/static/img/docs/alerting/unified/rule-edit-cortex-recording-rule-8-2.png 'Rule type section screenshot')
### Query
Enter a PromQL or LogQL expression. The result of this expression will get recorded as the value for the new metric.
![Query section](/static/img/docs/alerting/unified/rule-edit-cortex-recording-rule-query-8-2.png 'Query section screenshot')
### Details
You can optionally define labels in the details section.
![Details section](/static/img/docs/alerting/unified/rule-recording-rule-labels-8-2.png 'Details section screenshot')

View File

@@ -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.
![Alert type section screenshot](/static/img/docs/alerting/unified/rule-edit-cortex-alert-type-8-0.png 'Alert type section screenshot')
@@ -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`.
![Conditions section](/static/img/docs/alerting/unified/rule-edit-cortex-conditions-8-0.png 'Conditions section screenshot')
@@ -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.
![Details section](/static/img/docs/alerting/unified/rule-edit-details-8-0.png 'Details section screenshot')

View File

@@ -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.
![Alert type section screenshot](/static/img/docs/alerting/unified/rule-edit-grafana-alert-type-8-0.png 'Alert type section screenshot')
### 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` |
![Conditions section](/static/img/docs/alerting/unified/rule-edit-grafana-conditions-8-0.png 'Conditions section screenshot')
@@ -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.
![Details section](/static/img/docs/alerting/unified/rule-edit-details-8-0.png 'Details section screenshot')
@@ -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