Merge remote-tracking branch 'origin/main' into grafana-git-ui-sync

This commit is contained in:
Ryan McKinley committed 2025-02-13 09:45:28 +03:00
commit f2911bdebb
156 files changed
+4345 -485

No files matched your search

@@ -3,7 +3,7 @@ name: publish-technical-documentation-release
on:
push:
branches:
- release-v[0-9]+.[0-9]+.[0-9]+
- release-[0-9]+.[0-9]+.[0-9]+
tags:
- v[0-9]+.[0-9]+.[0-9]+
paths:
-12
View File
@@ -1118,18 +1118,6 @@
"1d"
],
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"2h",
" 6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"type": "timepicker"
},
"timezone": "browser",
@@ -1639,8 +1639,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Panel Tests - Graph",
@@ -490,17 +490,6 @@
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "browser",
@@ -3408,8 +3408,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Polystat",
@@ -312,7 +312,6 @@
"now": true,
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"status": "Stable",
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"],
"type": "timepicker"
},
"timezone": "browser",
@@ -537,8 +537,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Datasource tests - MSSQL",
@@ -2831,8 +2831,7 @@
"to": "2018-03-15T13:55:01.000Z"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Datasource tests - MSSQL (unit test)",
@@ -541,8 +541,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Datasource tests - MySQL",
@@ -2643,8 +2643,7 @@
"to": "2018-03-15T13:55:01.000Z"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Datasource tests - MySQL (unittest)",
@@ -577,8 +577,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Datasource tests - Postgres",
@@ -2621,8 +2621,7 @@
"to": "2018-03-15T13:55:01.000Z"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Datasource tests - Postgres (unittest)",
@@ -1092,7 +1092,6 @@
"now": true,
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"status": "Stable",
"time_options": ["5m", "15m", "1h", "2h", " 6h", "12h", "24h", "2d", "7d", "30d"],
"type": "timepicker"
},
"timezone": "browser",
@@ -1326,8 +1326,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "New Features in v6.2",
-11
View File
@@ -240,17 +240,6 @@
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
@@ -654,8 +654,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["2s", "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["2s", "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Bar Gauge Demo",
@@ -1423,17 +1423,6 @@
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
@@ -519,8 +519,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Bar Gauge 2",
@@ -2202,8 +2202,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Lazy Loading",
@@ -893,8 +893,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - With & Without title",
@@ -254,8 +254,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Gauge Multi Series",
@@ -1319,8 +1319,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Gauge",
@@ -372,8 +372,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Graph - Gradient Area Fills",
@@ -569,8 +569,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Panel Tests - Graph Time Regions",
@@ -1639,8 +1639,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Panel Tests - Graph",
@@ -3408,8 +3408,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Polystat",
@@ -440,8 +440,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Panel Tests - Table",
@@ -562,8 +562,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Graph NG - Gradient Area Fills",
@@ -1132,8 +1132,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel tests - Slow Queries & Annotations",
@@ -684,8 +684,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "utc",
"title": "Panel Tests - Time zone support",
@@ -7,7 +7,7 @@ RUN CGO_ENABLED=0 GOOS=linux go install -tags netgo -ldflags '-w' github.com/pro
# Final image.
FROM scratch
LABEL maintainer "The Prometheus Authors <prometheus-developers@googlegroups.com>"
LABEL maintainer="The Prometheus Authors <prometheus-developers@googlegroups.com>"
COPY --from=builder /go/bin/random .
EXPOSE 8080
ENTRYPOINT ["/random"]
@@ -151,17 +151,6 @@
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
@@ -5376,17 +5376,6 @@
"1d"
],
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"type": "timepicker"
},
"timezone": "browser",
@@ -151,17 +151,6 @@
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
@@ -5376,17 +5376,6 @@
"1d"
],
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"type": "timepicker"
},
"timezone": "browser",
@@ -138,12 +138,12 @@ The grid has a negative gravity that moves panels up if there is empty space abo
"nowDelay": "",
"quick_ranges": [
{
"display": "Last 6 hours"
"display": "Last 6 hours",
"from": "now-6h",
"to": "now"
},
{
"display": "Last 7 days"
"display": "Last 7 days",
"from": "now-7d",
"to": "now"
}
@@ -1821,7 +1821,7 @@ The timeout string is a possibly signed sequence of decimal numbers, followed by
#### `max_attempts`
Sets a maximum number of times Grafana attempts to evaluate an alert rule before giving up on that evaluation. The default value is `1`.
Sets a maximum number of times Grafana attempts to evaluate an alert rule before giving up on that evaluation. The default value is `3`.
#### `min_interval`
@@ -99,6 +99,7 @@ Here is an overview of projected version support through 2024:
| 11.2 | August 2024 | May 2025 |
| 11.3 | October 2024 | July 2025 |
| 11.4 | December 2024 | September 2025 |
| 11.5 | January 2025 | October 2025 |
{{< admonition type="note" >}}
Grafana 9.5.x was the last supported minor for the 9.0 major release and is no longer supported as of July 2024.
+1 -3
View File
@@ -74,7 +74,7 @@ lineage: schemas: [{
// Version of the JSON schema, incremented each time a Grafana update brings
// changes to said schema.
schemaVersion: uint16 | *39
schemaVersion: uint16 | *41
// Version of the dashboard, incremented each time the dashboard is updated.
version?: uint32
@@ -473,8 +473,6 @@ lineage: schemas: [{
hidden?: bool | *false
// Interval options available in the refresh picker dropdown.
refresh_intervals?: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
// Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
time_options?: [...string] | *["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
// Quick ranges for time picker.
quick_ranges?: [...#TimeOption]
// Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.
+3 -4
View File
@@ -56,8 +56,7 @@
"ci:test-frontend": "yarn run test:ci",
"i18n:stats": "node ./scripts/cli/reportI18nStats.mjs",
"betterer": "betterer --tsconfig ./scripts/cli/tsconfig.json",
"betterer:merge": "betterer merge --tsconfig ./scripts/cli/tsconfig.json",
"betterer:stats": "node ./scripts/cli/reportBettererStats.mjs",
"betterer:stats": "ts-node --transpile-only --project ./scripts/cli/tsconfig.json ./scripts/cli/reportBettererStats.ts",
"betterer:issues": "ts-node --transpile-only --project ./scripts/cli/tsconfig.json ./scripts/cli/generateBettererIssues.ts",
"plugin:build": "nx run-many -t build --projects='tag:scope:plugin'",
"plugin:build:commit": "nx run-many -t build:commit --projects='tag:scope:plugin'",
@@ -276,8 +275,8 @@
"@grafana/prometheus": "workspace:*",
"@grafana/runtime": "workspace:*",
"@grafana/saga-icons": "workspace:*",
"@grafana/scenes": "5.42.0",
"@grafana/scenes-react": "5.42.0",
"@grafana/scenes": "6.0.1",
"@grafana/scenes-react": "6.0.1",
"@grafana/schema": "workspace:*",
"@grafana/sql": "workspace:*",
"@grafana/ui": "workspace:*",
@@ -50,7 +50,9 @@ export interface SliderFieldConfigSettings {
ariaLabelForHandle?: string;
}
export interface DataLinksFieldConfigSettings {}
export interface DataLinksFieldConfigSettings {
showOneClick?: boolean;
}
export const dataLinksOverrideProcessor = (
value: any,
@@ -80,7 +80,7 @@ export function createComponents(colors: ThemeColors, shadows: ThemeShadows): Th
input,
panel,
dropdown: {
background: input.background,
background: colors.background.elevated,
},
tooltip: {
background: colors.background.elevated,
@@ -144,6 +144,7 @@ export enum FieldConfigProperty {
Thresholds = 'thresholds',
Mappings = 'mappings',
Links = 'links',
Actions = 'actions',
Color = 'color',
Filterable = 'filterable',
}
@@ -1178,8 +1178,7 @@
"to": "now"
},
"timepicker": {
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Grafana metrics",
@@ -1394,8 +1394,7 @@
},
"timepicker": {
"now": true,
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Prometheus 2.0 Stats",
@@ -825,8 +825,7 @@
},
"timepicker": {
"now": true,
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Prometheus Stats",
@@ -94,8 +94,8 @@ const getStyles = (theme: GrafanaTheme2) => {
return {
docBox: css({
overflow: 'hidden',
background: theme.colors.background.primary,
border: `1px solid ${theme.colors.border.strong}`,
background: theme.colors.background.elevated,
border: `1px solid ${theme.colors.border.weak}`,
boxShadow: theme.shadows.z3,
maxWidth: '600px',
padding: theme.spacing(1),
@@ -681,17 +681,12 @@ export interface TimePickerConfig {
* Interval options available in the refresh picker dropdown.
*/
refresh_intervals?: Array<string>;
/**
* Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
*/
time_options?: Array<string>;
}
export const defaultTimePickerConfig: Partial<TimePickerConfig> = {
hidden: false,
quick_ranges: [],
refresh_intervals: ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'],
time_options: ['5m', '15m', '1h', '6h', '12h', '24h', '2d', '7d', '30d'],
};
/**
@@ -1205,7 +1200,7 @@ export const defaultDashboard: Partial<Dashboard> = {
graphTooltip: DashboardCursorSync.Off,
links: [],
panels: [],
schemaVersion: 39,
schemaVersion: 41,
tags: [],
timezone: 'browser',
};
@@ -447,6 +447,12 @@ QueryGroupKind: {
spec: QueryGroupSpec
}
TimeRangeOption: {
display: string | *"Last 6 hours"
from: string | *"now-6h"
to: string | *"now"
}
// Time configuration
// It defines the default time config for the time picker, the refresh picker for the specific dashboard.
TimeSettingsSpec: {
@@ -463,7 +469,7 @@ TimeSettingsSpec: {
// Interval options available in the refresh picker dropdown.
autoRefreshIntervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] // v1: timepicker.refresh_intervals
// Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
quickRanges: [...string] | *["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] // v1: timepicker.time_options , not exposed in the UI
quickRanges?: [...TimeRangeOption] // v1: timepicker.quick_ranges , not exposed in the UI
// Whether timepicker is visible or not.
hideTimepicker: bool // v1: timepicker.hidden
// Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday".
@@ -15,7 +15,6 @@ export const handyTestingSchema: DashboardV2Spec = {
from: 'now-1h',
hideTimepicker: false,
nowDelay: '1m',
quickRanges: [],
timezone: 'UTC',
to: 'now',
weekStart: 'monday',
@@ -620,6 +620,18 @@ export const defaultQueryGroupKind = (): QueryGroupKind => ({
spec: defaultQueryGroupSpec(),
});
export interface TimeRangeOption {
display: string;
from: string;
to: string;
}
export const defaultTimeRangeOption = (): TimeRangeOption => ({
display: "Last 6 hours",
from: "now-6h",
to: "now",
});
// Time configuration
// It defines the default time config for the time picker, the refresh picker for the specific dashboard.
export interface TimeSettingsSpec {
@@ -638,8 +650,8 @@ export interface TimeSettingsSpec {
// v1: timepicker.refresh_intervals
autoRefreshIntervals: string[];
// Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
// v1: timepicker.time_options , not exposed in the UI
quickRanges: string[];
// v1: timepicker.quick_ranges , not exposed in the UI
quickRanges?: TimeRangeOption[];
// Whether timepicker is visible or not.
// v1: timepicker.hidden
hideTimepicker: boolean;
@@ -668,17 +680,6 @@ export const defaultTimeSettingsSpec = (): TimeSettingsSpec => ({
"1h",
"2h",
"1d",
],
quickRanges: [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d",
],
hideTimepicker: false,
fiscalYearStartMonth: 0,
@@ -72,8 +72,8 @@ export const getCascaderStyles = (theme: GrafanaTheme2) => ({
'.rc-cascader': {
'&-menus': {
overflow: 'hidden',
background: theme.colors.background.canvas,
border: `1px solid ${theme.colors.border.weak}`,
background: theme.colors.background.elevated,
border: `none`,
borderRadius: theme.shape.radius.default,
boxShadow: theme.shadows.z3,
whiteSpace: 'nowrap',
@@ -128,7 +128,7 @@ export const getCascaderStyles = (theme: GrafanaTheme2) => ({
height: '192px',
listStyle: 'none',
margin: 0,
padding: 0,
padding: theme.spacing(0.5),
borderRight: `1px solid ${theme.colors.border.weak}`,
overflow: 'auto',
@@ -140,6 +140,7 @@ export const getCascaderStyles = (theme: GrafanaTheme2) => ({
height: theme.spacing(4),
lineHeight: theme.spacing(4),
padding: theme.spacing(0, 4, 0, 2),
borderRadius: theme.shape.radius.default,
cursor: 'pointer',
whiteSpace: 'nowrap',
overflow: 'hidden',
@@ -407,7 +407,7 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
})}
>
{isOpen && (
<ScrollContainer showScrollIndicators maxHeight="inherit" ref={scrollRef}>
<ScrollContainer showScrollIndicators maxHeight="inherit" ref={scrollRef} padding={0.5}>
{!asyncError && (
<ul style={{ height: rowVirtualizer.getTotalSize() }} className={styles.menuUlContainer}>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
@@ -416,6 +416,7 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
key={`${items[virtualRow.index].value}-${virtualRow.index}`}
data-index={virtualRow.index}
className={cx(
styles.optionBasic,
styles.option,
selectedItem && items[virtualRow.index].value === selectedItem.value && styles.optionSelected,
highlightedIndex === virtualRow.index && styles.optionFocused
@@ -344,7 +344,7 @@ export const MultiCombobox = <T extends string | number>(props: MultiComboboxPro
{...getMenuProps({ ref: floatingRef })}
>
{isOpen && (
<ScrollContainer showScrollIndicators maxHeight="inherit" ref={scrollRef}>
<ScrollContainer showScrollIndicators maxHeight="inherit" ref={scrollRef} padding={0.5}>
<ul style={{ height: rowVirtualizer.getTotalSize() }} className={styles.menuUlContainer}>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const startingNewGroup = isNewGroup(options[virtualRow.index], options[virtualRow.index - 1]);
@@ -46,6 +46,7 @@ export const getComboboxStyles = (theme: GrafanaTheme2) => {
option: css({
padding: MENU_ITEM_PADDING,
cursor: 'pointer',
borderRadius: theme.shape.radius.default,
width: '100%',
'&:hover': {
background: theme.colors.action.hover,
@@ -9,7 +9,12 @@ type DataLinksInlineEditorProps = Omit<DataLinksInlineEditorBaseProps<DataLink>,
getSuggestions: () => VariableSuggestion[];
};
export const DataLinksInlineEditor = ({ links, getSuggestions, showOneClick, ...rest }: DataLinksInlineEditorProps) => (
export const DataLinksInlineEditor = ({
links,
getSuggestions,
showOneClick = false,
...rest
}: DataLinksInlineEditorProps) => (
<DataLinksInlineEditorBase<DataLink> type="link" items={links} {...rest}>
{(item, index, onSave, onCancel) => (
<DataLinkEditorModalContent
@@ -19,7 +24,7 @@ export const DataLinksInlineEditor = ({ links, getSuggestions, showOneClick, ...
onSave={onSave}
onCancel={onCancel}
getSuggestions={getSuggestions}
showOneClick={showOneClick ?? true}
showOneClick={showOneClick}
/>
)}
</DataLinksInlineEditorBase>
@@ -54,7 +54,7 @@ export const SelectMenu = ({
style={{ maxHeight }}
aria-label="Select options menu"
>
<ScrollContainer ref={innerRef} maxHeight="inherit" overflowX="hidden" showScrollIndicators>
<ScrollContainer ref={innerRef} maxHeight="inherit" overflowX="hidden" showScrollIndicators padding={0.5}>
{toggleAllOptions && (
<ToggleAllOption
state={toggleAllOptions.state}
@@ -27,6 +27,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
whiteSpace: 'nowrap',
cursor: 'pointer',
borderLeft: '2px solid transparent',
borderRadius: theme.shape.radius.default,
'&:hover': {
background: theme.colors.action.hover,
@@ -5,11 +5,13 @@ import "strconv"
type SchemaVersionMigrationFunc func(map[string]interface{}) error
const (
MINIUM_VERSION = 38
MINIUM_VERSION = 36
LATEST_VERSION = 40
)
var Migrations = map[int]SchemaVersionMigrationFunc{
37: V37,
38: V38,
39: V39,
40: V40,
}
@@ -0,0 +1,62 @@
package schemaversion
// V37 normalizes legend configuration in panels to use a consistent format:
// - Converts boolean legend values to object format
// - Standardizes hidden legends to use showLegend: false with displayMode: list
// - Ensures visible legends have showLegend: true
func V37(dashboard map[string]interface{}) error {
dashboard["schemaVersion"] = int(37)
panels, ok := dashboard["panels"].([]interface{})
if !ok {
return nil
}
for _, panel := range panels {
p, ok := panel.(map[string]interface{})
if !ok {
continue
}
options, ok := p["options"].(map[string]interface{})
if !ok {
continue
}
// Skip if no legend config exists
legendValue := options["legend"]
if legendValue == nil {
continue
}
// Convert boolean legend to object format
if legendBool, ok := legendValue.(bool); ok {
options["legend"] = map[string]interface{}{
"displayMode": "list",
"showLegend": legendBool,
}
continue
}
// Handle object format legend
legend, ok := legendValue.(map[string]interface{})
if !ok {
continue
}
displayMode, hasDisplayMode := legend["displayMode"].(string)
showLegend, hasShowLegend := legend["showLegend"].(bool)
// Normalize hidden legends
if (hasDisplayMode && displayMode == "hidden") || (hasShowLegend && !showLegend) {
legend["displayMode"] = "list"
legend["showLegend"] = false
continue
}
// Ensure visible legends have showLegend true
legend["showLegend"] = true
}
return nil
}
@@ -0,0 +1,170 @@
package schemaversion_test
import (
"testing"
"github.com/grafana/grafana/pkg/apis/dashboard/migration/schemaversion"
)
func TestV37(t *testing.T) {
tests := []migrationTestCase{
{
name: "no legend config",
input: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"options": map[string]interface{}{},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"options": map[string]interface{}{},
},
},
},
},
{
name: "boolean legend true",
input: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": true,
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "list",
"showLegend": true,
},
},
},
},
},
},
{
name: "boolean legend false",
input: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": false,
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "list",
"showLegend": false,
},
},
},
},
},
},
{
name: "hidden displayMode",
input: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "hidden",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "list",
"showLegend": false,
},
},
},
},
},
},
{
name: "showLegend false",
input: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"showLegend": false,
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "list",
"showLegend": false,
},
},
},
},
},
},
{
name: "visible legend",
input: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "table",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"options": map[string]interface{}{
"legend": map[string]interface{}{
"displayMode": "table",
"showLegend": true,
},
},
},
},
},
},
}
runMigrationTests(t, tests, schemaversion.V37)
}
@@ -0,0 +1,122 @@
package schemaversion
// V38 updates the configuration of the table panel to use the new cellOptions format
// and updates the overrides to use the new cellOptions format
func V38(dashboard map[string]interface{}) error {
dashboard["schemaVersion"] = int(38)
panels, ok := dashboard["panels"].([]interface{})
if !ok {
return nil
}
for _, panel := range panels {
p, ok := panel.(map[string]interface{})
if !ok {
continue
}
// Only process table panels
if p["type"] != "table" {
continue
}
fieldConfig, ok := p["fieldConfig"].(map[string]interface{})
if !ok {
continue
}
defaults, ok := fieldConfig["defaults"].(map[string]interface{})
if !ok {
continue
}
custom, ok := defaults["custom"].(map[string]interface{})
if !ok {
continue
}
// Migrate displayMode to cellOptions
if displayMode, exists := custom["displayMode"]; exists {
if displayModeStr, ok := displayMode.(string); ok {
custom["cellOptions"] = migrateTableDisplayModeToCellOptions(displayModeStr)
}
// Delete the legacy field
delete(custom, "displayMode")
}
// Update any overrides referencing the cell display mode
migrateOverrides(fieldConfig)
}
return nil
}
// migrateOverrides updates the overrides configuration to use the new cellOptions format
func migrateOverrides(fieldConfig map[string]interface{}) {
overrides, ok := fieldConfig["overrides"].([]interface{})
if !ok {
return
}
for _, override := range overrides {
o, ok := override.(map[string]interface{})
if !ok {
continue
}
properties, ok := o["properties"].([]interface{})
if !ok {
continue
}
for _, property := range properties {
prop, ok := property.(map[string]interface{})
if !ok {
continue
}
// Update the id to cellOptions
if prop["id"] == "custom.displayMode" {
prop["id"] = "custom.cellOptions"
if value, ok := prop["value"]; ok {
if valueStr, ok := value.(string); ok {
prop["value"] = migrateTableDisplayModeToCellOptions(valueStr)
}
}
}
}
}
}
// migrateTableDisplayModeToCellOptions converts the old displayMode string to the new cellOptions format
func migrateTableDisplayModeToCellOptions(displayMode string) map[string]interface{} {
switch displayMode {
case "basic", "gradient-gauge", "lcd-gauge":
gaugeMode := "basic"
if displayMode == "gradient-gauge" {
gaugeMode = "gradient"
} else if displayMode == "lcd-gauge" {
gaugeMode = "lcd"
}
return map[string]interface{}{
"type": "gauge",
"mode": gaugeMode,
}
case "color-background", "color-background-solid":
mode := "basic"
if displayMode == "color-background" {
mode = "gradient"
}
return map[string]interface{}{
"type": "color-background",
"mode": mode,
}
default:
return map[string]interface{}{
"type": displayMode,
}
}
}
@@ -0,0 +1,251 @@
package schemaversion_test
import (
"testing"
"github.com/grafana/grafana/pkg/apis/dashboard/migration/schemaversion"
)
func TestV38(t *testing.T) {
tests := []migrationTestCase{
{
name: "no table panels",
input: map[string]interface{}{
"schemaVersion": 37,
"title": "Test Dashboard",
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"title": "Panel 1",
},
},
},
expected: map[string]interface{}{
"title": "Test Dashboard",
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "graph",
"title": "Panel 1",
},
},
},
},
{
name: "table panel with basic gauge displayMode",
input: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"displayMode": "basic",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"cellOptions": map[string]interface{}{
"type": "gauge",
"mode": "basic",
},
},
},
},
},
},
},
},
{
name: "table panel with gradient-gauge displayMode",
input: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"displayMode": "gradient-gauge",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"cellOptions": map[string]interface{}{
"type": "gauge",
"mode": "gradient",
},
},
},
},
},
},
},
},
{
name: "table panel with lcd-gauge displayMode",
input: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"displayMode": "lcd-gauge",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"cellOptions": map[string]interface{}{
"type": "gauge",
"mode": "lcd",
},
},
},
},
},
},
},
},
{
name: "table panel with color-background displayMode",
input: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"displayMode": "color-background",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"cellOptions": map[string]interface{}{
"type": "color-background",
"mode": "gradient",
},
},
},
},
},
},
},
},
{
name: "table panel with color-background-solid displayMode",
input: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"displayMode": "color-background-solid",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"cellOptions": map[string]interface{}{
"type": "color-background",
"mode": "basic",
},
},
},
},
},
},
},
},
{
name: "table panel with default displayMode",
input: map[string]interface{}{
"schemaVersion": 37,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"displayMode": "some-other-mode",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 38,
"panels": []interface{}{
map[string]interface{}{
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"cellOptions": map[string]interface{}{
"type": "some-other-mode",
},
},
},
},
},
},
},
},
}
runMigrationTests(t, tests, schemaversion.V38)
}
@@ -0,0 +1,123 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"type": "graph",
"options": {},
"title": "No Legend Config",
"id": 1,
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
}
},
{
"options": {
"legend": true
},
"title": "Boolean Legend True",
"id": 2,
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
}
},
{
"options": {
"legend": false
},
"title": "Boolean Legend False",
"id": 3,
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
}
},
{
"options": {
"legend": {
"displayMode": "hidden"
}
},
"title": "Hidden DisplayMode",
"id": 4,
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
}
},
{
"options": {
"legend": {
"showLegend": false
}
},
"title": "ShowLegend False",
"id": 5,
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
}
},
{
"options": {
"legend": {
"displayMode": "table"
}
},
"title": "Visible Legend",
"id": 6,
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
}
}
],
"preload": false,
"refresh": true,
"schemaVersion": 36,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,360 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "basic"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Basic Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "gradient-gauge"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Gradient Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "lcd-gauge"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "LCD Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "color-background"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "color-background-solid"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Solid Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "some-other-mode"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Other Display Mode",
"type": "table"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 37,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,132 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {},
"title": "No Legend Config",
"type": "graph"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"displayMode": "list",
"showLegend": true
}
},
"title": "Boolean Legend True"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Boolean Legend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Hidden DisplayMode"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "ShowLegend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"legend": {
"displayMode": "table",
"showLegend": true
}
},
"title": "Visible Legend"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 37,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,132 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {},
"title": "No Legend Config",
"type": "graph"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"displayMode": "list",
"showLegend": true
}
},
"title": "Boolean Legend True"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Boolean Legend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Hidden DisplayMode"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "ShowLegend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"legend": {
"displayMode": "table",
"showLegend": true
}
},
"title": "Visible Legend"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,132 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {},
"title": "No Legend Config",
"type": "graph"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"displayMode": "list",
"showLegend": true
}
},
"title": "Boolean Legend True"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Boolean Legend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Hidden DisplayMode"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "ShowLegend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"legend": {
"displayMode": "table",
"showLegend": true
}
},
"title": "Visible Legend"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 39,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,132 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {},
"title": "No Legend Config",
"type": "graph"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"displayMode": "list",
"showLegend": true
}
},
"title": "Boolean Legend True"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Boolean Legend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "Hidden DisplayMode"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"legend": {
"displayMode": "list",
"showLegend": false
}
},
"title": "ShowLegend False"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"legend": {
"displayMode": "table",
"showLegend": true
}
},
"title": "Visible Legend"
}
],
"preload": false,
"refresh": "",
"schemaVersion": 40,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,358 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "basic"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Basic Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "gradient-gauge"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Gradient Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "lcd-gauge"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "LCD Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "color-background"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "color-background-solid"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Solid Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"displayMode": "some-other-mode"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Other Display Mode",
"type": "table"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 37,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,375 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "basic",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Basic Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "gradient",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Gradient Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "lcd",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "LCD Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "gradient",
"type": "color-background"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "basic",
"type": "color-background"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Solid Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"type": "some-other-mode"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Other Display Mode",
"type": "table"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,375 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "basic",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Basic Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "gradient",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Gradient Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "lcd",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "LCD Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "gradient",
"type": "color-background"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "basic",
"type": "color-background"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Solid Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"type": "some-other-mode"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Other Display Mode",
"type": "table"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 39,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,375 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "basic",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Basic Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "gradient",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Gradient Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "lcd",
"type": "gauge"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "LCD Gauge Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "gradient",
"type": "color-background"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"mode": "basic",
"type": "color-background"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Color Background Solid Display Mode",
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"cellOptions": {
"type": "some-other-mode"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"options": {
"showHeader": true
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"refId": "A"
}
],
"title": "Other Display Mode",
"type": "table"
}
],
"preload": false,
"refresh": "",
"schemaVersion": 40,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
@@ -0,0 +1,153 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"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": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "11.5.0-81438",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "randomWalk",
"refId": "A"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "randomWalk",
"refId": "B"
}
],
"title": "Panel Title",
"transformations": [
{
"id": "timeSeriesTable",
"options": {
"refIdToStat": {
"A": "mean",
"B": "max"
}
}
}
],
"type": "timeseries"
}
],
"preload": false,
"refresh": true,
"schemaVersion": 38,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "New dashboard",
"version": 0,
"weekStart": ""
}
+1 -4
View File
@@ -48,8 +48,6 @@ type TimePickerConfig struct {
Hidden *bool `json:"hidden,omitempty"`
// Interval options available in the refresh picker dropdown.
RefreshIntervals []string `json:"refresh_intervals,omitempty"`
// Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
TimeOptions []string `json:"time_options,omitempty"`
// Quick ranges for time picker.
QuickRanges []TimeOption `json:"quick_ranges,omitempty"`
// Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.
@@ -61,7 +59,6 @@ func NewTimePickerConfig() *TimePickerConfig {
return &TimePickerConfig{
Hidden: (func(input bool) *bool { return &input })(false),
RefreshIntervals: []string{"5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"},
TimeOptions: []string{"5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"},
}
}
@@ -927,7 +924,7 @@ func NewSpec() *Spec {
Editable: (func(input bool) *bool { return &input })(true),
GraphTooltip: (func(input DashboardCursorSync) *DashboardCursorSync { return &input })(DashboardCursorSyncOff),
FiscalYearStartMonth: (func(input uint8) *uint8 { return &input })(0),
SchemaVersion: 39,
SchemaVersion: 41,
}
}
@@ -209,8 +209,7 @@
},
"timepicker": {
"now": true,
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "browser",
"title": "Prometheus 2.0 Stats",
+11 -1
View File
@@ -295,7 +295,8 @@ type AlertRule struct {
}
type AlertRuleMetadata struct {
EditorSettings EditorSettings `json:"editor_settings"`
EditorSettings EditorSettings `json:"editor_settings"`
PrometheusStyleRule *PrometheusStyleRule `json:"prometheus_style_rule,omitempty"`
}
type EditorSettings struct {
@@ -303,6 +304,10 @@ type EditorSettings struct {
SimplifiedNotificationsSection bool `json:"simplified_notifications_section"`
}
type PrometheusStyleRule struct {
OriginalRuleDefinition string `json:"original_rule_definition,omitempty"`
}
// Namespaced describes a class of resources that are stored in a specific namespace.
type Namespaced interface {
GetNamespaceUID() string
@@ -748,6 +753,11 @@ func (alertRule *AlertRule) Copy() *AlertRule {
}
}
if alertRule.Metadata.PrometheusStyleRule != nil {
prometheusStyleRule := *alertRule.Metadata.PrometheusStyleRule
result.Metadata.PrometheusStyleRule = &prometheusStyleRule
}
for _, s := range alertRule.NotificationSettings {
result.NotificationSettings = append(result.NotificationSettings, CopyNotificationSettings(s))
}
+30 -5
View File
@@ -841,7 +841,7 @@ func TestDiff(t *testing.T) {
}
})
t.Run("should detect changes in Metadata", func(t *testing.T) {
t.Run("should detect changes in Metadata.EditorSettings", func(t *testing.T) {
rule1 := RuleGen.With(RuleGen.WithMetadata(AlertRuleMetadata{EditorSettings: EditorSettings{
SimplifiedQueryAndExpressionsSection: false,
SimplifiedNotificationsSection: false,
@@ -858,6 +858,21 @@ func TestDiff(t *testing.T) {
"Metadata.EditorSettings.SimplifiedNotificationsSection",
}, diff.Paths())
})
t.Run("should detect changes in Metadata.PrometheusStyleRule", func(t *testing.T) {
rule1 := RuleGen.With(RuleGen.WithMetadata(AlertRuleMetadata{PrometheusStyleRule: &PrometheusStyleRule{
OriginalRuleDefinition: "data",
}})).GenerateRef()
rule2 := CopyRule(rule1, RuleGen.WithMetadata(AlertRuleMetadata{PrometheusStyleRule: &PrometheusStyleRule{
OriginalRuleDefinition: "updated data",
}}))
diff := rule1.Diff(rule2)
assert.ElementsMatch(t, []string{
"Metadata.PrometheusStyleRule.OriginalRuleDefinition",
}, diff.Paths())
})
}
func TestSortByGroupIndex(t *testing.T) {
@@ -940,11 +955,21 @@ func TestAlertRuleGetKeyWithGroup(t *testing.T) {
}
func TestAlertRuleCopy(t *testing.T) {
for i := 0; i < 100; i++ {
rule := RuleGen.GenerateRef()
t.Run("should return a copy of the rule", func(t *testing.T) {
for i := 0; i < 100; i++ {
rule := RuleGen.GenerateRef()
copied := rule.Copy()
require.Empty(t, rule.Diff(copied))
}
})
t.Run("should create a copy of the prometheus rule definition from the metadata", func(t *testing.T) {
rule := RuleGen.With(RuleGen.WithMetadata(AlertRuleMetadata{PrometheusStyleRule: &PrometheusStyleRule{
OriginalRuleDefinition: "data",
}})).GenerateRef()
copied := rule.Copy()
require.Empty(t, rule.Diff(copied))
}
require.NotSame(t, rule.Metadata.PrometheusStyleRule, copied.Metadata.PrometheusStyleRule)
})
}
// This test makes sure the default generator
+220
View File
@@ -0,0 +1,220 @@
package prom
import (
"encoding/json"
"fmt"
"time"
"gopkg.in/yaml.v3"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/ngalert/models"
)
type Config struct {
DatasourceUID string
DatasourceType string
FromTimeRange *time.Duration
EvaluationOffset *time.Duration
ExecErrState models.ExecutionErrorState
NoDataState models.NoDataState
RecordingRules RulesConfig
AlertRules RulesConfig
}
type RulesConfig struct {
IsPaused bool
}
var (
defaultTimeRange = 600 * time.Second
defaultEvaluationOffset = 0 * time.Minute
defaultConfig = Config{
FromTimeRange: &defaultTimeRange,
EvaluationOffset: &defaultEvaluationOffset,
ExecErrState: models.ErrorErrState,
NoDataState: models.NoData,
}
)
type Converter struct {
cfg Config
}
func NewConverter(cfg Config) (*Converter, error) {
if cfg.DatasourceUID == "" {
return nil, fmt.Errorf("datasource UID is required")
}
if cfg.DatasourceType == "" {
return nil, fmt.Errorf("datasource type is required")
}
if cfg.FromTimeRange == nil {
cfg.FromTimeRange = defaultConfig.FromTimeRange
}
if cfg.EvaluationOffset == nil {
cfg.EvaluationOffset = defaultConfig.EvaluationOffset
}
if cfg.ExecErrState == "" {
cfg.ExecErrState = defaultConfig.ExecErrState
}
if cfg.NoDataState == "" {
cfg.NoDataState = defaultConfig.NoDataState
}
if cfg.DatasourceType != datasources.DS_PROMETHEUS && cfg.DatasourceType != datasources.DS_LOKI {
return nil, fmt.Errorf("invalid datasource type: %s", cfg.DatasourceType)
}
return &Converter{
cfg: cfg,
}, nil
}
// PrometheusRulesToGrafana converts a Prometheus rule group into Grafana Alerting rule group.
func (p *Converter) PrometheusRulesToGrafana(orgID int64, namespaceUID string, group PrometheusRuleGroup) (*models.AlertRuleGroup, error) {
for _, rule := range group.Rules {
err := validatePrometheusRule(rule)
if err != nil {
return nil, fmt.Errorf("invalid Prometheus rule '%s': %w", rule.Alert, err)
}
}
grafanaGroup, err := p.convertRuleGroup(orgID, namespaceUID, group)
if err != nil {
return nil, fmt.Errorf("failed to convert rule group '%s': %w", group.Name, err)
}
return grafanaGroup, nil
}
func validatePrometheusRule(rule PrometheusRule) error {
if rule.KeepFiringFor != nil {
return fmt.Errorf("keep_firing_for is not supported")
}
return nil
}
func (p *Converter) convertRuleGroup(orgID int64, namespaceUID string, promGroup PrometheusRuleGroup) (*models.AlertRuleGroup, error) {
uniqueNames := map[string]int{}
rules := make([]models.AlertRule, 0, len(promGroup.Rules))
interval := time.Duration(promGroup.Interval)
for i, rule := range promGroup.Rules {
gr, err := p.convertRule(orgID, namespaceUID, promGroup.Name, rule)
if err != nil {
return nil, fmt.Errorf("failed to convert Prometheus rule '%s' to Grafana rule: %w", rule.Alert, err)
}
gr.RuleGroupIndex = i + 1
gr.IntervalSeconds = int64(interval.Seconds())
// Check rule title uniqueness within the group.
uniqueNames[gr.Title]++
if val := uniqueNames[gr.Title]; val > 1 {
gr.Title = fmt.Sprintf("%s (%d)", gr.Title, val)
}
rules = append(rules, gr)
}
result := &models.AlertRuleGroup{
FolderUID: namespaceUID,
Interval: int64(interval.Seconds()),
Rules: rules,
Title: promGroup.Name,
}
return result, nil
}
func (p *Converter) convertRule(orgID int64, namespaceUID, group string, rule PrometheusRule) (models.AlertRule, error) {
var forInterval time.Duration
if rule.For != nil {
forInterval = time.Duration(*rule.For)
}
queryNode, err := createAlertQueryNode(p.cfg.DatasourceUID, p.cfg.DatasourceType, rule.Expr, *p.cfg.FromTimeRange, *p.cfg.EvaluationOffset)
if err != nil {
return models.AlertRule{}, err
}
var title string
if rule.Record != "" {
title = rule.Record
} else {
title = rule.Alert
}
labels := make(map[string]string, len(rule.Labels)+1)
for k, v := range rule.Labels {
labels[k] = v
}
originalRuleDefinition, err := yaml.Marshal(rule)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to marshal original rule definition: %w", err)
}
result := models.AlertRule{
OrgID: orgID,
NamespaceUID: namespaceUID,
Title: title,
Data: []models.AlertQuery{queryNode},
Condition: "A",
NoDataState: p.cfg.NoDataState,
ExecErrState: p.cfg.ExecErrState,
Annotations: rule.Annotations,
Labels: labels,
For: forInterval,
RuleGroup: group,
Metadata: models.AlertRuleMetadata{
PrometheusStyleRule: &models.PrometheusStyleRule{
OriginalRuleDefinition: string(originalRuleDefinition),
},
},
}
if rule.Record != "" {
result.Record = &models.Record{
From: "A",
Metric: rule.Record,
}
result.IsPaused = p.cfg.RecordingRules.IsPaused
} else {
result.IsPaused = p.cfg.AlertRules.IsPaused
}
return result, nil
}
func createAlertQueryNode(datasourceUID, datasourceType, expr string, fromTimeRange, evaluationOffset time.Duration) (models.AlertQuery, error) {
modelData := map[string]interface{}{
"datasource": map[string]interface{}{
"type": datasourceType,
"uid": datasourceUID,
},
"expr": expr,
"instant": true,
"range": false,
"refId": "A",
}
if datasourceType == datasources.DS_LOKI {
modelData["queryType"] = "instant"
}
modelJSON, err := json.Marshal(modelData)
if err != nil {
return models.AlertQuery{}, err
}
return models.AlertQuery{
DatasourceUID: datasourceUID,
Model: modelJSON,
RefID: "A",
RelativeTimeRange: models.RelativeTimeRange{
From: models.Duration(fromTimeRange + evaluationOffset),
To: models.Duration(0 + evaluationOffset),
},
}, nil
}
+192
View File
@@ -0,0 +1,192 @@
package prom
import (
"testing"
"time"
prommodel "github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/ngalert/models"
)
func TestPrometheusRulesToGrafana(t *testing.T) {
fiveMin := prommodel.Duration(5 * time.Minute)
testCases := []struct {
name string
orgID int64
namespace string
promGroup PrometheusRuleGroup
config Config
expectError bool
}{
{
name: "valid rule group",
orgID: 1,
namespace: "some-namespace-uid",
promGroup: PrometheusRuleGroup{
Name: "test-group-1",
Interval: prommodel.Duration(10 * time.Second),
Rules: []PrometheusRule{
{
Alert: "alert-1",
Expr: "cpu_usage > 80",
For: &fiveMin,
Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "CPU usage is critical",
},
},
},
},
expectError: false,
},
{
name: "rules with keep_firing_for are not supported",
orgID: 1,
namespace: "namespaceUID",
promGroup: PrometheusRuleGroup{
Name: "test-group-1",
Interval: prommodel.Duration(1 * time.Minute),
Rules: []PrometheusRule{
{
Alert: "alert-1",
Expr: "up == 0",
KeepFiringFor: &fiveMin,
},
},
},
expectError: true,
},
{
name: "rule with empty interval",
orgID: 1,
namespace: "namespaceUID",
promGroup: PrometheusRuleGroup{
Name: "test-group-1",
Rules: []PrometheusRule{
{
Alert: "alert-1",
Expr: "up == 0",
},
},
},
expectError: false,
},
{
name: "recording rule",
orgID: 1,
namespace: "namespaceUID",
promGroup: PrometheusRuleGroup{
Name: "test-group-1",
Rules: []PrometheusRule{
{
Record: "some_metric",
Expr: "sum(rate(http_requests_total[5m]))",
},
},
},
expectError: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tc.config.DatasourceUID = "datasource-uid"
tc.config.DatasourceType = datasources.DS_PROMETHEUS
converter, err := NewConverter(tc.config)
require.NoError(t, err)
grafanaGroup, err := converter.PrometheusRulesToGrafana(tc.orgID, tc.namespace, tc.promGroup)
if tc.expectError {
require.Error(t, err, tc.name)
return
}
require.NoError(t, err, tc.name)
require.Equal(t, tc.promGroup.Name, grafanaGroup.Title, tc.name)
expectedInterval := int64(time.Duration(tc.promGroup.Interval).Seconds())
require.Equal(t, expectedInterval, grafanaGroup.Interval, tc.name)
require.Equal(t, len(tc.promGroup.Rules), len(grafanaGroup.Rules), tc.name)
for j, promRule := range tc.promGroup.Rules {
grafanaRule := grafanaGroup.Rules[j]
if promRule.Record != "" {
require.Equal(t, promRule.Record, grafanaRule.Title)
} else {
require.Equal(t, promRule.Alert, grafanaRule.Title)
}
var expectedFor time.Duration
if promRule.For != nil {
expectedFor = time.Duration(*promRule.For)
}
require.Equal(t, expectedFor, grafanaRule.For, tc.name)
expectedLabels := make(map[string]string, len(promRule.Labels)+1)
for k, v := range promRule.Labels {
expectedLabels[k] = v
}
require.Equal(t, expectedLabels, grafanaRule.Labels, tc.name)
require.Equal(t, promRule.Annotations, grafanaRule.Annotations, tc.name)
require.Equal(t, models.Duration(0*time.Minute), grafanaRule.Data[0].RelativeTimeRange.To)
require.Equal(t, models.Duration(10*time.Minute), grafanaRule.Data[0].RelativeTimeRange.From)
originalRuleDefinition, err := yaml.Marshal(promRule)
require.NoError(t, err)
require.Equal(t, string(originalRuleDefinition), grafanaRule.Metadata.PrometheusStyleRule.OriginalRuleDefinition)
}
})
}
}
func TestPrometheusRulesToGrafanaWithDuplicateRuleNames(t *testing.T) {
cfg := Config{
DatasourceUID: "datasource-uid",
DatasourceType: datasources.DS_PROMETHEUS,
}
converter, err := NewConverter(cfg)
require.NoError(t, err)
promGroup := PrometheusRuleGroup{
Name: "test-group-1",
Interval: prommodel.Duration(10 * time.Second),
Rules: []PrometheusRule{
{
Alert: "alert",
Expr: "up",
},
{
Alert: "alert",
Expr: "up",
},
{
Alert: "another alert",
Expr: "up",
},
{
Alert: "alert",
Expr: "up",
},
},
}
group, err := converter.PrometheusRulesToGrafana(1, "namespaceUID", promGroup)
require.NoError(t, err)
require.Equal(t, "test-group-1", group.Title)
require.Len(t, group.Rules, 4)
require.Equal(t, "alert", group.Rules[0].Title)
require.Equal(t, "alert (2)", group.Rules[1].Title)
require.Equal(t, "another alert", group.Rules[2].Title)
require.Equal(t, "alert (3)", group.Rules[3].Title)
}
+25
View File
@@ -0,0 +1,25 @@
package prom
import (
prommodel "github.com/prometheus/common/model"
)
type PrometheusRulesFile struct {
Groups []PrometheusRuleGroup `yaml:"groups"`
}
type PrometheusRuleGroup struct {
Name string `yaml:"name"`
Interval prommodel.Duration `yaml:"interval"`
Rules []PrometheusRule `yaml:"rules"`
}
type PrometheusRule struct {
Alert string `yaml:"alert,omitempty"`
Expr string `yaml:"expr,omitempty"`
For *prommodel.Duration `yaml:"for,omitempty"`
KeepFiringFor *prommodel.Duration `yaml:"keep_firing_for,omitempty"`
Labels map[string]string `yaml:"labels,omitempty"`
Annotations map[string]string `yaml:"annotations,omitempty"`
Record string `yaml:"record,omitempty"`
}
+106
View File
@@ -0,0 +1,106 @@
package prom
import (
"testing"
"time"
prommodel "github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
func TestPrometheusRulesFileYAML(t *testing.T) {
interval := prommodel.Duration(5 * time.Minute)
alertFor := prommodel.Duration(10 * time.Minute)
keepFiring := prommodel.Duration(15 * time.Minute)
tests := []struct {
name string
input PrometheusRulesFile
expectedYAML string
}{
{
name: "simple alert rule and a recording rule",
input: PrometheusRulesFile{
Groups: []PrometheusRuleGroup{
{
Name: "test_group",
Interval: interval,
Rules: []PrometheusRule{
{
Alert: "alert-1",
Expr: "vector(0) > 90",
For: &alertFor,
KeepFiringFor: &keepFiring,
Labels: map[string]string{
"team": "alerting",
},
Annotations: map[string]string{
"summary": "some summary",
"description": "some description",
},
},
{
Record: "vector(1)",
},
},
},
},
},
expectedYAML: `
groups:
- name: test_group
interval: 5m
rules:
- alert: alert-1
expr: vector(0) > 90
for: 10m
keep_firing_for: 15m
labels:
team: alerting
annotations:
description: some description
summary: some summary
- record: vector(1)
`,
},
{
name: "empty rules file",
input: PrometheusRulesFile{
Groups: []PrometheusRuleGroup{},
},
expectedYAML: `groups: []`,
},
{
name: "empty group",
input: PrometheusRulesFile{
Groups: []PrometheusRuleGroup{
{
Name: "empty_group",
Interval: interval,
Rules: []PrometheusRule{},
},
},
},
expectedYAML: `
groups:
- name: empty_group
interval: 5m
rules: []`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
yamlData, err := yaml.Marshal(tt.input)
require.NoError(t, err, "Failed to marshal to YAML")
require.YAMLEq(t, tt.expectedYAML, string(yamlData))
var parsed PrometheusRulesFile
err = yaml.Unmarshal(yamlData, &parsed)
require.NoError(t, err, "Failed to unmarshal from YAML")
require.Equal(t, tt.input, parsed)
})
}
}
@@ -30,17 +30,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -134,17 +134,6 @@
"collapse": false,
"enable": true,
"status": "Stable",
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
],
"refresh_intervals": [
"5s",
"10s",
@@ -11,8 +11,9 @@ import (
)
var (
onceIndex sync.Once
IndexMetrics *BleveIndexMetrics
onceIndex sync.Once
IndexMetrics *BleveIndexMetrics
SprinklesIndexMetrics *SprinklesMetrics
)
type BleveIndexMetrics struct {
@@ -28,8 +29,30 @@ type BleveIndexMetrics struct {
IndexTenants *prometheus.CounterVec
}
type SprinklesMetrics struct {
SprinklesLatency prometheus.Histogram
}
var IndexCreationBuckets = []float64{1, 5, 10, 25, 50, 75, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}
func NewSprinklesMetrics() *SprinklesMetrics {
onceIndex.Do(func() {
SprinklesIndexMetrics = &SprinklesMetrics{
SprinklesLatency: prometheus.NewHistogram(prometheus.HistogramOpts{
Namespace: "index_server",
Name: "sprinkles_latency_seconds",
Help: "Time (in seconds) it takes until sprinkles are fetched",
Buckets: instrument.DefBuckets,
NativeHistogramBucketFactor: 1.1, // enable native histograms
NativeHistogramMaxBucketNumber: 160,
NativeHistogramMinResetDuration: time.Hour,
}),
}
})
return SprinklesIndexMetrics
}
func NewIndexMetrics(indexDir string, searchBackend SearchBackend) *BleveIndexMetrics {
onceIndex.Do(func() {
IndexMetrics = &BleveIndexMetrics{
@@ -79,6 +102,14 @@ func NewIndexMetrics(indexDir string, searchBackend SearchBackend) *BleveIndexMe
return IndexMetrics
}
func (s *SprinklesMetrics) Collect(ch chan<- prometheus.Metric) {
s.SprinklesLatency.Collect(ch)
}
func (s *SprinklesMetrics) Describe(ch chan<- *prometheus.Desc) {
s.SprinklesLatency.Describe(ch)
}
func (s *BleveIndexMetrics) Collect(ch chan<- prometheus.Metric) {
s.IndexLatency.Collect(ch)
s.IndexCreationTime.Collect(ch)
+5
View File
@@ -83,10 +83,15 @@ func NewResourceServer(ctx context.Context, db infraDB.DB, cfg *setting.Cfg,
InitMinCount: cfg.IndexMinCount,
}
// Register indexer metrics
err = reg.Register(resource.NewIndexMetrics(cfg.IndexPath, opts.Search.Backend))
if err != nil {
slog.Warn("Failed to register indexer metrics", "error", err)
}
err = reg.Register(resource.NewSprinklesMetrics())
if err != nil {
slog.Warn("Failed to register sprinkles metrics", "error", err)
}
}
rs, err := resource.NewResourceServer(opts)
-11
View File
@@ -210,17 +210,6 @@
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
@@ -3,13 +3,14 @@ import { DataLinksInlineEditor } from '@grafana/ui';
type Props = StandardEditorProps<DataLink[], DataLinksFieldConfigSettings>;
export const DataLinksValueEditor = ({ value, onChange, context }: Props) => {
export const DataLinksValueEditor = ({ value, onChange, context, item }: Props) => {
return (
<DataLinksInlineEditor
links={value}
onChange={onChange}
data={context.data}
getSuggestions={() => (context.getSuggestions ? context.getSuggestions(VariableSuggestionsScope.Values) : [])}
showOneClick={item.settings?.showOneClick}
/>
);
};
@@ -27,6 +27,7 @@ import {
FieldNamePickerConfigSettings,
booleanOverrideProcessor,
Action,
DataLinksFieldConfigSettings,
} from '@grafana/data';
import { actionsOverrideProcessor } from '@grafana/data/src/field/overrides/processors';
import { config } from '@grafana/runtime';
@@ -350,7 +351,7 @@ export const getAllStandardFieldConfigs = () => {
const dataLinksCategory = config.featureToggles.vizActions ? 'Data links and actions' : 'Data links';
const links: FieldConfigPropertyItem<FieldConfig, DataLink[], StringFieldConfigSettings> = {
const links: FieldConfigPropertyItem<FieldConfig, DataLink[], DataLinksFieldConfigSettings> = {
id: 'links',
path: 'links',
name: 'Data links',
@@ -358,14 +359,14 @@ export const getAllStandardFieldConfigs = () => {
override: standardEditorsRegistry.get('links').editor,
process: dataLinksOverrideProcessor,
settings: {
placeholder: '-',
showOneClick: false,
},
shouldApply: () => true,
category: [dataLinksCategory],
getItemsCount: (value) => (value ? value.length : 0),
};
const actions: FieldConfigPropertyItem<FieldConfig, Action[], StringFieldConfigSettings> = {
const actions: FieldConfigPropertyItem<FieldConfig, Action[], DataLinksFieldConfigSettings> = {
id: 'actions',
path: 'actions',
name: 'Actions',
@@ -373,12 +374,13 @@ export const getAllStandardFieldConfigs = () => {
override: standardEditorsRegistry.get('actions').editor,
process: actionsOverrideProcessor,
settings: {
placeholder: '-',
showOneClick: false,
},
shouldApply: () => true,
category: [dataLinksCategory],
getItemsCount: (value) => (value ? value.length : 0),
showIf: () => config.featureToggles.vizActions,
hideFromDefaults: true,
};
const color: FieldConfigPropertyItem<FieldConfig, FieldColor | undefined, FieldColorConfigSettings> = {
@@ -27,16 +27,17 @@ export const TagOption = ({ data, className, label, isFocused, innerProps }: Opt
const getStyles = (theme: GrafanaTheme2) => {
return {
option: css({
padding: theme.spacing(1),
padding: theme.spacing(0.5),
whiteSpace: 'nowrap',
cursor: 'pointer',
borderLeft: '2px solid transparent',
borderRadius: theme.shape.radius.default,
'&:hover': {
background: theme.colors.background.secondary,
background: theme.colors.action.hover,
},
}),
optionFocused: css({
background: theme.colors.background.secondary,
background: theme.colors.action.focus,
borderStyle: 'solid',
borderTop: 0,
borderRight: 0,
@@ -9,7 +9,12 @@ type DataLinksInlineEditorProps = Omit<DataLinksInlineEditorBaseProps<Action>, '
getSuggestions: () => VariableSuggestion[];
};
export const ActionsInlineEditor = ({ actions, getSuggestions, showOneClick, ...rest }: DataLinksInlineEditorProps) => (
export const ActionsInlineEditor = ({
actions,
getSuggestions,
showOneClick = false,
...rest
}: DataLinksInlineEditorProps) => (
<DataLinksInlineEditorBase<Action> type="action" items={actions} {...rest}>
{(item, index, onSave, onCancel) => (
<ActionEditorModalContent
@@ -19,7 +24,7 @@ export const ActionsInlineEditor = ({ actions, getSuggestions, showOneClick, ...
onSave={onSave}
onCancel={onCancel}
getSuggestions={getSuggestions}
showOneClick={showOneClick ?? false}
showOneClick={showOneClick}
/>
)}
</DataLinksInlineEditorBase>
Loaded 100 of 156 files, more files were not shown because too many files have changed in this diff. Show more