Merge branch 'main' into drew08t/canvas-add-zoom

This commit is contained in:
drew08t 2023-10-30 10:27:07 -07:00
commit 5a8f1d2957
622 changed files with 21622 additions and 7170 deletions

View File

@ -5,24 +5,8 @@
//
exports[`better eslint`] = {
value: `{
"e2e/cypress/support/index.d.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"e2e/utils/flows/addDataSource.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"e2e/utils/support/scenarioContext.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"e2e/utils/support/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Do not use any type assertions.", "5"],
[0, 0, 0, "Do not use any type assertions.", "6"],
[0, 0, 0, "Do not use any type assertions.", "7"]
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-data/src/dataframe/ArrayDataFrame.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@ -732,31 +716,15 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
[0, 0, 0, "Unexpected any. Specify a different type.", "12"]
],
"packages/grafana-runtime/src/services/live.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-runtime/src/utils/DataSourceWithBackend.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"packages/grafana-runtime/src/utils/plugin.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-runtime/src/utils/queryResponse.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-runtime/src/utils/queryResponse.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"]
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"packages/grafana-runtime/src/utils/queryResponse.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-schema/src/veneer/common.types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@ -816,12 +784,6 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/Drawer/Drawer.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/Forms/FieldArray.story.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/Forms/Legacy/Input/Input.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@ -871,28 +833,16 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/InfoBox/InfoBox.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/JSONFormatter/JSONFormatter.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/JSONFormatter/json_explorer/json_explorer.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/Layout/Layout.story.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/MatchersUI/FieldValueMatcher.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/MatchersUI/fieldMatchersUI.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/Menu/MenuGroup.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/Menu/MenuItem.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/Menu/SubMenu.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
@ -901,12 +851,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"packages/grafana-ui/src/components/Monaco/CodeEditor.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
@ -922,11 +867,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/QueryField/QueryField.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
],
"packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"packages/grafana-ui/src/components/Segment/SegmentSelect.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@ -1040,14 +981,6 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/Tags/Tag.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/TimeSeries/TimeSeries.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"packages/grafana-ui/src/components/TimeSeries/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
@ -1092,9 +1025,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"packages/grafana-ui/src/components/uPlot/plugins/TooltipPlugin2.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/uPlot/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@ -1459,27 +1389,6 @@ exports[`better eslint`] = {
"public/app/core/components/RolePicker/ValueContainer.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"]
],
"public/app/core/components/RolePicker/styles.ts:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"],
[0, 0, 0, "Styles should be written using objects.", "2"],
[0, 0, 0, "Styles should be written using objects.", "3"],
[0, 0, 0, "Styles should be written using objects.", "4"],
[0, 0, 0, "Styles should be written using objects.", "5"],
[0, 0, 0, "Styles should be written using objects.", "6"],
[0, 0, 0, "Styles should be written using objects.", "7"],
[0, 0, 0, "Styles should be written using objects.", "8"],
[0, 0, 0, "Styles should be written using objects.", "9"],
[0, 0, 0, "Styles should be written using objects.", "10"],
[0, 0, 0, "Styles should be written using objects.", "11"],
[0, 0, 0, "Styles should be written using objects.", "12"],
[0, 0, 0, "Styles should be written using objects.", "13"],
[0, 0, 0, "Styles should be written using objects.", "14"],
[0, 0, 0, "Styles should be written using objects.", "15"],
[0, 0, 0, "Styles should be written using objects.", "16"],
[0, 0, 0, "Styles should be written using objects.", "17"],
[0, 0, 0, "Styles should be written using objects.", "18"]
],
"public/app/core/components/Select/OldFolderPicker.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"]
@ -1556,10 +1465,6 @@ exports[`better eslint`] = {
"public/app/core/navigation/GrafanaRouteError.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"]
],
"public/app/core/navigation/__mocks__/routeProps.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/core/navigation/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@ -2055,16 +1960,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Styles should be written using objects.", "1"],
[0, 0, 0, "Styles should be written using objects.", "2"]
],
"public/app/features/alerting/unified/components/alert-groups/AlertGroup.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"],
[0, 0, 0, "Styles should be written using objects.", "2"],
[0, 0, 0, "Styles should be written using objects.", "3"],
[0, 0, 0, "Styles should be written using objects.", "4"],
[0, 0, 0, "Styles should be written using objects.", "5"],
[0, 0, 0, "Styles should be written using objects.", "6"],
[0, 0, 0, "Styles should be written using objects.", "7"]
],
"public/app/features/alerting/unified/components/alert-groups/AlertGroupAlertsTable.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"]
@ -2317,10 +2212,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Styles should be written using objects.", "3"],
[0, 0, 0, "Styles should be written using objects.", "4"]
],
"public/app/features/alerting/unified/components/receivers/grafanaAppReceivers/ReceiverMetadataBadge.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"]
],
"public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@ -3127,10 +3018,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard/components/DeleteDashboard/DeleteDashboardModal.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"]
],
"public/app/features/dashboard/components/GenAI/llms/openai.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/features/dashboard/components/HelpWizard/HelpWizard.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"],
@ -3409,9 +3296,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"]
],
"public/app/features/dashboard/containers/EmbeddedDashboardPage.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"]
],
"public/app/features/dashboard/dashgrid/DashboardGrid.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@ -3475,17 +3359,18 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
[0, 0, 0, "Do not use any type assertions.", "22"],
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
[0, 0, 0, "Unexpected any. Specify a different type.", "24"],
[0, 0, 0, "Unexpected any. Specify a different type.", "25"],
[0, 0, 0, "Unexpected any. Specify a different type.", "26"],
[0, 0, 0, "Unexpected any. Specify a different type.", "27"],
[0, 0, 0, "Do not use any type assertions.", "28"],
[0, 0, 0, "Unexpected any. Specify a different type.", "28"],
[0, 0, 0, "Do not use any type assertions.", "29"],
[0, 0, 0, "Unexpected any. Specify a different type.", "30"],
[0, 0, 0, "Do not use any type assertions.", "30"],
[0, 0, 0, "Unexpected any. Specify a different type.", "31"],
[0, 0, 0, "Do not use any type assertions.", "32"]
[0, 0, 0, "Unexpected any. Specify a different type.", "32"],
[0, 0, 0, "Do not use any type assertions.", "33"]
],
"public/app/features/dashboard/state/DashboardModel.repeat.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@ -4035,13 +3920,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Styles should be written using objects.", "11"],
[0, 0, 0, "Styles should be written using objects.", "12"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanBar.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"],
[0, 0, 0, "Styles should be written using objects.", "2"],
[0, 0, 0, "Styles should be written using objects.", "3"],
[0, 0, 0, "Styles should be written using objects.", "4"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanBarRow.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
[0, 0, 0, "Styles should be written using objects.", "1"],
@ -6583,8 +6461,7 @@ exports[`better eslint`] = {
],
"public/app/plugins/datasource/prometheus/components/PromQueryField.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],
@ -6711,8 +6588,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "Do not use any type assertions.", "6"]
[0, 0, 0, "Do not use any type assertions.", "5"]
],
"public/app/plugins/datasource/prometheus/language_utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@ -7275,6 +7151,9 @@ exports[`better eslint`] = {
"public/app/plugins/panel/geomap/layers/data/geojsonDynamic.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/geomap/layers/data/routeLayer.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/plugins/panel/geomap/layers/registry.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@ -7373,9 +7252,10 @@ exports[`better eslint`] = {
],
"public/app/plugins/panel/histogram/Histogram.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
[0, 0, 0, "Do not use any type assertions.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
],
"public/app/plugins/panel/live/LiveChannelEditor.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@ -7435,7 +7315,8 @@ exports[`better eslint`] = {
[0, 0, 0, "Styles should be written using objects.", "4"],
[0, 0, 0, "Styles should be written using objects.", "5"],
[0, 0, 0, "Styles should be written using objects.", "6"],
[0, 0, 0, "Styles should be written using objects.", "7"]
[0, 0, 0, "Styles should be written using objects.", "7"],
[0, 0, 0, "Styles should be written using objects.", "8"]
],
"public/app/plugins/panel/nodeGraph/NodeGraph.tsx:5381": [
[0, 0, 0, "Styles should be written using objects.", "0"],

View File

@ -2,7 +2,12 @@
# 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
ifeq ($(OS),Windows_NT)
PATHSEP := $(if $(COMSPEC),;,:)
GOBIN ?= $(firstword $(subst $(PATHSEP), ,$(subst \,/,${GOPATH})))/bin
else
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
endif
GO ?= $(shell which go)
# Below generated variables ensure that every time a tool under each variable is invoked, the correct version

View File

@ -122,14 +122,14 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- apk add --update git bash
- yarn betterer ci
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: betterer-frontend
- commands:
- apk add --update curl jq bash
@ -158,7 +158,7 @@ steps:
- yarn-install
environment:
TEST_MAX_WORKERS: 50%
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: test-frontend
trigger:
event:
@ -222,7 +222,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- yarn run prettier:check
@ -232,7 +232,7 @@ steps:
- yarn-install
environment:
TEST_MAX_WORKERS: 50%
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: lint-frontend
- commands:
- apk add --update git
@ -247,7 +247,7 @@ steps:
- yarn run i18n:compile
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: verify-i18n
trigger:
event:
@ -529,7 +529,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- apk add --update jq bash
@ -540,7 +540,7 @@ steps:
- yarn-install
environment:
NODE_OPTIONS: --max_old_space_size=8192
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: build-frontend-packages
- failure: ignore
image: grafana/drone-downstream
@ -678,7 +678,7 @@ steps:
- build-frontend-packages
environment:
NODE_OPTIONS: --max_old_space_size=4096
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: build-storybook
when:
paths:
@ -1035,7 +1035,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- pip3 install codespell
@ -1048,7 +1048,7 @@ steps:
- yarn-install
environment:
NODE_OPTIONS: --max_old_space_size=8192
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: lint-docs
- commands:
- mkdir -p /hugo/content/docs/grafana/latest
@ -1056,8 +1056,9 @@ steps:
true\n---\n'' > /hugo/content/docs/grafana/_index.md'
- cp -r docs/sources/* /hugo/content/docs/grafana/latest/
- cd /hugo && make prod
image: grafana/docs-base:dbd975af06
image: grafana/docs-base:latest
name: build-docs-website
pull: always
- commands:
- '# It is required that code generated from Thema/CUE be committed and in sync
with its inputs.'
@ -1132,6 +1133,67 @@ volumes:
clone:
retries: 3
depends_on: []
image_pull_secrets:
- dockerconfigjson
kind: pipeline
name: pr-swagger-gen
node:
type: no-parallel
platform:
arch: amd64
os: linux
services: []
steps:
- commands:
- apk add --update curl jq bash
- is_fork=$(curl "https://$GITHUB_TOKEN@api.github.com/repos/grafana/grafana/pulls/$DRONE_PULL_REQUEST"
| jq .head.repo.fork)
- if [ "$is_fork" != false ]; then return 1; fi
- git clone "https://$${GITHUB_TOKEN}@github.com/grafana/grafana-enterprise.git"
grafana-enterprise
- cd grafana-enterprise
- if git checkout ${DRONE_SOURCE_BRANCH}; then echo "checked out ${DRONE_SOURCE_BRANCH}";
elif git checkout main; then echo "git checkout main"; else git checkout main;
fi
environment:
GITHUB_TOKEN:
from_secret: github_token
failure: ignore
image: alpine/git:2.40.1
name: clone-enterprise
- commands:
- apk add --update git make
- make swagger-clean && make openapi3-gen
- for f in public/api-merged.json public/openapi3.json; do git add $f; done
- if [ -z "$(git diff --name-only --cached)" ]; then echo "Everything seems up to
date!"; else echo "Please ensure the branch is up-to-date, then regenerate the
specification by running make swagger-clean && make openapi3-gen" && return 1;
fi
depends_on:
- clone-enterprise
environment:
GITHUB_TOKEN:
from_secret: github_token
image: golang:1.20.10-alpine
name: swagger-gen
trigger:
event:
- pull_request
paths:
exclude:
- docs/**
- '*.md'
include:
- pkg/**
type: docker
volumes:
- host:
path: /var/run/docker.sock
name: docker
---
clone:
retries: 3
depends_on: []
environment:
EDITION: oss
image_pull_secrets:
@ -1328,7 +1390,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- pip3 install codespell
@ -1341,7 +1403,7 @@ steps:
- yarn-install
environment:
NODE_OPTIONS: --max_old_space_size=8192
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: lint-docs
- commands:
- mkdir -p /hugo/content/docs/grafana/latest
@ -1349,8 +1411,9 @@ steps:
true\n---\n'' > /hugo/content/docs/grafana/_index.md'
- cp -r docs/sources/* /hugo/content/docs/grafana/latest/
- cd /hugo && make prod
image: grafana/docs-base:dbd975af06
image: grafana/docs-base:latest
name: build-docs-website
pull: always
- commands:
- '# It is required that code generated from Thema/CUE be committed and in sync
with its inputs.'
@ -1402,14 +1465,14 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- apk add --update git bash
- yarn betterer ci
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: betterer-frontend
- commands:
- yarn run ci:test-frontend
@ -1417,7 +1480,7 @@ steps:
- yarn-install
environment:
TEST_MAX_WORKERS: 50%
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: test-frontend
trigger:
branch: main
@ -1459,7 +1522,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- yarn run prettier:check
@ -1469,7 +1532,7 @@ steps:
- yarn-install
environment:
TEST_MAX_WORKERS: 50%
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: lint-frontend
- commands:
- apk add --update git
@ -1484,7 +1547,7 @@ steps:
- yarn run i18n:compile
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: verify-i18n
trigger:
branch: main
@ -1718,7 +1781,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- apk add --update jq
@ -1729,7 +1792,7 @@ steps:
- yarn install --mode=update-lockfile
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: update-package-json-version
- commands:
- apk add --update jq bash
@ -1741,14 +1804,14 @@ steps:
- update-package-json-version
environment:
NODE_OPTIONS: --max_old_space_size=8192
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: build-frontend-packages
- commands:
- /src/grafana-build package --distro=linux/amd64,linux/arm64 --go-version=1.20.10
--yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER --grafana-dir=$$PWD
> packages.txt
depends_on:
- yarn-install
- update-package-json-version
image: grafana/grafana-build:main
name: rgm-package
pull: always
@ -1866,7 +1929,7 @@ steps:
- build-frontend-packages
environment:
NODE_OPTIONS: --max_old_space_size=4096
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: build-storybook
when:
paths:
@ -1916,7 +1979,7 @@ steps:
GRAFANA_MISC_STATS_API_KEY:
from_secret: grafana_misc_stats_api_key
failure: ignore
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: publish-frontend-metrics
when:
repo:
@ -1998,7 +2061,7 @@ steps:
environment:
NPM_TOKEN:
from_secret: npm_token
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: release-canary-npm-packages
when:
paths:
@ -2626,7 +2689,7 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- ./bin/build artifacts npm retrieve --tag ${DRONE_TAG}
@ -2650,7 +2713,7 @@ steps:
NPM_TOKEN:
from_secret: npm_token
failure: ignore
image: golang:1.20.10-alpine
image: node:20.9.0-alpine
name: release-npm-packages
trigger:
event:
@ -2771,7 +2834,7 @@ services: []
steps:
- commands:
- export GRAFANA_DIR=$$(pwd)
- cd /src && ./scripts/drone_publish_main.sh
- cd /src && ./scripts/drone_build_main.sh
environment:
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
from_secret: dagger_token
@ -2893,14 +2956,14 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- apk add --update git bash
- yarn betterer ci
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: betterer-frontend
- commands:
- yarn run ci:test-frontend
@ -2908,7 +2971,7 @@ steps:
- yarn-install
environment:
TEST_MAX_WORKERS: 50%
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: test-frontend
trigger:
event:
@ -3020,7 +3083,7 @@ services: []
steps:
- commands:
- export GRAFANA_DIR=$$(pwd)
- cd /src && ./scripts/drone_publish_tag_grafana.sh
- cd /src && ./scripts/drone_build_tag_grafana.sh
environment:
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
from_secret: dagger_token
@ -3198,7 +3261,7 @@ services: []
steps:
- commands:
- export GRAFANA_DIR=$$(pwd)
- cd /src && ./scripts/drone_publish_tag_grafana.sh
- cd /src && ./scripts/drone_build_tag_grafana.sh
environment:
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
from_secret: dagger_token
@ -3305,14 +3368,14 @@ steps:
- commands:
- yarn install --immutable
depends_on: []
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: yarn-install
- commands:
- apk add --update git bash
- yarn betterer ci
depends_on:
- yarn-install
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: betterer-frontend
- commands:
- yarn run ci:test-frontend
@ -3320,7 +3383,7 @@ steps:
- yarn-install
environment:
TEST_MAX_WORKERS: 50%
image: node:18.12.0-alpine
image: node:20.9.0-alpine
name: test-frontend
trigger:
cron:
@ -4326,7 +4389,7 @@ steps:
- commands:
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine/git:2.40.1
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.20.10-alpine
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:18.12.0-alpine
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:20.9.0-alpine
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM google/cloud-sdk:431.0.0
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana-ci-deploy:1.3.3
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.18.3
@ -4344,7 +4407,7 @@ steps:
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM osixia/openldap:1.4.0
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/drone-downstream
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/docker-puppeteer:1.1.0
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/docs-base:dbd975af06
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/docs-base:latest
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM cypress/included:13.1.0
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM jwilder/dockerize:0.6.1
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM koalaman/shellcheck:stable
@ -4360,7 +4423,7 @@ steps:
- commands:
- trivy --exit-code 1 --severity HIGH,CRITICAL alpine/git:2.40.1
- trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.20.10-alpine
- trivy --exit-code 1 --severity HIGH,CRITICAL node:18.12.0-alpine
- trivy --exit-code 1 --severity HIGH,CRITICAL node:20.9.0-alpine
- trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0
- trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana-ci-deploy:1.3.3
- trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.18.3
@ -4378,7 +4441,7 @@ steps:
- trivy --exit-code 1 --severity HIGH,CRITICAL osixia/openldap:1.4.0
- trivy --exit-code 1 --severity HIGH,CRITICAL grafana/drone-downstream
- trivy --exit-code 1 --severity HIGH,CRITICAL grafana/docker-puppeteer:1.1.0
- trivy --exit-code 1 --severity HIGH,CRITICAL grafana/docs-base:dbd975af06
- trivy --exit-code 1 --severity HIGH,CRITICAL grafana/docs-base:latest
- trivy --exit-code 1 --severity HIGH,CRITICAL cypress/included:13.1.0
- trivy --exit-code 1 --severity HIGH,CRITICAL jwilder/dockerize:0.6.1
- trivy --exit-code 1 --severity HIGH,CRITICAL koalaman/shellcheck:stable
@ -4607,6 +4670,6 @@ kind: secret
name: gcr_credentials
---
kind: signature
hmac: a7032573772937b59787f5c01c113b02afb07a9febf15664a68cbcee1458acc9
hmac: 64de498d74f13b64f233fe5d37751903a0efb03b3cab28e046797dc80d390965
...

15
.github/CODEOWNERS vendored
View File

@ -103,7 +103,6 @@
/pkg/services/correlations/ @grafana/explore-squad
/pkg/services/dashboardimport/ @grafana/backend-platform
/pkg/services/dashboards/ @grafana/backend-platform
/pkg/services/dashboardsnapshots/ @grafana/sharing-squad
/pkg/services/dashboardversion/ @grafana/backend-platform
/pkg/services/encryption/ @grafana/backend-platform
/pkg/services/folder/ @grafana/backend-platform
@ -118,7 +117,6 @@
/pkg/services/plugindashboards/ @grafana/backend-platform
/pkg/services/preference/ @grafana/backend-platform
/pkg/services/provisioning/ @grafana/backend-platform
/pkg/services/publicdashboards/ @grafana/sharing-squad
/pkg/services/query/ @grafana/backend-platform
/pkg/services/queryhistory/ @grafana/backend-platform
/pkg/services/quota/ @grafana/backend-platform
@ -411,7 +409,7 @@ cypress.config.js @grafana/grafana-frontend-platform
/public/app/features/storage/ @grafana/grafana-app-platform-squad
/public/app/features/teams/ @grafana/grafana-authnz-team
/public/app/features/templating/ @grafana/dashboards-squad
/public/app/features/transformers/ @grafana/dataviz-squad
/public/app/features/transformers/ @grafana/grafana-bi-squad
/public/app/features/users/ @grafana/grafana-authnz-team
/public/app/features/variables/ @grafana/dashboards-squad
/public/app/plugins/panel/alertGroups/ @grafana/alerting-frontend
@ -513,6 +511,7 @@ cypress.config.js @grafana/grafana-frontend-platform
/scripts/verify-repo-update/ @grafana/grafana-delivery
scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/grafana-frontend-platform
/scripts/docs/generate-transformations.ts @grafana/grafana-bi-squad
/scripts/webpack/ @grafana/frontend-ops
/scripts/generate-a11y-report.sh @grafana/grafana-frontend-platform
.pa11yci.conf.js @grafana/grafana-frontend-platform
@ -550,6 +549,14 @@ scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/graf
/public/app/plugins/datasource/parca/ @grafana/observability-traces-and-profiling
/public/app/plugins/datasource/alertmanager/ @grafana/alerting-squad
# Grafana Sharing Squad
/public/app/features/dashboard/components/ShareModal/ @grafana/sharing-squad
/public/app/features/manage-dashboards/components/PublicDashboardListTable/ @grafana/sharing-squad
/public/app/features/dashboard/containers/PublicDashboardPage.tsx @grafana/sharing-squad
/public/app/features/manage-dashboards/components/SnapshotListTable.tsx @grafana/sharing-squad
/pkg/services/dashboardsnapshots/ @grafana/sharing-squad
/pkg/services/publicdashboards/ @grafana/sharing-squad
# SSE - Server Side Expressions
/pkg/expr/ @grafana/observability-metrics
@ -654,7 +661,7 @@ embed.go @grafana/grafana-as-code
/.github/workflows/ephemeral-instances-pr-comment.yml @grafana/grafana-operator-experience-squad
/.github/workflows/ephemeral-instances-pr-opened-closed.yml @grafana/grafana-operator-experience-squad
/.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-delivery
/.github/workflows/core-plugins-build-and-release.yml @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
# Generated files not requiring owner approval
/packages/grafana-data/src/types/featureToggles.gen.ts @grafanabot

View File

@ -4,28 +4,20 @@
],
"enabledManagers": ["npm"],
"ignoreDeps": [
"commander", // we are planning to remove this, so no need to update it
"execa", // we should bump this once we move to esm modules
"history", // we should bump this together with react-router-dom
"@mdx-js/react", // storybook peer-depends on its 1.x version, we should upgrade this when we upgrade storybook
"history", // we should bump this together with react-router-dom (see https://github.com/grafana/grafana/issues/76744)
"react-router-dom", // we should bump this together with history (see https://github.com/grafana/grafana/issues/76744)
"monaco-editor", // due to us exposing this via @grafana/ui/CodeEditor's props bumping can break plugins
"react-hook-form", // due to us exposing these hooks via @grafana/ui form components bumping can break plugins
"react-redux", // react-beautiful-dnd depends on react-redux 7.x, we need to update that one first
"react-router-dom", // we should bump this together with history
"ts-loader", // we should remove ts-loader and use babel-loader instead
"ora", // we should bump this once we move to esm modules
"@locker/near-membrane-dom", // critical library. we need to bump this only intentionally
"@locker/near-membrane-shared", // critical library. we need to bump this only intentionally
"@locker/near-membrane-shared-dom", // critical library. we need to bump this only intentionally
],
"includePaths": ["package.json", "packages/**", "public/app/plugins/**"],
"ignorePaths": ["emails/**", "plugins-bundled/**", "**/mocks/**"],
"ignorePaths": ["emails/**", "plugins-bundled/**", "**/mocks/**", "packages/grafana-e2e/**"],
"labels": ["area/frontend", "dependencies", "no-backport", "no-changelog"],
"postUpdateOptions": ["yarnDedupeHighest"],
"packageRules": [
{
"matchUpdateTypes": ["patch"],
"excludePackagePatterns": ["^@?storybook"],
"excludePackagePatterns": ["^@?storybook", "^@locker"],
"extends": ["schedule:monthly"],
"groupName": "Monthly patch updates"
},
@ -78,6 +70,13 @@
],
"reviewers": ["leeoniya"],
},
{
"groupName": "locker",
"matchPackagePrefixes": [
"@locker/"
]
"reviewers": ["team:grafana/plugins-platform-frontend"],
},
],
"pin": {
"enabled": false

View File

@ -59,7 +59,7 @@ jobs:
- uses: actions/setup-go@v4
with:
go-version: '1.20'
- uses: actions/setup-node@v3.8.1
- uses: actions/setup-node@v4
with:
node-version: '16'
- name: Install Actions

View File

@ -0,0 +1,218 @@
on:
workflow_dispatch:
inputs:
plugin_id:
description: "ID of the plugin you want to publish"
required: true
type: choice
options:
- grafana-testdata-datasource
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}-${{ inputs.plugin_id }}
cancel-in-progress: true
env:
GRABPL_VERSION: 3.0.44
GCP_BUCKET: integration-artifacts # Dev: plugins-community-staging
GCOM_API: https://grafana.com # Dev: https://grafana-dev.com
jobs:
build-and-publish:
name: Build and publish ${{ inputs.plugin_id }}
runs-on: ubuntu-latest
outputs:
type: ${{ steps.get_dir.outputs.dir }}
has_backend: ${{ steps.check_backend.outputs.has_backend }}
version: ${{ steps.build_frontend.outputs.version }}
steps:
- name: checkout
uses: actions/checkout@v4
- name: Verify inputs
run: |
if [ -z ${{ inputs.plugin_id }} ]; then echo "Missing plugin ID"; exit 1; fi
- name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v1'
with:
credentials_json: '${{ secrets.PLUGINS_GOOGLE_CREDENTIALS }}'
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Setup nodejs environment
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: yarn
- name: Find plugin directory
shell: bash
id: get_dir
run: |
dir=$(find public/app/plugins -name ${{ inputs.plugin_id }} -print -quit)
echo "dir=${dir}" >> $GITHUB_OUTPUT
- name: Install frontend dependencies
shell: bash
working-directory: ${{ steps.get_dir.outputs.dir }}
run: |
yarn install --immutable
- name: Download grabpl executable
shell: sh
working-directory: ${{ steps.get_dir.outputs.dir }}
run: |
[ ! -d ./bin ] && mkdir -pv ./bin || true
curl -fL -o ./bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v${{ env.GRABPL_VERSION }}/grabpl
chmod 0755 ./bin/grabpl
- name: Check backend
id: check_backend
shell: bash
run: |
if [ -d ./pkg/tsdb/${{ inputs.plugin_id }} ]; then
echo "has_backend=true" >> $GITHUB_OUTPUT
else
echo "has_backend=false" >> $GITHUB_OUTPUT
fi
- name: Setup golang environment
uses: actions/setup-go@v4
if: steps.check_backend.outputs.has_backend == 'true'
with:
go-version-file: go.mod
- name: Install Mage
shell: bash
if: steps.check_backend.outputs.has_backend == 'true'
run: |
go install github.com/magefile/mage
- name: Check tools
shell: bash
working-directory: ${{ steps.get_dir.outputs.dir }}
run: |
echo "======================================="
echo " Frontend tools"
echo "======================================="
echo "-------- node version -----"
node --version
echo "-------- npm version -----"
npm --version
echo "-------- yarn version -----"
yarn --version
echo "======================================="
echo " Misc tools"
echo "======================================="
echo "-------- docker version -----"
docker --version
echo "-------- jq version -----"
jq --version
echo "-------- grabpl version -----"
./bin/grabpl --version
echo "======================================="
- name: Check backend tools
shell: bash
if: steps.check_backend.outputs.has_backend == 'true'
working-directory: ${{ steps.get_dir.outputs.dir }}
run: |
echo "======================================="
echo " Backend tools"
echo "======================================="
echo "-------- go version -----"
go version
echo "-------- mage version -----"
mage --version
echo "======================================="
- name: build:frontend
shell: bash
id: build_frontend
run: |
command="plugin:build:commit"
if [ "$GITHUB_REF" != "refs/heads/main" ]; then
# Release branch, do not add commit hash to version
command="plugin:build"
fi
yarn $command --scope="@grafana-plugins/${{ inputs.plugin_id }}"
version=$(cat ${{ steps.get_dir.outputs.dir }}/dist/plugin.json | jq -r .info.version)
echo "version=${version}" >> $GITHUB_OUTPUT
- name: build:backend
if: steps.check_backend.outputs.has_backend == 'true'
shell: bash
env:
VERSION: ${{ steps.build_frontend.outputs.version }}
run: |
make build-plugin-go PLUGIN_ID=${{ inputs.plugin_id }}
- name: package
working-directory: ${{ steps.get_dir.outputs.dir }}
run: |
mkdir -p ci/jobs/package
bin/grabpl plugin package
env:
GRAFANA_API_KEY: ${{ secrets.PLUGINS_GRAFANA_API_KEY }}
PLUGIN_SIGNATURE_TYPE: grafana
- name: Check existing release
env:
GCOM_TOKEN: ${{ secrets.PLUGINS_GCOM_TOKEN }}
VERSION: ${{ steps.build_frontend.outputs.version }}
run: |
api_res=$(curl -X 'GET' -H "Authorization: Bearer $GCOM_TOKEN" \
'${{ env.GCOM_API}}/api/plugins/${{ inputs.plugin_id }}?version=$VERSION' \
-H 'accept: application/json')
api_res_code=$(echo $api_res | jq -r .code)
if [ "$api_res_code" = "NotFound" ]; then
echo "No existing release found"
else
echo "Expecting a missing release, got:"
echo $api_res
exit 1
fi
- name: store build artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: ${{ steps.get_dir.outputs.dir }}/ci/packages/*.zip
- name: Publish release to Google Cloud Storage
working-directory: ${{ steps.get_dir.outputs.dir }}
env:
VERSION: ${{ steps.build_frontend.outputs.version }}
run: |
echo "Publish release to Google Cloud Storage:"
touch ci/packages/windows ci/packages/darwin ci/packages/linux ci/packages/any
gsutil -m cp -r ci/packages/*windows* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/windows
gsutil -m cp -r ci/packages/*linux* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux
gsutil -m cp -r ci/packages/*darwin* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin
gsutil -m cp -r ci/packages/*any* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/any
- name: Publish new plugin version on grafana.com
working-directory: ${{ steps.get_dir.outputs.dir }}
env:
GCOM_TOKEN: ${{ secrets.PLUGINS_GCOM_TOKEN }}
VERSION: ${{ steps.build_frontend.outputs.version }}
run: |
echo "Publish new plugin version on grafana.com:"
echo "Plugin version: ${VERSION}"
result=`curl -H "Authorization: Bearer $GCOM_TOKEN" -H "Content-Type: application/json" ${{ env.GCOM_API}}/api/plugins -d "{
\"url\": \"https://github.com/grafana/grafana/tree/main/${{ steps.get_dir.outputs.dir }}\",
\"download\": {
\"linux-amd64\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux/${{ inputs.plugin_id }}-${VERSION}.linux_amd64.zip\",
\"md5\": \"$(cat ci/packages/info-linux_amd64.json | jq -r .plugin.md5)\"
},
\"linux-arm64\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux/${{ inputs.plugin_id }}-${VERSION}.linux_arm64.zip\",
\"md5\": \"$(cat ci/packages/info-linux_arm64.json | jq -r .plugin.md5)\"
},
\"linux-arm\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/linux/${{ inputs.plugin_id }}-${VERSION}.linux_arm.zip\",
\"md5\": \"$(cat ci/packages/info-linux_arm.json | jq -r .plugin.md5)\"
},
\"windows-amd64\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/windows/${{ inputs.plugin_id }}-${VERSION}.windows_amd64.zip\",
\"md5\": \"$(cat ci/packages/info-windows_amd64.json | jq -r .plugin.md5)\"
},
\"darwin-amd64\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin/${{ inputs.plugin_id }}-${VERSION}.darwin_amd64.zip\",
\"md5\": \"$(cat ci/packages/info-darwin_amd64.json | jq -r .plugin.md5)\"
},
\"darwin-arm64\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin/${{ inputs.plugin_id }}-${VERSION}.darwin_arm64.zip\",
\"md5\": \"$(cat ci/packages/info-darwin_arm64.json | jq -r .plugin.md5)\"
}
}
}"`
if [[ "$(echo $result | jq -r .version)" == "null" ]]; then
echo "Failed to publish plugin version. Got:"
echo $result
exit 1
fi

View File

@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v4
with:
path: './pr'
- uses: actions/setup-node@v3.8.1
- uses: actions/setup-node@v4
with:
node-version: 16.16.0
@ -70,7 +70,7 @@ jobs:
path: './base'
ref: ${{ github.event.pull_request.base.ref }}
- uses: actions/setup-node@v3.8.1
- uses: actions/setup-node@v4
with:
node-version: 16.16.0

View File

@ -7,7 +7,7 @@ jobs:
doc-validator:
runs-on: "ubuntu-latest"
container:
image: "grafana/doc-validator:v3.2.1"
image: "grafana/doc-validator:v4.0.0"
steps:
- name: "Checkout code"
uses: "actions/checkout@v4"

6
.gitignore vendored
View File

@ -202,4 +202,8 @@ deployment_tools_config.json
.pr-body.txt
# Core plugin builds
public/app/plugins/**/dist/
public/app/plugins/**/dist/
# Ignore transpiled JavaScript resulting from the generate-transformations.ts script.
/public/app/features/transformers/docs/*.js
/scripts/docs/generate-transformations.js

2
.nvmrc
View File

@ -1 +1 @@
v18.12.0
v20.9.0

View File

@ -33,7 +33,8 @@ var dashboardSettings = [
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=permissions',
wait: 500,
rootElement: '.main-view',
threshold: 9,
// TODO: improve the accessibility of the permission tab https://github.com/grafana/grafana/issues/77203
threshold: 11,
},
{
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=dashboard_json',

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@ nodeLinker: pnp
packageExtensions:
'@storybook/core-common@7.4.5':
dependencies:
'@storybook/react-webpack5': '7.4.5'
'@storybook/react-webpack5': 7.4.5
doctrine@3.0.0:
dependencies:
assert: 2.0.0
@ -35,7 +35,7 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
spec: 'https://mskelton.dev/yarn-outdated/v2'
yarnPath: .yarn/releases/yarn-3.6.1.cjs
yarnPath: .yarn/releases/yarn-3.6.4.cjs
# Uncomment the following lines if you want to use Verdaccio local npm registry. Read more at packages/README.md
# npmScopes:
# grafana:

View File

@ -1,3 +1,324 @@
<!-- 10.2.0 START -->
# 10.2.0 (2023-10-24)
### Features and enhancements
- **Canvas:** Promote Button to beta. [#76582](https://github.com/grafana/grafana/issues/76582), [@adela-almasan](https://github.com/adela-almasan)
- **BarChart:** Improve data links UX in tooltip. [#76514](https://github.com/grafana/grafana/issues/76514), [@torkelo](https://github.com/torkelo)
- **PluginExtensions:** Make sure to pass default timeZone in context. [#76513](https://github.com/grafana/grafana/issues/76513), [@mckn](https://github.com/mckn)
- **PublicDashboards:** Enable feature by default for GA and remove public preview text. [#76484](https://github.com/grafana/grafana/issues/76484), [@juanicabanas](https://github.com/juanicabanas)
- **Grafana UI:** Add Avatar component. [#76429](https://github.com/grafana/grafana/issues/76429), [@Clarity-89](https://github.com/Clarity-89)
- **Alerting:** Add support for msteams contact point in external Alertmanagers. [#76392](https://github.com/grafana/grafana/issues/76392), [@alexweav](https://github.com/alexweav)
- **Alerting:** Enable Insights landing page. [#76381](https://github.com/grafana/grafana/issues/76381), [@VikaCep](https://github.com/VikaCep)
- **Transformations:** De-emphasize non-applicable transformations. [#76373](https://github.com/grafana/grafana/issues/76373), [@codeincarnate](https://github.com/codeincarnate)
- **Explore:** Use short units in graphs. [#76358](https://github.com/grafana/grafana/issues/76358), [@Elfo404](https://github.com/Elfo404)
- **Auth:** Enable `None` role for 10.2. [#76343](https://github.com/grafana/grafana/issues/76343), [@eleijonmarck](https://github.com/eleijonmarck)
- **Transformations:** Add context to transformation editor. [#76317](https://github.com/grafana/grafana/issues/76317), [@mdvictor](https://github.com/mdvictor)
- **Transformations:** Add support for setting timezone in Format time and Convert field type transformations. [#76316](https://github.com/grafana/grafana/issues/76316), [@codeincarnate](https://github.com/codeincarnate)
- **Playlist:** Add create+update timestamps to the database. [#76295](https://github.com/grafana/grafana/issues/76295), [@ryantxu](https://github.com/ryantxu)
- **Live:** Allow setting the engine password. [#76289](https://github.com/grafana/grafana/issues/76289), [@jcalisto](https://github.com/jcalisto)
- **Auth:** Add support for role mapping and allowed groups in Google OIDC. [#76266](https://github.com/grafana/grafana/issues/76266), [@Jguer](https://github.com/Jguer)
- **Alerting:** Add provenance field to /api/v1/provisioning/alert-rules. [#76252](https://github.com/grafana/grafana/issues/76252), [@grobinson-grafana](https://github.com/grobinson-grafana)
- **Plugins:** Add status_source label to plugin request metrics. [#76236](https://github.com/grafana/grafana/issues/76236), [@xnyo](https://github.com/xnyo)
- **PluginExtensions:** Made it possible to control modal size from extension. [#76232](https://github.com/grafana/grafana/issues/76232), [@mckn](https://github.com/mckn)
- **Loki:** Change run query button text based on number of queries. [#76196](https://github.com/grafana/grafana/issues/76196), [@ivanahuckova](https://github.com/ivanahuckova)
- **CloudWatch Logs:** Add pattern command to syntax. [#76152](https://github.com/grafana/grafana/issues/76152), [@iwysiu](https://github.com/iwysiu)
- **Caching:** Add feature toggle for memory efficient cache payload serialization. [#76145](https://github.com/grafana/grafana/issues/76145), [@mmandrus](https://github.com/mmandrus)
- **Flamegraph:** Make color by package the default color mode. [#76137](https://github.com/grafana/grafana/issues/76137), [@aocenas](https://github.com/aocenas)
- **Service Accounts:** Enable adding folder, dashboard and data source permissions to service accounts. [#76133](https://github.com/grafana/grafana/issues/76133), [@Jguer](https://github.com/Jguer)
- **SparklineCell:** Display absolute value. [#76125](https://github.com/grafana/grafana/issues/76125), [@domasx2](https://github.com/domasx2)
- **FeatureToggle:** Add awsDatasourcesNewFormStyling feature toggle. [#76110](https://github.com/grafana/grafana/issues/76110), [@idastambuk](https://github.com/idastambuk)
- **CloudWatch:** Add missing AWS/Transfer metrics. [#76079](https://github.com/grafana/grafana/issues/76079), [@jangaraj](https://github.com/jangaraj)
- **Transformations:** Add variable support to join by field. [#76056](https://github.com/grafana/grafana/issues/76056), [@oscarkilhed](https://github.com/oscarkilhed)
- **Alerting:** Add rules export on a folder level. [#76016](https://github.com/grafana/grafana/issues/76016), [@konrad147](https://github.com/konrad147)
- **PanelConfig:** Add option to calculate min/max per field instead of using the global min/max in the data frame. [#75952](https://github.com/grafana/grafana/issues/75952), [@oscarkilhed](https://github.com/oscarkilhed)
- **Transformations:** Add unary operations to Add field from calculation. [#75946](https://github.com/grafana/grafana/issues/75946), [@mdvictor](https://github.com/mdvictor)
- **Bar Gauge:** Add field name placement option. [#75932](https://github.com/grafana/grafana/issues/75932), [@nmarrs](https://github.com/nmarrs)
- **AzureMonitor:** Azure Monitor Cheat sheet. [#75931](https://github.com/grafana/grafana/issues/75931), [@alyssabull](https://github.com/alyssabull)
- **Chore:** Bump grafana-plugin-sdk-go to v0.179.0. [#75886](https://github.com/grafana/grafana/issues/75886), [@leandro-deveikis](https://github.com/leandro-deveikis)
- **Dashboards:** Add template variables to selectable options. [#75870](https://github.com/grafana/grafana/issues/75870), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Docs:** Update RBAC documentation. [#75869](https://github.com/grafana/grafana/issues/75869), [@mgyongyosi](https://github.com/mgyongyosi)
- **Alerting:** Export of contact points to HCL. [#75849](https://github.com/grafana/grafana/issues/75849), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **BrowseDashboards:** Enable new Browse Dashboards UI by default. [#75822](https://github.com/grafana/grafana/issues/75822), [@joshhunt](https://github.com/joshhunt)
- **Alerting:** Use new endpoints in the Modify Export. [#75796](https://github.com/grafana/grafana/issues/75796), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Transformations:** Rename "Transform" tab to "Transform data". [#75757](https://github.com/grafana/grafana/issues/75757), [@codeincarnate](https://github.com/codeincarnate)
- **Loki:** Support X-ray as internal link in derived fields. [#75756](https://github.com/grafana/grafana/issues/75756), [@harshabaddam](https://github.com/harshabaddam)
- **Table:** Make sparkline cell respect no value option. [#75750](https://github.com/grafana/grafana/issues/75750), [@oscarkilhed](https://github.com/oscarkilhed)
- **Transformations:** Extended support for variables in filter by name. [#75734](https://github.com/grafana/grafana/issues/75734), [@oscarkilhed](https://github.com/oscarkilhed)
- **Tempo:** TraceQL results as a spans list. [#75660](https://github.com/grafana/grafana/issues/75660), [@adrapereira](https://github.com/adrapereira)
- **Transformations:** Add naming mode to partition by value. [#75650](https://github.com/grafana/grafana/issues/75650), [@oscarkilhed](https://github.com/oscarkilhed)
- **Transformations:** Correct description of rename by regex. [#75641](https://github.com/grafana/grafana/issues/75641), [@oscarkilhed](https://github.com/oscarkilhed)
- **Team:** Support `sort` query param for teams search endpoint. [#75622](https://github.com/grafana/grafana/issues/75622), [@gamab](https://github.com/gamab)
- **CloudWatch Logs:** Make monaco query editor general availability. [#75589](https://github.com/grafana/grafana/issues/75589), [@iwysiu](https://github.com/iwysiu)
- **Explore:** Improve timeseries limit disclaimer. [#75587](https://github.com/grafana/grafana/issues/75587), [@Elfo404](https://github.com/Elfo404)
- **Stat:** Disable wide layout. [#75556](https://github.com/grafana/grafana/issues/75556), [@nmarrs](https://github.com/nmarrs)
- **DataSourceAPI:** Add adhoc filters to DataQueryRequest and make it not depend on global templateSrv. [#75552](https://github.com/grafana/grafana/issues/75552), [@torkelo](https://github.com/torkelo)
- **Playlist:** Remove unused/deprecated api and unused wrapper. [#75503](https://github.com/grafana/grafana/issues/75503), [@ryantxu](https://github.com/ryantxu)
- **Explore:** Make Explore Toolbar sticky. [#75500](https://github.com/grafana/grafana/issues/75500), [@harisrozajac](https://github.com/harisrozajac)
- **Elasticsearch:** Added support for calendar_interval in ES date histogram queries. [#75459](https://github.com/grafana/grafana/issues/75459), [@NikolayTsvetkov](https://github.com/NikolayTsvetkov)
- **Alerting:** Manage remote Alertmanager silences. [#75452](https://github.com/grafana/grafana/issues/75452), [@santihernandezc](https://github.com/santihernandezc)
- **TimeSeries:** Implement ad hoc y-zoom via Shift-drag. [#75408](https://github.com/grafana/grafana/issues/75408), [@leeoniya](https://github.com/leeoniya)
- **Cloudwatch:** Add missing AWS regions. [#75392](https://github.com/grafana/grafana/issues/75392), [@SijmenHuizenga](https://github.com/SijmenHuizenga)
- **Transformations:** Add support for dashboard variable in limit, sort by, filter by value, heatmap and histogram. [#75372](https://github.com/grafana/grafana/issues/75372), [@oscarkilhed](https://github.com/oscarkilhed)
- **GrafanaUI:** Smaller padding around Drawer's title, subtitle, and tabs. [#75354](https://github.com/grafana/grafana/issues/75354), [@polibb](https://github.com/polibb)
- **InteractiveTable:** Add controlled sort. [#75289](https://github.com/grafana/grafana/issues/75289), [@Clarity-89](https://github.com/Clarity-89)
- **Feature Toggles API:** Trigger webhook call when updating. [#75254](https://github.com/grafana/grafana/issues/75254), [@jcalisto](https://github.com/jcalisto)
- **Trace View:** Span list visual update. [#75238](https://github.com/grafana/grafana/issues/75238), [@adrapereira](https://github.com/adrapereira)
- **User:** Support `sort` query param for user and org user, search endpoints. [#75229](https://github.com/grafana/grafana/issues/75229), [@gamab](https://github.com/gamab)
- **Admin:** Use backend sort. [#75228](https://github.com/grafana/grafana/issues/75228), [@Clarity-89](https://github.com/Clarity-89)
- **Breadcrumbs:** Enable plugins to override breadcrumbs that are generated by pages defined in plugin.json. [#75218](https://github.com/grafana/grafana/issues/75218), [@torkelo](https://github.com/torkelo)
- **Cloudwatch:** Add Documentation on Temporary Credentials. [#75178](https://github.com/grafana/grafana/issues/75178), [@sarahzinger](https://github.com/sarahzinger)
- **Tracing:** Span filters reset show matches only. [#75150](https://github.com/grafana/grafana/issues/75150), [@joey-grafana](https://github.com/joey-grafana)
- **Toggle:** Enable Recorded Queries Multi support by default. [#75097](https://github.com/grafana/grafana/issues/75097), [@kylebrandt](https://github.com/kylebrandt)
- **GrafanaUI:** Support memoization of useStyles additional arguments. [#75000](https://github.com/grafana/grafana/issues/75000), [@joshhunt](https://github.com/joshhunt)
- **NodeGraph:** Allow to set node radius in dataframe. [#74963](https://github.com/grafana/grafana/issues/74963), [@piggito](https://github.com/piggito)
- **AdhocFilters:** Improve typing and signature of getTagKeys and getTagValues and behaviors. [#74962](https://github.com/grafana/grafana/issues/74962), [@torkelo](https://github.com/torkelo)
- **OpenSearch:** Add timeRange to parameters passed to getTagValues. [#74952](https://github.com/grafana/grafana/issues/74952), [@iwysiu](https://github.com/iwysiu)
- **PublicDashboards:** Refresh ds plugin supported list. [#74947](https://github.com/grafana/grafana/issues/74947), [@juanicabanas](https://github.com/juanicabanas)
- **Chore:** Update metrics for AWS/MediaConnect. [#74946](https://github.com/grafana/grafana/issues/74946), [@Deepali1211](https://github.com/Deepali1211)
- **Tempo:** Added not regex operator. [#74907](https://github.com/grafana/grafana/issues/74907), [@adrapereira](https://github.com/adrapereira)
- **MySQL:** Update configuration page styling. [#74902](https://github.com/grafana/grafana/issues/74902), [@gwdawson](https://github.com/gwdawson)
- **InteractiveTable:** Add horizontal scroll. [#74888](https://github.com/grafana/grafana/issues/74888), [@Clarity-89](https://github.com/Clarity-89)
- **SSE:** Reduce to apply Mode to instant vector (mathexp.Number). [#74859](https://github.com/grafana/grafana/issues/74859), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **CloudWatch:** Correctly add dimension values to labels. [#74847](https://github.com/grafana/grafana/issues/74847), [@iwysiu](https://github.com/iwysiu)
- **Alerting:** Add export drawer when exporting all Grafana managed alerts. [#74846](https://github.com/grafana/grafana/issues/74846), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Feature:** Allow to disable a plugin. [#74840](https://github.com/grafana/grafana/issues/74840), [@andresmgot](https://github.com/andresmgot)
- **Alerting:** Always show expression warnings and errors. [#74839](https://github.com/grafana/grafana/issues/74839), [@gillesdemey](https://github.com/gillesdemey)
- **Tempo:** Added spss config - spans per span set. [#74832](https://github.com/grafana/grafana/issues/74832), [@adrapereira](https://github.com/adrapereira)
- **Admin:** Use InteractiveTable for user and team tables. [#74821](https://github.com/grafana/grafana/issues/74821), [@Clarity-89](https://github.com/Clarity-89)
- **Canvas:** Button API Editor support template variables. [#74779](https://github.com/grafana/grafana/issues/74779), [@adela-almasan](https://github.com/adela-almasan)
- **PublicDashboards:** Title logo and footer redesign. [#74769](https://github.com/grafana/grafana/issues/74769), [@juanicabanas](https://github.com/juanicabanas)
- **Tempo:** Highlight errors in TraceQL query. [#74697](https://github.com/grafana/grafana/issues/74697), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Folders:** Do not allow modifying the folder UID via the API. [#74684](https://github.com/grafana/grafana/issues/74684), [@papagian](https://github.com/papagian)
- **Pyroscope:** Remove support for old pyroscope. [#74683](https://github.com/grafana/grafana/issues/74683), [@aocenas](https://github.com/aocenas)
- **AzureMonitor:** Improve Log Analytics query efficiency. [#74675](https://github.com/grafana/grafana/issues/74675), [@aangelisc](https://github.com/aangelisc)
- **Canvas:** Button API Editor support setting parameters. [#74637](https://github.com/grafana/grafana/issues/74637), [@adela-almasan](https://github.com/adela-almasan)
- **Alerting:** Support for single rule and multi-folder rule export. [#74625](https://github.com/grafana/grafana/issues/74625), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Loki:** Added query editor and builder support for new Logfmt features. [#74619](https://github.com/grafana/grafana/issues/74619), [@matyax](https://github.com/matyax)
- **Alerting:** Add export drawer with yaml and json formats, in policies and contact points view. [#74613](https://github.com/grafana/grafana/issues/74613), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Canvas:** Button API - Add support for GET requests. [#74566](https://github.com/grafana/grafana/issues/74566), [@adela-almasan](https://github.com/adela-almasan)
- **Explore:** Content Outline. [#74536](https://github.com/grafana/grafana/issues/74536), [@harisrozajac](https://github.com/harisrozajac)
- **Alerting:** Add Grafana-managed groups and rules export. [#74522](https://github.com/grafana/grafana/issues/74522), [@konrad147](https://github.com/konrad147)
- **Plugins:** Unset annotation editor variables. [#74519](https://github.com/grafana/grafana/issues/74519), [@oshirohugo](https://github.com/oshirohugo)
- **Internationalization:** Set lang of HTML page to user language preference. [#74513](https://github.com/grafana/grafana/issues/74513), [@ypnos](https://github.com/ypnos)
- **Chore:** Remove unused/deprecated method. [#74485](https://github.com/grafana/grafana/issues/74485), [@ryantxu](https://github.com/ryantxu)
- **Logging:** Add `WithContextualAttributes` to pass log params based on the given context. [#74428](https://github.com/grafana/grafana/issues/74428), [@svennergr](https://github.com/svennergr)
- **CloudWatch:** Add AWS/S3 replication metrics (#74416). [#74418](https://github.com/grafana/grafana/issues/74418), [@jordanefillatre](https://github.com/jordanefillatre)
- **Canvas:** New circle/ellipse element. [#74389](https://github.com/grafana/grafana/issues/74389), [@Develer](https://github.com/Develer)
- **Loki:** Add backend healthcheck. [#74330](https://github.com/grafana/grafana/issues/74330), [@svennergr](https://github.com/svennergr)
- **Transformations:** Show row index as percent in 'Add field from calculation'. [#74322](https://github.com/grafana/grafana/issues/74322), [@mdvictor](https://github.com/mdvictor)
- **Geomap:** Add Symbol Alignment Options. [#74293](https://github.com/grafana/grafana/issues/74293), [@drew08t](https://github.com/drew08t)
- **Dashboard:** Auto-generate panel title and description using AI. [#74284](https://github.com/grafana/grafana/issues/74284), [@nmarrs](https://github.com/nmarrs)
- **Alerting:** Adds additional pagination to several views. [#74268](https://github.com/grafana/grafana/issues/74268), [@gillesdemey](https://github.com/gillesdemey)
- **CloudWatch:** Add additional AWS/Firehose metrics for DynamicPartitioning support. [#74237](https://github.com/grafana/grafana/issues/74237), [@tristanburgess](https://github.com/tristanburgess)
- **Chore:** Replace entity GRN with infra/grn GRN. [#74198](https://github.com/grafana/grafana/issues/74198), [@DanCech](https://github.com/DanCech)
- **Dashboard:** Remove old panel code and leave only new panel design. [#74196](https://github.com/grafana/grafana/issues/74196), [@polibb](https://github.com/polibb)
- **Tempo:** Update default editor to TraceQL tab. [#74153](https://github.com/grafana/grafana/issues/74153), [@joey-grafana](https://github.com/joey-grafana)
- **Plugins:** Move filter back to DataSourceWithBackend. [#74147](https://github.com/grafana/grafana/issues/74147), [@ryantxu](https://github.com/ryantxu)
- **Axis:** Add separate show axis option. [#74117](https://github.com/grafana/grafana/issues/74117), [@Develer](https://github.com/Develer)
- **Alerting:** Do not show grouping when grouplabels are empty in email template. [#74090](https://github.com/grafana/grafana/issues/74090), [@gillesdemey](https://github.com/gillesdemey)
- **Currency:** Add Malaysian Ringgit (RM). [#74073](https://github.com/grafana/grafana/issues/74073), [@skangmy](https://github.com/skangmy)
- **Alerting:** Paginate silences table(s). [#74041](https://github.com/grafana/grafana/issues/74041), [@gillesdemey](https://github.com/gillesdemey)
- **Chore:** Update grafana-plugin-sdk-go version. [#74039](https://github.com/grafana/grafana/issues/74039), [@oshirohugo](https://github.com/oshirohugo)
- **Dashboards:** Add "import dashboard" to empty dashboard landing page. [#74018](https://github.com/grafana/grafana/issues/74018), [@ivanortegaalba](https://github.com/ivanortegaalba)
- **Dashlist:** Use new nested folder picker. [#74011](https://github.com/grafana/grafana/issues/74011), [@joshhunt](https://github.com/joshhunt)
- **Plugins:** Add dependency column in version table. [#73991](https://github.com/grafana/grafana/issues/73991), [@oshirohugo](https://github.com/oshirohugo)
- **Elasticsearch:** Unify default value for geo hash grid precision across the code to 3. [#73922](https://github.com/grafana/grafana/issues/73922), [@ivanahuckova](https://github.com/ivanahuckova)
- **Dashboard:** Store original JSON in DashboardModel. [#73881](https://github.com/grafana/grafana/issues/73881), [@Clarity-89](https://github.com/Clarity-89)
- **Grafana/ui:** Expose trigger method from `useForm` to children. [#73831](https://github.com/grafana/grafana/issues/73831), [@javiruiz01](https://github.com/javiruiz01)
- **RBAC:** Enable permission validation by default. [#73804](https://github.com/grafana/grafana/issues/73804), [@mgyongyosi](https://github.com/mgyongyosi)
- **Alerting:** Update provisioning to validate user-defined UID on create. [#73793](https://github.com/grafana/grafana/issues/73793), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Plugins:** Allow async panel migrations. [#73782](https://github.com/grafana/grafana/issues/73782), [@joshhunt](https://github.com/joshhunt)
- **Correlations:** Allow creating correlations for provisioned data sources. [#73737](https://github.com/grafana/grafana/issues/73737), [@ifrost](https://github.com/ifrost)
- **Alerting:** Add contact point for Grafana OnCall. [#73733](https://github.com/grafana/grafana/issues/73733), [@grobinson-grafana](https://github.com/grobinson-grafana)
- **Tempo:** Improve autocompletion and syntax highlighting for TraceQL tab. [#73707](https://github.com/grafana/grafana/issues/73707), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Auth:** Make sure that SAML responses with default namespaces are parsed correctly. [#73701](https://github.com/grafana/grafana/issues/73701), [@IevaVasiljeva](https://github.com/IevaVasiljeva)
- **ArrayVector:** Add vector field value warning. [#73692](https://github.com/grafana/grafana/issues/73692), [@Develer](https://github.com/Develer)
- **Loki:** Implement `keep` and `drop` operations. [#73636](https://github.com/grafana/grafana/issues/73636), [@ivanahuckova](https://github.com/ivanahuckova)
- **Explore Logs:** Update log filtering functions to only have effect in the source query. [#73626](https://github.com/grafana/grafana/issues/73626), [@matyax](https://github.com/matyax)
- **Transforms:** Add 'Format String' Transform. [#73624](https://github.com/grafana/grafana/issues/73624), [@sjd210](https://github.com/sjd210)
- **Explore:** Improve handling time range keyboard shortcuts inside Explore. [#73600](https://github.com/grafana/grafana/issues/73600), [@ifrost](https://github.com/ifrost)
- **MSSQL:** Add support for MI authentication to MSSQL. [#73597](https://github.com/grafana/grafana/issues/73597), [@oscarkilhed](https://github.com/oscarkilhed)
- **Tracing:** Support remote, rate-limited, and probabilistic sampling in tracing.opentelemetry config section. [#73587](https://github.com/grafana/grafana/issues/73587), [@hairyhenderson](https://github.com/hairyhenderson)
- **Cloudwatch:** Upgrade grafana-aws-sdk. [#73580](https://github.com/grafana/grafana/issues/73580), [@sarahzinger](https://github.com/sarahzinger)
- **Pyroscope:** Template variable support. [#73572](https://github.com/grafana/grafana/issues/73572), [@aocenas](https://github.com/aocenas)
- **CloudWatch:** Add missing region Middle East (UAE) me-central-1. [#73560](https://github.com/grafana/grafana/issues/73560), [@gelldur](https://github.com/gelldur)
- **Feat:** Feature toggle admin page frontend write UI and InteractiveTable sorting. [#73533](https://github.com/grafana/grafana/issues/73533), [@IbrahimCSAE](https://github.com/IbrahimCSAE)
- **Cloudwatch:** Add back support for old Log Group picker. [#73524](https://github.com/grafana/grafana/issues/73524), [@sarahzinger](https://github.com/sarahzinger)
- **Google Cloud Monitor:** Prom query editor. [#73503](https://github.com/grafana/grafana/issues/73503), [@bossinc](https://github.com/bossinc)
- **Plugins:** Remove deprecated grafana-toolkit. [#73489](https://github.com/grafana/grafana/issues/73489), [@Ukochka](https://github.com/Ukochka)
- **LibraryPanels:** Add RBAC support. [#73475](https://github.com/grafana/grafana/issues/73475), [@kaydelaney](https://github.com/kaydelaney)
- **Chore:** Remove DashboardPickerByID. [#73466](https://github.com/grafana/grafana/issues/73466), [@Clarity-89](https://github.com/Clarity-89)
- **Elastic:** Add `id` field to Elastic responses to allow permalinking. [#73382](https://github.com/grafana/grafana/issues/73382), [@svennergr](https://github.com/svennergr)
- **Correlations:** Add an editor in Explore. [#73315](https://github.com/grafana/grafana/issues/73315), [@gelicia](https://github.com/gelicia)
- **Tempo:** Replace template variables in TraceQL tab when streaming is enabled. [#73259](https://github.com/grafana/grafana/issues/73259), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **CloudWatch Logs:** Wrap sync error from executeGetQueryResults. [#73252](https://github.com/grafana/grafana/issues/73252), [@iwysiu](https://github.com/iwysiu)
- **Elasticsearch:** Enable running of queries trough data source backend. [#73222](https://github.com/grafana/grafana/issues/73222), [@ivanahuckova](https://github.com/ivanahuckova)
- **Tempo:** Metrics summary. [#73201](https://github.com/grafana/grafana/issues/73201), [@joey-grafana](https://github.com/joey-grafana)
- **Alerting:** Export of alert rules in HCL format. [#73166](https://github.com/grafana/grafana/issues/73166), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **SSE:** Localize/Contain Errors within an Expression. [#73163](https://github.com/grafana/grafana/issues/73163), [@kylebrandt](https://github.com/kylebrandt)
- **Dashboards:** PanelChrome - remove untitled placeholder and add border when panel is transparent. [#73150](https://github.com/grafana/grafana/issues/73150), [@axelavargas](https://github.com/axelavargas)
- **CloudWatch:** Add missing AppFlow metrics. [#73149](https://github.com/grafana/grafana/issues/73149), [@ciancullinan](https://github.com/ciancullinan)
- **Flamegraph:** Move to package. [#73113](https://github.com/grafana/grafana/issues/73113), [@aocenas](https://github.com/aocenas)
- **Plugins:** Forward feature toggles to plugins. [#72995](https://github.com/grafana/grafana/issues/72995), [@oshirohugo](https://github.com/oshirohugo)
- **SSE:** Group data source node execution by data source. [#72935](https://github.com/grafana/grafana/issues/72935), [@kylebrandt](https://github.com/kylebrandt)
- **Dashboard:** Support template variables in Search tab for Tempo. [#72867](https://github.com/grafana/grafana/issues/72867), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Cloudwatch:** Upgrade aws-sdk and display external ids for temporary credentials. [#72821](https://github.com/grafana/grafana/issues/72821), [@sarahzinger](https://github.com/sarahzinger)
- **Dashboards:** Add megawatt hour (MWh) unit. [#72779](https://github.com/grafana/grafana/issues/72779), [@zuchka](https://github.com/zuchka)
- **Dashboard:** Add support for Tempo query variables. [#72745](https://github.com/grafana/grafana/issues/72745), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Auth:** Add key_id config param to auth.jwt. [#72711](https://github.com/grafana/grafana/issues/72711), [@mgyongyosi](https://github.com/mgyongyosi)
- **Alerting:** Move legacy alert migration from sqlstore migration to service. [#72702](https://github.com/grafana/grafana/issues/72702), [@JacobsonMT](https://github.com/JacobsonMT)
- **Loki:** Introduce `$__auto` range variable for metric queries. [#72690](https://github.com/grafana/grafana/issues/72690), [@ivanahuckova](https://github.com/ivanahuckova)
- **GLDS:** Move Text component from the `unstable` package to `grafana-ui`. [#72660](https://github.com/grafana/grafana/issues/72660), [@eledobleefe](https://github.com/eledobleefe)
- **Datasource Plugins:** Allow tracking for configuration usage. [#72650](https://github.com/grafana/grafana/issues/72650), [@sarahzinger](https://github.com/sarahzinger)
- **Cloudwatch Logs:** Set Alerting timeout to datasource config's logsTimeout (#72611). [#72611](https://github.com/grafana/grafana/issues/72611), [@idastambuk](https://github.com/idastambuk)
- **Flamegraph:** Add nice empty state for dashboard panel. [#72583](https://github.com/grafana/grafana/issues/72583), [@aocenas](https://github.com/aocenas)
- **Explore:** Unified Node Graph Container. [#72558](https://github.com/grafana/grafana/issues/72558), [@harisrozajac](https://github.com/harisrozajac)
- **Tracing:** Split name column in search results. [#72449](https://github.com/grafana/grafana/issues/72449), [@joey-grafana](https://github.com/joey-grafana)
- **Tracing:** Trace to metrics default range. [#72433](https://github.com/grafana/grafana/issues/72433), [@joey-grafana](https://github.com/joey-grafana)
- **Email:** Light theme email templates. [#72398](https://github.com/grafana/grafana/issues/72398), [@gillesdemey](https://github.com/gillesdemey)
- **Correlations:** Add organization id. [#72258](https://github.com/grafana/grafana/issues/72258), [@ifrost](https://github.com/ifrost)
- **Feat:** Feature toggle admin page frontend interface. [#72164](https://github.com/grafana/grafana/issues/72164), [@IbrahimCSAE](https://github.com/IbrahimCSAE)
- **Alerting:** Show annotations markers in TimeSeries panel when using Loki as …. [#72084](https://github.com/grafana/grafana/issues/72084), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Alerting:** Custom contact point for OnCall in Grafana AM. [#72021](https://github.com/grafana/grafana/issues/72021), [@konrad147](https://github.com/konrad147)
- **Frontend:** Allows PanelChrome to be collapsed. [#71991](https://github.com/grafana/grafana/issues/71991), [@harisrozajac](https://github.com/harisrozajac)
- **Elasticsearch:** Implement modify query using a Lucene parser. [#71954](https://github.com/grafana/grafana/issues/71954), [@matyax](https://github.com/matyax)
- **Table:** Support display of multiple sub tables. [#71953](https://github.com/grafana/grafana/issues/71953), [@joey-grafana](https://github.com/joey-grafana)
- **A11y:** Make Annotations and Template Variables list and edit pages responsive . [#71791](https://github.com/grafana/grafana/issues/71791), [@juanicabanas](https://github.com/juanicabanas)
- **Dashboard:** Select the last used data source by default when adding a panel to a dashboard. [#71777](https://github.com/grafana/grafana/issues/71777), [@axelavargas](https://github.com/axelavargas)
- **Trace to logs:** Add service name and namespace to default tags. [#71776](https://github.com/grafana/grafana/issues/71776), [@connorlindsey](https://github.com/connorlindsey)
- **Alerting:** Add new metrics and tracings to state manager and scheduler. [#71398](https://github.com/grafana/grafana/issues/71398), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Alerting:** Add configuration options to migrate to an external Alertmanager. [#71318](https://github.com/grafana/grafana/issues/71318), [@santihernandezc](https://github.com/santihernandezc)
- **Annotations:** Improve updating annotation tags queries. [#71201](https://github.com/grafana/grafana/issues/71201), [@sakjur](https://github.com/sakjur)
- **SSE:** Support hysteresis threshold expression. [#70998](https://github.com/grafana/grafana/issues/70998), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Dashboards:** Add alert and panel icon for dashboards that use Angular plugins. [#70951](https://github.com/grafana/grafana/issues/70951), [@xnyo](https://github.com/xnyo)
- **Chore:** Update ubuntu image to 22.04. [#70719](https://github.com/grafana/grafana/issues/70719), [@orgads](https://github.com/orgads)
- **Auth:** Add support for OIDC RP-Initiated Logout. [#70357](https://github.com/grafana/grafana/issues/70357), [@venkatbvc](https://github.com/venkatbvc)
- **Dashboard:** Field Config - Add CFP franc currency (XPF). [#70036](https://github.com/grafana/grafana/issues/70036), [@smortex](https://github.com/smortex)
- **Auth:** Check id token expiry date. [#69829](https://github.com/grafana/grafana/issues/69829), [@akselleirv](https://github.com/akselleirv)
- **Alerting:** Update Discord settings to treat 'url' as a secure setting. [#69588](https://github.com/grafana/grafana/issues/69588), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Prometheus:** Add $\_\_rate_interval_ms to go along with $\_\_interval_ms. [#69582](https://github.com/grafana/grafana/issues/69582), [@ywwg](https://github.com/ywwg)
- **Alerting:** Update state manager to change all current states in the case when Error\NoData is executed as Ok\Nomal. [#68142](https://github.com/grafana/grafana/issues/68142), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Tempo:** Integrate context aware autocomplete API. [#67845](https://github.com/grafana/grafana/issues/67845), [@adrapereira](https://github.com/adrapereira)
- **GrafanaUI:** Add aria-label prop to RadioButtonGroup. [#67019](https://github.com/grafana/grafana/issues/67019), [@khushijain21](https://github.com/khushijain21)
- **Search API:** Search by folder UID. [#65040](https://github.com/grafana/grafana/issues/65040), [@joshhunt](https://github.com/joshhunt)
- **Alerting:** Migrate old alerting templates to Go templates. [#62911](https://github.com/grafana/grafana/issues/62911), [@grobinson-grafana](https://github.com/grobinson-grafana)
- **TeamGroupSync:** Delete group sync entries on team delete. (Enterprise)
- **ServiceAccounts:** Add SAs to managed permissions. (Enterprise)
- **PublicDashboards:** Title logo config. (Enterprise)
- **Caching:** Make cache payload serialization more resistant to out-of-memory crashes. (Enterprise)
- **Caching:** Change error logs for cache items not found to debug logs. (Enterprise)
- **Chore:** Add test console.warn catch. (Enterprise)
- **Emails:** Light theme. (Enterprise)
- **Reporting:** Switch to using dashboard UID. (Enterprise)
- **Recorded Queries:** Use new DS picker. (Enterprise)
- **Reporting:** Add ability to retry failed rendering requests (public preview). (Enterprise)
### Bug fixes
- **Snapshots:** Fix breakage of some panel types due to missing structureRev. [#76586](https://github.com/grafana/grafana/issues/76586), [@leeoniya](https://github.com/leeoniya)
- **Loki:** Fix Autocomplete in stream selector overwriting existing label names, or inserting autocomplete result within label value. [#76485](https://github.com/grafana/grafana/issues/76485), [@gtk-grafana](https://github.com/gtk-grafana)
- **Alerting:** Prevent cleanup of non-empty folders on migration revert. [#76439](https://github.com/grafana/grafana/issues/76439), [@JacobsonMT](https://github.com/JacobsonMT)
- **Flamegraph:** Fix inefficient regex generating error on some function names. [#76377](https://github.com/grafana/grafana/issues/76377), [@aocenas](https://github.com/aocenas)
- **Authn:** Prevent empty username and email during sync. [#76330](https://github.com/grafana/grafana/issues/76330), [@kalleep](https://github.com/kalleep)
- **RBAC:** Fix plugins pages access-control. [#76321](https://github.com/grafana/grafana/issues/76321), [@gamab](https://github.com/gamab)
- **Tabs:** Fixes focus style. [#76246](https://github.com/grafana/grafana/issues/76246), [@torkelo](https://github.com/torkelo)
- **Rendering:** Fix Windows plugin signature check. [#76123](https://github.com/grafana/grafana/issues/76123), [@AgnesToulet](https://github.com/AgnesToulet)
- **Dashboards:** It always detect changes when saving an existing dashboard . [#76116](https://github.com/grafana/grafana/issues/76116), [@ivanortegaalba](https://github.com/ivanortegaalba)
- **Flamegraph:** Fix theme propagation. [#76064](https://github.com/grafana/grafana/issues/76064), [@aocenas](https://github.com/aocenas)
- **Pyroscope:** Fix backend panic when querying out of bounds. [#76053](https://github.com/grafana/grafana/issues/76053), [@aocenas](https://github.com/aocenas)
- **DataSourcePicker:** Disable autocomplete for the search input . [#75898](https://github.com/grafana/grafana/issues/75898), [@ivanortegaalba](https://github.com/ivanortegaalba)
- **Loki:** Cache extracted labels. [#75842](https://github.com/grafana/grafana/issues/75842), [@gtk-grafana](https://github.com/gtk-grafana)
- **Tempo:** Fix service graph menu item links. [#75748](https://github.com/grafana/grafana/issues/75748), [@adrapereira](https://github.com/adrapereira)
- **Flamegraph:** Fix bug where package colors would be altered after focusin on a node. [#75695](https://github.com/grafana/grafana/issues/75695), [@aocenas](https://github.com/aocenas)
- **Legend:** Fix desc sort so NaNs are not display first. [#75685](https://github.com/grafana/grafana/issues/75685), [@nmarrs](https://github.com/nmarrs)
- **Transformations:** Fix bug with calculate field when using reduce and the all values calculation. [#75684](https://github.com/grafana/grafana/issues/75684), [@oscarkilhed](https://github.com/oscarkilhed)
- **Plugins:** Fix sorting issue with expandable rows. [#75553](https://github.com/grafana/grafana/issues/75553), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Alerting:** Show panels within collapsed rows in dashboard picker. [#75490](https://github.com/grafana/grafana/issues/75490), [@VikaCep](https://github.com/VikaCep)
- **Tempo:** Use timezone of selected range for timestamps. [#75438](https://github.com/grafana/grafana/issues/75438), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Flamegraph:** Fix css issues when embedded outside of Grafana. [#75369](https://github.com/grafana/grafana/issues/75369), [@aocenas](https://github.com/aocenas)
- **Alerting:** Make shareable alert rule link work if rule name contains forward slashes. [#75362](https://github.com/grafana/grafana/issues/75362), [@domasx2](https://github.com/domasx2)
- **SQLStore:** Fix race condition in RecursiveQueriesAreSupported. [#75274](https://github.com/grafana/grafana/issues/75274), [@grobinson-grafana](https://github.com/grobinson-grafana)
- **Connections:** Make the "Add new Connection" page work without internet access. [#75272](https://github.com/grafana/grafana/issues/75272), [@leventebalogh](https://github.com/leventebalogh)
- **TimeSeries:** Apply selected line style to custom pathBuilders. [#75261](https://github.com/grafana/grafana/issues/75261), [@leeoniya](https://github.com/leeoniya)
- **Alerting:** Fix non-applicable error checks for cloud and recording rules. [#75233](https://github.com/grafana/grafana/issues/75233), [@gillesdemey](https://github.com/gillesdemey)
- **TabsBar:** Fix height so that it aligns with grid, and alignItems center . [#75230](https://github.com/grafana/grafana/issues/75230), [@torkelo](https://github.com/torkelo)
- **Prometheus:** Fix creation of invalid dataframes with exemplars. [#75187](https://github.com/grafana/grafana/issues/75187), [@kylebrandt](https://github.com/kylebrandt)
- **Loki:** Fix filters not being added with multiple expressions and parsers. [#75152](https://github.com/grafana/grafana/issues/75152), [@svennergr](https://github.com/svennergr)
- **Pyroscope:** Fix error when no profile types are returned. [#75143](https://github.com/grafana/grafana/issues/75143), [@aocenas](https://github.com/aocenas)
- **BarChart:** Axes centered zero, borders, and colors. [#75136](https://github.com/grafana/grafana/issues/75136), [@leeoniya](https://github.com/leeoniya)
- **Plugins:** Refresh plugin info after installation. [#75074](https://github.com/grafana/grafana/issues/75074), [@oshirohugo](https://github.com/oshirohugo)
- **LDAP:** FIX Enable users on successfull login . [#75073](https://github.com/grafana/grafana/issues/75073), [@gamab](https://github.com/gamab)
- **XYChart:** Fix numerous axis options. [#75044](https://github.com/grafana/grafana/issues/75044), [@leeoniya](https://github.com/leeoniya)
- **Trace View:** Remove "deployment.environment" default traces 2 logs tag. [#74986](https://github.com/grafana/grafana/issues/74986), [@domasx2](https://github.com/domasx2)
- **Snapshots:** Use appUrl on snapshot list page. [#74944](https://github.com/grafana/grafana/issues/74944), [@evictorero](https://github.com/evictorero)
- **Canvas:** Fix inconsistent element placement when changing element type. [#74942](https://github.com/grafana/grafana/issues/74942), [@linghaoSu](https://github.com/linghaoSu)
- **Connections:** Display the type of the datasource. [#74808](https://github.com/grafana/grafana/issues/74808), [@leventebalogh](https://github.com/leventebalogh)
- **Alerting:** Indicate panels without identifier. [#74746](https://github.com/grafana/grafana/issues/74746), [@gillesdemey](https://github.com/gillesdemey)
- **Notifications:** Don't show toasts after refreshing. [#74712](https://github.com/grafana/grafana/issues/74712), [@joshhunt](https://github.com/joshhunt)
- **Alerting:** Fix default policy timing summary. [#74549](https://github.com/grafana/grafana/issues/74549), [@gillesdemey](https://github.com/gillesdemey)
- **Alerting:** Handle custom dashboard permissions in migration service. [#74504](https://github.com/grafana/grafana/issues/74504), [@JacobsonMT](https://github.com/JacobsonMT)
- **CloudWatch Logs:** Fix log query display name when used with expressions. [#74497](https://github.com/grafana/grafana/issues/74497), [@iwysiu](https://github.com/iwysiu)
- **Dashboards:** Escape tags. [#74437](https://github.com/grafana/grafana/issues/74437), [@fabrizio-grafana](https://github.com/fabrizio-grafana)
- **Cloudwatch:** Fix Unexpected error. [#74420](https://github.com/grafana/grafana/issues/74420), [@sarahzinger](https://github.com/sarahzinger)
- **Transformations:** Fix group by field transformation field name text-overflow. [#74173](https://github.com/grafana/grafana/issues/74173), [@oscarkilhed](https://github.com/oscarkilhed)
- **LDAP:** Disable removed users on login. [#74016](https://github.com/grafana/grafana/issues/74016), [@gamab](https://github.com/gamab)
- **Time Range:** Using relative time takes timezone into account. [#74013](https://github.com/grafana/grafana/issues/74013), [@ashharrison90](https://github.com/ashharrison90)
- **Loki:** Fix filtering with structured metadata. [#73955](https://github.com/grafana/grafana/issues/73955), [@svennergr](https://github.com/svennergr)
- **Dashboard embed:** Use port instead of callbackUrl. [#73883](https://github.com/grafana/grafana/issues/73883), [@Clarity-89](https://github.com/Clarity-89)
- **Alerting:** Fix data source copy when switching alert rule types. [#73854](https://github.com/grafana/grafana/issues/73854), [@gillesdemey](https://github.com/gillesdemey)
- **Alerting:** Fix delete cloud rule from detail page. [#73850](https://github.com/grafana/grafana/issues/73850), [@gillesdemey](https://github.com/gillesdemey)
- **LDAP:** Fix active sync with large quantities of users. [#73834](https://github.com/grafana/grafana/issues/73834), [@gamab](https://github.com/gamab)
- **PublicDashboards:** Data discrepancy fix. Use real datasource plugin when it is a public dashboard. . [#73708](https://github.com/grafana/grafana/issues/73708), [@juanicabanas](https://github.com/juanicabanas)
- **A11y:** Fix exemplar marker accessibility. [#73493](https://github.com/grafana/grafana/issues/73493), [@Develer](https://github.com/Develer)
- **A11y:** Fix resource picker accessibility. [#73488](https://github.com/grafana/grafana/issues/73488), [@Develer](https://github.com/Develer)
- **A11y:** Fix resource cards accessibility. [#73487](https://github.com/grafana/grafana/issues/73487), [@Develer](https://github.com/Develer)
- **Template Variables:** Fix conversion from non standard data to dataFrame. [#73486](https://github.com/grafana/grafana/issues/73486), [@aocenas](https://github.com/aocenas)
- **A11y:** Fix canvas element accessibility. [#73483](https://github.com/grafana/grafana/issues/73483), [@Develer](https://github.com/Develer)
- **Tempo:** Fix [object Object] shown as an Event message in Trace view. [#73473](https://github.com/grafana/grafana/issues/73473), [@aocenas](https://github.com/aocenas)
- **A11y:** Fix canvas setting button accessibility. [#73413](https://github.com/grafana/grafana/issues/73413), [@Develer](https://github.com/Develer)
- **PublicDashboards:** Query order bug fixed. [#73293](https://github.com/grafana/grafana/issues/73293), [@juanicabanas](https://github.com/juanicabanas)
- **DatePicker:** Fix calendar not showing correct selected range when changing time zones. [#73273](https://github.com/grafana/grafana/issues/73273), [@ashharrison90](https://github.com/ashharrison90)
- **Cloud Monitoring:** Support AliasBy property in MQL mode. [#73116](https://github.com/grafana/grafana/issues/73116), [@alyssabull](https://github.com/alyssabull)
- **Alerting:** Fix cloud rules editing. [#72927](https://github.com/grafana/grafana/issues/72927), [@konrad147](https://github.com/konrad147)
- **Dashboard:** Fixes dashboard setting Links overflow. [#72428](https://github.com/grafana/grafana/issues/72428), [@chauchausoup](https://github.com/chauchausoup)
- **A11y:** Fix toggletip predictable focus for keyboard users. [#72100](https://github.com/grafana/grafana/issues/72100), [@ckbedwell](https://github.com/ckbedwell)
- **Gauge:** Add overflow scrolling support for vertical and horizontal orientations. [#71690](https://github.com/grafana/grafana/issues/71690), [@nmarrs](https://github.com/nmarrs)
- **Export:** Remove DS input when dashboard is imported with a lib panel that already exists. [#69412](https://github.com/grafana/grafana/issues/69412), [@juanicabanas](https://github.com/juanicabanas)
- **Auditing and UsageInsights:** FIX Loki configuration to use proxy env variables. (Enterprise)
- **PDF:** Fix parenthesis in dashboard title. (Enterprise)
- **Reporting:** Handle commas in variables. (Enterprise)
- **Caching:** Fix caching metrics being doubled. (Enterprise)
### Breaking changes
The deprecated `/playlists/{uid}/dashboards` API endpoint has been removed. Dashboard information can be retrieved from the `/dashboard/...` APIs. Issue [#75503](https://github.com/grafana/grafana/issues/75503)
The `PUT /api/folders/:uid` endpoint no more supports modifying the folder's `UID`. Issue [#74684](https://github.com/grafana/grafana/issues/74684)
This is a breaking change as we're removing support for `Intersection` (although it is replaced with an option that is nearly the same). Issue [#74675](https://github.com/grafana/grafana/issues/74675)
<Breaking change description>
Removed all components for the old panel header design. Issue [#74196](https://github.com/grafana/grafana/issues/74196)
### Deprecations
Correlations created before 10.1.0 do not have an organization id assigned and are treated as global. In some rare cases, it may lead to confusing behavior described in #72259. Organization id is now added when a correlation is created. Any existing correlations without organization id will be kept intact and work as before for backward compatibility during the deprecation period that is set to 6 months after handling organization id is released. After that time, correlations without org_id (or org_id = 0 in the database) will stop showing up in Grafana.
To migrate existing correlations to handle organization id correctly:
- re-provision any correlations that were created as part of provisioning
- re-create any correlations created with Admin/Correlations page Issue [#72258](https://github.com/grafana/grafana/issues/72258)
Starting with 10.2, `parentRowIndex` is deprecated. It will be removed in a future release. From 10.2, sub-tables are supported by adding `FieldType.nestedFrames` to the field that contains the nested data in your dataframe. Issue [#71953](https://github.com/grafana/grafana/issues/71953)
### Plugin development fixes & changes
- **Toggletip:** Add support to programmatically close it. [#75846](https://github.com/grafana/grafana/issues/75846), [@adela-almasan](https://github.com/adela-almasan)
- **Drawer:** Make content scroll by default. [#75287](https://github.com/grafana/grafana/issues/75287), [@ashharrison90](https://github.com/ashharrison90)
<!-- 10.2.0 END -->
<!-- 10.1.5 START -->
# 10.1.5 (2023-10-11)

View File

@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
ARG BASE_IMAGE=alpine:3.18.3
ARG JS_IMAGE=node:18-alpine3.18
ARG JS_IMAGE=node:20-alpine3.18
ARG JS_PLATFORM=linux/amd64
ARG GO_IMAGE=golang:1.20.10-alpine3.18

View File

@ -1505,6 +1505,8 @@ public_key_retrieval_disabled = false
public_key_retrieval_on_startup = false
# Enter a comma-separated list of plugin identifiers to avoid loading (including core plugins). These plugins will be hidden in the catalog.
disable_plugins =
# Auth token for plugin installations and removal in managed instances
install_token =
#################################### Grafana Live ##########################################
[live]

View File

@ -18,7 +18,7 @@ We recommend using [Homebrew](https://brew.sh/) for installing any missing depen
```
brew install git
brew install go
brew install node@18
brew install node@20
npm install -g yarn
```
@ -61,7 +61,7 @@ To remove precommit hooks, run
make lefthook-uninstall
```
> [!NOTE]
> [!NOTE]
> Contributors working on the frontend are highly encouraged to install the precommit hooks, even if your IDE formats on save, so the `.betterer.results` file is kept up to sync.
## Build Grafana

View File

@ -452,6 +452,10 @@
{
"text": "CFP franc (XPF)",
"value": "currencyXPF"
},
{
"text": "Bulgarian Lev (BGN)",
"value": "currencyBGN"
}
],
"text": "currency"
@ -1611,6 +1615,10 @@
{
"text": "Malaysian Ringgit (RM)",
"value": "currencyMYR"
},
{
"text": "Bulgarian Lev (BGN)",
"value": "currencyBGN"
}
],
"text": "currency"
@ -2710,6 +2718,10 @@
{
"text": "Malaysian Ringgit (RM)",
"value": "currencyMYR"
},
{
"text": "Bulgarian Lev (BGN)",
"value": "currencyBGN"
}
],
"text": "currency"

View File

@ -0,0 +1,900 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 7004,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"description": "Transformations:\n- Count\n- Sort by\n- Limit 10",
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"luna\"} | logfmt | label=\"val2\" | float > 60",
"maxLines": 5000,
"queryType": "range",
"refId": "A"
}
],
"title": "Split logs",
"transformations": [
{
"id": "calculateField",
"options": {
"alias": "id_count",
"mode": "reduceRow",
"reduce": {
"include": [
"id"
],
"reducer": "count"
},
"replaceFields": false
}
},
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "tsNs"
}
]
}
},
{
"id": "limit",
"options": {
"limitField": 10
}
}
],
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"description": "Transformations:\n- Count\n- Sort by\n- Limit 10",
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"luna\"} | logfmt | label=\"val2\" | float > 60",
"maxLines": 5000,
"queryType": "range",
"refId": "do-not-chunk"
}
],
"title": "Logs without splitting",
"transformations": [
{
"id": "calculateField",
"options": {
"alias": "id_count",
"mode": "reduceRow",
"reduce": {
"include": [
"id"
],
"reducer": "count"
},
"replaceFields": false
}
},
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "tsNs"
}
]
}
},
{
"id": "limit",
"options": {}
}
],
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 7
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "count_over_time({place=\"luna\"} | logfmt | label=\"val2\" | float > 60 | drop wave, _entry, level, float, counter [$__auto])",
"queryType": "range",
"refId": "A"
}
],
"title": "Split TS",
"transformations": [],
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 7
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "count_over_time({place=\"luna\"} | logfmt | label=\"val2\" | float > 60 | drop wave, _entry, level, float, counter [$__auto])",
"queryType": "range",
"refId": "do-not-chunk"
}
],
"title": "TS without splitting",
"transformations": [],
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"gridPos": {
"h": 5,
"w": 12,
"x": 0,
"y": 15
},
"id": 5,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"luna\"} | logfmt",
"maxLines": 5000,
"queryType": "range",
"refId": "A"
}
],
"title": "Logs with filter transformation",
"transformations": [
{
"id": "filterByValue",
"options": {
"filters": [
{
"config": {
"id": "isNull",
"options": {}
},
"fieldName": "TraceID"
}
],
"match": "any",
"type": "exclude"
}
}
],
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"gridPos": {
"h": 5,
"w": 12,
"x": 12,
"y": 15
},
"id": 6,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"luna\"} | logfmt",
"maxLines": 5000,
"queryType": "range",
"refId": "do-not-chunk"
}
],
"title": "Logs with filter transformation, no splitting",
"transformations": [
{
"id": "filterByValue",
"options": {
"filters": [
{
"config": {
"id": "isNull",
"options": {}
},
"fieldName": "TraceID"
}
],
"match": "any",
"type": "exclude"
}
}
],
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 20
},
"id": 7,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "10.2.0-61469",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"luna\", age=\"new\"}",
"maxLines": 5000,
"queryType": "range",
"refId": "A"
}
],
"title": "Logs with extract fields transformation",
"transformations": [
{
"id": "extractFields",
"options": {
"format": "json",
"keepTime": true,
"replace": true,
"source": "labels"
}
},
{
"id": "calculateField",
"options": {
"alias": "Row",
"mode": "index",
"reduce": {
"reducer": "sum"
},
"replaceFields": false
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 20
},
"id": 8,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "10.2.0-61469",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"luna\", age=\"new\"}",
"maxLines": 5000,
"queryType": "range",
"refId": "do-not-chunk"
}
],
"title": "Logs with extract fields transformation, no splitting",
"transformations": [
{
"id": "extractFields",
"options": {
"format": "json",
"keepTime": true,
"replace": true,
"source": "labels"
}
},
{
"id": "calculateField",
"options": {
"alias": "Row",
"mode": "index",
"reduce": {
"reducer": "sum"
},
"replaceFields": false
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 28
},
"id": 9,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "10.2.0-61469",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"moon\"}",
"maxLines": 5,
"queryType": "range",
"refId": "A"
}
],
"title": "Logs with extract key=value and organize",
"transformations": [
{
"id": "extractFields",
"options": {
"format": "auto",
"keepTime": true,
"replace": true,
"source": "Line"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"31": true,
"32": true,
"33": true,
"34": true,
"35": true,
"36": true,
"37": true,
"38": true,
"39": true,
"40": true,
"41": true,
"42": true,
"43": true,
"44": true,
"45": true,
"46": true,
"2023-09-20T14": true,
"33+00": true,
"caller": true,
"main.go": true,
"t": true,
"ts": true
},
"indexByName": {},
"renameByName": {
"level": "nivel",
"ts": ""
}
}
}
],
"type": "table"
},
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 28
},
"id": 10,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "10.2.0-61469",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "gdev-loki"
},
"editorMode": "code",
"expr": "{place=\"moon\"}",
"maxLines": 5,
"queryType": "range",
"refId": "do-not-chunk"
}
],
"title": "Logs with extract key=value and organize, no splitting",
"transformations": [
{
"id": "extractFields",
"options": {
"format": "auto",
"keepTime": true,
"replace": true,
"source": "Line"
}
},
{
"id": "organize",
"options": {
"excludeByName": {
"31": true,
"32": true,
"33": true,
"34": true,
"35": true,
"36": true,
"37": true,
"38": true,
"39": true,
"40": true,
"41": true,
"42": true,
"43": true,
"44": true,
"45": true,
"46": true,
"2023-09-20T14": true,
"33+00": true,
"caller": true,
"main.go": true,
"t": true,
"ts": true
},
"indexByName": {},
"renameByName": {
"level": "nivel",
"ts": ""
}
}
}
],
"type": "table"
}
],
"refresh": "",
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Datasource tests - Loki query splitting",
"uid": "dc4ec947-7e6b-4c3b-be8f-0abec7b0652a",
"version": 13,
"weekStart": ""
}

View File

@ -449,9 +449,13 @@
"text": "Malaysian Ringgit (RM)",
"value": "currencyMYR"
},
{
{
"text": "CFP franc (XPF)",
"value": "currencyXPF"
},
{
"text": "Bulgarian Lev (BGN)",
"value": "currencyBGN"
}
],
"text": "currency"
@ -1611,6 +1615,10 @@
{
"text": "Malaysian Ringgit (RM)",
"value": "currencyMYR"
},
{
"text": "Bulgarian Lev (BGN)",
"value": "currencyBGN"
}
],
"text": "currency"
@ -2706,6 +2714,10 @@
{
"text": "Malaysian Ringgit (RM)",
"value": "currencyMYR"
},
{
"text": "Bulgarian Lev (BGN)",
"value": "currencyBGN"
}
],
"text": "currency"

View File

@ -0,0 +1,600 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 812,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"maxDataPoints": 500,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Dense (stroke only)",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 0
},
"id": 4,
"maxDataPoints": 50,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Normal (stroke only)",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 60,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 0,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 10
},
"id": 2,
"maxDataPoints": 500,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 1,
"refId": "A"
}
],
"title": "Dense (fill only)",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 60,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 0,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 10
},
"id": 3,
"maxDataPoints": 50,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 4,
"refId": "A"
}
],
"title": "Normal (fill only)",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 20,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 20
},
"id": 6,
"maxDataPoints": 500,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 1,
"refId": "A"
}
],
"title": "Dense (stroke + fill)",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 20,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 20
},
"id": 5,
"maxDataPoints": 50,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 4,
"refId": "A"
}
],
"title": "Normal (stroke + fill)",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 39,
"tags": [
"gdev",
"panel-tests",
"graph-ng"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Panel Tests - TimeSeries - bars high density (stroke + fill)",
"uid": "c295a76e-79d3-43b3-a688-ef0373224158",
"version": 3,
"weekStart": ""
}

View File

@ -3,7 +3,10 @@
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
@ -19,10 +22,16 @@
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"description": "",
"fieldConfig": {
"defaults": {
@ -30,6 +39,9 @@
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -41,6 +53,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 3,
"pointSize": 5,
@ -91,8 +104,9 @@
"options": {
"legend": {
"calcs": [],
"displayMode": "hidden",
"placement": "bottom"
"displayMode": "list",
"placement": "bottom",
"showLegend": false
},
"tooltip": {
"mode": "single",
@ -101,6 +115,10 @@
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,10,20,30,40,50"
@ -110,6 +128,10 @@
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"description": "",
"fieldConfig": {
"defaults": {
@ -117,6 +139,9 @@
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -128,6 +153,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 3,
"pointSize": 5,
@ -179,7 +205,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -188,6 +215,10 @@
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,10,20,30,40,50"
@ -197,12 +228,19 @@
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -214,6 +252,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 2,
"pointSize": 5,
@ -265,7 +304,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -274,6 +314,10 @@
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,10,20,30,40,50"
@ -282,6 +326,101 @@
"title": "15 orange, 50 red",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 25,
"gradientMode": "scheme",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "transparent"
},
{
"color": "orange",
"value": 20
},
{
"color": "red",
"value": 50
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 8,
"y": 7
},
"id": 14,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,0"
}
],
"title": "Transprent base",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
@ -293,6 +432,9 @@
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -304,6 +446,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 3,
"pointSize": 5,
@ -347,7 +490,7 @@
"h": 7,
"w": 12,
"x": 0,
"y": 7
"y": 15
},
"id": 9,
"maxDataPoints": 45,
@ -355,7 +498,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -364,6 +508,10 @@
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 4,
"refId": "A"
}
@ -372,12 +520,19 @@
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -389,6 +544,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 0,
"pointSize": 5,
@ -432,7 +588,7 @@
"h": 7,
"w": 12,
"x": 12,
"y": 7
"y": 15
},
"id": 4,
"interval": "80s",
@ -441,7 +597,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -450,6 +607,10 @@
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"max": 40,
"min": 0,
"noise": 1,
@ -473,6 +634,9 @@
"mode": "continuous-GrYlRd"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -484,6 +648,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 3,
"pointSize": 5,
@ -531,7 +696,7 @@
"h": 7,
"w": 12,
"x": 0,
"y": 14
"y": 22
},
"id": 6,
"maxDataPoints": 50,
@ -539,7 +704,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -548,6 +714,10 @@
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 4,
"refId": "A"
}
@ -566,6 +736,9 @@
"mode": "continuous-GrYlRd"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -577,6 +750,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 1,
"pointSize": 5,
@ -624,7 +798,7 @@
"h": 7,
"w": 12,
"x": 12,
"y": 14
"y": 22
},
"id": 10,
"maxDataPoints": 45,
@ -632,7 +806,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -641,6 +816,10 @@
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 4,
"refId": "A"
}
@ -659,6 +838,9 @@
"mode": "continuous-GrYlRd"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -670,6 +852,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 1,
"pointSize": 5,
@ -717,7 +900,7 @@
"h": 7,
"w": 12,
"x": 0,
"y": 21
"y": 29
},
"id": 7,
"maxDataPoints": 50,
@ -725,7 +908,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -734,6 +918,10 @@
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 4,
"refId": "A"
}
@ -742,12 +930,19 @@
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@ -759,6 +954,7 @@
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 3,
"pointSize": 5,
@ -806,7 +1002,7 @@
"h": 7,
"w": 12,
"x": 12,
"y": 21
"y": 29
},
"id": 8,
"maxDataPoints": 250,
@ -814,7 +1010,8 @@
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
@ -823,6 +1020,10 @@
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"max": 45,
"min": 20,
"noise": 0,
@ -832,6 +1033,10 @@
"startValue": 40
},
{
"datasource": {
"type": "grafana-testdata-datasource",
"uid": "PD8C576611E62080A"
},
"hide": false,
"max": 20,
"min": 1,
@ -845,8 +1050,8 @@
"type": "timeseries"
}
],
"refresh": false,
"schemaVersion": 33,
"refresh": "",
"schemaVersion": 38,
"tags": [
"gdev",
"panel-tests",
@ -863,5 +1068,6 @@
"timezone": "",
"title": "Panel Tests - Graph NG - By value color schemes",
"uid": "aBXrJ0R7z",
"version": 11
"version": 4,
"weekStart": ""
}

View File

@ -387,6 +387,13 @@ local dashboard = grafana.dashboard;
id: 0,
}
},
dashboard.new('loki_query_splitting', import '../dev-dashboards/datasource-loki/loki_query_splitting.json') +
resource.addMetadata('folder', 'dev-dashboards') +
{
spec+: {
id: 0,
}
},
dashboard.new('migrations', import '../dev-dashboards/migrations/migrations.json') +
resource.addMetadata('folder', 'dev-dashboards') +
{
@ -709,6 +716,13 @@ local dashboard = grafana.dashboard;
id: 0,
}
},
dashboard.new('timeseries-bars-high-density', import '../dev-dashboards/panel-timeseries/timeseries-bars-high-density.json') +
resource.addMetadata('folder', 'dev-dashboards') +
{
spec+: {
id: 0,
}
},
dashboard.new('timeseries-by-value-color-schemes', import '../dev-dashboards/panel-timeseries/timeseries-by-value-color-schemes.json') +
resource.addMetadata('folder', 'dev-dashboards') +
{

View File

@ -6,3 +6,11 @@ MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rule
include docs.mk
.PHONY: sources/panels-visualizations/query-transform-data/transform-data/index.md
sources/panels-visualizations/query-transform-data/transform-data/index.md: ## Generate the Transform Data page source.
sources/panels-visualizations/query-transform-data/transform-data/index.md:
cd $(CURDIR)/..
npx tsc ./scripts/docs/generate-transformations.ts
node ./scripts/docs/generate-transformations.js > $(CURDIR)/$@
npx prettier -w $(CURDIR)/$@

View File

@ -23,7 +23,23 @@ If you have the grafana/website repo checked out in the same directory as the gr
## Content guidelines
Edit content in the `sources` directory.
Generally, one can edit content in the `sources` directory.
The following paths are built instead from a typescript file and are auto-generated. Please do not edit these files directly.
Instead, navigate to the appropriate typescript source file and edit the content there, then follow the build instructions to generate the markdown files.
### Transformations
Auto-generated markdown location:
- docs/sources/panels-visualizations/query-transform-data/transform-data/index.md
Typescript location for editing and instructions:
- scripts/docs/generate-transformations.ts - Includes all content not specific to a transformation.
- public/app/features/transformers/docs/content.ts - Transformation-specific content.
Only use [reference style links](https://grafana.com/docs/writers-toolkit/write/shortcodes/#docsreference) in the `content.ts` file or else link text will be visible in the UI.
### [Contributing](/contribute/documentation/README.md)

View File

@ -3,19 +3,20 @@ aliases:
- /docs/grafana/v1.1/
- /docs/grafana/v3.1/
- guides/reference/admin/
description: Guides, installation, and feature documentation
description: Open source documentation for Grafana
keywords:
- grafana
- open source
- installation
- documentation
labels:
products:
- enterprise
- oss
title: Grafana documentation
title: Grafana open source documentation
---
# Grafana documentation
# Grafana open source documentation
## Installing Grafana
@ -74,8 +75,8 @@ title: Grafana documentation
<h4>Provisioning</h4>
<p>Learn how to automate your Grafana configuration.</p>
</a>
<a href="{{< relref "whatsnew/whats-new-in-v10-1/" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>What's new in v10.1</h4>
<a href="{{< relref "whatsnew/whats-new-in-v10-2/" >}}" class="nav-cards__item nav-cards__item--guide">
<h4>What's new in v10.2</h4>
<p>Explore the features and enhancements in the latest release.</p>
</a>

View File

@ -13,7 +13,7 @@ labels:
- oss
menuTitle: Configure
title: Configure Alerting
weight: 130
weight: 120
---
# Configure Alerting

View File

@ -11,7 +11,7 @@ labels:
- oss
menuTitle: Introduction
title: Introduction to Alerting
weight: 105
weight: 100
---
# Introduction to Alerting

View File

@ -11,7 +11,7 @@ labels:
- enterprise
- oss
title: Alert rules
weight: 106
weight: 130
---
# Alert rules

View File

@ -12,7 +12,7 @@ labels:
- enterprise
- oss
title: Alertmanager
weight: 103
weight: 140
---
# Alertmanager

View File

@ -16,7 +16,7 @@ labels:
- enterprise
- oss
title: Labels and annotations
weight: 110
weight: 120
---
# Labels and annotations

View File

@ -18,7 +18,7 @@ labels:
- enterprise
- oss
title: Contact points
weight: 106
weight: 150
---
# Contact points

View File

@ -10,7 +10,7 @@ labels:
- enterprise
- oss
title: Alerting on numeric data
weight: 116
weight: 110
---
# Alerting on numeric data

View File

@ -16,25 +16,22 @@ labels:
- enterprise
- oss
title: Alerting high availability
weight: 430
weight: 170
---
# Alerting high availability
The Grafana Alerting system has two main components: a `Scheduler` and an internal `Alertmanager`. The `Scheduler` evaluates your alert rules, while the internal Alertmanager manages **routing** and **grouping**.
When running Grafana Alerting in high availability, the operational mode of the scheduler remains unaffected, and each Grafana instance evaluates all alerts. The operational change happens in the Alertmanager when it deduplicates alert notifications across Grafana instances.
Grafana Alerting uses the Prometheus model of separating the evaluation of alert rules from the delivering of notifications. In this model the evaluation of alert rules is done in the alert generator and the delivering of notifications is done in the alert receiver. In Grafana Alerting, the alert generator is the Scheduler and the receiver is the Alertmanager.
{{< figure src="/static/img/docs/alerting/unified/high-availability-ua.png" class="docs-image--no-shadow" max-width= "750px" caption="High availability" >}}
The coordination between Grafana instances happens via [a Gossip protocol](https://en.wikipedia.org/wiki/Gossip_protocol). Alerts are not gossiped between instances and each scheduler delivers the same volume of alerts to each Alertmanager.
When running multiple instances of Grafana, all alert rules are evaluated on all instances. You can think of the evaluation of alert rules as being duplicated. This is how Grafana Alerting makes sure that as long as at least one Grafana instance is working, alert rules will still be evaluated and notifications for alerts will still be sent. You will see this duplication in state history, and is a good way to tell if you are using high availability.
The two types of messages gossiped between Grafana instances are:
While the alert generator evaluates all alert rules on all instances, the alert receiver makes a best-effort attempt to avoid sending duplicate notifications. Alertmanager chooses availability over consistency, which may result in occasional duplicated or out-of-order notifications. It takes the opinion that duplicate or out-of-order notifications are better than no notifications.
- Notification logs: Who (which instance) notified what (which alert).
- Silences: If an alert should fire or not.
The Alertmanager uses a gossip protocol to share information about notifications between Grafana instances. It also gossips silences, which means a silence created on one Grafana instance is replicated to all other Grafana instances. Both notifications and silences are persisted to the database periodically, and during graceful shut down.
The notification logs and silences are persisted in the database periodically and during a graceful Grafana shut down.
It is important to make sure that gossiping is configured and tested. You can find the documentation on how to do that [here][configure-high-availability].
## Useful links

View File

@ -11,7 +11,7 @@ labels:
- enterprise
- oss
title: Notifications
weight: 107
weight: 160
---
# Notifications

View File

@ -12,7 +12,7 @@ labels:
- oss
menuTitle: Manage
title: Manage your alerts
weight: 160
weight: 130
---
# Manage your alerts

View File

@ -63,7 +63,7 @@ A time interval is a definition for a moment in time. If an alert fires during t
Supported time interval options are:
- Time range: The time inclusive of the starting time and exclusive of the end time in UTC.
- Time range: The time inclusive of the start and exclusive of the end time (in UTC if no location has been selected, otherwise local time).
- Days of the week: The day or range of days of the week. Example: `monday:thursday`.
- Days of the month: The date 1-31 of a month. Negative values can also be used to represent days that begin at the end of the month. For example: `-1` for the last day of the month.
- Months: The months of the year in either numerical or the full calendar month. For example: `1, may:august`.

View File

@ -25,15 +25,17 @@ Notification templates are not tied to specific contact point integrations, such
You can use notification templates to:
- Add, remove, or re-order information in the notification including the summary, description, labels and annotations, values, and links
- Format text in bold and italic, and add or remove line breaks
- Customize the subject of an email or the title of a message.
- Add, change or remove text in notifications. For example, to select or omit certain labels, annotations and links.
- Format text in bold and italic, and add or remove line breaks.
You cannot use notification templates to:
- Change how images are included in notifications, such as the number of images in each notification or where in the notification inline images are shown
- Change the design of notifications in instant messaging services such as Slack and Microsoft Teams
- Change the data in webhook notifications, including the structure of the JSON request or sending data in other formats such as XML
- Add or remove HTTP headers in webhook notifications other than those in the contact point configuration
- Add HTML and CSS to email notifications to change their visual appearance.
- Change the design of notifications in instant messaging services such as Slack and Microsoft Teams. For example, to add or remove custom blocks with Slack Block Kit or adaptive cards with Microsoft Teams.
- Choose the number and size of images, or where in the notification images are shown.
- Customize the data in webhooks, including the fields or structure of the JSON data or send the data in other formats such as XML.
- Add or remove HTTP headers in webhooks other than those in the contact point configuration.
[Using Go's templating language][using-go-templating-language]

View File

@ -14,7 +14,7 @@ labels:
- oss
menuTitle: Monitor
title: Meta monitoring
weight: 200
weight: 140
---
# Meta monitoring

View File

@ -8,7 +8,7 @@ labels:
- oss
menuTitle: Set up
title: Set up Alerting
weight: 107
weight: 110
---
# Set up Alerting

View File

@ -192,7 +192,7 @@ We strongly recommend not doing this in case you are using Azure AD as an identi
#### Learn more
- [CVE-2023-3128 Advisory](https://grafana.com/security/security-advisories/CVE-2023-3128)
- [CVE-2023-3128 Advisory](https://grafana.com/security/security-advisories/cve-2023-3128/)
- [Enable email lookup]({{< relref "../setup-grafana/configure-security/configure-authentication/" >}})
### The "Alias" field in the CloudWatch data source is removed

View File

@ -31,6 +31,9 @@ Before you begin, ensure that you have configured a data source. See also:
- [JSON model][]
{{% docs/reference %}}
[data source]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/datasources"
[data source]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/datasources"
[Reporting]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/create-reports"
[Reporting]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/create-reports"

View File

@ -34,7 +34,7 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee
![Empty dashboard state](/media/docs/grafana/dashboards/empty-dashboard-10.2.png)
1. In the modal that opens, do one of the following:
1. In the dialog box that opens, do one of the following:
- Select one of your existing data sources.
- Select one of the Grafana's [built-in special data sources][].
@ -43,7 +43,7 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee
{{< figure class="float-right" src="/media/docs/grafana/dashboards/screenshot-data-source-selector-10.0.png" max-width="800px" alt="Select data source modal" >}}
The **Edit panel** view opens with your data source selected.
You can change the panel data source later using the dropdown in the **Query** tab of the panel editor if needed.
You can change the panel data source later using the drop-down in the **Query** tab of the panel editor if needed.
For more information about data sources, refer to [Data sources][] for specific guidelines.
@ -61,6 +61,10 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee
For more information about individual visualizations, refer to [Visualizations options][].
1. Under **Panel options**, enter a title and description for your panel.
Alternatively, Grafana can generate a panel title and description for you using the OpenAI integration. Learn more in the [Set up generative AI features for dashboards documentation][].
1. Refer to the following documentation for ways you can adjust panel settings.
While not required, most visualizations need some adjustment before they properly display the information that you need.
@ -75,11 +79,18 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee
Alternatively, click **Apply** if you want to see your changes applied to the dashboard first. Then click the save icon in the dashboard header.
1. Enter a name for your dashboard and select a folder, if applicable.
1. Click **Save**.
1. To add more panels to the dashboard, click **Add** in the dashboard header and select **Visualization** in the dropdown.
1. Enter a summary of your dashboard changes.
![Add dropdown](/media/docs/grafana/dashboards/screenshot-add-dropdown-10.0.png)
Alternatively, Grafana can generate a summary for you using the OpenAI integration. Learn more in the [Set up generative AI features for dashboards documentation][].
1. Enter a title for your dashboard and select a folder, if applicable.
Alternatively, Grafana can generate a dashboard title for you using the OpenAI integration. Learn more in the [Set up generative AI features for dashboards documentation][].
1. Click **Save**.
1. To add more panels to the dashboard, click **Add** in the dashboard header and select **Visualization** in the drop-down.
![Add drop-down](/media/docs/grafana/dashboards/screenshot-add-dropdown-10.0.png)
When you add additional panels to the dashboard, you're taken straight to the **Edit panel** view.
@ -97,7 +108,7 @@ To see an example of repeating rows, refer to [Dashboard with repeating rows](ht
1. Click **Dashboards** in the left-side menu.
1. Navigate to the dashboard you want to work on.
1. At the top of the dashboard, click **Add** and select **Row** in the dropdown.
1. At the top of the dashboard, click **Add** and select **Row** in the drop-down.
If the dashboard is empty, you can click the **+ Add row** button in the middle of the dashboard.
@ -170,4 +181,7 @@ You can size a dashboard panel to suits your needs.
[Configure standard options]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/configure-standard-options"
[Configure standard options]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/configure-standard-options"
[Set up generative AI features for dashboards documentation]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/manage-dashboards#set-up-generative-ai-features-for-dashboards"
[Set up generative AI features for dashboards documentation]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/manage-dashboards#set-up-generative-ai-features-for-dashboards"
{{% /docs/reference %}}

View File

@ -27,27 +27,6 @@ You can see a list of all your public dashboards in one place by navigating to *
- Arbitrary queries **cannot** be run against your data sources through public dashboards. Public dashboards can only execute the
queries stored on the original dashboard.
## Enable the feature
Add the `publicDashboards` feature toggle to your `custom.ini` file.
```
[feature_toggles]
publicDashboards = true
```
If you are using Docker, use an environment variable to enable public dashboards:
```
--env GF_FEATURE_TOGGLES_ENABLE=publicDashboards
```
{{% admonition type="note" %}}
For Grafana Cloud, contact support to have the feature enabled.
{{% /admonition %}}
## Make a dashboard public
1. Click the sharing icon in the dashboard header.

View File

@ -46,10 +46,10 @@ For more information about creating dashboards, refer to [Add and organize panel
On the **Dashboards** page, you can browse and manage folders and dashboards. This includes the options to:
- Create folders and dashboards
- Move dashboards between folders
- Delete multiple dashboards and folders
- Navigate to a folder
- Manage folder permissions. For more information, refer to [Dashboard permissions](https://grafana.com/docs/grafana/<GRAFANA VERSION>/administration/roles-and-permissions/#dashboard-permissions).
- Move dashboards between folders.
- Delete multiple dashboards and folders.
- Navigate to a folder.
- Manage folder permissions. For more information, refer to [Dashboard permissions][].
{{% admonition type="note" %}}
As of Grafana 10.2, there is no longer a special **General** folder. Dashboards without a folder are now shown at the top level alongside folders.
@ -70,7 +70,7 @@ Folders help you organize and group dashboards, which is useful when you have ma
When you save a dashboard, you can either select a folder for the dashboard to be saved in or create a new folder.
{{% admonition type="note" %}}
Alerts cannot be placed in folders with slashes (\ /) in the name. If you wish to place alerts in the folder, do not use slashes in the folder name.
Alerts can't be placed in folders with slashes (\ /) in the name. If you wish to place alerts in the folder, don't use slashes in the folder name.
{{% /admonition %}}
**To edit the name of a folder:**
@ -83,7 +83,7 @@ The new folder name is automatically saved.
### Folder permissions
You can assign permissions to a folder. Any permissions you assign are inherited by the dashboards in the folder. You can assign permissions to organization roles, teams, and users.
You can assign permissions to a folder. Dashboards in the folder inherit any permissions that you've assigned to the folder. You can assign permissions to organization roles, teams, and users.
**To modify permissions for a folder:**
@ -119,7 +119,7 @@ Grafana downloads a JSON file to your local machine.
If you want to export a dashboard for others to use, you can add template variables for things like a metric prefix (use a constant variable) and server name.
A template variable of the type `Constant` will automatically be hidden in the dashboard, and will also be added as a required input when the dashboard is imported.
A template variable of the type `Constant` is automatically hidden in the dashboard, and is also added as a required input when the dashboard is imported.
### Import a dashboard
@ -136,12 +136,25 @@ A template variable of the type `Constant` will automatically be hidden in the d
The import process enables you to change the name of the dashboard, pick the data source you want the dashboard to use, and specify any metric prefixes (if the dashboard uses any).
### Discover dashboards on Grafana.com
### Discover dashboards on grafana.com
Find dashboards for common server applications at [Grafana.com/dashboards](https://grafana.com/dashboards).
{{< figure src="/media/docs/grafana/dashboards/screenshot-gcom-dashboards.png" >}}
## Set up generative AI features for dashboards
{{< docs/public-preview product="Generative AI in dashboards" featureFlag="`dashgpt`" >}}
You can use generative AI to help you with the following tasks:
- **Generate panel and dashboard titles and descriptions**: Generate a title and description based on the data youve added for your panel or dashboard. This is useful when you want to visualize your data quickly and dont want to spend time coming up with a title or description.
- **Generate dashboard save changes summary**: Generate a summary of the changes youve made to a dashboard when you save it. This is great for easily tracking the history of a dashboard.
To access these features, enable the `dashgpt` feature toggle. Then install and configure Grafanas Large Language Model (LLM) app plugin. For more information, refer to the [Grafana LLM plugin documentation][].
When enabled, the **✨ Auto generate** option displays next to the **Title** and **Description** fields in your panels and dashboards, or when you press the **Save** button.
## Troubleshoot dashboards
This section provides information to help you solve common dashboard problems.
@ -159,15 +172,15 @@ By default, Grafana queries your data source every 30 seconds. Setting a low ref
We recommend the following:
- Do not enable auto-refreshing on dashboards, panels, or variables unless you need it. Users can refresh their browser manually, or you can set the refresh rate for a time period that makes sense (every ten minutes, every hour, and so on).
- If it is required, then set the refresh rate to once a minute. Users can always refresh the dashboard manually.
- Only enable auto-refreshing on dashboards, panels, or variables unless if necessary. Users can refresh their browser manually, or you can set the refresh rate for a time period that makes sense (every ten minutes, every hour, and so on).
- If it's required, then set the refresh rate to once a minute. Users can always refresh the dashboard manually.
- If your dashboard has a longer time period (such as a week), then you really don't need automated refreshing.
#### Handling or rendering null data is wrong or confusing
Some applications publish data intermittently; for example, they only post a metric when an event occurs. By default, Grafana graphs connect lines between the data points. This can be very deceiving.
In the picture below we have enabled:
In the picture below we've enabled:
- Points and 3-point radius to highlight where data points are actually present.
- **Connect null values\* is set to **Always\*\*.
@ -187,8 +200,11 @@ You can find more examples in `public/dashboards/` directory of your Grafana ins
[Dashboard permissions]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/administration/roles-and-permissions#dashboard-permissions"
[panels]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations"
[panels]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations"
[panels]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations"
[HTTP API]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/developers/http_api"
[HTTP API]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/developers/http_api"
[HTTP API]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/developer-resources/api-reference/http-api"
[Grafana LLM plugin documentation]: "/docs/grafana/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin"
[Grafana LLM plugin documentation]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin"
{{% /docs/reference %}}

View File

@ -21,23 +21,22 @@ weight: 200
# Configure the Elasticsearch data source
Grafana ships with built-in support for Elasticsearch.
You can make many types of queries to visualize logs or metrics stored in Elasticsearch, and annotate graphs with log events stored in Elasticsearch.
For general documentation on querying data sources in Grafana, see [Query and transform data][].
You can create a variety of queries to visualize logs or metrics stored in Elasticsearch, and annotate graphs with log events stored in Elasticsearch.
For instructions on how to add a data source to Grafana, refer to the [administration documentation][].
Only users with the organization administrator role can add data sources.
Only users with the organization `administrator` role can add data sources.
Administrators can also [configure the data source via YAML](#provision-the-data-source) with Grafana's provisioning system.
## Configure the data source
## Add the data source
To add the Elasticsearch data source, complete the following steps:
1. Click **Connections** in the left-side menu.
1. Under **Connections**, click **Add new connection**.
1. Enter `Elasticsearch` in the search bar.
1. Select **Elasticsearch data source**.
1. Click **Create a Elasticsearch data source** in the upper right.
1. Click **Elasticsearch** under the **Data source** section.
1. Click **Add new data source** in the upper right.
You will be taken to the **Settings** tab where you will set up your Elasticsearch configuration.
@ -51,40 +50,55 @@ The first option to configure is the name of your connection:
- **Default** - Toggle to select as the default data source option. When you go to a dashboard panel or Explore, this will be the default selected data source.
### HTTP section
## Connection
- **URL** - The URL of your Elasticsearch server. If your Elasticsearch server is local, use `<http://localhost:9200>`. If it is on a server within a network, this is the URL with port where you are running Elasticsearch. Example: `<http://elasticsearch.example.orgname:9200>`.
Connect the Elasticsearch data source by specifying a URL.
- **Allowed cookies** - Specify cookies by name that should be forwarded to the data source. The Grafana proxy deletes all forwarded cookies by default.
- **URL** - The URL of your Elasticsearch server. If your Elasticsearch server is local, use `http://localhost:9200`. If it is on a server within a network, this is the URL with the port where you are running Elasticsearch. Example: `http://elasticsearch.example.orgname:9200`.
- **Timeout** - The HTTP request timeout. This must be in seconds. There is no default, so this setting is up to you.
### Auth section
## Authentication
There are several authentication methods you can choose in the Authentication section.
Select one of the following authentication methods from the dropdown menu.
- **Basic authentication** - The most common authentication method. Use your `data source` user name and `data source` password to connect.
- **Forward OAuth identity** - Forward the OAuth access token (and the OIDC ID token if available) of the user querying the data source.
- **No authentication** - Make the data source available without authentication. Grafana recommends using some type of authentication method.
<!-- - **With credentials** - Toggle to enable credentials such as cookies or auth headers to be sent with cross-site requests. -->
### TLS settings
{{% admonition type="note" %}}
Use TLS (Transport Layer Security) for an additional layer of security when working with Elasticsearch. For information on setting up TLS encryption with Elasticsearch see [Configure TLS](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/configuring-tls.html#configuring-tls). You must add TLS settings to your Elasticsearch configuration file **prior** to setting these options in Grafana.
{{% /admonition %}}
- **Basic authentication** - The most common authentication method. Use your `data source` user name and `data source` password to connect.
- **Add self-signed certificate** - Check the box to authenticate with a CA certificate. Follow the instructions of the CA (Certificate Authority) to download the certificate file. Required for verifying self-signed TLS certificates.
- **With credentials** - Toggle to enable credentials such as cookies or auth headers to be sent with cross-site requests.
- **TLS client authentication** - Check the box to authenticate with the TLS client, where the server authenticates the client. Add the `Server name`, `Client certificate` and `Client key`. The **ServerName** is used to verify the hostname on the returned certificate. The **Client certificate** can be generated from a Certificate Authority (CA) or be self-signed. The **Client key** can also be generated from a Certificate Authority (CA) or be self-signed. The client key encrypts the data between client and server.
- **TLS client authentication** - Toggle to use client authentication. When enabled, add the `Server name`, `Client cert` and `Client key`. The client provides a certificate that is validated by the server to establish the client's trusted identity. The client key encrypts the data between client and server.
- **Skip TLS certificate validation** - Check the box to bypass TLS certificate validation. Skipping TLS certificate validation is not recommended unless absolutely necessary or for testing purposes.
- **With CA cert** - Toggle to authenticate with a CA certificate. Follow the instructions of the CA (Certificate Authority) to download the certificate file.
### HTTP headers
- **Skip TLS verify** - Toggle on to bypass TLS certificate validation.
- **Forward OAuth identity** - Forward the OAuth access token (and the OIDC ID token if available) of the user querying the data source.
### Custom HTTP headers
Click **+ Add header** to add one or more HTTP headers. HTTP headers pass additional context and metadata about the request/response.
- **Header** - Add a custom header. This allows custom headers to be passed based on the needs of your Elasticsearch instance.
- **Value** - The value of the header.
## Additional settings
Additional settings are optional settings that can be configured for more control over your data source.
### Advanced HTTP settings
- **Allowed cookies** - Specify cookies by name that should be forwarded to the data source. The Grafana proxy deletes all forwarded cookies by default.
- **Timeout** - The HTTP request timeout. This must be in seconds. There is no default, so this setting is up to you.
### Elasticsearch details
The following settings are specific to the Elasticsearch data source.
@ -124,7 +138,7 @@ You can also override this setting in a dashboard panel under its data source op
- **X-Pack enabled** - Toggle to enable `X-Pack`-specific features and options, which provide the [query editor]({{< relref "./query-editor" >}}) with additional aggregations, such as `Rate` and `Top Metrics`.
- **Include frozen indices** - Toggle on when the `X-Pack enabled` setting is active. You can configure Grafana to include [frozen indices](https://www.elastic.co/guide/en/elasticsearch/reference/7.13/frozen-indices.html) when performing search requests.
- **Include frozen indices** - Toggle on when the `X-Pack enabled` setting is active. Includes frozen indices in searches. You can configure Grafana to include [frozen indices](https://www.elastic.co/guide/en/elasticsearch/reference/7.13/frozen-indices.html) when performing search requests.
{{% admonition type="note" %}}
Frozen indices are [deprecated in Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/frozen-indices.html) since v7.14.
@ -140,7 +154,7 @@ In this section you can configure which fields the data source uses for log mess
### Data links
Data links create a link from a specified field that can be accessed in Explore's logs view. You can add multiple data links
Data links create a link from a specified field that can be accessed in Explore's logs view. You can add multiple data links by clicking **+ Add**.
Each data link configuration consists of:
@ -152,6 +166,14 @@ Each data link configuration consists of:
- **Internal link** - Toggle on to set an internal link. For an internal link, you can select the target data source with a data source selector. This supports only tracing data sources.
## Private data source connect (PDC) and Elasticsearch
Use private data source connect (PDC) to connect to and query data within a secure network without opening that network to inbound traffic from Grafana Cloud. See [Private data source connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) for more information on how PDC works and [Configure Grafana private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc) for steps on setting up a PDC connection.
- **Private data source connect** - Click in the box to set the default PDC connection from the dropdown menu or create a new connection.
Once you have configured your Elasticsearch data source options, click **Save & test** at the bottom to test out your data source connection. You can also remove a connection by clicking **Delete**.
{{% docs/reference %}}
[administration documentation]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/administration/data-source-management"
[administration documentation]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/administration/data-source-management"

View File

@ -23,7 +23,8 @@ weight: 300
# Elasticsearch query editor
Grafana provides a query editor for Elasticsearch. Elasticsearch queries are in Lucene format. See [Query string syntax](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/query-dsl-query-string-query.html#query-string-syntax) if you are new to working with Elasticsearch.
Grafana provides a query editor for Elasticsearch. Elasticsearch queries are in Lucene format.
See [Lucene query syntax](https://www.elastic.co/guide/en/kibana/current/lucene-query.html) and and [Query string syntax](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/query-dsl-query-string-query.html#query-string-syntax) if you are new to working with Lucene queries in Elasticsearch.
{{< figure src="/static/img/docs/elasticsearch/elastic-query-editor-10.1.png" max-width="800px" class="docs-image--no-shadow" caption="Elasticsearch query editor" >}}
@ -39,18 +40,6 @@ Elasticsearch groups aggregations into three categories:
- **Pipeline** - Elasticsearch pipeline aggregations work with inputs or metrics created from other aggregations (not documents or fields). There are parent and sibling and sibling pipeline aggregations. See [Pipeline aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-pipeline.html) for additional information.
## Common options
There are several different types of queries you can create using the Elasticsearch query editor. The following options are available for all query types.
### Add query
Regardless of query type, you can create multiple queries by clicking **+ Add query**.
### Query inspector
Click **Query inspector** to get detailed statistics regarding your query. Query inspector functions as a kind of debugging tool that "inspects" your query. It provides query statistics under **Stats**, request response time under **Query**, data frame details under **{} JSON**, and the shape of your data under **Data**.
## Select a query type
There are three types of queries you can create with the Elasticsearch query builder. Each type is explained in detail below.
@ -70,13 +59,13 @@ Metrics queries aggregate data and produce a variety of calculations such as cou
- min - see [Min aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-min-aggregation.html)
- extended stats - see [Extended stats aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html)
- percentiles - see [Percentiles aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-percentile-aggregation.html)
- unique count - see [Cardinlaity aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-cardinality-aggregation.html)
- unique count - see [Cardinality aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-cardinality-aggregation.html)
- top metrics - see [Top metrics aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-top-metrics.html)
- rate - see [Rate aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-rate-aggregation.html)
You can select multiple metrics and group by multiple terms or filters when using the Elasticsearch query editor.
Use the **plus icon** to the right to add multiple metrics to your query. Click on the **eye icon** next to "Metric" to hide metrics, and the **garbage can icon** to remove metrics.
Use the **+ sign** to the right to add multiple metrics to your query. Click on the **eye icon** next to **Metric** to hide metrics, and the **garbage can icon** to remove metrics.
- **Group by options** - Create multiple group by options when constructing your Elasticsearch query. Date histogram is the default option. Below is a list of options in the dropdown menu.

View File

@ -27,124 +27,30 @@ title: Datasource Permissions HTTP API
> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information.
This API can be used to enable, disable, list, add and remove permissions for a data source.
This API can be used to list, add and remove permissions for a data source.
Permissions can be set for a user or a team. Permissions cannot be set for Admins - they always have access to everything.
The permission levels for the permission field:
- 1 = Query
## Enable permissions for a data source
`POST /api/datasources/:id/enable-permissions`
Enables permissions for the data source with the given `id`. No one except Org Admins will be able to query the data source until permissions have been added which permit certain users or teams to query the data source.
**Required permissions**
See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation.
| Action | Scope |
| ----------------------------- | ---------------------------------------------------------------------------- |
| datasources.permissions:write | datasources:\*<br>datasources:id:\*<br>datasources:id:1 (single data source) |
### Examples
**Example request:**
```http
POST /api/datasources/1/enable-permissions
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{}
```
**Example response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message":"Datasource permissions enabled"}
```
Status codes:
- **200** - Ok
- **400** - Permissions cannot be enabled, see response body for details
- **401** - Unauthorized
- **403** - Access denied
- **404** - Datasource not found
## Disable permissions for a data source
`POST /api/datasources/:id/disable-permissions`
Disables permissions for the data source with the given `id`. All existing permissions will be removed and anyone will be able to query the data source.
**Required permissions**
See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation.
| Action | Scope |
| ----------------------------- | ---------------------------------------------------------------------------- |
| datasources.permissions:write | datasources:\*<br>datasources:id:\*<br>datasources:id:1 (single data source) |
### Examples
**Example request:**
```http
POST /api/datasources/1/disable-permissions
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{}
```
**Example response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message":"Datasource permissions disabled"}
```
Status codes:
- **200** - Ok
- **400** - Permissions cannot be disabled, see response body for details
- **401** - Unauthorized
- **403** - Access denied
- **404** - Datasource not found
Permissions can be set for a user, team, service account or a basic role (Admin, Editor, Viewer).
## Get permissions for a data source
`GET /api/datasources/:id/permissions`
`GET /api/access-control/datasources/:uid`
Gets all existing permissions for the data source with the given `id`.
Gets all existing permissions for the data source with the given `uid`.
**Required permissions**
See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation.
| Action | Scope |
| ---------------------------- | ---------------------------------------------------------------------------- |
| datasources.permissions:read | datasources:\*<br>datasources:id:\*<br>datasources:id:1 (single data source) |
| Action | Scope |
| ---------------------------- | ------------------------------------------------------------------------------------------ |
| datasources.permissions:read | datasources:\*<br>datasources:uid:\*<br>datasources:uid:my_datasource (single data source) |
### Examples
**Example request:**
```http
GET /api/datasources/1/permissions HTTP/1.1
GET /api/access-control/datasources/my_datasource HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
@ -157,36 +63,57 @@ HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 551
{
"datasourceId": 1,
"enabled": true,
"permissions":
[
[
{
"id": 1,
"datasourceId": 1,
"userId": 1,
"userLogin": "user",
"userEmail": "user@test.com",
"userAvatarUrl": "/avatar/46d229b033af06a191ff2267bca9ae56",
"permission": 1,
"permissionName": "Query",
"created": "2017-06-20T02:00:00+02:00",
"updated": "2017-06-20T02:00:00+02:00",
"id": 1,
"roleName": "fixed:datasources:reader",
"isManaged": false,
"isInherited": false,
"isServiceAccount": false,
"userId": 1,
"userLogin": "admin_user",
"userAvatarUrl": "/avatar/admin_user",
"actions": [
"datasources:read",
"datasources:query",
"datasources:read",
"datasources:query",
"datasources:write",
"datasources:delete"
],
"permission": "Edit"
},
{
"id": 2,
"datasourceId": 1,
"teamId": 1,
"team": "A Team",
"teamAvatarUrl": "/avatar/46d229b033af06a191ff2267bca9ae56",
"permission": 1,
"permissionName": "Query",
"created": "2017-06-20T02:00:00+02:00",
"updated": "2017-06-20T02:00:00+02:00",
}
]
}
"id": 2,
"roleName": "managed:teams:1:permissions",
"isManaged": true,
"isInherited": false,
"isServiceAccount": false,
"team": "A team",
"teamId": 1,
"teamAvatarUrl": "/avatar/523d70c8551046f441727d690431858c",
"actions": [
"datasources:read",
"datasources:query"
],
"permission": "Query"
},
{
"id": 3,
"roleName": "basic:admin",
"isManaged": false,
"isInherited": false,
"isServiceAccount": false,
"builtInRole": "Admin",
"actions": [
"datasources:query",
"datasources:read",
"datasources:write",
"datasources:delete"
],
"permission": "Edit"
},
]
```
Status codes:
@ -194,35 +121,37 @@ Status codes:
- **200** - Ok
- **401** - Unauthorized
- **403** - Access denied
- **404** - Datasource not found
- **500** - Internal error
## Add permission for a data source
## Add or revoke access to a data source for a user
`POST /api/datasources/:id/permissions`
`POST /api/access-control/datasources/:uid/users/:id`
Adds a user permission for the data source with the given `id`.
Sets user permission for the data source with the given `uid`.
To add a permission, set the `permission` field to either `Query`, `Edit`, or `Admin`.
To remove a permission, set the `permission` field to an empty string.
**Required permissions**
See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation.
| Action | Scope |
| ----------------------------- | ---------------------------------------------------------------------------- |
| datasources.permissions:write | datasources:\*<br>datasources:id:\*<br>datasources:id:1 (single data source) |
| Action | Scope |
| ----------------------------- | ------------------------------------------------------------------------------------------ |
| datasources.permissions:write | datasources:\*<br>datasources:uid:\*<br>datasources:uid:my_datasource (single data source) |
### Examples
**Example request:**
```http
POST /api/datasources/1/permissions
POST /api/access-control/datasources/my_datasource/users/1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"userId": 1,
"permission": 1
"permission": "Query",
}
```
@ -233,22 +162,19 @@ HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message":"Datasource permission added"}
{"message": "Permission updated"}
```
Adds a team permission for the data source with the given `id`.
**Example request:**
```http
POST /api/datasources/1/permissions
POST /api/access-control/datasources/my_datasource/users/1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"teamId": 1,
"permission": 1
"permission": "",
}
```
@ -259,7 +185,7 @@ HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message":"Datasource permission added"}
{"message": "Permission removed"}
```
Status codes:
@ -268,31 +194,37 @@ Status codes:
- **400** - Permission cannot be added, see response body for details
- **401** - Unauthorized
- **403** - Access denied
- **404** - Datasource not found
## Remove permission for a data source
## Add or revoke access to a data source for a team
`DELETE /api/datasources/:id/permissions/:permissionId`
`POST /api/access-control/datasources/:uid/teams/:id`
Removes the permission with the given `permissionId` for the data source with the given `id`.
Sets team permission for the data source with the given `uid`.
To add a permission, set the `permission` field to either `Query`, `Edit`, or `Admin`.
To remove a permission, set the `permission` field to an empty string.
**Required permissions**
See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation.
| Action | Scope |
| ----------------------------- | ---------------------------------------------------------------------------- |
| datasources.permissions:write | datasources:\*<br>datasources:id:\*<br>datasources:id:1 (single data source) |
| Action | Scope |
| ----------------------------- | ------------------------------------------------------------------------------------------ |
| datasources.permissions:write | datasources:\*<br>datasources:uid:\*<br>datasources:uid:my_datasource (single data source) |
### Examples
**Example request:**
```http
DELETE /api/datasources/1/permissions/2
POST /api/access-control/datasources/my_datasource/teams/1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"permission": "Edit",
}
```
**Example response:**
@ -302,12 +234,109 @@ HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message":"Datasource permission removed"}
{"message": "Permission updated"}
```
**Example request:**
```http
POST /api/access-control/datasources/my_datasource/teams/1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"permission": "",
}
```
**Example response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message": "Permission removed"}
```
Status codes:
- **200** - Ok
- **400** - Permission cannot be added, see response body for details
- **401** - Unauthorized
- **403** - Access denied
## Add or revoke access to a data source for a basic role
`POST /api/access-control/datasources/:uid/builtInRoles/:builtinRoleName`
Sets permission for the data source with the given `uid` to all users who have the specified basic role.
You can set permissions for the following basic roles: `Admin`, `Editor`, `Viewer`.
To add a permission, set the `permission` field to either `Query`, `Edit`, or `Admin`.
To remove a permission, set the `permission` field to an empty string.
**Required permissions**
See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation.
| Action | Scope |
| ----------------------------- | ------------------------------------------------------------------------------------------ |
| datasources.permissions:write | datasources:\*<br>datasources:uid:\*<br>datasources:uid:my_datasource (single data source) |
### Examples
**Example request:**
```http
POST /api/access-control/datasources/my_datasource/builtInRoles/Admin
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"permission": "Edit",
}
```
**Example response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message": "Permission updated"}
```
**Example request:**
```http
POST /api/access-control/datasources/my_datasource/builtInRoles/Viewer
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
{
"permission": "",
}
```
**Example response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 35
{"message": "Permission removed"}
```
Status codes:
- **200** - Ok
- **400** - Permission cannot be added, see response body for details
- **401** - Unauthorized
- **403** - Access denied
- **404** - Datasource not found or permission not found

View File

@ -6,12 +6,14 @@ labels:
products:
- enterprise
- oss
title: Get started
title: Get started with Grafana Open Source
weight: 9
---
# Get started
# Get started with Grafana Open Source
This section provides guidance on how build your first dashboard after you have installed Grafana. It also provides step-by-step instructions on how to add a Prometheus, InfluxDB, or an MS SQL Server data source. Refer to [Data sources]({{< relref "../datasources" >}}) for a list of all supported data sources.
Grafana helps you collect, correlate, and visualize data with beautiful dashboards — the open source data visualization and monitoring solution that drives informed decisions, enhances system performance, and streamlines troubleshooting.
This section provides guidance to our open source community about how to build your first dashboard after you have installed Grafana. It also provides step-by-step instructions on how to add a Prometheus, InfluxDB, or an MS SQL Server data source. If you are connecting a different data source, please refer to our complete list of supported [Data sources]({{< relref "../datasources" >}}). If you would like to learn how to get started with Grafana Cloud, our fully managed observability stack, visit the [Grafana Cloud documentation](https://grafana.com/docs/grafana-cloud/quickstart/) for more information.
{{< section >}}

View File

@ -35,7 +35,7 @@ To sign in to Grafana for the first time:
1. On the sign-in page, enter `admin` for both the username and password.
1. Click **Sign in**.
If successful, you will see a prompt to change the password.
If successful, you'll see a prompt to change the password.
1. Click **OK** on the prompt and change your password.
@ -50,14 +50,14 @@ If you've already set up a data source that you know how to query, refer to [Cre
To create your first dashboard using the built-in `-- Grafana --` data source:
1. Click **Dashboards** in the left-side menu.
1. On the Dashboards page, click **New** and select **New Dashboard** from the dropdown menu.
1. On the Dashboards page, click **New** and select **New Dashboard** from the drop-down menu.
1. On the dashboard, click **+ Add visualization**.
![Empty dashboard state](/media/docs/grafana/dashboards/empty-dashboard-10.2.png)
1. In the modal that opens, click `-- Grafana --`:
1. In the dialog box that opens, click `-- Grafana --`:
{{< figure class="float-right" src="/media/docs/grafana/dashboards/screenshot-data-source-selector-10.0.png" max-width="800px" alt="Select data source modal" >}}
{{< figure class="float-right" src="/media/docs/grafana/dashboards/screenshot-data-source-selector-10.0.png" max-width="800px" alt="Select data source dialog box" >}}
This configures your [query]({{< relref "../panels-visualizations/query-transform-data#add-a-query" >}}) and generates the Random Walk dashboard.
@ -69,9 +69,11 @@ To create your first dashboard using the built-in `-- Grafana --` data source:
Alternatively, click **Apply** if you want to see your changes applied to the dashboard first. Then click the save icon in the dashboard header.
1. Add a descriptive name for the dashboard, and then click **Save**.
1. Add a descriptive title for the dashboard, and then click **Save**.
Congratulations, you have created your first dashboard and it is displaying results.
Alternatively, Grafana can generate a dashboard title and summary for you using the OpenAI integration. Learn more in the [Set up generative AI features for dashboards documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/dashboards/manage-dashboards#set-up-generative-ai-features-for-dashboards).
Congratulations, you have created your first dashboard and it's displaying results.
#### Next steps

View File

@ -84,7 +84,6 @@ With a Grafana Enterprise license, you also get access to premium data sources,
- [k6 Cloud App](/grafana/plugins/grafana-k6-app)
- [MongoDB](/grafana/plugins/grafana-mongodb-datasource)
- [New Relic](/grafana/plugins/grafana-newrelic-datasource)
- [Sqlyze Datasource](/grafana/plugins/grafana-odbc-datasource)
- [Oracle Database](/grafana/plugins/grafana-oracle-datasource)
- [Salesforce](/grafana/plugins/grafana-salesforce-datasource)
- [SAP HANA®](/grafana/plugins/grafana-saphana-datasource)
@ -92,7 +91,8 @@ With a Grafana Enterprise license, you also get access to premium data sources,
- [Snowflake](/grafana/plugins/grafana-snowflake-datasource)
- [Splunk](/grafana/plugins/grafana-splunk-datasource)
- [Splunk Infrastructure monitoring (SignalFx)](/grafana/plugins/grafana-splunk-monitoring-datasource)
- [Sqlyze](/grafana/plugins/grafana-odbc-datasource/)
- [Sqlyze Datasource](/grafana/plugins/grafana-odbc-datasource)
- [SumoLogic](/grafana/plugins/grafana-sumologic-datasource)
- [Wavefront](/grafana/plugins/grafana-wavefront-datasource)
## Try Grafana Enterprise

View File

@ -53,6 +53,8 @@ After you add a panel to a dashboard, you can open it at any time to change or u
## Add a title and description to a panel
You can use generative AI to create panel titles and descriptions with the [Grafana LLM plugin][], which is currently in public preview. To enable this, refer to the [Set up generative AI features for dashboards documentation][]. Alternatively, you can take the following steps to create them yourself.
Add a title and description to a panel to share with users any important information about the visualization. For example, use the description to document the purpose of the visualization.
1. [Edit a panel](#edit-a-panel).
@ -92,7 +94,7 @@ Explore and export panel, panel data, and data frame JSON models.
You can configure Grafana to dynamically add panels or rows to a dashboard. A dynamic panel is a panel that the system creates based on the value of a variable. Variables dynamically change your queries across all panels in a dashboard. For more information about repeating rows, refer to [Configure repeating rows][].
{{% admonition type="note" %}}
Repeating panels require variables to have one or more items selected; you cannot repeat a panel zero times to hide it.
Repeating panels require variables to have one or more items selected; you can't repeat a panel zero times to hide it.
{{% /admonition %}}
To see an example of repeating panels, refer to [this dashboard with repeating panels](https://play.grafana.org/d/testdata-repeating/testdata-repeating-panels?orgId=1).
@ -109,7 +111,7 @@ To see an example of repeating panels, refer to [this dashboard with repeating p
1. Select a `direction`.
- Choose `horizontal` to arrange panels side-by-side. Grafana adjusts the width of a repeated panel. Currently, you cannot mix other panels on a row with a repeated panel.
- Choose `horizontal` to arrange panels side-by-side. Grafana adjusts the width of a repeated panel. Currently, you can't mix other panels on a row with a repeated panel.
- Choose `vertical` to arrange panels in a column. The width of repeated panels is the same as the original, repeated panel.
1. To propagate changes to all panels, reload the dashboard.
@ -123,4 +125,10 @@ To see an example of repeating panels, refer to [this dashboard with repeating p
[Configure repeating rows]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/build-dashboards/create-dashboard#configure-repeating-rows"
[Configure repeating rows]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/build-dashboards/create-dashboard#configure-repeating-rows"
[Grafana LLM plugin]: "/docs/grafana/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin"
[Grafana LLM plugin]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin"
[Set up generative AI features for dashboards documentation]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/dashboards/manage-dashboards#set-up-generative-ai-features-for-dashboards"
[Set up generative AI features for dashboards documentation]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/manage-dashboards#set-up-generative-ai-features-for-dashboards"
{{% /docs/reference %}}

View File

@ -33,10 +33,32 @@ In the panel editor, you can update all the elements of a visualization includin
![Panel editor](/media/docs/grafana/panels-visualizations/screenshot-panel-editor-view.png)
To add a panel in a new dashboard click **+ Add visualization** in the middle of the dashboard. To add a panel to an existing dashboard, click **Add** in the dashboard header and select **Visualization** in the dropdown:
To add a panel in a new dashboard click **+ Add visualization** in the middle of the dashboard. To add a panel to an existing dashboard, click **Add** in the dashboard header and select **Visualization** in the drop-down:
![Add dropdown](/media/docs/grafana/dashboards/screenshot-add-dropdown-10.0.png)
## Panel menu
To access the panel editor, hover over the top-right corner of any panel. Click the panel menu icon that appears and select **Edit**. The panel menu gives you access to the following actions:
- **View**: View the panel in full screen.
- **Edit**: Open the panel editor to edit panel and visualization options.
- **Share**: Share the panel as a link, embed, or library panel.
- **Explore**: Open the panel in **Explore**, where you can focus on your query.
- **Inspect**: Open the **Inspect** drawer, where you can review the panel data, stats, metadata, JSON, and query.
- **Data**: Open the **Inspect** drawer in the **Data** tab.
- **Query**: Open the **Inspect** drawer in the **Query** tab.
- **Panel JSON**: Open the **Inspect** drawer in the **JSON** tab.
- **Extensions**: Access other actions provided by installed applications, such as declaring an incident. Note that this option doesn't appear unless you have app plugins installed which contribute an [extension](https://grafana.com/developers/plugin-tools/ui-extensions/) to the panel menu.
- **More**: Access other panel actions.
- **Duplicate**: Make a copy of the panel. Duplicated panels query data separately from the original panel. You can use the special `Dashboard` data source to [share the same query results across panels][] instead.
- **Copy**: Copy the panel to the clipboard.
- **Create library panel**: Create a panel that can be imported into other dashboards.
- **Create alert**: Open the alert rule configuration page in **Alerting**, where you can [create a Grafana-managed alert] based on the panel queries.
- **Hide legend**: Hide the panel legend.
- **Get help**: Send a snapshot or panel data to Grafana Labs Technical Support.
- **Remove**: Remove the panel from the dashboard.
## Panel editor
This section describes the areas of the Grafana panel editor.
@ -45,18 +67,18 @@ This section describes the areas of the Grafana panel editor.
- **Discard:** Discards changes you have made to the panel since you last saved the dashboard.
- **Save:** Saves changes you made to the panel.
- **Apply:** Applies changes you made and closes the panel editor, returning you to the dashboard. You will have to save the dashboard to persist the applied changes.
- **Apply:** Applies changes you made and closes the panel editor, returning you to the dashboard. You'll have to save the dashboard to persist the applied changes.
1. Visualization preview: The visualization preview section contains the following options:
- **Table view:** Convert any visualization to a table so you can see the data. Table views are helpful for troubleshooting. This view only contains the raw data. It does not include transformations you might have applied to the data or the formatting options available in the [Table][] visualization.
- **Table view:** Convert any visualization to a table so you can see the data. Table views are helpful for troubleshooting. This view only contains the raw data. It doesn't include transformations you might have applied to the data or the formatting options available in the [Table][] visualization.
- **Fill:** The visualization preview fills the available space. If you change the width of the side pane or height of the bottom pane the visualization changes to fill the available space.
- **Actual:** The visualization preview will have the exact size as the size on the dashboard. If not enough space is available, the visualization will scale down preserving the aspect ratio.
- **Actual:** The visualization preview has the exact size as the size on the dashboard. If not enough space is available, the visualization scales down preserving the aspect ratio.
- **Time range controls:** **Default** is either the browser local timezone or the timezone selected at a higher level.
1. Data section: The data section contains tabs where you enter queries, transform your data, and create alert rules (if applicable).
- **Query tab:** Select your data source and enter queries here. For more information, refer to [Add a query][]. When you create a new dashboard, you'll be prompted to select a data source before you get to the panel editor. You set or update the data source in existing dashboards using the dropdown in the **Query** tab.
- **Query tab:** Select your data source and enter queries here. For more information, refer to [Add a query][]. When you create a new dashboard, you'll be prompted to select a data source before you get to the panel editor. You set or update the data source in existing dashboards using the drop-down in the **Query** tab.
- **Transform tab:** Apply data transformations. For more information, refer to [Transform data][].
- **Alert tab:** Write alert rules. For more information, refer to [the overview of Grafana Alerting][].
@ -69,14 +91,14 @@ The inspect drawer helps you understand and troubleshoot your panels. You can vi
To access the panel inspect drawer from the edit view, hover over any part of the panel to display the actions menu on the top right corner. Click the menu and select **Inspect**.
{{% admonition type="note" %}}
Not all panel types include all tabs. For example, dashboard list panels do not have raw data to inspect, so they do not display the Stats, Data, or Query tabs.
Not all panel types include all tabs. For example, dashboard list panels don't have raw data to inspect, so they don't display the Stats, Data, or Query tabs.
{{% /admonition %}}
The panel inspector consists of the following options:
1. The panel inspect drawer displays opens a drawer on the right side. Click the arrow in the upper right corner to expand or reduce the drawer pane.
1. **Data tab -** Shows the raw data returned by the query with transformations applied. Field options such as overrides and value mappings are not applied by default.
1. **Data tab -** Shows the raw data returned by the query with transformations applied. Field options such as overrides and value mappings aren't applied by default.
1. **Stats tab -** Shows how long your query takes and how much it returns.
@ -98,4 +120,10 @@ The panel inspector consists of the following options:
[the overview of Grafana Alerting]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/alerting"
[the overview of Grafana Alerting]: "/docs/grafana-cloud/ -> /docs/grafana/<GRAFANA VERSION>/alerting"
[share the same query results across panels]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/query-transform-data/share-query"
[share the same query results across panels]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/share-query"
[create a Grafana-managed alert]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/alerting/alerting-rules/create-grafana-managed-rule#create-alerts-from-panels"
[create a Grafana-managed alert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/create-grafana-managed-rule#create-alerts-from-panels"
{{% /docs/reference %}}

View File

@ -1,4 +1,24 @@
---
comments: |
This Markdown file is auto-generated. DO NOT EDIT THIS FILE DIRECTLY.
To update this Markdown, navigate to the following Typescript files and edit them based on what you need to update:
scripts/docs/generate-transformations.ts - Includes all content not specific to a transformation.
public/app/features/transformers/docs/content.ts - Transformation-specific content.
Only use reference style links in the 'content.ts' file or else link text will be visible in the UI.
To build this Markdown, do the following:
$ cd /docs (from the root of the repository)
$ make sources/panels-visualizations/query-transform-data/transform-data/index.md
$ make docs
Browse to http://localhost:3003/docs/grafana/latest/panels-visualizations/query-transform-data/transform-data/
Refer to ./docs/README.md "Content guidelines" for more information about editing and building these docs.
aliases:
- ../../panels/reference-transformation-functions/
- ../../panels/transform-data/
@ -123,21 +143,21 @@ Use this transformation to add a new field calculated from two other fields. Eac
- **Alias -** (Optional) Enter the name of your new field. If you leave this blank, then the field will be named to match the calculation.
- **Replace all fields -** (Optional) Select this option if you want to hide all other fields and display only your calculated field in the visualization.
In the example below, I added two fields together and named them Sum.
In the example below, we added two fields together and named them Sum.
{{< figure src="/static/img/docs/transformations/add-field-from-calc-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
### Concatenate fields
This transformation combines all fields from all frames into one result. Consider:
Use this transformation to combine all fields from all frames into one result. Consider the following:
Query A:
**Query A:**
| Temp | Uptime |
| ---- | ------- |
| 15.4 | 1230233 |
Query B:
**Query B:**
| AQI | Errors |
| --- | ------ |
@ -151,9 +171,9 @@ After you concatenate the fields, the data frame would be:
### Config from query results
This transformation allow you to select one query and from it extract standard options like **Min**, **Max**, **Unit** and **Thresholds** and apply it to other query results. This enables dynamic query driven visualization configuration.
If you want to extract a unique config for every row in the config query result then try the rows to fields transformation.
Use this transformation to select one query and from it extract standard options such as
**Min**, **Max**, **Unit**, and **Thresholds** and apply them to other query results.
This enables dynamic query driven visualization configuration.
#### Options
@ -161,9 +181,63 @@ If you want to extract a unique config for every row in the config query result
- **Apply to**: Select what fields or series to apply the configuration to.
- **Apply to options**: Usually a field type or field name regex depending on what option you selected in **Apply to**.
#### Field mapping table
Below the configuration listed above you will find the field table. Here all fields found in the data returned by the config query will be listed along with a **Use as** and **Select** option. This table gives you control over what field should be mapped to which config property and if there are multiple rows which value to select.
#### Example
Input[0] (From query: A, name: ServerA)
| Time | Value |
| ------------- | ----- |
| 1626178119127 | 10 |
| 1626178119129 | 30 |
Input[1] (From query: B)
| Time | Value |
| ------------- | ----- |
| 1626178119127 | 100 |
| 1626178119129 | 100 |
Output (Same as Input[0] but now with config on the Value field)
| Time | Value (config: Max=100) |
| ------------- | ----------------------- |
| 1626178119127 | 10 |
| 1626178119129 | 30 |
Each row in the source data becomes a separate field. Each field now also has a maximum
configuration option set. Options such as **min**, **max**, **unit**, and **thresholds** are all part of field configuration, and if they are set like this, they will be used by the visualization instead of any options that are manually configured.
in the panel editor options pane.
#### Value mappings
You can also transform a query result into value mappings. This is is a bit different because every
row in the configuration query result is used to define a single value mapping row. See the following example.
Config query result:
| Value | Text | Color |
| ----- | ------ | ----- |
| L | Low | blue |
| M | Medium | green |
| H | High | red |
In the field mapping specify:
| Field | Use as | Select |
| ----- | ----------------------- | ---------- |
| Value | Value mappings / Value | All values |
| Text | Value mappings / Text | All values |
| Color | Value mappings / Ciolor | All values |
Grafana will build the value mappings from you query result and apply it the the real data query results. You should see values being mapped and colored according to the config query results.
### Convert field type
This transformation changes the field type of the specified field.
Use this transformation to change the field type of the specified field.
- **Field -** Select from available fields
- **as -** Select the FieldType to convert to
@ -173,7 +247,9 @@ This transformation changes the field type of the specified field.
- Will show an option to specify a DateFormat as input by a string like yyyy-mm-dd or DD MM YYYY hh:mm:ss
- **Boolean -** will make the values booleans
For example the following query could be modified by selecting the time field, as Time, and Date Format as YYYY.
For example, the following query could be modified by selecting the time field, as Time, and Date Format as YYYY.
#### Sample Query
| Time | Mark | Value |
| ---------- | ----- | ----- |
@ -184,6 +260,8 @@ For example the following query could be modified by selecting the time field, a
The result:
#### Transformed Query
| Time | Mark | Value |
| ------------------- | ----- | ----- |
| 2017-01-01 00:00:00 | above | 25 |
@ -191,29 +269,6 @@ The result:
| 2019-01-01 00:00:00 | below | 29 |
| 2020-01-01 00:00:00 | above | 22 |
### Create heatmap
Use this transformation to prepare histogram data to be visualized over time. Similar to the [Heatmap panel][], this transformation allows you to convert histogram metrics to buckets over time.
#### X Bucket
This setting determines how the x-axis is split into buckets.
- **Size** - Specify a time interval in the input field. For example, a time range of `1h` makes the cells one hour wide on the x-axis.
- **Count** - For non-time related series, use this option to define the number of elements in a bucket.
#### Y Bucket
This setting determines how the y-axis is split into buckets.
#### Y Bucket scale
Use this option to set the scale of the y-axes. Select from:
- **Linear**
- **Logarithmic** - Use a base 2 or base 10.
- **Symlog** - A symmetrical logarithmic scale. Use a base 2 or base 10; allows negative values.
### Extract fields
Use this transformation to select one source of data and extract content from it in different formats. Set the following fields:
@ -221,13 +276,15 @@ Use this transformation to select one source of data and extract content from it
- **Source** - Select the field for the source of data.
- **Format** - Select one of the following:
- **JSON** - To parse JSON content from the source.
- **Key+value parse** - To parse content in the format `a=b` or `c:d` from the source.
- **Key+value parse** - To parse content in the format 'a=b' or 'c:d' from the source.
- **Auto** - To discover fields automatically.
- **Replace all fields** - Optional: Select this option if you want to hide all other fields and display only your calculated field in the visualization.
- **Keep time** - Optional: Only available if **Replace all fields** is true. Keep the time field in the output.
Consider the following data set:
#### Data Set Example
| Timestamp | json_data |
| ------------------- | ------------- |
| 1636678740000000000 | {"value": 1} |
@ -239,19 +296,21 @@ You could prepare the data to be used by a [Time series panel][] with this confi
- Source: json_data
- Format: JSON
- Field: value
- alias: my_value
- Alias: my_value
- Replace all fields: true
- Keep time: true
This will generate the following output:
#### Transformed Data
| Timestamp | my_value |
| ------------------- | -------- |
| 1636678740000000000 | 1 |
| 1636678680000000000 | 5 |
| 1636678620000000000 | 12 |
### Field lookup
### Lookup fields from resource
Use this transformation on a field value to look up additional fields from an external source.
@ -262,6 +321,8 @@ This transformation currently supports spatial data.
For example, if you have this data:
#### Data Set Example
| Location | Values |
| --------- | ------ |
| AL | 0 |
@ -277,6 +338,8 @@ With this configuration:
You'll get the following output:
#### Transformed Data
| Location | ID | Name | Lng | Lat | Values |
| --------- | --- | -------- | ----------- | --------- | ------ |
| AL | AL | Alabama | -80.891064 | 12.448457 | 0 |
@ -285,7 +348,84 @@ You'll get the following output:
| Arkansas | | | | | 1 |
| Somewhere | | | | | 5 |
### Filter by name
### Filter data by query refId
Use this transformation in panels that have multiple queries, if you want to hide one or more of the queries.
Grafana displays the query identification letters in dark gray text. Click a query identifier to toggle filtering. If the query letter is white, then the results are displayed. If the query letter is dark, then the results are hidden.
> **Note:** This transformation is not available for Graphite because this data source does not support correlating returned data with queries.
In the example below, the panel has three queries (A, B, C). We removed the B query from the visualization.
{{< figure src="/static/img/docs/transformations/filter-by-query-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
### Filter data by values
Use this transformation to filter your data directly in Grafana and remove some data points from your query result. You have the option to include or exclude data that match one or more conditions you define. The conditions are applied on a selected field.
This transformation is very useful if your data source does not natively filter by values. You might also use this to narrow values to display if you are using a shared query.
The available conditions for all fields are:
- **Regex:** Match a regex expression
- **Is Null:** Match if the value is null
- **Is Not Null:** Match if the value is not null
- **Equal:** Match if the value is equal to the specified value
- **Different:** Match if the value is different than the specified value
The available conditions for number fields are:
- **Greater:** Match if the value is greater than the specified value
- **Lower:** Match if the value is lower than the specified value
- **Greater or equal:** Match if the value is greater or equal
- **Lower or equal:** Match if the value is lower or equal
- **Range:** Match a range between a specified minimum and maximum, min and max included
Consider the following data set:
#### Data Set Example
| Time | Temperature | Altitude |
| ------------------- | ----------- | -------- |
| 2020-07-07 11:34:23 | 32 | 101 |
| 2020-07-07 11:34:22 | 28 | 125 |
| 2020-07-07 11:34:21 | 26 | 110 |
| 2020-07-07 11:34:20 | 23 | 98 |
| 2020-07-07 10:32:24 | 31 | 95 |
| 2020-07-07 10:31:22 | 20 | 85 |
| 2020-07-07 09:30:57 | 19 | 101 |
If you **Include** the data points that have a temperature below 30°C, the configuration will look as follows:
- Filter Type: 'Include'
- Condition: Rows where 'Temperature' matches 'Lower Than' '30'
And you will get the following result, where only the temperatures below 30°C are included:
#### Transformed Data
| Time | Temperature | Altitude |
| ------------------- | ----------- | -------- |
| 2020-07-07 11:34:22 | 28 | 125 |
| 2020-07-07 11:34:21 | 26 | 110 |
| 2020-07-07 11:34:20 | 23 | 98 |
| 2020-07-07 10:31:22 | 20 | 85 |
| 2020-07-07 09:30:57 | 19 | 101 |
You can add more than one condition to the filter. For example, you might want to include the data only if the altitude is greater than 100. To do so, add that condition to the following configuration:
- Filter type: 'Include' rows that 'Match All' conditions
- Condition 1: Rows where 'Temperature' matches 'Lower' than '30'
- Condition 2: Rows where 'Altitude' matches 'Greater' than '100'
When you have more than one condition, you can choose if you want the action (include / exclude) to be applied on rows that **Match all** conditions or **Match any** of the conditions you added.
In the example above, we chose **Match all** because we wanted to include the rows that have a temperature lower than 30°C _AND_ an altitude higher than 100. If we wanted to include the rows that have a temperature lower than 30°C _OR_ an altitude higher than 100 instead, then we would select **Match any**. This would include the first row in the original data, which has a temperature of 32°C (does not match the first condition) but an altitude of 101 (which matches the second condition), so it is included.
Conditions that are invalid or incompletely configured are ignored.
### Filter fields by name
Use this transformation to remove parts of the query results.
@ -306,14 +446,14 @@ From the input data:
| 2023-03-04 23:56:23 | 23.5 | 24.5 | 22.2 | 20.2 |
| 2023-03-04 23:56:23 | 23.6 | 24.4 | 22.1 | 20.1 |
The result from using the regular expression `prod.*` would be:
The result from using the regular expression 'prod.\*' would be:
| Time | prod-eu-west | prod-eu-north |
| ------------------- | ------------ | ------------- |
| 2023-03-04 23:56:23 | 22.2 | 20.2 |
| 2023-03-04 23:56:23 | 22.1 | 20.1 |
The regular expression can include an interpolated dashboard variable by using the `${[variable name]}` syntax.
The regular expression can include an interpolated dashboard variable by using the ${$variableName} syntax.
#### Manually select included fields
@ -321,86 +461,44 @@ Click and uncheck the field names to remove them from the result. Fields that ar
#### Use a dashboard variable
Enable `From variable` to let you select a dashboard variable that's used to include fields. By setting up a [dashboard variable][] with multiple choices, the same fields can be displayed across multiple visualizations.
Enable 'From variable' to let you select a dashboard variable that's used to include fields. By setting up a [dashboard variable][] with multiple choices, the same fields can be displayed across multiple visualizations.
### Filter data by query
{{< figure src="/static/img/docs/transformations/filter-name-table-before-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
Use this transformation in panels that have multiple queries, if you want to hide one or more of the queries.
Here's the table after we applied the transformation to remove the Min field.
Grafana displays the query identification letters in dark gray text. Click a query identifier to toggle filtering. If the query letter is white, then the results are displayed. If the query letter is dark, then the results are hidden.
{{< figure src="/static/img/docs/transformations/filter-name-table-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
In the example below, the panel has three queries (A, B, C). I removed the B query from the visualization.
Here is the same query using a Stat visualization.
{{< figure src="/static/img/docs/transformations/filter-by-query-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
{{< figure src="/static/img/docs/transformations/filter-name-stat-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
{{% admonition type="note" %}}
This transformation is not available for Graphite because this data source does not support correlating returned data with queries.
{{% /admonition %}}
### Format string
### Filter data by value
> **Note:** This transformation is an experimental feature. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the 'formatString' in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud.
This transformation allows you to filter your data directly in Grafana and remove some data points from your query result. You have the option to include or exclude data that match one or more conditions you define. The conditions are applied on a selected field.
Use this transformation to format the output of a string field. You can format output in the following ways:
This transformation is very useful if your data source does not natively filter by values. You might also use this to narrow values to display if you are using a shared query.
- Upper case - Formats the entire string in upper case characters.
- Lower case - Formats the entire string in lower case characters.
- Sentence case - Formats the the first character of the string in upper case.
- Title case - Formats the first character of each word in the string in upper case.
- Pascal case - Formats the first character of each word in the string in upper case and doesn't include spaces between words.
- Camel case - Formats the first character of each word in the string in upper case, except the first word, and doesn't include spaces between words.
- Snake case - Formats all characters in the string in lower case and uses underscores instead of spaces between words.
- Kebab case - Formats all characters in the string in lower case and uses dashes instead of spaces between words.
- Trim - Removes all leading and trailing spaces from the string.
- Substring - Returns a substring of the string, using the specified start and end positions.
The available conditions for all fields are:
### Format time
- **Regex:** Match a regex expression
- **Is Null:** Match if the value is null
- **Is Not Null:** Match if the value is not null
- **Equal:** Match if the value is equal to the specified value
- **Different:** match if the value is different than the specified value
Use this transformation to format the output of a time field. Output can be formatted using [Moment.js format strings](https://momentjs.com/docs/#/displaying/). For instance, if you would like to display only the year of a time field the format string 'YYYY' can be used to show the calendar year (e.g. 1999, 2012, etc.).
The available conditions for number fields are:
- **Greater:** Match if the value is greater than the specified value
- **Lower:** Match if the value is lower than the specified value
- **Greater or equal:** Match if the value is greater or equal
- **Lower or equal:** Match if the value is lower or equal
- **Range:** Match a range between a specified minimum and maximum, min and max included
Consider the following data set:
| Time | Temperature | Altitude |
| ------------------- | ----------- | -------- |
| 2020-07-07 11:34:23 | 32 | 101 |
| 2020-07-07 11:34:22 | 28 | 125 |
| 2020-07-07 11:34:21 | 26 | 110 |
| 2020-07-07 11:34:20 | 23 | 98 |
| 2020-07-07 10:32:24 | 31 | 95 |
| 2020-07-07 10:31:22 | 20 | 85 |
| 2020-07-07 09:30:57 | 19 | 101 |
If you **Include** the data points that have a temperature below 30°C, the configuration will look as follows:
- Filter Type: `Include`
- Condition: Rows where `Temperature` matches `Lower Than` `30`
And you will get the following result, where only the temperatures below 30°C are included:
| Time | Temperature | Altitude |
| ------------------- | ----------- | -------- |
| 2020-07-07 11:34:22 | 28 | 125 |
| 2020-07-07 11:34:21 | 26 | 110 |
| 2020-07-07 11:34:20 | 23 | 98 |
| 2020-07-07 10:31:22 | 20 | 85 |
| 2020-07-07 09:30:57 | 19 | 101 |
You can add more than one condition to the filter. For example, you might want to include the data only if the altitude is greater than 100. To do so, add that condition to the following configuration:
- Filter type: `Include` rows that `Match All` conditions
- Condition 1: Rows where `Temperature` matches `Lower` than `30`
- Condition 2: Rows where `Altitude` matches `Greater` than `100`
When you have more than one condition, you can choose if you want the action (include / exclude) to be applied on rows that **Match all** conditions or **Match any** of the conditions you added.
In the example above we chose **Match all** because we wanted to include the rows that have a temperature lower than 30 _AND_ an altitude higher than 100. If we wanted to include the rows that have a temperature lower than 30 _OR_ an altitude higher than 100 instead, then we would select **Match any**. This would include the first row in the original data, which has a temperature of 32°C (does not match the first condition) but an altitude of 101 (which matches the second condition), so it is included.
Conditions that are invalid or incompletely configured are ignored.
> **Note:** This transformation is available in Grafana 10.1+ as an alpha feature.
### Group by
This transformation groups the data by a specified field (column) value and processes calculations on each group. Click to see a list of calculation choices. For information about available calculations, refer to [Calculation types][].
Use this transformation to group the data by a specified field (column) value and process calculations on each group. Click to see a list of calculation choices. For information about available calculations, refer to [Calculation types][].
Here's an example of original data.
@ -468,15 +566,34 @@ Use this transformation to combine three fields-that will be used as input for t
| server 2 | 88.6 | OK |
| server 3 | 59.6 | Shutdown |
We can generate a matrix using the values of `Server Status` as column names, the `Server ID` values as row names, and the `CPU Temperature` as content of each cell. The content of each cell will appear for the existing column (`Server Status`) and row combination (`Server ID`). For the rest of the cells, you can select which value to display between: **Null**, **True**, **False**, or **Empty**.
We can generate a matrix using the values of 'Server Status' as column names, the 'Server ID' values as row names, and the 'CPU Temperature' as content of each cell. The content of each cell will appear for the existing column ('Server Status') and row combination ('Server ID'). For the rest of the cells, you can select which value to display between: **Null**, **True**, **False**, or **Empty**.
**Output**
| Server ID\Server Status | OK | Shutdown |
| ----------------------- | ---- | -------- |
| server 1 | 82 | |
| server 2 | 88.6 | |
| server 3 | | 59.6 |
| Server IDServer Status | OK | Shutdown |
| ---------------------- | ---- | -------- |
| server 1 | 82 | |
| server 2 | 88.6 | |
| server 3 | | 59.6 |
### Create heatmap
Use this transformation to prepare histogram data to be visualized over time. Similar to the Heatmap panel, this transformation allows you to convert histogram metrics to buckets over time.
#### X Bucket
This setting determines how the x-axis is split into buckets.
- **Size** - Specify a time interval in the input field. For example, a time range of '1h' makes the cells one hour wide on the x-axis.
- **Count** - For non-time related series, use this option to define the number of elements in a bucket.
#### Y Bucket
This setting determines how the y-axis is split into buckets.
- **Linear**
- **Logarithmic** - Use a base 2 or base 10.
- **Symlog** - A symmetrical logarithmic scale. Use a base 2 or base 10; allows negative values.
### Histogram
@ -561,7 +678,7 @@ The result after applying the inner join transformation looks like the following
#### Outer join
An outer join includes all data from an inner join and rows where values do not match in every input. While the inner join joins Query A and Query B on the time field, the outer join includes all rows that dont match on the time field.
An outer join includes all data from an inner join and rows where values do not match in every input. While the inner join joins Query A and Query B on the time field, the outer join includes all rows that don't match on the time field.
In the following example, two queries return table data. It is visualized as two tables before applying the outer join transformation.
@ -610,21 +727,21 @@ time series results into a single wide table with a shared **Label** field.
##### Input
serie1{what="Temp", cluster="A", job="J1"}
series1{what="Temp", cluster="A", job="J1"}
| Time | Value |
| ---- | ----- |
| 1 | 10 |
| 2 | 200 |
serie2{what="Temp", cluster="B", job="J1"}
series2{what="Temp", cluster="B", job="J1"}
| Time | Value |
| ---- | ----- |
| 1 | 10 |
| 2 | 200 |
serie3{what="Speed", cluster="B", job="J1"}
series3{what="Speed", cluster="B", job="J1"}
| Time | Value |
| ---- | ----- |
@ -646,7 +763,7 @@ value: "what"
### Labels to fields
This transformation changes time series results that include labels or tags into a table where each label keys and values are included in the table result. The labels can be displayed either as columns or as row values.
Use this transformation to change time series results that include labels or tags into a table where each label's keys and values are included in the table result. The labels can be displayed as either columns or row values.
Given a query result of two time series:
@ -706,6 +823,29 @@ After merge:
| 2020-07-07 11:34:20 | ServerA | 10 | |
| 2020-07-07 11:34:20 | | 20 | EU |
### Limit
Use this transformation to limit the number of rows displayed.
In the example below, we have the following response from the data source:
| Time | Metric | Value |
| ------------------- | ----------- | ----- |
| 2020-07-07 11:34:20 | Temperature | 25 |
| 2020-07-07 11:34:20 | Humidity | 22 |
| 2020-07-07 10:32:20 | Humidity | 29 |
| 2020-07-07 10:31:22 | Temperature | 22 |
| 2020-07-07 09:30:57 | Humidity | 33 |
| 2020-07-07 09:30:05 | Temperature | 19 |
Here is the result after adding a Limit transformation with a value of '3':
| Time | Metric | Value |
| ------------------- | ----------- | ----- |
| 2020-07-07 11:34:20 | Temperature | 25 |
| 2020-07-07 11:34:20 | Humidity | 22 |
| 2020-07-07 10:32:20 | Humidity | 29 |
### Merge
Use this transformation to combine the result from multiple queries into one single result. This is helpful when using the table panel visualization. Values that can be merged are combined into the same row. Values are mergeable if the shared fields contain the same data. For information, refer to [Table panel][].
@ -733,13 +873,11 @@ Here is the result after applying the Merge transformation.
| 2020-07-07 11:34:20 | node | 15 | 25260122 |
| 2020-07-07 11:24:20 | postgre | 5 | 123001233 |
### Organize fields
### Oraganize fields
Use this transformation to rename, reorder, or hide fields returned by the query.
{{% admonition type="note" %}}
This transformation only works in panels with a single query. If your panel has multiple queries, then you must either apply an Outer join transformation or remove the extra queries.
{{% /admonition %}}
> **Note:** This transformation only works in panels with a single query. If your panel has multiple queries, then you must either apply an Outer join transformation or remove the extra queries.
Grafana displays a list of fields returned by the query. You can:
@ -747,13 +885,9 @@ Grafana displays a list of fields returned by the query. You can:
- Hide or show a field by clicking the eye icon next to the field name.
- Rename fields by typing a new name in the **Rename <field>** box.
In the example below, I hid the value field and renamed Max and Min.
{{< figure src="/static/img/docs/transformations/organize-fields-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}}
### Partition by values
This transformation can help eliminate the need for multiple queries to the same datasource with different `WHERE` clauses when graphing multiple series. Consider a metrics SQL table with the following data:
Use this transformation to eliminate the need for multiple queries to the same data source with different 'WHERE' clauses when graphing multiple series. Consider a metrics SQL table with the following data:
| Time | Region | Value |
| ------------------- | ------ | ----- |
@ -764,14 +898,14 @@ This transformation can help eliminate the need for multiple queries to the same
Prior to v9.3, if you wanted to plot a red trendline for US and a blue one for EU in the same TimeSeries panel, you would likely have to split this into two queries:
`SELECT Time, Value FROM metrics WHERE Time > '2022-10-20' AND Region='US'`<br>
`SELECT Time, Value FROM metrics WHERE Time > '2022-10-20' AND Region='EU'`
'SELECT Time, Value FROM metrics WHERE Time > "2022-10-20" AND Region="US"'<br>
'SELECT Time, Value FROM metrics WHERE Time > "2022-10-20" AND Region="EU"'
This also requires you to know ahead of time which regions actually exist in the metrics table.
With the _Partition by values_ transformer, you can now issue a single query and split the results by unique values in one or more columns (`fields`) of your choosing. The following example uses `Region`.
With the _Partition by values_ transformer, you can now issue a single query and split the results by unique values in one or more columns ('fields') of your choosing. The following example uses 'Region'.
`SELECT Time, Region, Value FROM metrics WHERE Time > '2022-10-20'`
'SELECT Time, Region, Value FROM metrics WHERE Time > "2022-10-20"'
| Time | Region | Value |
| ------------------- | ------ | ----- |
@ -783,14 +917,21 @@ With the _Partition by values_ transformer, you can now issue a single query and
| 2022-10-20 12:00:00 | EU | 2936 |
| 2022-10-20 01:00:00 | EU | 912 |
There are two naming modes:
### Prepare time series
- **As labels** - The value that results are partitioned by is set as a label.
- **As frame name** - The value is used to set the frame name. This is useful if the data will be visualized in a table.
Use this transformation when a data source returns time series data in a format that isn't supported by the panel you want to use. For more information about data frame formats, refer to [Data frames][].
This transformation helps you resolve this issue by converting the time series data from either the wide format to the long format or the other way around.
Select the 'Multi-frame time series' option to transform the time series data frame from the wide to the long format.
Select the 'Wide time series' option to transform the time series data frame from the long to the wide format.
> **Note:** This transformation is available in Grafana 7.5.10+ and Grafana 8.0.6+.
### Reduce
The _Reduce_ transformation applies a calculation to each field in the frame and return a single value. Time fields are removed when applying this transformation.
Use this transformation to apply a calculation to each field in the frame and return a single value. Time fields are removed when applying this transformation.
Consider the input:
@ -842,9 +983,9 @@ Query B:
Use this transformation to rename parts of the query results using a regular expression and replacement pattern.
You can specify a regular expression, which is only applied to matches, along with a replacement pattern that support back references. For example, let's imagine you're visualizing CPU usage per host and you want to remove the domain name. You could set the regex to `([^\.]+)\..+` and the replacement pattern to `$1`, `web-01.example.com` would become `web-01`.
You can specify a regular expression, which is only applied to matches, along with a replacement pattern that support back references. For example, let's imagine you're visualizing CPU usage per host and you want to remove the domain name. You could set the regex to '([^.]+)..+' and the replacement pattern to '$1', 'web-01.example.com' would become 'web-01'.
In the following example, we are stripping the prefix from event types. In the before image, you can see everything is prefixed with `system.`
In the following example, we are stripping the prefix from event types. In the before image, you can see everything is prefixed with 'system.'
{{< figure src="/static/img/docs/transformations/rename-by-regex-before-7-3.png" class="docs-image--no-shadow" max-width= "1100px" >}}
@ -854,7 +995,7 @@ With the transformation applied, you can see we are left with just the remainder
### Rows to fields
The rows to fields transformation converts rows into separate fields. This can be useful as fields can be styled and configured individually. It can also use additional fields as sources for dynamic field configuration or map them to field labels. The additional labels can then be used to define better display names for the resulting fields.
Use this transformation to convert rows into separate fields. This can be useful because fields can be styled and configured individually. It can also use additional fields as sources for dynamic field configuration or map them to field labels. The additional labels can then be used to define better display names for the resulting fields.
This transformation includes a field table which lists all fields in the data returned by the config query. This table gives you control over what field should be mapped to each config property (the \*Use as\*\* option). You can also choose which value to select if there are multiple rows in the returned data.
@ -913,26 +1054,8 @@ Output:
As you can see each row in the source data becomes a separate field. Each field now also has a max config option set. Options like **Min**, **Max**, **Unit** and **Thresholds** are all part of field configuration and if set like this will be used by the visualization instead of any options manually configured in the panel editor options pane.
### Prepare time series
{{% admonition type="note" %}}
This transformation is available in Grafana 7.5.10+ and Grafana 8.0.6+.
{{% /admonition %}}
Prepare time series transformation is useful when a data source returns time series data in a format that isn't supported by the panel you want to use. For more information about data frame formats, refer to [Data frames](https://grafana.com/developers/plugin-tools/introduction/data-frames).
This transformation helps you resolve this issue by converting the time series data from either the wide format to the long format or the other way around.
Select the `Multi-frame time series` option to transform the time series data frame from the wide to the long format.
Select the `Wide time series` option to transform the time series data frame from the long to the wide format.
### Series to rows
{{% admonition type="note" %}}
This transformation is available in Grafana 7.1+.
{{% /admonition %}}
Use this transformation to combine the result from multiple time series data queries into one single result. This is helpful when using the table panel visualization.
The result from this transformation will contain three columns: Time, Metric, and Value. The Metric column is added so you easily can see from which query the metric originates from. Customize this value by defining Label on the source query.
@ -966,32 +1089,15 @@ Here is the result after applying the Series to rows transformation.
| 2020-07-07 09:30:57 | Humidity | 33 |
| 2020-07-07 09:30:05 | Temperature | 19 |
> **Note:** This transformation is available in Grafana 7.1+.
### Sort by
This transformation will sort each frame by the configured field, When `reverse` is checked, the values will return in the opposite order.
Use this transformation to sort each frame by the configured field. When the **Reverse** switch is on, the values will return in the opposite order.
### Limit
### Spatial
Use this transformation to limit the number of rows displayed.
In the example below, we have the following response from the data source:
| Time | Metric | Value |
| ------------------- | ----------- | ----- |
| 2020-07-07 11:34:20 | Temperature | 25 |
| 2020-07-07 11:34:20 | Humidity | 22 |
| 2020-07-07 10:32:20 | Humidity | 29 |
| 2020-07-07 10:31:22 | Temperature | 22 |
| 2020-07-07 09:30:57 | Humidity | 33 |
| 2020-07-07 09:30:05 | Temperature | 19 |
Here is the result after adding a Limit transformation with a value of '3':
| Time | Metric | Value |
| ------------------- | ----------- | ----- |
| 2020-07-07 11:34:20 | Temperature | 25 |
| 2020-07-07 11:34:20 | Humidity | 22 |
| 2020-07-07 10:32:20 | Humidity | 29 |
Use this transformation to apply spatial operations to query results
### Time series to table transform
@ -999,30 +1105,7 @@ Use this transformation to convert time series result into a table, converting t
For each generated "Trend" field value calculation function can be selected. Default is "last non null value". This value will be displayed next to the sparkline and used for sorting table rows.
### Format Time
{{% admonition type="note" %}}
This transformation is available in Grafana 10.1+ as an alpha feature.
{{% /admonition %}}
Use this transformation to format the output of a time field. Output can be formatted using (Moment.js format strings)[https://momentjs.com/docs/#/displaying/]. For instance, if you would like to display only the year of a time field the format string `YYYY` can be used to show the calendar year (e.g. 1999, 2012, etc.).
### Format string
> **Note:** This transformation is an experimental feature. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the `formatString` in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud.
Use this transformation to format the output of a string field. You can format output in the following ways:
- Upper case - Formats the entire string in upper case characters.
- Lower case - Formats the entire string in lower case characters.
- Sentence case - Formats the the first character of the string in upper case.
- Title case - Formats the first character of each word in the string in upper case.
- Pascal case - Formats the first character of each word in the string in upper case and doesn't include spaces between words.
- Camel case - Formats the first character of each word in the string in upper case, except the first word, and doesn't include spaces between words.
- Snake case - Formats all characters in the string in lower case and uses underscores instead of spaces between words.
- Kebab case - Formats all characters in the string in lower case and uses dashes instead of spaces between words.
- Trim - Removes all leading and trailing spaces from the string.
- Substring - Returns a substring of the string, using the specified start and end positions.
> **Note:** This transformation is available in Grafana 9.5+ as an opt-in beta feature. Modify Grafana [configuration file][] to use it.
{{% docs/reference %}}
[Table panel]: "/docs/grafana/ -> /docs/grafana/<GRAFANA VERSION>/panels-visualizations/visualizations/table"
@ -1050,3 +1133,5 @@ Use this transformation to format the output of a string field. You can format o
[dashboard variable]: "/docs/grafana-cloud/ -> docs/grafana/<GRAFANA VERSION>/dashboards/variables"
{{% /docs/reference %}}
[Data frames]: https://grafana.com/developers/plugin-tools/introduction/data-frames/

View File

@ -108,6 +108,8 @@ Optional fields:
| mainstat | string/number | First stat shown in the overlay when hovering over the edge. It can be a string showing the value as is or it can be a number. If it is a number, any unit associated with that field is also shown |
| secondarystat | string/number | Same as mainStat, but shown right under it. |
| detail\_\_\* | string/number | Any field prefixed with `detail__` will be shown in the header of context menu when clicked on the edge. Use `config.displayName` for more human readable label. |
| thickness | number | The thickness of the edge. Default: `1` |
| highlighted | boolean | Sets whether the edge should be highlighted. Useful, for example, to represent a specific path in the graph by highlighting several nodes and edges. Default: `false` |
### Nodes data frame structure
@ -130,3 +132,4 @@ Optional fields:
| color | string/number | Can be used to specify a single color instead of using the `arc__` fields to specify color sections. It can be either a string which should then be an acceptable HTML color string or it can be a number in which case the behaviour depends on `field.config.color.mode` setting. This can be for example used to create gradient colors controlled by the field value. |
| icon | string | Name of the icon to show inside the node instead of the default stats. Only Grafana built in icons are allowed (see the available icons [here](https://developers.grafana.com/ui/latest/index.html?path=/story/docs-overview-icon--icons-overview)). |
| nodeRadius | number | Radius value in pixels. Used to manage node size. |
| highlighted | boolean | Sets whether the node should be highlighted. Useful for example to represent a specific path in the graph by highlighting several nodes and edges. Default: `false` |

View File

@ -13,15 +13,15 @@ weight: 300
# Configure custom branding
Custom branding allows you to replace the Grafana brand and logo with your own corporate brand and logo.
Custom branding enables you to replace the Grafana Labs brand and logo with your corporate brand and logo.
{{% admonition type="note" %}}
Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). For Cloud Advanced and Enterprise customers, please provide your desired custom elements and corresponding logos to our Support team. We will help you in hosting your images and updating your Custom Branding.
Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). For Cloud Advanced and Enterprise customers, please provide custom elements and logos to our Support team. We will help you host your images and update your custom branding.
{{% /admonition %}}
Grafana Enterprise has custom branding options in the `grafana.ini` file. As with all configuration options, you can also set them with environment variables.
The `grafana.ini` file includes Grafana Enterprise custom branding. As with all configuration options, you can use environment variables to set custom branding.
You can change the following elements:
With custom branding, you have the ability to modify the following elements:
- Application title
- Login background
@ -38,7 +38,7 @@ You can change the following elements:
{{< figure src="/static/img/docs/v66/whitelabeling_1.png" max-width="800px" caption="Custom branding example" >}}
The configuration file in Grafana Enterprise contains the following options. Each option is defined in the file. For more information about configuring Grafana, refer to [Configuration]({{< relref "../../configure-grafana" >}}).
The configuration file in Grafana Enterprise contains the following options. For more information about configuring Grafana, refer to [Configure Grafana]({{< relref "../../configure-grafana" >}}).
```ini
# Enterprise only
@ -78,8 +78,7 @@ The configuration file in Grafana Enterprise contains the following options. Eac
;hide_edition =
```
You can replace the default footer links (Documentation, Support, Community) and even add your own custom links.
An example follows for replacing the default footer and help links with new custom links.
You have the option of adding custom links in place of the default footer links (Documentation, Support, Community). Below is an example of how to replace the default footer and help links with custom links.
```ini
footer_links = support guides extracustom
@ -91,7 +90,7 @@ footer_links_extracustom_text = Custom text
footer_links_extracustom_url = http://your.custom.site
```
Here is the same example using environment variables instead of the custom.ini or grafana.ini file.
The following example shows configuring custom branding using environment variables instead of the `custom.ini` or `grafana.ini` files.
```
GF_WHITE_LABELING_FOOTER_LINKS=support guides extracustom
@ -110,9 +109,9 @@ The following two links are always present in the footer:
- Grafana edition
- Grafana version with build number
If you specify `footer_links` or `GF_WHITE_LABELING_FOOTER_LINKS`, then all other default links are removed from the footer and only what is specified is included.
If you specify `footer_links` or `GF_WHITE_LABELING_FOOTER_LINKS`, then all other default links are removed from the footer, and only what is specified is included.
## Custom branding for Public Dashboards
## Custom branding for public dashboards
In addition to the customizations described below, you can customize the footer of your public dashboards.
To customize the footer of a public dashboard, add the following section to the `grafana.ini` file.

View File

@ -34,6 +34,7 @@ Some features are enabled by default. You can disable these feature by setting t
| `emptyDashboardPage` | Enable the redesigned user interface of a dashboard page that includes no panels | Yes |
| `disablePrometheusExemplarSampling` | Disable Prometheus exemplar sampling | |
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
| `gcomOnlyExternalOrgRoleSync` | Prohibits a user from changing organization roles synced with Grafana Cloud auth provider | |
| `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes |
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
@ -47,7 +48,6 @@ Some features are enabled by default. You can disable these feature by setting t
| `cloudWatchLogsMonacoEditor` | Enables the Monaco editor for CloudWatch Logs queries | Yes |
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
| `transformationsRedesign` | Enables the transformations redesign | Yes |
| `toggleLabelsInLogsUI` | Enable toggleable filters in log details view | Yes |
| `azureMonitorDataplane` | Adds dataplane compliant frame metadata in the Azure Monitor datasource | Yes |
| `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes |
| `dashgpt` | Enable AI powered features in dashboards | Yes |
@ -79,6 +79,7 @@ Some features are enabled by default. You can disable these feature by setting t
| `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the `useCachingService` feature toggle is enabled and the datasource has caching and async query support enabled |
| `splitScopes` | Support faster dashboard and folder search by splitting permission scopes into parts |
| `reportingRetries` | Enables rendering retries for the reporting feature |
| `alertingContactPointsV2` | Show the new contacpoints list view |
| `cloudWatchBatchQueries` | Runs CloudWatch metrics queries as separate batches |
## Experimental feature toggles
@ -104,7 +105,6 @@ Experimental features might be changed or removed without prior notice.
| `mysqlAnsiQuotes` | Use double quotes to escape keyword in a MySQL query |
| `alertingBacktesting` | Rule backtesting API for alerting |
| `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files |
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals |
| `lokiQuerySplittingConfig` | Give users the option to configure split durations for Loki queries |
| `individualCookiePreferences` | Support overriding cookie preferences per user |
| `clientTokenRotation` | Replaces the current in-request token rotation so that the client initiates the rotation |
@ -156,6 +156,9 @@ Experimental features might be changed or removed without prior notice.
| `costManagementUi` | Toggles the display of the cost management ui plugin |
| `managedPluginsInstall` | Install managed plugins directly from plugins catalog |
| `prometheusPromQAIL` | Prometheus and AI/ML to assist users in creating a query |
| `alertmanagerRemoteSecondary` | Enable Grafana to sync configuration and state with a remote Alertmanager. |
| `alertmanagerRemotePrimary` | Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager. |
| `alertmanagerRemoteOnly` | Disable the internal Alertmanager and only use the external one defined. |
## Development feature toggles

View File

@ -16,7 +16,7 @@ weight: 1000
Team sync lets you set up synchronization between your auth providers teams and teams in Grafana. This enables LDAP, OAuth, or SAML users who are members of certain teams or groups to automatically be added or removed as members of certain teams in Grafana.
> **Note:** Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud/).
> **Note:** Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud Advanced](/docs/grafana-cloud/).
Grafana keeps track of all synchronized users in teams, and you can see which users have been synchronized in the team members list, see `LDAP` label in screenshot.
This mechanism allows Grafana to remove an existing synchronized user from a team when its group membership changes. This mechanism also enables you to manually add a user as member of a team, and it will not be removed when the user signs in. This gives you flexibility to combine LDAP group memberships and Grafana team memberships.

View File

@ -13,10 +13,10 @@ Because Grafana upgrades are backward compatible, the upgrade process is straigh
In addition to common tasks you should complete for all versions of Grafana, there might be additional upgrade tasks to complete for a version.
{{% admonition type="note" %}}
There might be breaking changes in some releases. We outline these changes in the [What's New ]({{< relref "../../whatsnew/" >}}) document for most releases or a separate [Breaking changes]({{< relref "../../breaking-changes/" >}}) document for releases with many breaking changes.
There might be breaking changes in some releases. We outline these changes in the [What's New ](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/) document for most releases or a separate [Breaking changes](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/breaking-changes/) document for releases with many breaking changes.
{{% /admonition %}}
For versions of Grafana prior to v9.2, we published additional information in the [Release Notes]({{< relref "../../release-notes/" >}}).
For versions of Grafana prior to v9.2, we published additional information in the [Release Notes](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/release-notes/).
When available, we list all changes with links to pull requests or issues in the [Changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md).

View File

@ -67,7 +67,7 @@ To upgrade Grafana installed using RPM or YUM complete the following steps:
1. Perform one of the following steps based on your installation.
- If you [downloaded an RPM package](https://grafana.com/grafana/download) to install Grafana, then complete the steps documented in [Install Grafana on Red Hat, RHEL, or Fedora]({{< relref "../../setup-grafana/installation/redhat-rhel-fedora/" >}}) or [Install Grafana on SUSE or openSUSE]({{< relref "../../setup-grafana/installation/suse-opensuse/" >}}) to upgrade Grafana.
- If you [downloaded an RPM package](https://grafana.com/grafana/download) to install Grafana, then complete the steps documented in [Install Grafana on Red Hat, RHEL, or Fedora](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/installation/redhat-rhel-fedora/) or [Install Grafana on SUSE or openSUSE](https://grafana.com/docs/grafana/<GRAFANA_VERSION>//setup-grafana/installation/suse-opensuse/) to upgrade Grafana.
- If you used the Grafana YUM repository, run the following command:
```bash

View File

@ -0,0 +1,21 @@
---
description: Guide for upgrading to Grafana v10.2
keywords:
- grafana
- configuration
- documentation
- upgrade
title: Upgrade to Grafana v10.2
menuTitle: Upgrade to v10.2
weight: 1500
---
# Upgrade to Grafana v10.2
{{< docs/shared lookup="upgrade/intro.md" source="grafana" version="<GRAFANA VERSION>" >}}
{{< docs/shared lookup="back-up/back-up-grafana.md" source="grafana" version="<GRAFANA VERSION>" leveloffset="+1" >}}
{{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="<GRAFANA VERSION>" >}}
## Technical notes

View File

@ -76,6 +76,7 @@ For a complete list of every change, with links to pull requests and related iss
## Grafana 10
- [What's new in 10.2](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/whatsnew/whats-new-in-v10-2/)
- [What's new in 10.1]({{< relref "whats-new-in-v10-1/" >}})
- [What's new in 10.0]({{< relref "whats-new-in-v10-0/" >}})

View File

@ -0,0 +1,498 @@
---
description: Feature and improvement highlights for Grafana v10.2
keywords:
- grafana
- new
- documentation
- '10.2'
- release notes
labels:
products:
- cloud
- enterprise
- oss
title: What's new in Grafana v10.2
weight: -39
---
# Whats new in Grafana v10.2
Welcome to Grafana 10.2! Read on to learn about changes to dashboards and visualizations, data sources, security and authentication, and more. Were particularly excited about the addition of generative AI features for dashboards, a new kind of basic role, and improvements to visualization transformations.
For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/master/CHANGELOG.md). For the specific steps we recommend when you upgrade to v10.2, check out our [Upgrade Guide](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/upgrade-guide/upgrade-v10.2/).
<!-- Template below
> Add on-prem only features here. Features documented in the Cloud What's new will be copied from those release notes.
## Feature
<!-- Name of contributor -->
<!-- _[Generally available | Available in private/public preview | Experimental] in Grafana [Open Source, Enterprise]_
Description. Include an overview of the feature and problem it solves, and where to learn more (like a link to the docs).
{{% admonition type="note" %}}
Use full URLs for links. When linking to versioned docs, replace the version with the version interpolation placeholder (for example, <GRAFANA_VERSION>, <TEMPO_VERSION>, <MIMIR_VERSION>) so the system can determine the correct set of docs to point to. For example, "https://grafana.com/docs/grafana/latest/administration/" becomes "https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/".
{{% /admonition %}}
-->
<!-- Add an image, GIF or video as below
{{< figure src="/media/docs/grafana/dashboards/WidgetVizSplit.png" max-width="750px" caption="DESCRIPTIVE CAPTION" >}}
Learn how to upload images here: https://grafana.com/docs/writers-toolkit/write/image-guidelines/#where-to-store-media-assets
-->
## Share your dashboard with the world: Public dashboards are generally available
<!-- Thanos Karachalios -->
_Generally available in all editions of Grafana_
Public dashboards allow you to share your visualizations and insights with a broader audience without the requirement of a login. You can effortlessly use our current sharing model and create a public dashboard URL to share with anyone using the generated public URL link. To learn more, refer to the [Public dashboards documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/dashboards/dashboard-public/), as well as the following video demo:
{{< youtube id="XHwwRCdxHMg?rel=0" >}}
## Navigate lengthy, mixed data in Explore with Content Outline
<!-- Thanos Karachalios -->
_Generally available in all editions of Grafana_
Introducing Content Outline in Grafana Explore. It's easy to lose track of your place when you're running complex mixed queries or switching between logs and traces. Content outline is our first step towards seamless navigation from log lines to traces and back to queries, ensuring quicker searches while preserving context. Experience efficient, contextual investigations with this update in Grafana Explore. To learn more, refer to the [Content outline documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/explore/#content-outline), as well as the following video demo.
{{< youtube id="cE7J1-S4ZCQ?rel=0" >}}
## Correlations
Grafana Correlations is a new public preview feature you can use to establish links from any data source query to any other, carrying forward data like namespace, host, or label values. This is extremely powerful for performing root cause analysis with a diverse set of data sources. For more information, refer to [the documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/correlations/).
### Create Correlations the easy way in Grafana Explore
<!-- Kristina Durivage -->
_Available in public preview in all editions of Grafana_
Creating correlations has just become easier. Try out our new correlations editor in Explore by selecting the **+ Add > Add correlation** option from the top bar or from the command palette. The editor shows all possible places where you can place data links and guides you through building and testing target queries. For more information, refer to [the documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/correlations/).
To try out **Correlations**, enable the `correlations` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#preview-feature-toggles).
{{< figure src="/media/docs/grafana/correlations-explore-editor-10-2.png" max-width="750px" caption="Create a correlation with variables from within Grafana Explore" >}}
### Create correlations for provisioned data sources
<!-- Piotr Jamróz -->
_Available in public preview in all editions of Grafana_
In previous versions of Grafana, if a data source was provisioned, the only way to add correlations to it was also with provisioning. Now, that's no longer the case, and you can easily create new correlations mixing both methods—using the **Administration** page or provisioning. For more information, refer to [the documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/correlations/).
To try out **Correlations**, enable the `correlations` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#preview-feature-toggles).
## Dashboards and visualizations
### Use AI to generate titles, descriptions, and change summaries
_Available in public preview in all editions of Grafana_
<!-- Nathan Marrs -->
<!-- Cloud -->
You can now use generative AI to assist you in your Grafana dashboards. So far generative AI can help you with the following tasks:
- **Generate panel and dashboard titles and descriptions** - You can now generate a title and description for your panel or dashboard based on the data you've added to it. This is useful when you want to quickly visualize your data and don't want to spend time coming up with a title or description.
- **Generate dashboard save changes summary** - You can now generate a summary of the changes you've made to a dashboard when you save it. This is great for effortlessly tracking the history of a dashboard.
To enable these features, you must first enable the `dashgpt` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). Then install and configure Grafana's LLM app plugin. For more information, refer to the [Grafana LLM app plugin documentation](https://grafana.com/docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin/).
When enabled, look for the **✨ Auto generate** option next to the **Title** and **Description** fields in your panels and dashboards, or when you press the **Save** button.
{{< youtube id="tgBussaYJww?rel=0" >}}
### Find your dashboard faster with the new Dashboards browse screen
<!-- Yaelle Chaudy for Frontend Platform -->
_Generally available in all editions of Grafana_
The new browse screen for dashboards features a more compact design, making it easier to navigate, search for, and manage your folders and dashboards. The new interface also has many performance improvements, especially for instances with a large number of folders and dashboards.
To make using folders easier and more consistent, there's no longer a special **General** folder. Dashboards without a folder, or dashboards previously in the **General** folder, are now shown at the root level.
To try it out, go to the **Dashboards** section of your Grafana instance.
{{< youtube id="-S_Jjuwj74k?rel=0" >}}
### Create interactive buttons in canvas visualizations
_Available in public preview in all editions of Grafana_
<!-- Nathan Marrs -->
<!-- Cloud -->
You can now add buttons to your canvas visualizations. Buttons can be configured to call an API endpoint. This pushes Grafana's capabilities to new heights, allowing you to create interactive dashboards that can be used to control external systems.
To learn more, refer to our [Canvas button element documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/canvas/#button), as well as the following video demo.
{{< youtube id="T6fg1TpfBUg?rel=0" >}}
### Zoom in on the y-axis of the time series and candlestick visualizations
_Generally available in all editions of Grafana_
<!-- Nathan Marrs -->
<!-- Cloud -->
You can now zoom in on the y-axis of your time series and candlestick visualizations. This is useful when you want to focus on a specific range of values. To zoom in on the y-axis on supported visualizations, hold the Shift key while clicking and dragging; double-click to reset the zoom.
{{< video-embed src="/media/docs/grafana/screen-recording-10-2-y-axis-zoom-demo.mp4" max-width="750px" caption="Y-axis zooming demo" >}}
### Calculate visualization min/max individually per field
<!-- Oscar Kilhed -->
_Generally available in all editions of Grafana_
When visualizing multiple fields with a wide spread of values, calculating the min or max value of the visualization based on all fields can hide useful details.
{{< figure src="/media/docs/grafana/panels-visualizations/globalminmax.png" max-width="300px" caption="Stat visualization with min/max calculated from all fields" >}}
In this example in the stat visualization, it's hard to get an idea of how the values of each series relate to the historical values of that series. The threshold of 10% is exceeded by the A-series even though the A-series is below 10% of its historical maximum.
Now, you can automatically calculate the min or max of each visualized field based on the lowest and highest value of the individual field. This setting is available in the standard options of most visualizations.
{{< figure src="/media/docs/grafana/panels-visualizations/localminmax.png" max-width="300px" caption="Stat visualization with min/max calculated per field" >}}
In this example, using the same data, with the min and max calculated for each individual field, we get a much better understanding of how the current value relates to the historical values. The A-series no longer exceeds the 10% threshold; in fact, it's now clear that it's at a historical low.
This isn't only useful in the stat visualization&mdash;gauge, bar gauge, and status history visualizations, table cells formatted by thresholds, and gauge table cells all benefit from this addition.
### Data visualization quality of life improvements
_Generally available in all editions of Grafana_
<!-- Nathan Marrs -->
<!-- Cloud -->
We've made a number of smaller improvements to the data visualization experience in Grafana.
#### Geomap marker symbol alignment options
You can now offset geomap marker symbols from the underlying data point.
{{< figure src="/media/docs/grafana/gif-grafana-10-2-geomap-marker-symbol-alignment.gif" max-width="750px" caption="Geomap marker symbol alignment" >}}
#### Gauge visualization overflow support
You can now visualize gauges in vertical and horizontal orientations with overflow. This resolves an issue where the design would break when the number of gauges exceeded the available space.
{{< figure src="/media/docs/grafana/gif-grafana-10-2-gauge-overflow.gif" max-width="750px" caption="Gauge overflow" >}}
#### Bar chart axes improvements
You can now center bar chart axes on zero and configure axes border and color settings.
{{< figure src="/media/docs/grafana/screenshot-grafana-10-2-bar-chart-axes-improvements.png" max-width="750px" caption="Bar chart improvements" >}}
## Data sources and querying
### Tempo data source
We've placed special focus on the Tempo data source over the past couple of months with new features, query performance improvements, and a better query experience.
#### Compute RED metrics over spans aggregated by attribute with the "Aggregate By" Search option
<!-- Joey Tawadrous, Jen Villa -->
_Experimental in all editions of Grafana_
Requires Tempo or Grafana Enterprise Traces (GET) v2.2 or greater.
We've added an **Aggregate By** option to the [TraceQL query editor](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/datasources/tempo/query-editor/traceql-search/#write-traceql-queries-using-search) to leverage Tempo's [metrics summary API](https://grafana.com/docs/tempo/<TEMPO_VERSION>/api_docs/metrics-summary/). You can calculate RED metrics (total span count, percent erroring spans, and latency information) for spans of `kind=server` received in the last hour that match your filter criteria, grouped by whatever attributes you specify.
This feature is disabled by default. To enable it, use the `metricsSummary` [experimental feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles).
For more information, refer to the [documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/datasources/tempo/query-editor/traceql-search/#optional-use-aggregate-by), as well as the following video demo.
{{< youtube id="g97CjKOZqT4?rel=0" >}}
#### Query traces more easily with the Improved TraceQL editor
<!-- Fabrizio Casati -->
_Generally available in all editions of Grafana_
The [TraceQL query editor](https://grafana.com/docs/tempo/latest/traceql/#traceql-query-editor) has been improved to facilitate the creation of TraceQL queries. In particular, it now features improved autocompletion, syntax highlighting, and error reporting.
{{< video-embed src="/media/docs/tempo/screen-recording-grafana-10.2-traceql-query-editor-improvements.mp4" >}}
#### Group multiple spansets per trace
<!-- Joey Tawadrous -->
_Generally available in all editions of Grafana_
The [TraceQL query editor](https://grafana.com/docs/tempo/<TEMPO_VERSION>/traceql/#traceql-query-editor) has been improved to facilitate the grouping of multiple spans per trace in TraceQL queries. For example, when `by(resource.service.name)` is added to your TraceQL query, it will group the spans in each trace by `resource.service.name`.
{{< youtube id="fraepWra00Y?rel=0" >}}
#### Create query-type template variables for the Tempo data source
<!-- Fabrizio Casati -->
_Generally available in all editions of Grafana_
The Tempo data source now supports query-type template variables. With this update, you can create variables for which the values are a list of attribute names or attribute values seen on spans received by Tempo.
To learn more, refer to the following video demo, as well as the [Grafana Variables documentation](/docs/grafana/next/dashboards/variables/).
{{< video-embed src="/media/docs/tempo/screen-recording-grafana-10.2-tempo-query-type-template-variables.mp4" >}}
### SAP HANA®: Configure your data source with tenant database instance name and number
<!-- Miguel Palau -->
_Generally available in Grafana Enterprise and Grafana Cloud_
The SAP HANA® data source now supports tenant database connections by using the database name and/or instance number. This is helpful because these are less likely to change than the port for your database. For more information, refer to our [SAP HANA® configuration documentation](/docs/plugins/grafana-saphana-datasource/latest/#configuration).
{{< video-embed src="/media/docs/sap-hana/tenant.mp4" >}}
### Datadog: Aggregate logs to compute metrics and time series
<!-- Taewoo Kim -->
_Generally available in Grafana Enterprise and Grafana Cloud_
The Datadog data source now supports log aggregation. This feature helps aggregate logs/events into buckets and compute metrics and time series. For more information, refer to [Datadog log aggregation](/docs/plugins/grafana-datadog-datasource/latest#logs-analytics--aggregation).
{{< video-embed src="/media/docs/datadog/datadog-log-aggregation.mp4" >}}
### Datadog: Rate-limit requests from the Datadog data source
<!-- Taewoo Kim -->
_Generally available in Grafana Enterprise and Grafana Cloud_
In the Datadog data source, you can now block API requests for metric queries based on upstream rate limits. With this update, you can set a rate limit percentage at which the plugin stops sending queries.
To learn more, refer to [Datadog data source settings](/docs/plugins/grafana-datadog-datasource/latest#configure-the-data-source), as well as the following video demo.
{{< video-embed src="/media/docs/datadog/datadog-rate-limit.mp4" >}}
### Microsoft SQL Server: Support for Azure Authentication (Service principal/MSI)
<!-- Jev Forsberg, Oscar Kilhed -->
_Generally available in all editions of Grafana_
We've added support for Azure Authentication (Service principal/MSI) on our MS SQL plugin to authenticate and allow querying of content stored in SQL Managed Instance databases.
Enable this feature by setting the `managed_identity_enabled` property to `true` under the `Azure` heading in your configuration file (/conf/<your_config_file>.ini). Then take the following steps in your Microsoft SQL Server data source configuration UI:
1. Under **Authentication**, select **Azure AD Authentication** in the drop-down to reveal the **Azure Authentication Settings** section.
2. In this section, select either **Managed Identity** or **App Registration**.
3. Enter the credentials accordingly.
{{< figure src="/media/docs/grafana/data-sources/screenshot-managed-identity-mssql-ui-cropped.png" caption="Azure MSI Authentication" max-width="550px" >}}
Learn more in the [Microsoft SQL Server documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/datasources/mssql/).
## Transformations
As our work on improving the user experience of transforming data continues, we've also been adding new capabilities to transformations.
### Use dashboard variables in transformations
<!-- Oscar Kilhed, Victor Marin -->
_Experimental in all editions of Grafana_
Previously, the only transformation that supported [dashboard variables](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/dashboards/variables/) was the **Add field from calculation** transformation. We've now extended the support for variables to the **Filter by value**, **Create heatmap**, **Histogram**, **Sort by**, **Limit**, **Filter by name**, and **Join by field** transformations.
We've also made it easier to find the correct dashboard variable by displaying available variables in the fields that support them, either in the drop-down or as a suggestion when you type **$** or press Ctrl + Space.
{{< youtube id="WE0tt69ApO4?rel=0" >}}
### New modes for the Add field from calculation transformation
<!-- Victor Marin -->
_Generally available in all editions of Grafana_
The **Add field from calculation** transformation has been updated.
**Unary operation** is a new mode that lets you apply mathematical operations to a field. The currently supported operations are:
- **Absolute value (abs)** - Returns the absolute value of a given expression. It represents its distance from zero as a positive number.
- **Natural exponential (exp)** - Returns _e_ raised to the power of a given expression.
- **Natural logarithm (ln)** - Returns the natural logarithm of a given expression.
- **Floor (floor)** - Returns the largest integer less than or equal to a given expression.
- **Ceiling (ceil)** - Returns the smallest integer greater than or equal to a given expression.
{{< figure src="/media/docs/grafana/transformations/unary-operation.png" >}}
Also, **Row index** can now show the index as a percentage.
Learn more in the [Add field from calculation documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/transform-data/#add-field-from-calculation).
### Format strings with transformations
<!-- Solomon Dubock, BI Squad -->
_Experimental in all editions of Grafana_
With the new **Format string** transformation, you can manipulate string fields to improve how they're displayed. The currently supported operations are:
- **Change case** changes the case of your string to upper case, lower case, sentence case, title case, pascal case, camel case, or snake case.
- **Trim** removes white space characters at the start and end of your string.
- **Substring** selects a part of your string field.
Learn more in the [Format string documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/panels-visualizations/query-transform-data/transform-data/#format-string).
### See which transformations will work with your data
<!-- Kyle Cunningham -->
_Available in public preview in all editions of Grafana_
We've added initial support to detect situations in which various transformations won't work appropriately based on current data. Previously, selecting the appropriate transformation and configuring it correctly required a process of trial and error or already knowing how a given transformation worked. Now, transformations that we've detected can't be used are shaded in the interface to indicate this, along with a helpful message explaining why.
{{< figure src="/media/docs/grafana/transformations/disabled-transformation.png" caption="Transformation that has been disabled because it doesn't have the necessary data" >}}
If you have the `transformationsRedesign` feature flag set, you'll be able to access this functionality right away. If you'd like to try it, enable this feature flag in your [Grafana configuration](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#feature_toggles).
### Choose your timezome in the Format time and Convert field type transformations
<!-- Kyle Cunningham -->
_Generally available in all editions of Grafana_
We've added support for setting timezones manually when formatting times as strings using the **Format time** and **Convert field type** transformations. This allows times to be formatted relative to any timezone across the globe.
{{< figure src="/media/docs/grafana/transformations/format-timezone.png" caption="Timezone support in the Format time transformation" >}}
## Alerting
### Grafana OnCall integration for Alerting
<!-- Brenda Muir -->
_Generally available in all editions of Grafana_
Use the Grafana Alerting - Grafana OnCall integration to effortlessly connect alerts generated by Grafana Alerting with Grafana OnCall. From there, you can route them according to defined escalation chains and schedules.
To learn more, refer to the [Grafana OnCall integration for Alerting documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/alerting/alerting-rules/manage-contact-points/configure-oncall/), as well as the following video demo.
{{< youtube id="abRn5I61hxs?rel=0" >}}
### Export alerting resources to Terraform
<!-- Yuri Tseretyan -->
_Generally available in all editions of Grafana_
Export your alerting resources, such as alert rules, contact points, and notification policies as Terraform resources. A new “Modify export” mode for alert rules enables you to edit provisioned alert rules and export a modified version.
### Additional contact points for external Alertmanager
<!-- Alexander Weaver -->
_Generally available in Grafana Open Source and Enterprise_
We've added support for the Microsoft Teams contact points when using an external Alertmanager.
## Authentication and authorization
### No basic role
<!-- Eric Leijonmarck -->
_Generally available in Grafana Enterprise and Grafana Cloud_
We're excited to introduce the "No basic role," a new basic role with no permissions. A basic role in Grafana dictates the set of actions a user or entity can perform, known as permissions. This new role is especially beneficial if you're aiming for tailored, customized RBAC permissions for your service accounts or users. You can set this as a basic role through the API or UI.
Previously, permissions were granted based on predefined sets of capabilities. Now, with the "No basic role," you have the flexibility to be even more granular.
For more details on basic roles and permissions, refer to the [documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/).
### New service account permissions
[Service accounts](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/service-accounts/) allow you to create tokens to access Grafana's API and dashboards. Service accounts are a powerful tool for authenticating with Grafana's API and accessing data sources. However, without proper access controls, service accounts can pose a security risk to your Grafana instance. In Grafana 10.2, we've added new tools to limit service accounts to just the resources they need to access.
#### Add dashboard and folder permissions to service accounts
<!-- Jo Guerreiro -->
_Generally available in all editions of Grafana_
In this release, we've added the ability to assign dashboard and folder permissions to service accounts.
This means that you can now create a service account that can be used to access a specific dashboard and nothing else.
This is useful if you want to limit the access service accounts have to your Grafana instance.
Learn more in our [dashboard and folder permissions documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/user-management/manage-dashboard-permissions/#manage-dashboard-permissions).
#### Add data source permissions to service accounts
<!-- Jo Guerreiro -->
_Generally available in Grafana Cloud and Grafana Enterprise_
Grafana 10.2 also introduces the ability to assign _data source_ permissions to service accounts, for Grafana CLoud and Enterprise users.
With this feature, you can create a service account that has access to a specific data source and nothing else.
This is useful in scenarios where you want to limit the access service accounts have to your Grafana instance.
For example, imagine you have a team of developers who need to access a specific data source to develop a new feature.
Instead of giving them full access to your Grafana instance, you can create a service account that has access only to that data source.
This way, you can limit the potential damage that could be caused by a compromised service account.
Learn more in our [data source permissions documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/data-source-management/#data-source-permissions).
{{< figure src="/media/docs/grafana/screenshot-grafana-10-2-sa-managed-permissions.png" max-width="600px" caption="Data source permissions in 10.2" >}}
### Role mapping support for Google OIDC
<!-- Jo Guerreiro -->
_Generally available in all editions of Grafana_
You can now map Google groups to Grafana organizational roles when using Google OIDC.
This is useful if you want to limit the access users have to your Grafana instance.
We've also added support for controlling allowed groups when using Google OIDC.
Refer to the [Google Authentication documentation](http://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-authentication/google/) to learn how to use these new options.
### Configure refresh token handling separately for OAuth providers
<!-- Mihaly Gyongyosi -->
_Available in public preview in all editions of Grafana_
With Grafana v9.3, we introduced a [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/) called `accessTokenExpirationCheck`. It improves the security of Grafana by checking the expiration of the access token and automatically refreshing the expired access token when a user is logged in using one of the OAuth providers.
With the current release, we've introduced a new configuration option for each OAuth provider called `use_refresh_token` that allows you to configure whether the particular OAuth integration should use refresh tokens to automatically refresh access tokens when they expire. In addition, to further improve security and provide secure defaults, `use_refresh_token` is enabled by default for providers that support either refreshing tokens automatically or client-controlled fetching of refresh tokens. It's enabled by default for the following OAuth providers: `AzureAD`, `GitLab`, `Google`.
For more information on how to set up refresh token handling, please refer to [the documentation of the particular OAuth provider.](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-authentication/).
{{% admonition type="note" %}}
The `use_refresh_token` configuration must be used in conjunction with the `accessTokenExpirationCheck` [feature toggle](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/). If you disable the `accessTokenExpirationCheck` feature toggle, Grafana won't check the expiration of the access token and won't automatically refresh the expired access token, even if the `use_refresh_token` configuration is set to `true`.
The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.
{{% /admonition %}}
### Permission validation on custom role creation and update
<!-- Mihaly Gyongyosi -->
_Generally available in Grafana Enterprise and Grafana Cloud_
With the current release, we enabled RBAC permission validation (`rbac.permission_validation_enabled` setting) by default. This means that the permissions provided in the request during custom role creation or update are validated against the list of [available permissions and their scopes](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/access-control/custom-role-actions-scopes/#action-definitions). If the request contains a permission that is not available or the scope of the permission is not valid, the request is rejected with an error message.
## Recorded queries: Record multiple metrics from a single query
<!-- Kyle Brandt, Observability Metrics -->
_Generally available in Grafana Enterprise and Grafana Cloud_
Recorded queries provide a way to take a _static_ number, (for example, the number of GitHub issues open at a given time, or the number of rows in a database table) and record it periodically as a Prometheus metric. This is great for tracking numbers over time for quick querying later. Previously, recorded queries were limited to a single series, so you needed to narrow your query down to a single number in order to record it. Now, you can record multiple metrics with a single recorded query, which makes them more powerful _and_ easier to create and manage.
<!-- TODO: add graphic or video -->

View File

@ -18,7 +18,7 @@ weight: -37
Welcome to Grafana Cloud! Read on to learn about the newest changes to Grafana Cloud.
## Export alert rules and notification resources to Terraform
## Export alerting resources to Terraform
<!-- Yuri Tseretyan -->
<!-- OSS, Enterprise -->
@ -27,7 +27,7 @@ October 30, 2023
_Generally available in Grafana Cloud_
This feature provides a way to export Alerting resources such as rules, contact points, and notification policies as Terraform resources. A new "Modify export" mode for alert rules provides a convenient way of editing provisioned alert rules and exporting the modified version.
Export your alerting resources, such as alert rules, contact points, and notification policies as Terraform resources. A new “Modify export” mode for alert rules enables you to edit provisioned alert rules and export a modified version.
## Alerting insights
@ -39,6 +39,27 @@ _Generally available in Grafana Cloud_
Use Alerting insights to monitor your alerting data, discover key trends about your organizations alert management performance, and find patterns in why things go wrong.
## Configure refresh token handling separately for OAuth providers
<!-- Mihaly Gyongyosi -->
<!-- already in on-prem -->
October 24, 2023
_Generally available in Grafana Cloud_
With Grafana v9.3, we introduced a feature toggle called `accessTokenExpirationCheck`. It improves the security of Grafana by checking the expiration of the access token and automatically refreshing the expired access token when a user is logged in using one of the OAuth providers.
With the current release, we've introduced a new configuration option for each OAuth provider called `use_refresh_token` that allows you to configure whether the particular OAuth integration should use refresh tokens to automatically refresh access tokens when they expire. In addition, to further improve security and provide secure defaults, `use_refresh_token` is enabled by default for providers that support either refreshing tokens automatically or client-controlled fetching of refresh tokens. It's enabled by default for the following OAuth providers: `AzureAD`, `GitLab`, `Google`.
For more information on how to set up refresh token handling, please refer to [the documentation of the particular OAuth provider.](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-authentication/).
{{% admonition type="note" %}}
The `use_refresh_token` configuration must be used in conjunction with the `accessTokenExpirationCheck` feature toggle. If you disable the `accessTokenExpirationCheck` feature toggle, Grafana won't check the expiration of the access token and won't automatically refresh the expired access token, even if the `use_refresh_token` configuration is set to `true`.
The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.
{{% /admonition %}}
## Use AI to generate dashboard titles, descriptions, and change summaries
<!-- Nathan Marrs -->

View File

@ -8,7 +8,7 @@ interface CompareScreenshotsConfig {
declare namespace Cypress {
interface Chainable {
compareScreenshots(config: CompareScreenshotsConfig | string): Chainable;
logToConsole(message: string, optional?: any): void;
logToConsole(message: string, optional?: unknown): void;
readProvisions(filePaths: string[]): Chainable;
getJSONFilesFromDir(dirPath: string): Chainable;
startBenchmarking(testName: string): void;

View File

@ -31,7 +31,7 @@ describe('Dashboard templating', () => {
`Server:percentencode = %7BA%27A%22A%2CBB%5CB%2CCCC%7D`,
`Server:singlequote = 'A\\'A"A','BB\\B','CCC'`,
`Server:doublequote = "A'A\\"A","BB\\B","CCC"`,
`Server:sqlstring = 'A''A"A','BB\\\B','CCC'`,
`Server:sqlstring = 'A''A\\"A','BB\\\B','CCC'`,
`Server:date = NaN`,
`Server:text = All`,
`Server:queryparam = var-Server=All`,

View File

@ -2,8 +2,6 @@ import { v4 as uuidv4 } from 'uuid';
import { e2e } from '../index';
import { DeleteDataSourceConfig } from './deleteDataSource';
export interface AddDataSourceConfig {
basicAuth: boolean;
basicAuthPassword: string;
@ -96,7 +94,7 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
return cy.url().then(() => {
e2e.getScenarioContext().then(({ addedDataSources }) => {
e2e.setScenarioContext({
addedDataSources: [...addedDataSources, { name } as DeleteDataSourceConfig],
addedDataSources: [...addedDataSources, { name, id: '' }],
});
});

View File

@ -9,7 +9,6 @@ export interface ScenarioContext {
lastAddedDataSource: string; // @todo rename to `lastAddedDataSourceName`
lastAddedDataSourceId: string;
hasChangedUserPreferences: boolean;
[key: string]: any;
}
const scenarioContext: ScenarioContext = {
@ -50,9 +49,7 @@ export const setScenarioContext = (newContext: Partial<ScenarioContext>): Cypres
.wrap(
{
setScenarioContext: () => {
Object.entries(newContext).forEach(([key, value]) => {
scenarioContext[key] = value;
});
Object.assign(scenarioContext, newContext);
},
},
{ log: false }

View File

@ -17,7 +17,7 @@ export type TypeSelectors<S> = S extends StringSelector
? E2EFunction
: S extends UrlSelector
? E2EVisit & Omit<E2EFunctions<S>, 'url'>
: S extends Record<any, any>
: S extends Record<string, string | FunctionSelector | CssSelector | UrlSelector | Selectors>
? E2EFunctions<S>
: S;
@ -32,7 +32,7 @@ export type E2EFactoryArgs<S extends Selectors> = { selectors: S };
export type CypressOptions = Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>;
const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, selectors: S): E2EFunctions<S> => {
const logOutput = (data: any) => cy.logToConsole('Retrieving Selector:', data);
const logOutput = (data: unknown) => cy.logToConsole('Retrieving Selector:', data);
const keys = Object.keys(selectors);
for (let index = 0; index < keys.length; index++) {
const key = keys[index];
@ -80,7 +80,7 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
e2eObjects[key] = function (textOrOptions?: string | CypressOptions, options?: CypressOptions) {
// the input can only be ()
if (arguments.length === 0) {
const selector = value(undefined as unknown as string);
const selector = value('');
logOutput(selector);
return cy.get(selector);
@ -97,7 +97,7 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
logOutput(selector);
return cy.get(selector);
}
const selector = value(undefined as unknown as string);
const selector = value('');
logOutput(selector);
return cy.get(selector, textOrOptions);

View File

@ -0,0 +1,47 @@
import { e2e } from '../utils';
import { fromBaseUrl } from '../utils/support/url';
describe('Docked Navigation', () => {
beforeEach(() => {
cy.viewport(1280, 800);
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
cy.visit(fromBaseUrl('/'), {
onBeforeLoad(window) {
window.localStorage.setItem('grafana.featureToggles', 'dockedMegaMenu=1');
},
});
});
it('should remain docked when reloading the page', () => {
// Expand, then dock the mega menu
cy.get('[aria-label="Toggle menu"]').click();
cy.get('[aria-label="Dock menu"]').click();
e2e.components.NavMenu.Menu().should('be.visible');
cy.reload();
e2e.components.NavMenu.Menu().should('be.visible');
});
it('should remain docked when navigating to another page', () => {
// Expand, then dock the mega menu
cy.get('[aria-label="Toggle menu"]').click();
cy.get('[aria-label="Dock menu"]').click();
cy.contains('a', 'Administration').click();
e2e.components.NavMenu.Menu().should('be.visible');
cy.contains('a', 'Users').click();
e2e.components.NavMenu.Menu().should('be.visible');
});
it('should become docked at larger viewport sizes', () => {
e2e.components.NavMenu.Menu().should('not.exist');
cy.viewport(1920, 1080);
cy.reload();
e2e.components.NavMenu.Menu().should('be.visible');
});
});

54
go.mod
View File

@ -57,11 +57,11 @@ require (
github.com/gogo/protobuf v1.3.2 // @grafana/alerting-squad-backend
github.com/golang/mock v1.6.0 // @grafana/alerting-squad-backend
github.com/golang/snappy v0.0.4 // @grafana/alerting-squad-backend
github.com/google/go-cmp v0.5.9 // @grafana/backend-platform
github.com/google/go-cmp v0.6.0 // @grafana/backend-platform
github.com/google/uuid v1.3.1 // @grafana/backend-platform
github.com/google/wire v0.5.0 // @grafana/backend-platform
github.com/gorilla/websocket v1.5.0 // @grafana/grafana-app-platform-squad
github.com/grafana/alerting v0.0.0-20231017091417-a53b5db2235d // @grafana/alerting-squad-backend
github.com/grafana/alerting v0.0.0-20231026192550-079966731bbe // @grafana/alerting-squad-backend
github.com/grafana/cuetsy v0.1.10 // @grafana/grafana-as-code
github.com/grafana/grafana-aws-sdk v0.19.1 // @grafana/aws-datasources
github.com/grafana/grafana-azure-sdk-go v1.9.0 // @grafana/backend-platform
@ -110,13 +110,13 @@ require (
golang.org/x/crypto v0.14.0 // @grafana/backend-platform
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // @grafana/alerting-squad-backend
golang.org/x/net v0.17.0 // @grafana/grafana-bi-squad
golang.org/x/oauth2 v0.10.0 // @grafana/grafana-authnz-team
golang.org/x/sync v0.3.0 // @grafana/alerting-squad-backend
golang.org/x/oauth2 v0.13.0 // @grafana/grafana-authnz-team
golang.org/x/sync v0.4.0 // @grafana/alerting-squad-backend
golang.org/x/time v0.3.0 // @grafana/backend-platform
golang.org/x/tools v0.12.0 // @grafana/grafana-as-code
gonum.org/v1/gonum v0.12.0 // @grafana/observability-metrics
google.golang.org/api v0.126.0 // @grafana/backend-platform
google.golang.org/grpc v1.58.2 // @grafana/plugins-platform-backend
google.golang.org/api v0.148.0 // @grafana/backend-platform
google.golang.org/grpc v1.58.3 // @grafana/plugins-platform-backend
google.golang.org/protobuf v1.31.0 // @grafana/plugins-platform-backend
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // @grafana/alerting-squad-backend
@ -169,7 +169,7 @@ require (
github.com/golang/protobuf v1.5.3 // @grafana/backend-platform
github.com/google/btree v1.1.2 // indirect
github.com/google/flatbuffers v23.1.21+incompatible // indirect
github.com/googleapis/gax-go/v2 v2.11.0 // @grafana/backend-platform
github.com/googleapis/gax-go/v2 v2.12.0 // @grafana/backend-platform
github.com/gorilla/mux v1.8.0 // @grafana/backend-platform
github.com/grafana/grafana-google-sdk-go v0.1.0 // @grafana/partner-datasources
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
@ -220,11 +220,11 @@ require (
golang.org/x/text v0.13.0 // @grafana/backend-platform
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf // indirect; @grafana/backend-platform
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect; @grafana/backend-platform
)
require (
cloud.google.com/go/kms v1.15.0 // @grafana/backend-platform
cloud.google.com/go/kms v1.15.2 // @grafana/backend-platform
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // @grafana/backend-platform
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys v0.9.0 // @grafana/backend-platform
github.com/Azure/azure-storage-blob-go v0.15.0 // @grafana/backend-platform
@ -291,7 +291,7 @@ require github.com/grafana/pyroscope/api v0.2.0 // @grafana/observability-traces
require github.com/apache/arrow/go/v13 v13.0.0 // @grafana/observability-metrics
require (
cloud.google.com/go v0.110.6 // indirect
cloud.google.com/go v0.110.8 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
@ -299,12 +299,13 @@ require (
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/agext/levenshtein v1.2.1 // indirect
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/bmatcuk/doublestar v1.1.1 // indirect
github.com/buildkite/yaml v2.1.0+incompatible // indirect
github.com/bwmarrin/snowflake v0.3.0 // @grafan/grafana-app-platform-squad
github.com/centrifugal/protocol v0.10.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
@ -335,12 +336,11 @@ require (
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/status v1.1.1 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/google/cel-go v0.12.6 // indirect
github.com/google/gnostic v0.6.9 // indirect
github.com/google/cel-go v0.16.1 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db // indirect
github.com/grafana/sqlds/v2 v2.3.10 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@ -396,20 +396,20 @@ require (
github.com/yuin/gopher-lua v1.1.0 // indirect
github.com/zclconf/go-cty v1.13.0 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
go.etcd.io/etcd/client/v3 v3.5.7 // indirect
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/term v0.13.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
k8s.io/api v0.27.1 // indirect
k8s.io/kms v0.27.1 // indirect
lukechampine.com/uint128 v1.2.0 // indirect
@ -425,12 +425,12 @@ require (
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
sigs.k8s.io/yaml v1.3.0 // @grafana-app-platform-squad
)
require (
cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/iam v1.1.2 // indirect
filippo.io/age v1.1.1 // @grafana/grafana-authnz-team
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.0 // indirect
@ -450,7 +450,7 @@ require (
github.com/blugelabs/ice v1.0.0 // indirect
github.com/caio/go-tdigest v3.1.0+incompatible // indirect
github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/docker/docker v23.0.4+incompatible // @grafana/grafana-delivery
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 // indirect
@ -482,8 +482,10 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
)
require github.com/google/gnostic v0.6.9 // indirect
// Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream
replace github.com/crewjam/saml => github.com/grafana/saml v0.4.13-0.20231011134114-94154cb1bda6
replace github.com/crewjam/saml => github.com/grafana/saml v0.4.15-0.20231025143828-a6c0e9b86a4c
// Thema's thema CLI requires cobra, which eventually works its way down to go-hclog@v1.0.0.
// Upgrading affects backend plugins: https://github.com/grafana/grafana/pull/47653#discussion_r850508593

98
go.sum
View File

@ -45,8 +45,8 @@ cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRY
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q=
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME=
cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
@ -282,8 +282,8 @@ cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQE
cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE=
cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY=
cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY=
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
cloud.google.com/go/iam v1.1.2 h1:gacbrBdWcoVmGLozRuStX45YKvJtzIjJdAolzUs1sm4=
cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc=
cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=
cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk=
@ -298,8 +298,8 @@ cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxs
cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg=
cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0=
cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w=
cloud.google.com/go/kms v1.15.0 h1:xYl5WEaSekKYN5gGRyhjvZKM22GVBBCzegGNVPy+aIs=
cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM=
cloud.google.com/go/kms v1.15.2 h1:lh6qra6oC4AyWe5fUUUBe/S27k12OHAleOOOw6KakdE=
cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w=
cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=
@ -699,8 +699,8 @@ github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/apache/arrow/go/arrow v0.0.0-20210223225224-5bea62493d91/go.mod h1:c9sxoIT3YgLxH4UhLOCKaBlEojuMhVYpk4Ntv3opUTQ=
github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
github.com/apache/arrow/go/v13 v13.0.0 h1:kELrvDQuKZo8csdWYqBQfyi431x6Zs/YJTEgUuSVcWk=
@ -844,6 +844,8 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2
github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8=
github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
@ -927,8 +929,9 @@ github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkE
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@ -946,7 +949,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
github.com/cristalhq/jwt/v4 v4.0.2 h1:g/AD3h0VicDamtlM70GWGElp8kssQEv+5wYd7L9WOhU=
github.com/cristalhq/jwt/v4 v4.0.2/go.mod h1:HnYraSNKDRag1DZP92rYHyrjyQHnVEHPNqesmzs+miQ=
github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA=
@ -976,7 +978,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY=
github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s=
github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas=
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
@ -1669,8 +1670,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/cel-go v0.12.6 h1:kjeKudqV0OygrAqA9fX6J55S8gj+Jre2tckIm5RoG4M=
github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw=
github.com/google/cel-go v0.16.1 h1:3hZfSNiAU3KOiNtxuFXVp5WFy4hf/Ly3Sa4/7F8SXNo=
github.com/google/cel-go v0.16.1/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY=
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA=
@ -1692,8 +1693,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI=
@ -1736,8 +1738,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 h1:CqYfpuYIjnlNxM3msdyPRKabhXZWbKjf3Q8BWROFBso=
github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -1753,8 +1755,9 @@ github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ=
github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
@ -1765,8 +1768,8 @@ github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK
github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gophercloud/gophercloud v1.2.0 h1:1oXyj4g54KBg/kFtCdMM6jtxSzeIyg8wv4z1HoGPp1E=
@ -1798,6 +1801,8 @@ github.com/gotestyourself/gotestyourself v1.3.0/go.mod h1:zZKM6oeNM8k+FRljX1mnzV
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
github.com/grafana/alerting v0.0.0-20231017091417-a53b5db2235d h1:fxHDUyKFc1mfyJAtW+Qxi66dMahYu+o5/lH+f8SoMHg=
github.com/grafana/alerting v0.0.0-20231017091417-a53b5db2235d/go.mod h1:6BES5CyEqz7fDAG3MYvJLe0hqGwvIoGDN8A1aNrLGus=
github.com/grafana/alerting v0.0.0-20231026192550-079966731bbe h1:6jY5mWR//GbYOjvqpnoncgkdxbeYImkTsy9rPvVFOlk=
github.com/grafana/alerting v0.0.0-20231026192550-079966731bbe/go.mod h1:6BES5CyEqz7fDAG3MYvJLe0hqGwvIoGDN8A1aNrLGus=
github.com/grafana/codejen v0.0.3 h1:tAWxoTUuhgmEqxJPOLtJoxlPBbMULFwKFOcRsPRPXDw=
github.com/grafana/codejen v0.0.3/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s=
github.com/grafana/cue v0.0.0-20230926092038-971951014e3f h1:TmYAMnqg3d5KYEAaT6PtTguL2GjLfvr6wnAX8Azw6tQ=
@ -1831,8 +1836,8 @@ github.com/grafana/pyroscope/api v0.2.0/go.mod h1:nhH+xai9cYFgs6lMy/+L0pKj0d5yCM
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db h1:7aN5cccjIqCLTzedH7MZzRZt5/lsAHch6Z3L2ZGn5FA=
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
github.com/grafana/saml v0.4.13-0.20231011134114-94154cb1bda6 h1:CuCfH9nIpkrOkv1UasyLexbskquvgxsmrUy6MaJEwDM=
github.com/grafana/saml v0.4.13-0.20231011134114-94154cb1bda6/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA=
github.com/grafana/saml v0.4.15-0.20231025143828-a6c0e9b86a4c h1:1pHLC1ZTz7N5QI3jzCs5sqmVvAKe+JwGnpp9lQ+iUjY=
github.com/grafana/saml v0.4.15-0.20231025143828-a6c0e9b86a4c/go.mod h1:S4+611dxnKt8z/ulbvaJzcgSHsuhjVc1QHNTcr1R7Fw=
github.com/grafana/sqlds/v2 v2.3.10 h1:HWKhE0vR6LoEiE+Is8CSZOgaB//D1yqb2ntkass9Fd4=
github.com/grafana/sqlds/v2 v2.3.10/go.mod h1:c6ibxnxRVGxV/0YkEgvy7QpQH/lyifFyV7K/14xvdIs=
github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b h1:mDlkqgTEJuK7vjPG44f3ZMtId5AAYLWHvBVbiGqIOOQ=
@ -2650,7 +2655,6 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rubenv/sql-migrate v0.0.0-20190212093014-1007f53448d7/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
github.com/russellhaering/goxmldsig v1.4.0 h1:8UcDh/xGyQiyrW+Fq5t8f+l2DLB1+zlhYzkPUJ7Qhys=
github.com/russellhaering/goxmldsig v1.4.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@ -2931,7 +2935,6 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
@ -2946,19 +2949,19 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY=
go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA=
go.etcd.io/etcd/api/v3 v3.5.9 h1:4wSsluwyTbGGmyjJktOf3wFQoTBIURXHnq9n/G/JQHs=
go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg=
go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY=
go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2IGsE=
go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
go.etcd.io/etcd/client/v2 v2.305.7 h1:AELPkjNR3/igjbO7CjyF1fPuVPjrblliiKj+Y6xSGOU=
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4=
go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw=
go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E=
go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA=
go.etcd.io/etcd/pkg/v3 v3.5.7 h1:obOzeVwerFwZ9trMWapU/VjDcYUJb5OfgC1zqEGWO/0=
go.etcd.io/etcd/raft/v3 v3.5.7 h1:aN79qxLmV3SvIq84aNTliYGmjwsW6NqJSnqmI1HLJKc=
go.etcd.io/etcd/server/v3 v3.5.7 h1:BTBD8IJUV7YFgsczZMHhMTS67XuA4KpRquL0MFOJGRk=
@ -3049,8 +3052,8 @@ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKY
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@ -3119,8 +3122,6 @@ golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@ -3349,8 +3350,8 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -3370,8 +3371,9 @@ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -3805,8 +3807,8 @@ google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/
google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI=
google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=
google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
google.golang.org/api v0.148.0 h1:HBq4TZlN4/1pNcu0geJZ/Q50vIwIXT532UIMYoo0vOs=
google.golang.org/api v0.148.0/go.mod h1:8/TBgwaKjfqTdacOJrOv2+2Q6fBDU1uHKK06oGSkxzU=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -3971,12 +3973,12 @@ google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoR
google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf h1:v5Cf4E9+6tawYrs/grq1q1hFpGtzlGFzgWHqwt6NFiU=
google.golang.org/genproto v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf h1:xkVZ5FdZJF4U82Q/JS+DcZA83s/GRVL+QrFMlexk9Yo=
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf h1:guOdSPaeFgN+jEJwTo1dQ71hdBm+yKSCCKuTRkJzcVo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I=
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0=
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk=
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU=
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@ -4026,8 +4028,8 @@ google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200910201057-6591123024b3/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/grpc/examples v0.0.0-20210304020650-930c79186c99/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE=
@ -4087,8 +4089,8 @@ gopkg.in/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKx
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.1.9/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=

View File

@ -28,6 +28,7 @@ module.exports = {
moduleNameMapper: {
'\\.svg': '<rootDir>/public/test/mocks/svg.ts',
'\\.css': '<rootDir>/public/test/mocks/style.ts',
'react-inlinesvg': '<rootDir>/public/test/mocks/react-inlinesvg.tsx',
'monaco-editor/esm/vs/editor/editor.api': '<rootDir>/public/test/mocks/monaco.ts',
// near-membrane-dom won't work in a nodejs environment.
'@locker/near-membrane-dom': '<rootDir>/public/test/mocks/nearMembraneDom.ts',

View File

@ -1,4 +1,4 @@
{
"stable": "10.1.4",
"testing": "10.1.4"
"stable": "10.2.0",
"testing": "10.2.0"
}

View File

@ -177,7 +177,7 @@
"eslint": "8.52.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "27.4.2",
"eslint-plugin-jest": "27.6.0",
"eslint-plugin-jsdoc": "46.8.2",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-lodash": "7.4.0",
@ -254,7 +254,7 @@
"@grafana/flamegraph": "workspace:*",
"@grafana/google-sdk": "0.1.1",
"@grafana/lezer-logql": "0.2.1",
"@grafana/lezer-traceql": "0.0.7",
"@grafana/lezer-traceql": "0.0.8",
"@grafana/monaco-logql": "^0.0.7",
"@grafana/runtime": "workspace:*",
"@grafana/scenes": "^1.18.0",
@ -361,7 +361,7 @@
"prismjs": "1.29.0",
"prop-types": "15.8.1",
"pseudoizer": "^0.1.0",
"rc-cascader": "3.19.0",
"rc-cascader": "3.20.0",
"rc-drawer": "6.5.2",
"rc-slider": "10.3.1",
"rc-time-picker": "3.7.3",
@ -374,7 +374,7 @@
"react-draggable": "4.4.5",
"react-dropzone": "^14.2.3",
"react-enable": "^3.1.0",
"react-grid-layout": "1.3.4",
"react-grid-layout": "1.4.2",
"react-highlight-words": "0.20.0",
"react-hook-form": "7.5.3",
"react-i18next": "^12.0.0",
@ -416,7 +416,7 @@
"tinycolor2": "1.6.0",
"tslib": "2.6.0",
"tween-functions": "^1.2.0",
"uplot": "1.6.26",
"uplot": "1.6.27",
"uuid": "9.0.0",
"vendor": "link:./public/vendor",
"visjs-network": "4.25.0",
@ -443,9 +443,9 @@
]
},
"engines": {
"node": ">= 18"
"node": ">= 20"
},
"packageManager": "yarn@3.6.1",
"packageManager": "yarn@3.6.4",
"dependenciesMeta": {
"prettier@3.0.0": {
"unplugged": true

View File

@ -58,7 +58,7 @@
"string-hash": "^1.1.3",
"tinycolor2": "1.6.0",
"tslib": "2.6.0",
"uplot": "1.6.26",
"uplot": "1.6.27",
"xss": "^1.0.14"
},
"devDependencies": {

View File

@ -3,10 +3,16 @@ import { DataFrame, FieldType } from '../types/dataFrame';
import { getTimeField } from './processDataFrame';
export function isTimeSeriesFrame(frame: DataFrame) {
if (frame.fields.length > 2) {
// If we have less than two frames we can't have a timeseries
if (frame.fields.length < 2) {
return false;
}
return Boolean(frame.fields.find((field) => field.type === FieldType.time));
// In order to have a time series we need a time field
// and at least one number field
const timeField = frame.fields.find((field) => field.type === FieldType.time);
const numberField = frame.fields.find((field) => field.type === FieldType.number);
return timeField !== undefined && numberField !== undefined;
}
export function isTimeSeriesFrames(data: DataFrame[]) {

View File

@ -14,7 +14,7 @@ describe('Date Formats', () => {
''
);
expect(format).toBe('MM/DD/YYYY, hh:mm:ss A');
expect(format).toBe('MM/DD/YYYY, hh:mm:ssA');
});
});
@ -52,8 +52,8 @@ describe('systemDateFormats', () => {
it('contains correct browser-localized date formats', () => {
systemDateFormats.useBrowserLocale();
expect(systemDateFormats.fullDate).toBe('MM/DD/YYYY, hh:mm:ss A');
expect(systemDateFormats.fullDateMS).toBe('MM/DD/YYYY, hh:mm:ss.SSS A');
expect(systemDateFormats.fullDate).toBe('MM/DD/YYYY, hh:mm:ssA');
expect(systemDateFormats.fullDateMS).toBe('MM/DD/YYYY, hh:mm:ss.SSSA');
expect(systemDateFormats.interval.millisecond).toBe('HH:mm:ss.SSS');
expect(systemDateFormats.interval.second).toBe('HH:mm:ss');
expect(systemDateFormats.interval.minute).toBe('HH:mm');

View File

@ -89,7 +89,7 @@ export function concatenateFields(data: DataFrame[], opts: ConcatenateTransforme
if (f.values.length === maxLength) {
return f;
}
const values = f.values;
const values = f.values.slice();
values.length = maxLength;
return {
...f,

View File

@ -183,6 +183,95 @@ export interface HistogramFields {
* @alpha
*/
export function getHistogramFields(frame: DataFrame): HistogramFields | undefined {
// we ignore xMax (time field) and sum all counts together for each found bucket
if (frame.meta?.type === DataFrameType.HeatmapCells) {
// we assume uniform bucket size for now
// we assume xMax, yMin, yMax fields
let yMinField = frame.fields.find((f) => f.name === 'yMin')!;
let yMaxField = frame.fields.find((f) => f.name === 'yMax')!;
let countField = frame.fields.find((f) => f.name === 'count')!;
let uniqueMaxs = [...new Set(yMaxField.values)].sort((a, b) => a - b);
let uniqueMins = [...new Set(yMinField.values)].sort((a, b) => a - b);
let countsByMax = new Map<number, number>();
uniqueMaxs.forEach((max) => countsByMax.set(max, 0));
for (let i = 0; i < yMaxField.values.length; i++) {
let max = yMaxField.values[i];
countsByMax.set(max, countsByMax.get(max) + countField.values[i]);
}
let fields = {
xMin: {
...yMinField,
name: 'xMin',
values: uniqueMins,
},
xMax: {
...yMaxField,
name: 'xMax',
values: uniqueMaxs,
},
counts: [
{
...countField,
values: [...countsByMax.values()],
},
],
};
return fields;
} else if (frame.meta?.type === DataFrameType.HeatmapRows) {
// assumes le
// tick label strings (will be ordinal-ized)
let minVals: string[] = [];
let maxVals: string[] = [];
// sums of all timstamps per bucket
let countVals: number[] = [];
let minVal = '0';
frame.fields.forEach((f) => {
if (f.type === FieldType.number) {
let countsSum = f.values.reduce((acc, v) => acc + v, 0);
countVals.push(countsSum);
minVals.push(minVal);
maxVals.push((minVal = f.name));
}
});
// fake extra value for +Inf (for x scale ranging since bars are right-aligned)
countVals.push(0);
minVals.push(minVal);
maxVals.push(minVal);
let fields = {
xMin: {
...frame.fields[1],
name: 'xMin',
type: FieldType.string,
values: minVals,
},
xMax: {
...frame.fields[1],
name: 'xMax',
type: FieldType.string,
values: maxVals,
},
counts: [
{
...frame.fields[1],
name: 'count',
type: FieldType.number,
values: countVals,
},
],
};
return fields;
}
let xMin: Field | undefined = undefined;
let xMax: Field | undefined = undefined;
const counts: Field[] = [];

View File

@ -713,7 +713,7 @@ abstract class LanguageProvider {
* Returns startTask that resolves with a task list when main syntax is loaded.
* Task list consists of secondary promises that load more detailed language features.
*/
abstract start: () => Promise<Array<Promise<any>>>;
abstract start: (timeRange?: TimeRange) => Promise<Array<Promise<any>>>;
startTask?: Promise<any[]>;
}

View File

@ -46,6 +46,8 @@ export interface ExploreTracePanelState {
export interface ExploreLogsPanelState {
id?: string;
columns?: Record<number, string>;
visualisationType?: 'table' | 'logs';
}
export interface SplitOpenOptions<T extends AnyQuery = AnyQuery> {

View File

@ -103,7 +103,6 @@ export interface FeatureToggles {
logsExploreTableVisualisation?: boolean;
awsDatasourcesTempCredentials?: boolean;
transformationsRedesign?: boolean;
toggleLabelsInLogsUI?: boolean;
mlExpressions?: boolean;
traceQLStreaming?: boolean;
metricsSummary?: boolean;
@ -128,6 +127,7 @@ export interface FeatureToggles {
lokiRunQueriesInParallel?: boolean;
wargamesTesting?: boolean;
alertingInsights?: boolean;
alertingContactPointsV2?: boolean;
externalCorePlugins?: boolean;
pluginsAPIMetrics?: boolean;
httpSLOLevels?: boolean;
@ -150,4 +150,7 @@ export interface FeatureToggles {
costManagementUi?: boolean;
managedPluginsInstall?: boolean;
prometheusPromQAIL?: boolean;
alertmanagerRemoteSecondary?: boolean;
alertmanagerRemotePrimary?: boolean;
alertmanagerRemoteOnly?: boolean;
}

View File

@ -93,6 +93,7 @@ export const availableIconsIndex = {
eye: true,
'eye-slash': true,
'ellipsis-h': true,
/* @deprecated, use 'spinner' instead */
'fa fa-spinner': true,
favorite: true,
'file-alt': true,
@ -198,6 +199,7 @@ export const availableIconsIndex = {
sitemap: true,
slack: true,
'sliders-v-alt': true,
spinner: true,
'sort-amount-down': true,
'sort-amount-up': true,
'square-shape': true,

View File

@ -26,5 +26,12 @@ export enum NodeGraphDataFrameFieldNames {
// Prefix for fields which will be shown in a context menu [nodes + edges]
detail = 'detail__',
// Radius of the node [nodes]
nodeRadius = 'noderadius',
// Thickness of the edge [edges]
thickness = 'thickness',
// Whether the node or edge should be highlighted (e.g., shown in red) in the UI
highlighted = 'highlighted',
}

View File

@ -144,6 +144,7 @@ export const getCategories = (): ValueFormatCategory[] => [
{ name: 'Turkish Lira (₺)', id: 'currencyTRY', fn: currency('₺', true) },
{ name: 'Malaysian Ringgit (RM)', id: 'currencyMYR', fn: currency('RM') },
{ name: 'CFP franc (XPF)', id: 'currencyXPF', fn: currency('XPF') },
{ name: 'Bulgarian Lev (BGN)', id: 'currencyBGN', fn: currency('BGN') },
],
},
{

View File

@ -264,6 +264,7 @@ export const Components = {
},
},
NavMenu: {
Menu: 'data-testid navigation mega-menu',
item: 'data-testid Nav menu item',
},
NavToolbar: {
@ -386,7 +387,7 @@ export const Components = {
singleLink: 'Data link',
},
CodeEditor: {
container: 'Code editor container',
container: 'data-testid Code editor container',
},
DashboardImportPage: {
textarea: 'data-testid-import-dashboard-textarea',

View File

@ -13,6 +13,7 @@
"fork-ts-checker-webpack-plugin": "8.0.0",
"glob": "10.3.3",
"replace-in-file-webpack-plugin": "1.0.6",
"swc-loader": "0.2.3",
"webpack": "5.89.0"
},
"packageManager": "yarn@3.6.0"

View File

@ -3,7 +3,7 @@ import ESLintPlugin from 'eslint-webpack-plugin';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import path from 'path';
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
import { Configuration } from 'webpack';
import { Configuration, DefinePlugin } from 'webpack';
import { DIST_DIR } from './constants';
import { getPackageJson, getPluginJson, getEntries, hasLicense } from './utils';
@ -29,12 +29,6 @@ const config = async (env: Record<string, unknown>): Promise<Configuration> => {
config: [__filename],
},
cacheDirectory: path.resolve(__dirname, '../../.yarn/.cache/webpack', path.basename(process.cwd())),
cacheLocation: path.resolve(
__dirname,
'../../.yarn/.cache/eslint-webpack-plugin',
path.basename(process.cwd()),
'.eslintcache'
),
},
context: process.cwd(),
@ -89,7 +83,7 @@ const config = async (env: Record<string, unknown>): Promise<Configuration> => {
exclude: /(node_modules)/,
test: /\.[tj]sx?$/,
use: {
loader: 'swc-loader',
loader: require.resolve('swc-loader'),
options: {
jsc: {
baseUrl: '.',
@ -185,22 +179,44 @@ const config = async (env: Record<string, unknown>): Promise<Configuration> => {
},
],
},
]),
new ForkTsCheckerWebpackPlugin({
async: Boolean(env.development),
issue: {
include: [{ file: '**/*.{ts,tsx}' }],
{
dir: path.resolve(DIST_DIR),
files: ['package.json'],
rules: [
{
search: `"version": "${getPackageJson().version}"`,
replace: env.commit
? `"version": "${getPackageJson().version}-${env.commit}"`
: `"version": "${getPackageJson().version}"`,
},
],
},
typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
}),
new ESLintPlugin({
extensions: ['.ts', '.tsx'],
lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files
}),
]),
env.development
? new ForkTsCheckerWebpackPlugin({
async: true,
issue: {
include: [{ file: '**/*.{ts,tsx}' }],
},
typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
})
: new DefinePlugin({}),
env.development
? new ESLintPlugin({
extensions: ['.ts', '.tsx'],
lintDirtyModulesOnly: true, // don't lint on start, only lint changed files
cacheLocation: path.resolve(
__dirname,
'../../.yarn/.cache/eslint-webpack-plugin',
path.basename(process.cwd()),
'.eslintcache'
),
})
: new DefinePlugin({}),
],
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
extensions: ['.ts', '.tsx', '.js', '.jsx'],
unsafeCache: true,
},

View File

@ -79,7 +79,7 @@ export interface GrafanaLiveSrv {
*
* @alpha -- experimental
*/
publish(address: LiveChannelAddress, data: unknown): Promise<any>;
publish(address: LiveChannelAddress, data: unknown): Promise<unknown>;
}
let singletonInstance: GrafanaLiveSrv;

View File

@ -11,6 +11,7 @@ import {
createDataFrame,
AdHocVariableFilter,
ScopedVars,
getDefaultTimeRange,
} from '@grafana/data';
import { config } from '../config';
@ -61,6 +62,15 @@ jest.mock('../services', () => ({
jest.mock('./publicDashboardQueryHandler');
describe('DataSourceWithBackend', () => {
beforeEach(async () => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2023-10-13'));
});
afterEach(() => {
jest.useRealTimers();
});
test('check the executed queries', () => {
const { mock, ds } = createMockDatasource();
ds.query({
@ -70,6 +80,7 @@ describe('DataSourceWithBackend', () => {
dashboardUID: 'dashA',
panelId: 123,
filters: [{ key: 'key1', operator: '=', value: 'val1' }],
range: getDefaultTimeRange(),
queryGroupId: 'abc',
} as DataQueryRequest);
@ -79,6 +90,7 @@ describe('DataSourceWithBackend', () => {
expect(args).toMatchInlineSnapshot(`
{
"data": {
"from": "1697133600000",
"queries": [
{
"applyTemplateVariablesCalled": true,
@ -111,6 +123,7 @@ describe('DataSourceWithBackend', () => {
"refId": "B",
},
],
"to": "1697155200000",
},
"headers": {
"X-Dashboard-Uid": "dashA",
@ -135,6 +148,7 @@ describe('DataSourceWithBackend', () => {
targets: [{ refId: 'A' }, { refId: 'B', datasource: { type: '__expr__' } }],
dashboardUID: 'dashA',
panelId: 123,
range: getDefaultTimeRange(),
queryGroupId: 'abc',
} as DataQueryRequest);
@ -144,6 +158,7 @@ describe('DataSourceWithBackend', () => {
expect(args).toMatchInlineSnapshot(`
{
"data": {
"from": "1697133600000",
"queries": [
{
"applyTemplateVariablesCalled": true,
@ -167,6 +182,7 @@ describe('DataSourceWithBackend', () => {
"refId": "B",
},
],
"to": "1697155200000",
},
"headers": {
"X-Dashboard-Uid": "dashA",
@ -190,6 +206,7 @@ describe('DataSourceWithBackend', () => {
ds.query({
maxDataPoints: 10,
intervalMs: 5000,
range: getDefaultTimeRange(),
targets: [{ refId: 'A' }, { refId: 'B', datasource: { type: 'sample' } }],
} as DataQueryRequest);
@ -205,6 +222,7 @@ describe('DataSourceWithBackend', () => {
targets: [{ refId: 'A' }, { refId: 'B', datasource: { type: 'sample' } }],
hideFromInspector: true,
dashboardUID: 'dashA',
range: getDefaultTimeRange(),
panelId: 123,
} as DataQueryRequest);
@ -214,6 +232,7 @@ describe('DataSourceWithBackend', () => {
expect(args).toMatchInlineSnapshot(`
{
"data": {
"from": "1697133600000",
"queries": [
{
"applyTemplateVariablesCalled": true,
@ -240,6 +259,7 @@ describe('DataSourceWithBackend', () => {
"refId": "B",
},
],
"to": "1697155200000",
},
"headers": {
"X-Dashboard-Uid": "dashA",
@ -353,6 +373,7 @@ describe('DataSourceWithBackend', () => {
dashboardUID: 'dashA',
panelId: 123,
queryGroupId: 'abc',
range: getDefaultTimeRange(),
} as DataQueryRequest;
ds.query(request);
@ -371,6 +392,7 @@ describe('DataSourceWithBackend', () => {
dashboardUID: 'dashA',
panelId: 123,
queryGroupId: 'abc',
range: getDefaultTimeRange(),
} as DataQueryRequest;
ds.query(request);

View File

@ -190,12 +190,11 @@ class DataSourceWithBackend<
return of({ data: [] });
}
const body: any = { queries };
if (range) {
body.from = range.from.valueOf().toString();
body.to = range.to.valueOf().toString();
}
const body = {
queries,
from: range?.from.valueOf().toString(),
to: range?.to.valueOf().toString(),
};
if (config.featureToggles.queryOverLive) {
return getGrafanaLiveSrv().getQueryData({

View File

@ -31,10 +31,10 @@ export const SystemJS = window.System;
* @param options - plugin styling for light and dark theme.
* @public
*/
export async function loadPluginCss(options: PluginCssOptions): Promise<any> {
export async function loadPluginCss(options: PluginCssOptions): Promise<System.Module | void> {
try {
const cssPath = config.bootData.user.theme === 'light' ? options.light : options.dark;
return await SystemJS.import(cssPath);
return SystemJS.import(cssPath);
} catch (err) {
console.error(err);
}

View File

@ -262,13 +262,13 @@ describe('Query Response parser', () => {
data: {
results: {
X: {
series: [{ name: 'Requests/s', points: [[13.594958983547151, 1611839862951]] }] as any,
series: [{ target: '', datapoints: [[13.594958983547151, 1611839862951]] }],
},
B: {
series: [{ name: 'Requests/s', points: [[13.594958983547151, 1611839862951]] }] as any,
series: [{ target: '', datapoints: [[13.594958983547151, 1611839862951]] }],
},
A: {
series: [{ name: 'Requests/s', points: [[13.594958983547151, 1611839862951]] }] as any,
series: [{ target: '', datapoints: [[13.594958983547151, 1611839862951]] }],
},
},
},

View File

@ -73,10 +73,11 @@ export function toDataQueryResponse(
}
// If the response isn't in a correct shape we just ignore the data and pass empty DataQueryResponse.
if ((res as FetchResponse).data?.results) {
const results = (res as FetchResponse).data.results;
const fetchResponse = res as FetchResponse;
if (fetchResponse.data?.results) {
const results = fetchResponse.data.results;
const refIDs = queries?.length ? queries.map((q) => q.refId) : Object.keys(results);
const cachedResponse = isCachedResponse(res as FetchResponse);
const cachedResponse = isCachedResponse(fetchResponse);
const data: DataResponse[] = [];
for (const refId of refIDs) {
@ -144,7 +145,7 @@ export function toDataQueryResponse(
}
// When it is not an OK response, make sure the error gets added
if ((res as FetchResponse).status && (res as FetchResponse).status !== 200) {
if (fetchResponse.status && fetchResponse.status !== 200) {
if (rsp.state !== LoadingState.Error) {
rsp.state = LoadingState.Error;
}

View File

@ -1,7 +1,5 @@
# Grafana UI components library
> **@grafana/ui is currently in BETA**.
@grafana/ui is a collection of components used by [Grafana](https://github.com/grafana/grafana)
Our goal is to deliver Grafana's common UI elements for plugins developers and contributors.

View File

@ -81,7 +81,7 @@
"monaco-editor": "0.34.0",
"ol": "7.4.0",
"prismjs": "1.29.0",
"rc-cascader": "3.19.0",
"rc-cascader": "3.20.0",
"rc-drawer": "6.5.2",
"rc-slider": "10.3.1",
"rc-time-picker": "^3.7.3",
@ -111,13 +111,12 @@
"slate-react": "0.22.10",
"tinycolor2": "1.6.0",
"tslib": "2.6.0",
"uplot": "1.6.26",
"uplot": "1.6.27",
"uuid": "9.0.0"
},
"devDependencies": {
"@babel/core": "7.23.2",
"@grafana/tsconfig": "^1.2.0-rc1",
"@mdx-js/react": "1.6.22",
"@rollup/plugin-node-resolve": "15.2.3",
"@storybook/addon-a11y": "7.4.5",
"@storybook/addon-actions": "7.4.5",

View File

@ -2,11 +2,9 @@ import { Meta } from '@storybook/blocks';
<Meta title="Docs Overview/Intro" parameters={{ options: { isToolshown: false }, id: 1 }} />
# Grafana design system
# Grafana React Components
> **@grafana/ui is currently in BETA**.
With the design system @grafana/ui, we want to democratize development. This library of reusable [Grafana](https://github.com/grafana/grafana) components and guidelines helps you with contribution and plugin development.
With @grafana/ui, we want to democratize development. This library of reusable [Grafana](https://github.com/grafana/grafana) components and guidelines is part of the [Saga Design System](https://grafana.com/developers/saga/About/overview) and should help you with contribution and plugin development.
## Our vision
@ -17,23 +15,19 @@ Grafana Labs started @grafana/ui to make contributing to Grafana as easy as poss
- A beautiful, visually consistent Grafana experience.
- Transparency about how we work and what we do.
### Maintained by Grafana Labs and you
Grafana Labs has a task force that helps create and maintain components. We make sure that components are documented and easy to use. The current status of the @grafana/ui development is available on [GitHub](https://github.com/grafana/grafana/projects/26). Feel free to contribute!
### How to get involved
When we notice that we need to change something, we determine together what the change should be, then we put the change in place and communicate it publicly. Developers and designers create and improve @grafana/ui together. Throughout the process, we strive to involve you and meet your needs. We are looking forward to discussing your design and improvement ideas on [GitHub](https://github.com/grafana/grafana/projects/26).
When we notice that we need to change something, we determine together what the change should be, then we put the change in place and communicate it publicly. Developers and designers create and improve @grafana/ui together. Throughout the process, we strive to involve you and meet your needs. We are looking forward to discussing your design and improvement ideas, find out how you can help in the [Contribution Guidelines](https://grafana.com/developers/saga/contributing).
## Get started
- **Explore UI components**
Click on any of the component in the sidebar to see how they look, and how to configure them. Each component pages contains documentation of its properties, as well as code examples for how to use it.
Click on any of the components in the sidebar to see how they look, and how to configure them. Each component contains documentation of its properties, as well as code examples for how to use it.
- **Try them out**
- Experiment with different properties, by clicking **Canvas** at the top of each component page.
- Change the properties under **Knobs** in the bottom panel.
- Experiment with different properties, by clicking on each component story.
- Change the properties under **Controls** in the side panel.
- **Use them**
Once you've found the right component for your use case, click the **Story** tab to see the code implementation, or look at examples under **Docs**.
Once you've found the right component for your use case, click the **Code** tab to see the code implementation, or look at examples under **Docs**.
For more details, refer to the [package source](https://github.com/grafana/grafana/tree/main/packages/grafana-ui).

View File

@ -0,0 +1,11 @@
import { render } from '@testing-library/react';
import React from 'react';
import { Button } from './Button';
describe('Button', () => {
it('spins the spinner when specified as an icon', () => {
const { container } = render(<Button icon="spinner">Loading...</Button>);
expect(container.querySelector('.fa-spin')).toBeInTheDocument();
});
});

Some files were not shown because too many files have changed in this diff Show More