Merge branch 'main' into kristina/static-transform-refIds

This commit is contained in:
Kristina Durivage
2025-09-24 11:13:57 -05:00
437 changed files with 160941 additions and 26604 deletions
+1
View File
@@ -952,6 +952,7 @@ playwright.storybook.config.ts @grafana/grafana-frontend-platform
/public/app/features/variables/ @grafana/dashboards-squad
/public/app/features/preferences/ @grafana/grafana-frontend-platform
/public/app/features/bookmarks/ @grafana/grafana-search-navigate-organise
/public/app/plugins/panel/* @grafana/dataviz-squad
/public/app/plugins/panel/alertlist/ @grafana/alerting-frontend
/public/app/plugins/panel/annolist/ @grafana/dashboards-squad
/public/app/plugins/panel/barchart/ @grafana/dataviz-squad
@@ -58,6 +58,7 @@ jobs:
run: |
CODEGEN_VERIFY=1 make gen-cue
CODEGEN_VERIFY=1 make gen-jsonnet
CODEGEN_VERIFY=1 make gen-apps
- name: Validate go.mod
run: go run scripts/modowners/modowners.go check go.mod
+221
View File
@@ -1,3 +1,224 @@
<!-- 12.2.0 START -->
# 12.2.0 (2025-09-23)
### Features and enhancements
- ** Alerting:** Add feedback buttons for the new AI helpers (Enterprise)
- **Access:** Remove plugin app access in plugin basic role seeder (Enterprise)
- **Actions:** Infinity authentication [#109493](https://github.com/grafana/grafana/pull/109493), [@adela-almasan](https://github.com/adela-almasan)
- **Alerting:** Add GMA export to the new list page [#109784](https://github.com/grafana/grafana/pull/109784), [@konrad147](https://github.com/konrad147)
- **Alerting:** Add alerting AI buttons for cloud (Enterprise)
- **Alerting:** Add contact point filter to Active Notifications page [#109775](https://github.com/grafana/grafana/pull/109775), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Add enrichment per rule extension component (Enterprise)
- **Alerting:** Add extension point link from alert rule to grafana-metricsdrilldown-app [#108566](https://github.com/grafana/grafana/pull/108566), [@bohandley](https://github.com/bohandley)
- **Alerting:** Add feature toggle and extension point [#110141](https://github.com/grafana/grafana/pull/110141), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Alerting:** Add keepFiringFor and missing_series_evals_to_resolve to file provisioning [#109699](https://github.com/grafana/grafana/pull/109699), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Add observability to enrichment UI (Enterprise)
- **Alerting:** Add tooltips in enrichment list for enrichment type (Enterprise)
- **Alerting:** Alert enrichment list page (Enterprise)
- **Alerting:** Allow filter by rule source in Filter V2 [#110336](https://github.com/grafana/grafana/pull/110336), [@laurenashleigh](https://github.com/laurenashleigh)
- **Alerting:** Auto refresh contact points in the rule form [#109539](https://github.com/grafana/grafana/pull/109539), [@konrad147](https://github.com/konrad147)
- **Alerting:** Check if TimeInterval is used in ActiveTimings when deleting [#110691](https://github.com/grafana/grafana/pull/110691), [@fayzal-g](https://github.com/fayzal-g)
- **Alerting:** Disable group consistency check for GMA rules [#109599](https://github.com/grafana/grafana/pull/109599), [@konrad147](https://github.com/konrad147)
- **Alerting:** Display Error Message in Alert History View [#110123](https://github.com/grafana/grafana/pull/110123), [@laurenashleigh](https://github.com/laurenashleigh)
- **Alerting:** Enrichment Config Form (Enterprise)
- **Alerting:** Filter out private labels before writing recording rules [#109295](https://github.com/grafana/grafana/pull/109295), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** List V2 - Add a group link to the rule list item [#108960](https://github.com/grafana/grafana/pull/108960), [@konrad147](https://github.com/konrad147)
- **Alerting:** List V2 - datasource icons for rules [#109033](https://github.com/grafana/grafana/pull/109033), [@konrad147](https://github.com/konrad147)
- **Alerting:** Load labels in drop-downs without blocking the interaction with the form inputs [#110648](https://github.com/grafana/grafana/pull/110648), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Alerting:** Mark Prometheus to Grafana conversion API as stable [#103499](https://github.com/grafana/grafana/pull/103499), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Move alerting file to an alerting folder [#110257](https://github.com/grafana/grafana/pull/110257), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron)
- **Alerting:** Support JSON responses in the Prometheus conversion API [#109070](https://github.com/grafana/grafana/pull/109070), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Support extra labels in the Prometheus conversion API [#109136](https://github.com/grafana/grafana/pull/109136), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Support retry with backoff in alert rule evaluation [#99710](https://github.com/grafana/grafana/pull/99710), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Triage alert history with Assistant if available (Enterprise)
- **Auditing:** Add settings to control recording of datasource query request and response body (Enterprise)
- **Auth:** Add setting to disable username based brute force login protection [#109152](https://github.com/grafana/grafana/pull/109152), [@TheoBrigitte](https://github.com/TheoBrigitte)
- **Auth:** Support JWT configs `tls_client_ca` and `jwk_set_bearer_token_file` [#109095](https://github.com/grafana/grafana/pull/109095), [@Baarsgaard](https://github.com/Baarsgaard)
- **Azure:** Resource picker improvements (#109458) [#109520](https://github.com/grafana/grafana/pull/109520), [@aangelisc](https://github.com/aangelisc)
- **Azure:** Show resource group in picker [#110442](https://github.com/grafana/grafana/pull/110442), [@aangelisc](https://github.com/aangelisc)
- **Canvas:** Add option to disable tooltips for one-click elements [#109937](https://github.com/grafana/grafana/pull/109937), [@adela-almasan](https://github.com/adela-almasan)
- **Canvas:** Dynamic connection direction [#108423](https://github.com/grafana/grafana/pull/108423), [@adela-almasan](https://github.com/adela-almasan)
- **Chore:** Remove prometheusCodeModeMetricNamesSearch feature toggle [#109024](https://github.com/grafana/grafana/pull/109024), [@itsmylife](https://github.com/itsmylife)
- **Chore:** Removes HideAngularDeprecation configuration [#110665](https://github.com/grafana/grafana/pull/110665), [@hugohaggmark](https://github.com/hugohaggmark)
- **CloudConfig:** Add config from defaults.ini to StackInfo (Enterprise)
- **CloudWatch:** Append query type to the request id [#109068](https://github.com/grafana/grafana/pull/109068), [@idastambuk](https://github.com/idastambuk)
- **CloudWatch:** Use default region when query region is unset [#109089](https://github.com/grafana/grafana/pull/109089), [@iwysiu](https://github.com/iwysiu)
- **CloudWatch:** Use the correct metric name for errors per function panel in the AWS Lambda sample dashboard [#110718](https://github.com/grafana/grafana/pull/110718), [@kevinwcyu](https://github.com/kevinwcyu)
- **CommandPalette:** Use fuzzySearch util from grafana/data [#108884](https://github.com/grafana/grafana/pull/108884), [@Clarity-89](https://github.com/Clarity-89)
- **Dashboard:** Inspect drawer can no longer be opened with url or linked to [#109617](https://github.com/grafana/grafana/pull/109617), [@torkelo](https://github.com/torkelo)
- **Dashboards:** Add support for full screen panel view and embedded (solo panel) route to repeated panels and new layouts (via new SoloPanelContex) [#107375](https://github.com/grafana/grafana/pull/107375), [@torkelo](https://github.com/torkelo)
- **Dashboards:** Conserve timestamp on time range copy-paste across timezones [#109769](https://github.com/grafana/grafana/pull/109769), [@alik-r](https://github.com/alik-r)
- **Dashboards:** Enable kubernetesDashboards by default [#107618](https://github.com/grafana/grafana/pull/107618), [@dprokop](https://github.com/dprokop)
- **Dashboards:** Make it possible to render variables under a drop-down [#109225](https://github.com/grafana/grafana/pull/109225), [@leventebalogh](https://github.com/leventebalogh)
- **Database:** Add primary key to Settings table (Enterprise)
- **Database:** Add primary key to settings table (Enterprise)
- **Dependencies:** Bump Go to v1.24.5 (Enterprise)
- **Docs:** Deprecate `grafana/grafana-oss` docker repo in favor of `grafana/grafana` [#110065](https://github.com/grafana/grafana/pull/110065), [@kminehart](https://github.com/kminehart)
- **Flame Graph:** Analyze with Grafana Assistant [#108684](https://github.com/grafana/grafana/pull/108684), [@ifrost](https://github.com/ifrost)
- **Folders:** Add team folders feature toggle [#109389](https://github.com/grafana/grafana/pull/109389), [@tomratcliffe](https://github.com/tomratcliffe)
- **Folders:** Update folder using app platform APIs [#110449](https://github.com/grafana/grafana/pull/110449), [@tomratcliffe](https://github.com/tomratcliffe)
- **Folders:** Use app platform search endpoint and update tests [#108814](https://github.com/grafana/grafana/pull/108814), [@tomratcliffe](https://github.com/tomratcliffe)
- **Go:** Update to 1.24.6 [#109313](https://github.com/grafana/grafana/pull/109313), [@Proximyst](https://github.com/Proximyst)
- **InfluxDB:** Ad hoc filters support for expressions [#109344](https://github.com/grafana/grafana/pull/109344), [@aangelisc](https://github.com/aangelisc)
- **Metrics:** Add http_response_size_bytes metric [#110428](https://github.com/grafana/grafana/pull/110428), [@joshhunt](https://github.com/joshhunt)
- **Nested folders:** Remove feature flag [#109212](https://github.com/grafana/grafana/pull/109212), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
- **NestedFolderPicker:** Add rootFolderUID prop [#109991](https://github.com/grafana/grafana/pull/109991), [@ywzheng1](https://github.com/ywzheng1)
- **P2P Filter:** Add adhoc filter option toggle [#110160](https://github.com/grafana/grafana/pull/110160), [@Develer](https://github.com/Develer)
- **PieChart:** Add panel options for ascending/descending sort, and no sorting [#109564](https://github.com/grafana/grafana/pull/109564), [@cglukas](https://github.com/cglukas)
- **Plugin Extensions:** DataSource Configuration Components [#108350](https://github.com/grafana/grafana/pull/108350), [@shelldandy](https://github.com/shelldandy)
- **Plugins:** Add Connections homepage [#108316](https://github.com/grafana/grafana/pull/108316), [@oshirohugo](https://github.com/oshirohugo)
- **Plugins:** Record plugin version in request metrics [#110210](https://github.com/grafana/grafana/pull/110210), [@njvrzm](https://github.com/njvrzm)
- **Preferences:** Move codegen to apps [#109178](https://github.com/grafana/grafana/pull/109178), [@ryantxu](https://github.com/ryantxu)
- **Prometheus data source:** Migration service [#107364](https://github.com/grafana/grafana/pull/107364), [@bossinc](https://github.com/bossinc)
- **Prometheus:** Refactor metrics modal to handle high cardinality metrics [#108437](https://github.com/grafana/grafana/pull/108437), [@itsmylife](https://github.com/itsmylife)
- **Pyroscope:** Process and display sampling annotations [#109707](https://github.com/grafana/grafana/pull/109707), [@aleks-p](https://github.com/aleks-p)
- **Reporting:** Permit valid but weird emails (Enterprise)
- **Reporting:** Show correct recipient count (Enterprise)
- **Revert:** DataSource: Support config CRUD from apiservers (#106996) [#110342](https://github.com/grafana/grafana/pull/110342), [@njvrzm](https://github.com/njvrzm)
- **Revert:** DataSource: Support config CRUD from apiservers (#8860) (Enterprise)
- **SCIM:** Add flag for rejecting non provisioned users from logging in (Enterprise)
- **SCIM:** Allow empty externalId on update operation (Enterprise)
- **SCIM:** Delete user instead of disabling it on SCIM DELETE user request (Enterprise)
- **SQL Expressions:** Switch feature toggle to public preview [#110473](https://github.com/grafana/grafana/pull/110473), [@kylebrandt](https://github.com/kylebrandt)
- **Table:** Frozen columns [#109276](https://github.com/grafana/grafana/pull/109276), [@fastfrwrd](https://github.com/fastfrwrd)
- **Table:** Max row height for variable height rows [#109639](https://github.com/grafana/grafana/pull/109639), [@fastfrwrd](https://github.com/fastfrwrd)
- **Table:** Tooltip from Field [#109428](https://github.com/grafana/grafana/pull/109428), [@fastfrwrd](https://github.com/fastfrwrd)
- **Table:** Update UX for uniform-reducer case in new footer and overflow [#110493](https://github.com/grafana/grafana/pull/110493), [@fastfrwrd](https://github.com/fastfrwrd)
- **TableNG:** Footer enhancements [#102948](https://github.com/grafana/grafana/pull/102948), [@alexjonspencer1](https://github.com/alexjonspencer1)
- **Text:** Add Inter italic font variants to Grafana UI [#110313](https://github.com/grafana/grafana/pull/110313), [@kapowaz](https://github.com/kapowaz)
- **TraceView:** Refine UI visual hierarchy inside details section [#108929](https://github.com/grafana/grafana/pull/108929), [@ifrost](https://github.com/ifrost)
- **Transformations:** Add empty values options to Transpose [#108421](https://github.com/grafana/grafana/pull/108421), [@gelicia](https://github.com/gelicia)
- **Trend/TimeSeries:** Add "Show values" option [#108090](https://github.com/grafana/grafana/pull/108090), [@HasithDeAlwis](https://github.com/HasithDeAlwis)
- **Trend:** Add support for a logarithmic x axis [#101433](https://github.com/grafana/grafana/pull/101433), [@gelicia](https://github.com/gelicia)
- **Variables:** shows warning when user tries to save erroneous variables [#110154](https://github.com/grafana/grafana/pull/110154), [@hugohaggmark](https://github.com/hugohaggmark)
- **VizTooltip:** Replace `ExemplarHoverView` with `VizTooltip` components [#109369](https://github.com/grafana/grafana/pull/109369), [@adela-almasan](https://github.com/adela-almasan)
### Bug fixes
- **Alerting:** Fix bug where rules with identical mute/active intervals produced conflicting routes [#110971](https://github.com/grafana/grafana/pull/110971), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Fix copying of recording rule fields [#110311](https://github.com/grafana/grafana/pull/110311), [@moustafab](https://github.com/moustafab)
- **Alerting:** Fix field names on webhook HMAC/TLS config HCL export [#110722](https://github.com/grafana/grafana/pull/110722), [@JacobsonMT](https://github.com/JacobsonMT)
- **Alerting:** Fix newly created alert rules not immediately showing up in folder view [#109584](https://github.com/grafana/grafana/pull/109584), [@tomratcliffe](https://github.com/tomratcliffe)
- **Alerting:** Fix permission checks for the Import to GMA [#109950](https://github.com/grafana/grafana/pull/109950), [@konrad147](https://github.com/konrad147)
- **Alerting:** Fix permissions for enrichment routes (Enterprise)
- **Alerting:** Fix subpath handling in the alerting package [#109448](https://github.com/grafana/grafana/pull/109448), [@konrad147](https://github.com/konrad147)
- **Alerting:** Fix wrong import (Enterprise)
- **Alerting:** Hide list view loader if we don't have anything yet [#110464](https://github.com/grafana/grafana/pull/110464), [@gillesdemey](https://github.com/gillesdemey)
- **Alerting:** Set dataSourceName to GRAFANA_RULES_SOURCE_NAME when switch… [#109900](https://github.com/grafana/grafana/pull/109900), [@laurenashleigh](https://github.com/laurenashleigh)
- **Alerting:** Update alerting module to 10915888e4f099586ad37bea5f4a70f45101d2f5 [#109989](https://github.com/grafana/grafana/pull/109989), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Azure:** Fix logs editor rendering [#109491](https://github.com/grafana/grafana/pull/109491), [@aangelisc](https://github.com/aangelisc)
- **Canvas:** Fix element selection being cleared on panel resize [#110010](https://github.com/grafana/grafana/pull/110010), [@adela-almasan](https://github.com/adela-almasan)
- **CloudConfig:** Fix panic in defaults.ini merge (Enterprise)
- **CloudWatch:** Fix handling region for legacy alerts [#109217](https://github.com/grafana/grafana/pull/109217), [@iwysiu](https://github.com/iwysiu)
- **CloudWatch:** Fix logs query requestId to prevent setting undefined-logs as a requestId [#109930](https://github.com/grafana/grafana/pull/109930), [@kevinwcyu](https://github.com/kevinwcyu)
- **CloudWatch:** Update grafana/aws-sdk-go with STS endpoint bugfix [#109120](https://github.com/grafana/grafana/pull/109120), [@idastambuk](https://github.com/idastambuk)
- **Config:** Fix date_formats options being moved to a different section [#109339](https://github.com/grafana/grafana/pull/109339), [@joshhunt](https://github.com/joshhunt)
- **Dashboard List:** Fix how link query part is created when variables are included [#109861](https://github.com/grafana/grafana/pull/109861), [@aocenas](https://github.com/aocenas)
- **Dashboard versions:** Fix list for large dashboards [#109433](https://github.com/grafana/grafana/pull/109433), [@stephaniehingtgen](https://github.com/stephaniehingtgen)
- **Dashboard:** Fix AngularJS deprecation in grafana-overview dashboard [#106462](https://github.com/grafana/grafana/pull/106462), [@schoen2](https://github.com/schoen2)
- **Dashboard:** Fixes url links to embedded panels in scene based dashboards [#109837](https://github.com/grafana/grafana/pull/109837), [@torkelo](https://github.com/torkelo)
- **Dashboards:** Fix UTF-8 characters not working with excel downloads by replacing download for excel with excel compatibility mode. [#110099](https://github.com/grafana/grafana/pull/110099), [@oscarkilhed](https://github.com/oscarkilhed)
- **Dashboards:** Fix issue where the time range picker would seemingly be hidden behind the side menu if it was set to always open. [#108607](https://github.com/grafana/grafana/pull/108607), [@oscarkilhed](https://github.com/oscarkilhed)
- **Dashboards:** Fix kiosk mode not persisting through refresh [#110284](https://github.com/grafana/grafana/pull/110284), [@oscarkilhed](https://github.com/oscarkilhed)
- **Dashboards:** Fixing saving and viewing snapshots for repeated panels [#109856](https://github.com/grafana/grafana/pull/109856), [@torkelo](https://github.com/torkelo)
- **Explore:** Fix units overflow for trace durations [#108515](https://github.com/grafana/grafana/pull/108515), [@martincostello](https://github.com/martincostello)
- **Fix:** Install plugins when they have no plugin archive info(catalog en… [#109200](https://github.com/grafana/grafana/pull/109200), [@s4kh](https://github.com/s4kh)
- **InfluxDB:** Fix Unable to use self-signed CA for adding influxdb data source [#105586](https://github.com/grafana/grafana/pull/105586), [@geekeryy](https://github.com/geekeryy)
- **Prometheus:** Don't use incremental querying if one of the queries has $\_\_range variable [#108823](https://github.com/grafana/grafana/pull/108823), [@itsmylife](https://github.com/itsmylife)
- **Prometheus:** Fix eager auto completion [#109128](https://github.com/grafana/grafana/pull/109128), [@itsmylife](https://github.com/itsmylife)
- **Prometheus:** QueryEditor fix error when switching from code to builder for undefined aggregation operations [#110179](https://github.com/grafana/grafana/pull/110179), [@jcolladokuri](https://github.com/jcolladokuri)
- **Pyroscope:** Add start and end date to profiletypes call [#110277](https://github.com/grafana/grafana/pull/110277), [@zoltanbedi](https://github.com/zoltanbedi)
- **Pyroscope:** Fix incorrect rate calculation from flamegraph totals [#110470](https://github.com/grafana/grafana/pull/110470), [@marcsanmi](https://github.com/marcsanmi)
- **Service Accounts:** Fix typo on page indicating none are present [#109560](https://github.com/grafana/grafana/pull/109560), [@eamonryan](https://github.com/eamonryan)
- **Tempo:** Fix instant query streaming [#108924](https://github.com/grafana/grafana/pull/108924), [@adrapereira](https://github.com/adrapereira)
- **TimeSeries:** Use exported time shift and fix time comparison tooltip [#109947](https://github.com/grafana/grafana/pull/109947), [@drew08t](https://github.com/drew08t)
- **Transformations:** Account for group by / count when assessing if calculation is needed [#110546](https://github.com/grafana/grafana/pull/110546), [@gelicia](https://github.com/gelicia)
- **Transforms:** GroupToMatrix transform should retain keyRowField config [#109066](https://github.com/grafana/grafana/pull/109066), [@fastfrwrd](https://github.com/fastfrwrd)
### Breaking changes
- **Alerting:** Enable alertingSaveStateCompressed by default [#109390](https://github.com/grafana/grafana/pull/109390), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Dashboards:** Repeating with no clone keys [#109839](https://github.com/grafana/grafana/pull/109839), [@torkelo](https://github.com/torkelo)
- **Provisioning:** Use inline secrets for gitsync [#109908](https://github.com/grafana/grafana/pull/109908), [@ryantxu](https://github.com/ryantxu)
- **Stars:** Remove deprecated internal ID apis [#110499](https://github.com/grafana/grafana/pull/110499), [@ryantxu](https://github.com/ryantxu)
### Plugin development fixes & changes
- **Drawer:** Truncate Drawer title to just one line [#109540](https://github.com/grafana/grafana/pull/109540), [@joshhunt](https://github.com/joshhunt)
- **Modal:** Center modals at smaller screen heights [#109256](https://github.com/grafana/grafana/pull/109256), [@ashharrison90](https://github.com/ashharrison90)
- **MultiCombobox:** Fix async options to being able to be removed [#109473](https://github.com/grafana/grafana/pull/109473), [@joshhunt](https://github.com/joshhunt)
- **MultiCombobox:** Fix select all when only a single option is available [#109910](https://github.com/grafana/grafana/pull/109910), [@aangelisc](https://github.com/aangelisc)
<!-- 12.2.0 END -->
<!-- 12.1.2 START -->
# 12.1.2 (2025-09-23)
### Features and enhancements
- **Alerting:** Update alerting module [#109999](https://github.com/grafana/grafana/pull/109999), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Auditing:** Add settings to control recording of datasource query request and response body (Enterprise)
- **Auditing:** Document new options for recording datasource query request/response body [#109981](https://github.com/grafana/grafana/pull/109981), [@macabu](https://github.com/macabu)
- **Chore:** Don't show a "Not found" for public-dashboard fetches if the service is disabled via config [#110144](https://github.com/grafana/grafana/pull/110144), [@mmandrus](https://github.com/mmandrus)
- **CloudWatch:** Use default region when query region is unset [#111079](https://github.com/grafana/grafana/pull/111079), [@iwysiu](https://github.com/iwysiu)
### Bug fixes
- **Alerting:** Fix bug where rules with identical mute/active intervals produced conflicting routes [#110973](https://github.com/grafana/grafana/pull/110973), [@alexander-akhmetov](https://github.com/alexander-akhmetov)
- **Alerting:** Fix copying of recording rule fields [#110312](https://github.com/grafana/grafana/pull/110312), [@moustafab](https://github.com/moustafab)
- **Fix:** Fix redirection after login when Grafana is served from subpath [#111097](https://github.com/grafana/grafana/pull/111097), [@mgyongyosi](https://github.com/mgyongyosi)
### Plugin development fixes & changes
- **Fix:** Prevent Rollup from treeshaking NPM packages [#108570](https://github.com/grafana/grafana/pull/108570), [@jackw](https://github.com/jackw)
<!-- 12.1.2 END -->
<!-- 12.0.5 START -->
# 12.0.5 (2025-09-23)
### Features and enhancements
- **Alerting:** Update alerting module [#110000](https://github.com/grafana/grafana/pull/110000), [@yuri-tceretian](https://github.com/yuri-tceretian)
- **Auditing:** Add settings to control recording of datasource query request and response body (Enterprise)
- **Auditing:** Document new options for recording datasource query request/response body [#109980](https://github.com/grafana/grafana/pull/109980), [@macabu](https://github.com/macabu)
### Bug fixes
- **Alerting:** Fix copying of recording rule fields [#110346](https://github.com/grafana/grafana/pull/110346), [@moustafab](https://github.com/moustafab)
- **Azure:** Fix time management field [#108481](https://github.com/grafana/grafana/pull/108481), [@aangelisc](https://github.com/aangelisc)
- **Fix:** Fix redirection after login when Grafana is served from subpath [#111156](https://github.com/grafana/grafana/pull/111156), [@mgyongyosi](https://github.com/mgyongyosi)
### Plugin development fixes & changes
- **Fix:** Prevent Rollup from treeshaking NPM packages [#110523](https://github.com/grafana/grafana/pull/110523), [@jackw](https://github.com/jackw)
<!-- 12.0.5 END -->
<!-- 11.6.6 START -->
# 11.6.6 (2025-09-23)
### Features and enhancements
- **Auditing:** Add settings to control recording of datasource query request and response body (Enterprise)
<!-- 11.6.6 END -->
<!-- 11.5.9 START -->
# 11.5.9 (2025-09-23)
### Features and enhancements
- **Auditing:** Add settings to control recording of datasource query request and response body (Enterprise)
- **Auditing:** Document new options for recording datasource query request/response body [#109976](https://github.com/grafana/grafana/pull/109976), [@macabu](https://github.com/macabu)
### Bug fixes
- **Fix:** Fix redirection after login when Grafana is served from subpath [#111099](https://github.com/grafana/grafana/pull/111099), [@mgyongyosi](https://github.com/mgyongyosi)
<!-- 11.5.9 END -->
<!-- 12.1.1 START -->
# 12.1.1 (2025-08-13)
+14 -2
View File
@@ -173,7 +173,19 @@ gen-cuev2: ## Do all CUE code generation
APPS_DIRS := ./apps/dashboard ./apps/folder ./apps/alerting/notifications
.PHONY: gen-apps
gen-apps: ## Generate code for Grafana App SDK apps
gen-apps: do-gen-apps gofmt ## Generate code for Grafana App SDK apps and run gofmt
@if [ -n "$$CODEGEN_VERIFY" ]; then \
echo "Verifying generated code is up to date..."; \
if ! git diff --quiet; then \
echo "Error: Generated apps code is not up to date. Please run 'make gen-apps' to regenerate."; \
git diff --name-only; \
exit 1; \
fi; \
echo "Generated apps code is up to date."; \
fi
.PHONY: do-gen-apps
do-gen-apps: ## Generate code for Grafana App SDK apps
for dir in $(APPS_DIRS); do \
$(MAKE) -C $$dir generate; \
done
@@ -388,7 +400,7 @@ lint-go-diff:
.PHONY: gofmt
gofmt: ## Run gofmt for all Go files.
gofmt -s -w .
@go list -m -f '{{.Dir}}' | xargs -I{} sh -c 'test ! -f {}/.nolint && echo {}' | xargs gofmt -s -w 2>&1 | grep -v '/pkg/build/' || true
# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts
.PHONY: shellcheck
+1 -1
View File
@@ -51,7 +51,7 @@ require (
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/grafana/authlib v0.0.0-20250917093142-83a502239781 // indirect
github.com/grafana/authlib v0.0.0-20250924100039-ea07223cdb6c // indirect
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect
github.com/grafana/otel-profiling-go v0.5.1 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
+2 -2
View File
@@ -95,8 +95,8 @@ github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25d
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/grafana/authlib v0.0.0-20250917093142-83a502239781 h1:sdI2P18j78expDtLB6YbVI5dV+HguV719iiQNqx3wqw=
github.com/grafana/authlib v0.0.0-20250917093142-83a502239781/go.mod h1:C6CmTG6vfiqebjJswKsc6zes+1F/OtTCi6aAtL5Um6A=
github.com/grafana/authlib v0.0.0-20250924100039-ea07223cdb6c h1:8GIMe1KclDdfogaeRsiU69Ev2zTF9kmjqjQqqZMzerc=
github.com/grafana/authlib v0.0.0-20250924100039-ea07223cdb6c/go.mod h1:C6CmTG6vfiqebjJswKsc6zes+1F/OtTCi6aAtL5Um6A=
github.com/grafana/authlib/types v0.0.0-20250917093142-83a502239781 h1:jymmOFIWnW26DeUjFgYEoltI170KeT5r1rI8a/dUf0E=
github.com/grafana/authlib/types v0.0.0-20250917093142-83a502239781/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw=
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 h1:jSojuc7njleS3UOz223WDlXOinmuLAIPI0z2vtq8EgI=
@@ -31,7 +31,7 @@ import (
func TestConversionMatrixExist(t *testing.T) {
// Initialize the migrator with a test data source provider
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
versions := []metav1.Object{
&dashv0.Dashboard{Spec: common.Unstructured{Object: map[string]any{"title": "dashboardV0"}}},
@@ -82,7 +82,7 @@ func TestDeepCopyValid(t *testing.T) {
func TestDashboardConversionToAllVersions(t *testing.T) {
// Initialize the migrator with a test data source provider
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
// Set up conversion scheme
scheme := runtime.NewScheme()
@@ -234,7 +234,7 @@ func testConversion(t *testing.T, convertedDash metav1.Object, filename, outputD
// TestConversionMetrics tests that conversion-level metrics are recorded correctly
func TestConversionMetrics(t *testing.T) {
// Initialize migration with test providers
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
// Create a test registry for metrics
registry := prometheus.NewRegistry()
@@ -370,7 +370,7 @@ func TestConversionMetrics(t *testing.T) {
// TestConversionMetricsWrapper tests the withConversionMetrics wrapper function
func TestConversionMetricsWrapper(t *testing.T) {
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
// Create a test registry for metrics
registry := prometheus.NewRegistry()
@@ -529,7 +529,7 @@ func TestSchemaVersionExtraction(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Test the schema version extraction logic by creating a wrapper and checking the metrics labels
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
// Create a test registry for metrics
registry := prometheus.NewRegistry()
@@ -572,7 +572,7 @@ func TestSchemaVersionExtraction(t *testing.T) {
// TestConversionLogging tests that conversion-level logging works correctly
func TestConversionLogging(t *testing.T) {
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
// Create a test registry for metrics
registry := prometheus.NewRegistry()
@@ -662,7 +662,7 @@ func TestConversionLogging(t *testing.T) {
// TestConversionLogLevels tests that appropriate log levels are used
func TestConversionLogLevels(t *testing.T) {
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
t.Run("log levels and structured fields verification", func(t *testing.T) {
// Create test wrapper to verify logging behavior
@@ -731,7 +731,7 @@ func TestConversionLogLevels(t *testing.T) {
// TestConversionLoggingFields tests that all expected fields are included in log messages
func TestConversionLoggingFields(t *testing.T) {
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
migration.Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
t.Run("verify all log fields are present", func(t *testing.T) {
// Test that the conversion wrapper includes all expected structured fields
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+105
View File
@@ -13,6 +13,15 @@ func Initialize(dsInfoProvider schemaversion.DataSourceInfoProvider) {
migratorInstance.init(dsInfoProvider)
}
// ResetForTesting resets the migrator singleton for testing purposes.
func ResetForTesting() {
migratorInstance = &migrator{
migrations: map[int]schemaversion.SchemaVersionMigrationFunc{},
ready: make(chan struct{}),
}
initOnce = sync.Once{}
}
// Migrate migrates the given dashboard to the target version.
// This will block until the migrator is initialized.
func Migrate(ctx context.Context, dash map[string]interface{}, targetVersion int) error {
@@ -47,6 +56,51 @@ func (m *migrator) migrate(ctx context.Context, dash map[string]interface{}, tar
// wait for the migrator to be initialized
<-m.ready
// 0. Clean up dashboard properties that frontend never includes in save model
// These properties are added by backend but frontend filters them out
delete(dash, "__elements")
delete(dash, "__inputs")
delete(dash, "__requires")
// 1. Track which panels had transformations in original input (before any defaults applied)
// This is needed to match frontend hasOwnProperty behavior
trackOriginalTransformations(dash)
// 2. Apply ALL frontend defaults FIRST (DashboardModel + PanelModel defaults)
// This replicates the behavior of the frontend DashboardModel and PanelModel constructors
applyFrontendDefaults(dash)
// 2. Apply panel defaults to ALL panels (both top-level and nested in rows)
// The frontend creates PanelModel instances for all panels, including those in rows
if dashboardPanels, ok := dash["panels"].([]interface{}); ok {
for _, panelInterface := range dashboardPanels {
if panel, ok := panelInterface.(map[string]interface{}); ok {
applyPanelDefaults(panel)
}
}
}
// Apply defaults to panels inside rows (for pre-v16 dashboards)
// Match frontend upgradeToGridLayout: only panels NOT in collapsed rows get new PanelModel() constructor
if rows, ok := dash["rows"].([]interface{}); ok {
showRows := shouldShowRows(rows)
for _, rowInterface := range rows {
row, ok := rowInterface.(map[string]interface{})
if !ok {
continue
}
applyRowPanelDefaults(row, showRows)
}
}
// 3. Ensure panel IDs are unique for ALL panels (including nested ones)
// This matches the frontend ensurePanelsHaveUniqueIds() behavior
ensurePanelsHaveUniqueIds(dash)
// TODO: Probably we can check if we can migrate at the beginning of the function
// 4. Ensure schema version is set and if not default to 0
inputVersion := schemaversion.GetSchemaVersion(dash)
dash["schemaVersion"] = inputVersion
@@ -56,6 +110,8 @@ func (m *migrator) migrate(ctx context.Context, dash map[string]interface{}, tar
return schemaversion.NewMinimumVersionError(inputVersion)
}
// 5. Run existing migration pipeline UNCHANGED
// (All the existing v28, v29, etc. migrators run exactly as before)
for nextVersion := inputVersion + 1; nextVersion <= targetVersion; nextVersion++ {
if migration, ok := m.migrations[nextVersion]; ok {
if err := migration(ctx, dash); err != nil {
@@ -66,9 +122,58 @@ func (m *migrator) migrate(ctx context.Context, dash map[string]interface{}, tar
}
}
// 6. Clean up the dashboard to match frontend getSaveModel behavior
// This removes properties that shouldn't be persisted and filters out default values
cleanupDashboardForSave(dash)
if schemaversion.GetSchemaVersion(dash) != targetVersion {
return schemaversion.NewMigrationError("schema version not migrated to target version", inputVersion, targetVersion, "")
}
return nil
}
// shouldShowRows determines if row panels will be created (showRows logic)
func shouldShowRows(rows []interface{}) bool {
for _, rowInterface := range rows {
row, ok := rowInterface.(map[string]interface{})
if !ok {
continue
}
collapse := schemaversion.GetBoolValue(row, "collapse")
showTitle := schemaversion.GetBoolValue(row, "showTitle")
repeat := schemaversion.GetStringValue(row, "repeat")
if collapse || showTitle || repeat != "" {
return true
}
}
return false
}
// applyRowPanelDefaults applies panel defaults to panels within a row based on frontend logic
func applyRowPanelDefaults(row map[string]interface{}, showRows bool) {
rowPanels, ok := row["panels"].([]interface{})
if !ok {
return
}
collapse := schemaversion.GetBoolValue(row, "collapse")
// Frontend: if (rowPanelModel && rowPanel.collapsed) { push(panel) } else { push(new PanelModel(panel)) }
// Only non-collapsed panels get PanelModel defaults (refId: "A", overrides: [], etc.)
applyDefaults := !showRows || !collapse
if !applyDefaults {
return
}
for _, panelInterface := range rowPanels {
panel, ok := panelInterface.(map[string]interface{})
if !ok {
continue
}
applyPanelDefaults(panel)
}
}
+157 -38
View File
@@ -1,4 +1,4 @@
package migration_test
package migration
import (
"bytes"
@@ -8,36 +8,53 @@ import (
"log/slog"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/apps/dashboard/pkg/migration"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
migrationtestutil "github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
)
const INPUT_DIR = "testdata/input"
const OUTPUT_DIR = "testdata/output"
const SINGLE_VERSION_OUTPUT_DIR = "testdata/output/single_version"
const LATEST_VERSION_OUTPUT_DIR = "testdata/output/latest_version"
const DEV_DASHBOARDS_INPUT_DIR = "../../../../devenv/dev-dashboards"
const DEV_DASHBOARDS_OUTPUT_DIR = "testdata/dev-dashboards-output"
func TestMigrate(t *testing.T) {
files, err := os.ReadDir(INPUT_DIR)
require.NoError(t, err)
// Use the same datasource provider as the frontend test to ensure consistency
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
// Reset the migration singleton and use the same datasource provider as the frontend test to ensure consistency
ResetForTesting()
Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
t.Run("minimum version check", func(t *testing.T) {
err := migration.Migrate(context.Background(), map[string]interface{}{
err := Migrate(context.Background(), map[string]interface{}{
"schemaVersion": schemaversion.MIN_VERSION - 1,
}, schemaversion.MIN_VERSION)
}, schemaversion.LATEST_VERSION)
var minVersionErr = schemaversion.NewMinimumVersionError(schemaversion.MIN_VERSION - 1)
require.ErrorAs(t, err, &minVersionErr)
})
runMigrationTests(t, schemaversion.LATEST_VERSION, LATEST_VERSION_OUTPUT_DIR)
}
func TestMigrateSingleVersion(t *testing.T) {
// Use the same datasource provider as the frontend test to ensure consistency
Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
runSingleVersionMigrationTests(t, SINGLE_VERSION_OUTPUT_DIR)
}
// runMigrationTests runs migration tests with a unified approach
func runMigrationTests(t *testing.T, targetVersion int, outputDir string) {
files, err := os.ReadDir(INPUT_DIR)
require.NoError(t, err)
for _, f := range files {
if f.IsDir() {
continue
@@ -48,47 +65,120 @@ func TestMigrate(t *testing.T) {
t.Fatalf("input filename must use v{N}.{name}.json format, got: %s", f.Name())
}
versionStr := strings.TrimPrefix(f.Name(), "v")
dotIndex := strings.Index(versionStr, ".")
if dotIndex == -1 {
t.Fatalf("input filename must use v{N}.{name}.json format, got: %s", f.Name())
}
filenameTargetVersion, err := strconv.Atoi(versionStr[:dotIndex])
require.NoError(t, err, "failed to parse version from filename: %s", f.Name())
// Load a fresh copy of the dashboard for this test (ensures no object sharing)
inputDash := loadDashboard(t, filepath.Join(INPUT_DIR, f.Name()))
inputVersion := getSchemaVersion(t, inputDash)
t.Run("input check "+f.Name(), func(t *testing.T) {
// use input version as the target version to ensure there are no changes
require.NoError(t, migration.Migrate(context.Background(), inputDash, inputVersion), "input check migration failed")
outBytes, err := json.MarshalIndent(inputDash, "", " ")
require.NoError(t, err, "failed to marshal migrated dashboard")
// We can ignore gosec G304 here since it's a test
// nolint:gosec
expectedDash, err := os.ReadFile(filepath.Join(INPUT_DIR, f.Name()))
require.NoError(t, err, "failed to read expected output file")
require.JSONEq(t, string(expectedDash), string(outBytes), "%s input check did not match", f.Name())
})
// Validate naming convention: filename version should be the tested version, schemaVersion should be target - 1
expectedSchemaVersion := filenameTargetVersion - 1
require.Equal(t, expectedSchemaVersion, inputVersion,
"naming convention violation for %s: filename suggests target v%d, but schemaVersion is %d (should be %d)",
f.Name(), filenameTargetVersion, inputVersion, expectedSchemaVersion)
testName := fmt.Sprintf("%s v%d to v%d", f.Name(), inputVersion, schemaversion.LATEST_VERSION)
testName := fmt.Sprintf("%s v%d to v%d", f.Name(), inputVersion, targetVersion)
t.Run(testName, func(t *testing.T) {
testMigration(t, inputDash, f.Name(), schemaversion.LATEST_VERSION)
testMigrationUnified(t, inputDash, f.Name(), inputVersion, targetVersion, outputDir)
})
}
}
func testMigration(t *testing.T, dash map[string]interface{}, inputFileName string, targetVersion int) {
t.Helper()
require.NoError(t, migration.Migrate(context.Background(), dash, targetVersion), "%d migration failed", targetVersion)
// runSingleVersionMigrationTests runs single version migration tests
func runSingleVersionMigrationTests(t *testing.T, outputDir string) {
files, err := os.ReadDir(INPUT_DIR)
require.NoError(t, err)
outPath := filepath.Join(OUTPUT_DIR, inputFileName)
for _, f := range files {
if f.IsDir() {
continue
}
// Validate filename format
if !strings.HasPrefix(f.Name(), "v") || !strings.HasSuffix(f.Name(), ".json") {
t.Fatalf("input filename must use v{N}.{name}.json format, got: %s", f.Name())
}
// Extract version from filename (e.g., v16.grid_layout_upgrade.json -> 16)
versionStr := strings.TrimPrefix(f.Name(), "v")
dotIndex := strings.Index(versionStr, ".")
if dotIndex == -1 {
t.Fatalf("input filename must use v{N}.{name}.json format, got: %s", f.Name())
}
targetVersion, err := strconv.Atoi(versionStr[:dotIndex])
require.NoError(t, err, "failed to parse version from filename: %s", f.Name())
// Skip if target version exceeds latest version
if targetVersion > schemaversion.LATEST_VERSION {
t.Skipf("skipping %s: target version %d exceeds latest version %d", f.Name(), targetVersion, schemaversion.LATEST_VERSION)
}
// Load a fresh copy of the dashboard for this test (ensures no object sharing)
inputDash := loadDashboard(t, filepath.Join(INPUT_DIR, f.Name()))
inputVersion := getSchemaVersion(t, inputDash)
// Validate naming convention: filename version should be target version, schemaVersion should be target - 1
expectedSchemaVersion := targetVersion - 1
require.Equal(t, expectedSchemaVersion, inputVersion,
"naming convention violation for %s: filename suggests target v%d, but schemaVersion is %d (should be %d)",
f.Name(), targetVersion, inputVersion, expectedSchemaVersion)
testName := fmt.Sprintf("%s v%d to v%d", f.Name(), inputVersion, targetVersion)
t.Run(testName, func(t *testing.T) {
testMigrationUnified(t, inputDash, f.Name(), inputVersion, targetVersion, outputDir)
})
}
}
// testMigrationUnified is the unified test function that handles both single and full migrations
func testMigrationUnified(t *testing.T, dash map[string]interface{}, inputFileName string, inputVersion, targetVersion int, outputDir string) {
t.Helper()
// 1. Verify input version matches filename
actualInputVersion := getSchemaVersion(t, dash)
require.Equal(t, inputVersion, actualInputVersion, "input version mismatch for %s", inputFileName)
// 2. Run migration to target version
require.NoError(t, Migrate(context.Background(), dash, targetVersion), "migration from v%d to v%d failed", inputVersion, targetVersion)
// 3. Verify final schema version
finalVersion := getSchemaVersion(t, dash)
require.Equal(t, targetVersion, finalVersion, "dashboard not migrated to target version %d", targetVersion)
// 4. Generate output filename with target version suffix
outputFileName := strings.TrimSuffix(inputFileName, ".json") + fmt.Sprintf(".v%d.json", targetVersion)
outPath := filepath.Join(outputDir, outputFileName)
// 5. Marshal the migrated dashboard
outBytes, err := json.MarshalIndent(dash, "", " ")
require.NoError(t, err, "failed to marshal migrated dashboard")
// 6. Check if output file already exists
if _, err := os.Stat(outPath); os.IsNotExist(err) {
// 7a. If no existing file, create a new one (ensure directory exists first)
outDir := filepath.Dir(outPath)
err = os.MkdirAll(outDir, 0750)
require.NoError(t, err, "failed to create output directory %s", outDir)
err = os.WriteFile(outPath, outBytes, 0644)
require.NoError(t, err, "failed to write new output file", outPath)
require.NoError(t, err, "failed to write new output file %s", outPath)
return
}
// 7b. If existing file exists, compare them and fail if different
// We can ignore gosec G304 here since it's a test
// nolint:gosec
existingBytes, err := os.ReadFile(outPath)
require.NoError(t, err, "failed to read existing output file")
require.JSONEq(t, string(existingBytes), string(outBytes), "%s did not match", outPath)
require.NoError(t, err, "failed to read existing output file %s", outPath)
require.JSONEq(t, string(existingBytes), string(outBytes), "output file %s did not match expected result", outPath)
}
func getSchemaVersion(t *testing.T, dash map[string]interface{}) int {
@@ -122,11 +212,11 @@ func loadDashboard(t *testing.T, path string) map[string]interface{} {
// TestSchemaMigrationMetrics tests that schema migration metrics are recorded correctly
func TestSchemaMigrationMetrics(t *testing.T) {
// Initialize migration with test providers
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
// Create a test registry for metrics
registry := prometheus.NewRegistry()
migration.RegisterMetrics(registry)
RegisterMetrics(registry)
tests := []struct {
name string
@@ -192,7 +282,7 @@ func TestSchemaMigrationMetrics(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Execute migration
err := migration.Migrate(context.Background(), tt.dashboard, tt.targetVersion)
err := Migrate(context.Background(), tt.dashboard, tt.targetVersion)
// Check error expectation
if tt.expectSuccess {
@@ -206,7 +296,7 @@ func TestSchemaMigrationMetrics(t *testing.T) {
// TestSchemaMigrationLogging tests that schema migration logging works correctly
func TestSchemaMigrationLogging(t *testing.T) {
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig))
tests := []struct {
name string
@@ -262,7 +352,7 @@ func TestSchemaMigrationLogging(t *testing.T) {
// and check that the migration behaves correctly (logs are called internally)
// Execute migration
err := migration.Migrate(context.Background(), tt.dashboard, tt.targetVersion)
err := Migrate(context.Background(), tt.dashboard, tt.targetVersion)
// Check error expectation
if tt.expectSuccess {
@@ -286,8 +376,6 @@ func TestSchemaMigrationLogging(t *testing.T) {
// TestLogMessageStructure tests that log messages contain expected structured fields
func TestLogMessageStructure(t *testing.T) {
migration.Initialize(migrationtestutil.GetTestDataSourceProvider())
t.Run("log messages include all required fields", func(t *testing.T) {
// Test that migration functions execute successfully, ensuring log code paths are hit
dashboard := map[string]interface{}{
@@ -296,7 +384,7 @@ func TestLogMessageStructure(t *testing.T) {
}
// Successful migration - should trigger debug log
err := migration.Migrate(context.Background(), dashboard, schemaversion.LATEST_VERSION)
err := Migrate(context.Background(), dashboard, schemaversion.LATEST_VERSION)
require.NoError(t, err, "migration should succeed")
// Failed migration - should trigger error log
@@ -304,7 +392,7 @@ func TestLogMessageStructure(t *testing.T) {
"schemaVersion": schemaversion.MIN_VERSION - 1,
"title": "old dashboard",
}
err = migration.Migrate(context.Background(), oldDashboard, schemaversion.LATEST_VERSION)
err = Migrate(context.Background(), oldDashboard, schemaversion.LATEST_VERSION)
require.Error(t, err, "migration should fail")
// Both cases above execute the logging code in reportMigrationMetrics
@@ -320,3 +408,34 @@ func TestLogMessageStructure(t *testing.T) {
t.Log("✓ Success logging uses Debug level, failure logging uses Error level")
})
}
func TestMigrateDevDashboards(t *testing.T) {
// Reset the migration singleton and use the dev dashboard datasource provider
// to match the frontend devDashboardDataSources configuration
ResetForTesting()
Initialize(migrationtestutil.NewDataSourceProvider(migrationtestutil.DevDashboardConfig))
runDevDashboardMigrationTests(t, schemaversion.LATEST_VERSION, DEV_DASHBOARDS_OUTPUT_DIR)
}
// runDevDashboardMigrationTests runs migration tests for dev dashboards with a unified approach (same as runMigrationTests)
func runDevDashboardMigrationTests(t *testing.T, targetVersion int, outputDir string) {
// Find all JSON files in the dev-dashboards directory
jsonFiles, err := migrationtestutil.FindJSONFiles(DEV_DASHBOARDS_INPUT_DIR)
require.NoError(t, err, "failed to find JSON files in dev-dashboards directory")
t.Logf("Found %d JSON files in dev-dashboards", len(jsonFiles))
for _, jsonFile := range jsonFiles {
relativeOutputPath := migrationtestutil.GetRelativeOutputPath(jsonFile, DEV_DASHBOARDS_INPUT_DIR)
// Load a fresh copy of the dashboard for this test (ensures no object sharing)
inputDash := loadDashboard(t, jsonFile)
inputVersion := getSchemaVersion(t, inputDash)
testName := fmt.Sprintf("%s v%d to v%d", relativeOutputPath, inputVersion, targetVersion)
t.Run(testName, func(t *testing.T) {
testMigrationUnified(t, inputDash, relativeOutputPath, inputVersion, targetVersion, outputDir)
})
}
}
@@ -34,51 +34,29 @@ func GetDefaultDSInstanceSettings(datasources []DataSourceInfo) *DataSourceInfo
return nil
}
// GetInstanceSettings looks up a datasource by name or uid reference
func GetInstanceSettings(nameOrRef interface{}, datasources []DataSourceInfo) *DataSourceInfo {
if nameOrRef == nil || nameOrRef == "default" {
return GetDefaultDSInstanceSettings(datasources)
}
// Check if it's a reference object
if ref, ok := nameOrRef.(map[string]interface{}); ok {
if _, hasUID := ref["uid"]; !hasUID {
// Reference object without UID should return default
return GetDefaultDSInstanceSettings(datasources)
}
// It's a reference object with UID, search for matching UID
for _, ds := range datasources {
if uid, hasUID := ref["uid"]; hasUID && uid == ds.UID {
return &DataSourceInfo{
UID: ds.UID,
Type: ds.Type,
Name: ds.Name,
APIVersion: ds.APIVersion,
}
}
}
// Unknown UID-only reference should return nil (preserve it)
return nil
}
// Check if it's a string
str, ok := nameOrRef.(string)
// isDataSourceRef checks if the object is a valid DataSourceRef (has uid or type)
// Matches the frontend isDataSourceRef function in datasource.ts
func isDataSourceRef(ref interface{}) bool {
dsRef, ok := ref.(map[string]interface{})
if !ok {
return GetDefaultDSInstanceSettings(datasources)
return false
}
// Search for matching name or UID
for _, ds := range datasources {
if str == ds.Name || str == ds.UID {
return &DataSourceInfo{
UID: ds.UID,
Type: ds.Type,
Name: ds.Name,
APIVersion: ds.APIVersion,
}
hasUID := false
if uid, exists := dsRef["uid"]; exists {
if uidStr, ok := uid.(string); ok && uidStr != "" {
hasUID = true
}
}
return nil
hasType := false
if typ, exists := dsRef["type"]; exists {
if typStr, ok := typ.(string); ok && typStr != "" {
hasType = true
}
}
return hasUID || hasType
}
// MigrateDatasourceNameToRef converts a datasource name/uid string to a reference object
@@ -91,26 +69,42 @@ func MigrateDatasourceNameToRef(nameOrRef interface{}, options map[string]bool,
return nil
}
if dsRef, ok := nameOrRef.(map[string]interface{}); ok {
if _, hasUID := dsRef["uid"]; hasUID {
return dsRef
// Frontend: if (isDataSourceRef(nameOrRef)) { return nameOrRef; }
if isDataSourceRef(nameOrRef) {
return nameOrRef.(map[string]interface{})
}
// Look up datasource by name/UID
if nameOrRef == nil || nameOrRef == "default" {
ds := GetDefaultDSInstanceSettings(datasources)
if ds != nil {
return GetDataSourceRef(ds)
}
}
ds := GetInstanceSettings(nameOrRef, datasources)
if ds != nil {
return GetDataSourceRef(ds)
}
// Handle string cases (including empty strings)
if dsName, ok := nameOrRef.(string); ok {
if dsName == "" {
// Empty string should return empty object (frontend behavior)
// Check if it's a string name/UID
if str, ok := nameOrRef.(string); ok {
// Handle empty string case
if str == "" {
// Empty string should return {} (frontend behavior)
return map[string]interface{}{}
}
// Search for matching datasource
for _, ds := range datasources {
if str == ds.Name || str == ds.UID {
return GetDataSourceRef(&DataSourceInfo{
UID: ds.UID,
Type: ds.Type,
Name: ds.Name,
APIVersion: ds.APIVersion,
})
}
}
// Unknown datasource name should be preserved as UID-only reference
return map[string]interface{}{
"uid": dsName,
"uid": str,
}
}
@@ -123,122 +123,6 @@ func TestGetDefaultDSInstanceSettings(t *testing.T) {
}
}
func TestGetInstanceSettings(t *testing.T) {
datasources := []schemaversion.DataSourceInfo{
{UID: "default-ds-uid", Type: "prometheus", Name: "Default Test Datasource Name", Default: true, APIVersion: "v1"},
{UID: "existing-target-uid", Type: "elasticsearch", Name: "Existing Target Name", Default: false, APIVersion: "v2"},
{UID: "existing-ref-uid", Type: "prometheus", Name: "Existing Ref Name", Default: false, APIVersion: "v1"},
}
tests := []struct {
name string
nameOrRef interface{}
expected *schemaversion.DataSourceInfo
}{
{
name: "nil should return default",
nameOrRef: nil,
expected: &schemaversion.DataSourceInfo{
UID: "default-ds-uid",
Type: "prometheus",
Name: "Default Test Datasource Name",
APIVersion: "v1",
},
},
{
name: "default string should return default",
nameOrRef: "default",
expected: &schemaversion.DataSourceInfo{
UID: "default-ds-uid",
Type: "prometheus",
Name: "Default Test Datasource Name",
APIVersion: "v1",
},
},
{
name: "lookup by UID",
nameOrRef: "existing-target-uid",
expected: &schemaversion.DataSourceInfo{
UID: "existing-target-uid",
Type: "elasticsearch",
Name: "Existing Target Name",
APIVersion: "v2",
},
},
{
name: "lookup by name",
nameOrRef: "Existing Target Name",
expected: &schemaversion.DataSourceInfo{
UID: "existing-target-uid",
Type: "elasticsearch",
Name: "Existing Target Name",
APIVersion: "v2",
},
},
{
name: "lookup by UID without apiVersion",
nameOrRef: "existing-ref-uid",
expected: &schemaversion.DataSourceInfo{
UID: "existing-ref-uid",
Type: "prometheus",
Name: "Existing Ref Name",
APIVersion: "v1",
},
},
{
name: "lookup by reference object with UID",
nameOrRef: map[string]interface{}{
"uid": "existing-target-uid",
},
expected: &schemaversion.DataSourceInfo{
UID: "existing-target-uid",
Type: "elasticsearch",
Name: "Existing Target Name",
APIVersion: "v2",
},
},
{
name: "lookup by reference object without UID",
nameOrRef: map[string]interface{}{
"type": "prometheus",
},
expected: &schemaversion.DataSourceInfo{
UID: "default-ds-uid",
Type: "prometheus",
Name: "Default Test Datasource Name",
APIVersion: "v1",
},
},
{
name: "unknown datasource should return nil",
nameOrRef: "unknown-ds",
expected: nil,
},
{
name: "empty string should return nil",
nameOrRef: "",
expected: nil,
},
{
name: "unsupported input type should return default",
nameOrRef: 123,
expected: &schemaversion.DataSourceInfo{
UID: "default-ds-uid",
Type: "prometheus",
Name: "Default Test Datasource Name",
APIVersion: "v1",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := schemaversion.GetInstanceSettings(tt.nameOrRef, datasources)
assert.Equal(t, tt.expected, result)
})
}
}
func TestMigrateDatasourceNameToRef(t *testing.T) {
datasources := []schemaversion.DataSourceInfo{
{UID: "default-ds-uid", Type: "prometheus", Name: "Default Test Datasource Name", Default: true, APIVersion: "v1"},
@@ -386,26 +270,20 @@ func TestMigrateDatasourceNameToRef(t *testing.T) {
t.Run("edge cases", func(t *testing.T) {
options := map[string]bool{"returnDefaultAsNull": false}
t.Run("reference without uid should lookup default", func(t *testing.T) {
t.Run("reference without uid should be preserved as-is", func(t *testing.T) {
nameOrRef := map[string]interface{}{
"type": "prometheus",
}
result := schemaversion.MigrateDatasourceNameToRef(nameOrRef, options, datasources)
expected := map[string]interface{}{
"uid": "default-ds-uid",
"type": "prometheus",
"apiVersion": "v1",
"type": "prometheus",
}
assert.Equal(t, expected, result)
})
t.Run("integer input should return default reference", func(t *testing.T) {
t.Run("integer input should return nil", func(t *testing.T) {
result := schemaversion.MigrateDatasourceNameToRef(123, options, datasources)
expected := map[string]interface{}{
"uid": "default-ds-uid",
"type": "prometheus",
"apiVersion": "v1",
}
expected := map[string]interface{}(nil)
assert.Equal(t, expected, result)
})
@@ -1,5 +1,10 @@
package schemaversion
import (
"strconv"
"strings"
)
// migration_utils.go contains shared utility functions used across multiple schema version migrations.
// GetStringValue safely extracts a string value from a map, returning empty string if not found or not a string
@@ -55,6 +60,14 @@ func ConvertToFloat(value interface{}) (float64, bool) {
return float64(v), true
case int32:
return float64(v), true
case string:
// Handle string values like "700px" - strip px suffix and parse
// This matches frontend behavior: parseInt(height.replace('px', ''), 10)
cleanStr := strings.TrimSuffix(v, "px")
if parsed, err := strconv.ParseFloat(cleanStr, 64); err == nil {
return parsed, true
}
return 0, false
default:
return 0, false
}
@@ -77,3 +90,12 @@ func ConvertToInt(value interface{}) (int, bool) {
return 0, false
}
}
// IsArray checks if a value is an array (slice)
func IsArray(value interface{}) bool {
if value == nil {
return false
}
_, ok := value.([]interface{})
return ok
}
@@ -97,12 +97,11 @@ func upgradeToGridLayout(dashboard map[string]interface{}) {
if showRows {
// add special row panel (lines 1041-1058 in TS)
rowPanel = map[string]interface{}{
"id": nextRowID,
"type": "row",
"title": GetStringValue(row, "title"),
"collapsed": isCollapsed,
"repeat": GetStringValue(row, "repeat"),
"panels": []interface{}{},
"id": nextRowID,
"type": "row",
"title": GetStringValue(row, "title"),
"repeat": GetStringValue(row, "repeat"),
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": yPos,
@@ -110,6 +109,12 @@ func upgradeToGridLayout(dashboard map[string]interface{}) {
"h": rowGridHeight,
},
}
// Set collapsed property only if the original row had a collapse property
// This matches the frontend behavior: rowPanel.collapsed = row.collapse
if _, hasCollapse := row["collapse"]; hasCollapse {
rowPanel["collapsed"] = isCollapsed
}
nextRowID++
yPos++
}
@@ -189,12 +189,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 5, // Next ID after row panel (4)
"type": "row",
"title": "",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 5, // Next ID after row panel (4)
"type": "row",
"title": "",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 1,
@@ -260,12 +259,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 4, // Next ID after max panel ID (3)
"type": "row",
"title": "Row",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 4, // Next ID after max panel ID (3)
"type": "row",
"title": "Row",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 0,
@@ -283,12 +281,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 5, // Next ID after row panel (4)
"type": "row",
"title": "",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 5, // Next ID after row panel (4)
"type": "row",
"title": "",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 9,
@@ -391,12 +388,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 8,
"type": "row",
"title": "",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 8,
"type": "row",
"title": "",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 1,
@@ -433,12 +429,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 9,
"type": "row",
"title": "",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 9,
"type": "row",
"title": "",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 10,
@@ -552,12 +547,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 5, // Next ID after row panel (4)
"type": "row",
"title": "",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 5, // Next ID after row panel (4)
"type": "row",
"title": "",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 1,
@@ -1230,12 +1224,11 @@ func TestV16(t *testing.T) {
},
// Repeated row panel (comes after its panels)
map[string]interface{}{
"id": 3,
"type": "row",
"title": "Row",
"collapsed": false,
"repeat": "server",
"panels": []interface{}{},
"id": 3,
"type": "row",
"title": "Row",
"repeat": "server",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 0,
@@ -1255,12 +1248,11 @@ func TestV16(t *testing.T) {
},
// Second row panel (comes after its panels)
map[string]interface{}{
"id": 4,
"type": "row",
"title": "",
"collapsed": false,
"repeat": "",
"panels": []interface{}{},
"id": 4,
"type": "row",
"title": "",
"repeat": "",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 9,
@@ -1316,12 +1308,11 @@ func TestV16(t *testing.T) {
},
},
map[string]interface{}{
"id": 3, // Next ID after max panel ID (2)
"type": "row",
"title": "Row1",
"collapsed": false,
"repeat": "server",
"panels": []interface{}{},
"id": 3, // Next ID after max panel ID (2)
"type": "row",
"title": "Row1",
"repeat": "server",
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 0,
@@ -1458,6 +1449,89 @@ func TestV16(t *testing.T) {
// rows field should be removed
},
},
{
name: "should parse string heights with px suffix during rows to panels migration",
input: map[string]interface{}{
"schemaVersion": 15,
"rows": []interface{}{
map[string]interface{}{
"collapse": false,
"height": "700px", // String height with px suffix
"showTitle": true,
"title": "Rollout progress",
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "barchart",
"span": 4,
"title": "Versions running",
"targets": []interface{}{
map[string]interface{}{
"expr": "up",
},
},
},
map[string]interface{}{
"id": 2,
"type": "barchart",
"span": 4,
"title": "Deployment progress",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 16,
"panels": []interface{}{
// First panel
map[string]interface{}{
"id": 1,
"type": "barchart",
"title": "Versions running",
"targets": []interface{}{
map[string]interface{}{
"expr": "up",
},
},
"gridPos": map[string]interface{}{
"x": 0,
"y": 1, // After row panel
"w": 8, // 4 span * 2 = 8 width
"h": 19, // 700px parsed correctly: ceil(700/38) = 19
},
},
// Second panel
map[string]interface{}{
"id": 2,
"type": "barchart",
"title": "Deployment progress",
"gridPos": map[string]interface{}{
"x": 8, // Next to first panel
"y": 1,
"w": 8,
"h": 19,
},
},
// Row panel (created because showTitle is true)
map[string]interface{}{
"id": 3, // Next available ID
"type": "row",
"title": "Rollout progress",
"collapsed": false, // Backend always sets this
"repeat": "", // Backend always sets this
"panels": []interface{}{},
"gridPos": map[string]interface{}{
"x": 0,
"y": 0,
"w": 24,
"h": 19, // Same height as calculated from "700px"
},
},
},
// rows field should be removed
},
},
}
runMigrationTests(t, tests, schemaversion.V16)
@@ -82,7 +82,8 @@ func migrateMinSpanToMaxPerRow(panel map[string]interface{}) {
max := gridColumnCount / minSpan
factors := getFactors(gridColumnCount)
// Find the first factor greater than max
// Find the first factor greater than max, then use the previous factor
// This matches the frontend logic: findIndex(factors, (o) => o > max) - 1
factorIndex := -1
for i, factor := range factors {
if float64(factor) > max {
@@ -91,16 +92,20 @@ func migrateMinSpanToMaxPerRow(panel map[string]interface{}) {
}
}
// Use the previous factor as maxPerRow
// Use the previous factor as maxPerRow (matching frontend logic exactly)
// The frontend code does: factors[findIndex(factors, (o) => o > max) - 1]
// When findIndex returns -1, this becomes factors[-2] which is undefined
// So we need to match this behavior
if factorIndex > 0 {
panel["maxPerRow"] = factors[factorIndex-1]
} else if factorIndex == 0 {
// If the first factor is already greater than max, use 1
panel["maxPerRow"] = 1
} else {
// If no factor is greater than max, use the largest factor
panel["maxPerRow"] = factors[len(factors)-1]
}
// If no factor is greater than max, don't set maxPerRow
// This matches frontend behavior when findIndex returns -1
// The frontend sets maxPerRow to undefined, which gets filtered out
// So we don't set it at all
// Remove the minSpan property
delete(panel, "minSpan")
@@ -144,7 +144,7 @@ func TestV17(t *testing.T) {
},
},
{
name: "panel with minSpan 1 gets converted to maxPerRow 24",
name: "panel with minSpan 1 gets minSpan removed without setting maxPerRow",
input: map[string]interface{}{
"title": "V17 MinSpan Migration Test",
"schemaVersion": 16,
@@ -162,10 +162,9 @@ func TestV17(t *testing.T) {
"schemaVersion": 17,
"panels": []interface{}{
map[string]interface{}{
"id": 6,
"type": "graph",
"title": "Tiny Panel",
"maxPerRow": 24,
"id": 6,
"type": "graph",
"title": "Tiny Panel",
},
},
},
@@ -47,10 +47,10 @@ import "context"
func V18(_ context.Context, dashboard map[string]interface{}) error {
dashboard["schemaVersion"] = 18
panels, ok := dashboard["panels"].([]interface{})
if !ok {
if !IsArray(dashboard["panels"]) {
return nil
}
panels := dashboard["panels"].([]interface{})
for _, p := range panels {
panel, ok := p.(map[string]interface{})
@@ -91,12 +91,15 @@ func migrateGaugePanelOptions(panel map[string]interface{}) {
options["valueOptions"] = valueOptions
if thresholds, ok := optionsGauge["thresholds"].([]interface{}); ok && len(thresholds) > 0 {
reversedThresholds := make([]interface{}, len(thresholds))
for i, threshold := range thresholds {
reversedThresholds[len(thresholds)-1-i] = threshold
if IsArray(optionsGauge["thresholds"]) {
thresholds := optionsGauge["thresholds"].([]interface{})
if len(thresholds) > 0 {
reversedThresholds := make([]interface{}, len(thresholds))
for i, threshold := range thresholds {
reversedThresholds[len(thresholds)-1-i] = threshold
}
options["thresholds"] = reversedThresholds
}
options["thresholds"] = reversedThresholds
}
// Copy any other properties from options-gauge to options
@@ -84,9 +84,14 @@ func upgradePanelLink(link map[string]interface{}) map[string]interface{} {
url := buildPanelLinkURL(link)
result := map[string]interface{}{
"url": url,
"title": GetStringValue(link, "title"),
"targetBlank": GetBoolValue(link, "targetBlank"),
"url": url,
"title": GetStringValue(link, "title"),
}
// Only add targetBlank if it's explicitly set to true (matches frontend behavior)
// Frontend filters out targetBlank: false as a default, so we shouldn't add it
if GetBoolValue(link, "targetBlank") {
result["targetBlank"] = true
}
return result
@@ -97,12 +102,12 @@ func buildPanelLinkURL(link map[string]interface{}) string {
var url string
// Check for existing URL first
if existingURL, ok := link["url"].(string); ok && existingURL != "" {
if existingURL := GetStringValue(link, "url"); existingURL != "" {
url = existingURL
} else if dashboard, ok := link["dashboard"].(string); ok && dashboard != "" {
} else if dashboard := GetStringValue(link, "dashboard"); dashboard != "" {
// Convert dashboard name to slugified URL
url = "dashboard/db/" + slugifyForURL(dashboard)
} else if dashUri, ok := link["dashUri"].(string); ok && dashUri != "" {
} else if dashUri := GetStringValue(link, "dashUri"); dashUri != "" {
url = "dashboard/" + dashUri
} else {
// Default fallback
@@ -120,7 +125,7 @@ func buildPanelLinkURL(link map[string]interface{}) string {
params = append(params, "$__all_variables")
}
if customParams, ok := link["params"].(string); ok && customParams != "" {
if customParams := GetStringValue(link, "params"); customParams != "" {
params = append(params, customParams)
}
@@ -33,9 +33,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "dashboard/db/my-dashboard",
"title": "Dashboard Link",
"targetBlank": false,
"url": "dashboard/db/my-dashboard",
"title": "Dashboard Link",
},
},
},
@@ -67,9 +66,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "dashboard/my-dashboard-uid",
"title": "DashUri Link",
"targetBlank": false,
"url": "dashboard/my-dashboard-uid",
"title": "DashUri Link",
},
},
},
@@ -102,9 +100,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "http://example.com?$__url_time_range",
"title": "KeepTime Link",
"targetBlank": false,
"url": "http://example.com?$__url_time_range",
"title": "KeepTime Link",
},
},
},
@@ -137,9 +134,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "http://example.com?$__all_variables",
"title": "IncludeVars Link",
"targetBlank": false,
"url": "http://example.com?$__all_variables",
"title": "IncludeVars Link",
},
},
},
@@ -172,9 +168,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "http://example.com?customParam=value",
"title": "Custom Params Link",
"targetBlank": false,
"url": "http://example.com?customParam=value",
"title": "Custom Params Link",
},
},
},
@@ -229,9 +224,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "http://example.com",
"title": "Existing URL Link",
"targetBlank": false,
"url": "http://example.com",
"title": "Existing URL Link",
},
},
},
@@ -245,9 +239,8 @@ func TestV19(t *testing.T) {
"id": 1,
"links": []interface{}{
map[string]interface{}{
"url": "http://example.com",
"title": "Existing URL Link",
"targetBlank": false,
"url": "http://example.com",
"title": "Existing URL Link",
},
},
},
@@ -3,8 +3,6 @@ package schemaversion
import (
"context"
"regexp"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
)
// V20 migrates legacy variable syntax in data links and field options.
@@ -92,7 +90,7 @@ func V20(_ context.Context, dashboard map[string]interface{}) error {
// updateDataLinksVariableSyntax updates variable syntax in panel data links
func updateDataLinksVariableSyntax(options map[string]interface{}) {
dataLinks, ok := options["dataLinks"].([]interface{})
if !ok || !utils.IsArray(dataLinks) {
if !ok || !IsArray(dataLinks) {
return
}
@@ -124,7 +122,7 @@ func updateFieldOptionsVariableSyntax(options map[string]interface{}) {
// Update field option links
links, ok := defaults["links"].([]interface{})
if !ok || !utils.IsArray(links) {
if !ok || !IsArray(links) {
return
}
@@ -3,8 +3,6 @@ package schemaversion
import (
"context"
"strings"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
)
// V21 migrates data links to replace __series.labels with __field.labels.
@@ -82,7 +80,7 @@ func V21(_ context.Context, dashboard map[string]interface{}) error {
func updateDataLinks(options map[string]interface{}) {
dataLinks, ok := options["dataLinks"].([]interface{})
if !ok || !utils.IsArray(dataLinks) {
if !ok || !IsArray(dataLinks) {
return
}
@@ -2,8 +2,6 @@ package schemaversion
import (
"context"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/utils"
)
// V23 migrates multi variables to ensure their current property is aligned with their multi property.
@@ -89,6 +87,7 @@ func isEmptyObject(value interface{}) bool {
}
// alignCurrentWithMulti aligns the current property with the multi property
// This matches the frontend's alignCurrentWithMulti function behavior
func alignCurrentWithMulti(current map[string]interface{}, multi bool) map[string]interface{} {
if current == nil {
return current
@@ -100,38 +99,53 @@ func alignCurrentWithMulti(current map[string]interface{}, multi bool) map[strin
}
if multi {
// Convert single values to arrays
if value, ok := result["value"]; ok {
if !utils.IsArray(value) {
result["value"] = []interface{}{value}
}
}
if text, ok := result["text"]; ok {
if !utils.IsArray(text) {
result["text"] = []interface{}{text}
}
}
convertToArrays(result)
} else {
// Convert arrays to single values
if value, ok := result["value"]; ok {
if utils.IsArray(value) {
if arr, ok := value.([]interface{}); ok && len(arr) > 0 {
result["value"] = arr[0]
} else {
result["value"] = ""
}
}
}
if text, ok := result["text"]; ok {
if utils.IsArray(text) {
if arr, ok := text.([]interface{}); ok && len(arr) > 0 {
result["text"] = arr[0]
} else {
result["text"] = ""
}
}
}
convertToSingleValues(result)
}
return result
}
// convertToArrays converts single values to arrays (match frontend behavior)
// Frontend only converts when current.value is NOT an array
func convertToArrays(result map[string]interface{}) {
value, hasValue := result["value"]
if !hasValue || IsArray(value) {
return
}
// Convert value to array
result["value"] = []interface{}{value}
// Only convert text to array when we're converting value
if text, ok := result["text"]; ok && !IsArray(text) {
result["text"] = []interface{}{text}
}
}
// convertToSingleValues converts arrays to single values (both value and text must be single values)
func convertToSingleValues(result map[string]interface{}) {
convertArrayToSingle(result, "value")
convertArrayToSingle(result, "text")
}
// convertArrayToSingle converts an array field to a single value
func convertArrayToSingle(result map[string]interface{}, key string) {
value, ok := result[key]
if !ok || !IsArray(value) {
return
}
arr, ok := value.([]interface{})
if !ok {
result[key] = ""
return
}
if len(arr) > 0 {
result[key] = arr[0]
} else {
result[key] = ""
}
}
@@ -1,229 +1,162 @@
package schemaversion_test
package schemaversion
import (
"context"
"testing"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
)
func TestV23(t *testing.T) {
tests := []migrationTestCase{
func TestV23TemplateVariableMigration(t *testing.T) {
tests := []struct {
name string
input map[string]interface{}
expected map[string]interface{}
description string
}{
{
name: "multi variable with single value gets converted to array",
name: "align_text_with_multi_for_multi_variables",
input: map[string]interface{}{
"title": "V23 Multi Variable Single Value Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "multi_single_value",
"multi": true,
"current": map[string]interface{}{"value": "A", "text": "A", "selected": true},
"name": "multiVar",
"multi": true,
"current": map[string]interface{}{
"text": "All",
"value": "All",
},
},
},
},
},
expected: map[string]interface{}{
"title": "V23 Multi Variable Single Value Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "multi_single_value",
"multi": true,
"current": map[string]interface{}{"value": []interface{}{"A"}, "text": []interface{}{"A"}, "selected": true},
"name": "multiVar",
"multi": true,
"current": map[string]interface{}{
"text": []interface{}{"All"},
"value": []interface{}{"All"},
},
},
},
},
},
description: "For multi variables, both text and value should be converted to arrays to match frontend alignCurrentWithMulti behavior",
},
{
name: "multi variable with array value stays as array",
name: "preserve_text_as_string_when_value_already_array",
input: map[string]interface{}{
"title": "V23 Multi Variable Array Value Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "multi_array_value",
"multi": true,
"current": map[string]interface{}{"value": []interface{}{"B", "C"}, "text": []interface{}{"B", "C"}, "selected": true},
"name": "multiVar",
"multi": true,
"current": map[string]interface{}{
"text": "All",
"value": []interface{}{"All"},
},
},
},
},
},
expected: map[string]interface{}{
"title": "V23 Multi Variable Array Value Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "multi_array_value",
"multi": true,
"current": map[string]interface{}{"value": []interface{}{"B", "C"}, "text": []interface{}{"B", "C"}, "selected": true},
},
},
},
},
},
{
name: "non-multi variable with array value gets converted to single value",
input: map[string]interface{}{
"title": "V23 Non-Multi Variable Array Value Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "non_multi_array_value",
"multi": false,
"current": map[string]interface{}{"value": []interface{}{"D"}, "text": []interface{}{"D"}, "selected": true},
},
},
},
},
expected: map[string]interface{}{
"title": "V23 Non-Multi Variable Array Value Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "non_multi_array_value",
"multi": false,
"current": map[string]interface{}{"value": "D", "text": "D", "selected": true},
},
},
},
},
},
{
name: "non-multi variable with single value stays as single value",
input: map[string]interface{}{
"title": "V23 Non-Multi Variable Single Value Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "non_multi_single_value",
"multi": false,
"current": map[string]interface{}{"value": "E", "text": "E", "selected": true},
},
},
},
},
expected: map[string]interface{}{
"title": "V23 Non-Multi Variable Single Value Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "non_multi_single_value",
"multi": false,
"current": map[string]interface{}{"value": "E", "text": "E", "selected": true},
},
},
},
},
},
{
name: "variable without multi property is unchanged",
input: map[string]interface{}{
"title": "V23 No Multi Property Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "no_multi_property",
"current": map[string]interface{}{"value": "F", "text": "F", "selected": true},
},
},
},
},
expected: map[string]interface{}{
"title": "V23 No Multi Property Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "no_multi_property",
"current": map[string]interface{}{"value": "F", "text": "F", "selected": true},
},
},
},
},
},
{
name: "variable with empty current is unchanged",
input: map[string]interface{}{
"title": "V23 Empty Current Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "empty_current",
"multi": true,
"current": map[string]interface{}{},
},
},
},
},
expected: map[string]interface{}{
"title": "V23 Empty Current Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "empty_current",
"multi": true,
"current": map[string]interface{}{},
},
},
},
},
},
{
name: "variable with nil current is unchanged",
input: map[string]interface{}{
"title": "V23 Nil Current Test",
"schemaVersion": 22,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "nil_current",
"multi": true,
"current": nil,
},
},
},
},
expected: map[string]interface{}{
"title": "V23 Nil Current Test",
"schemaVersion": 23,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "nil_current",
"multi": true,
"current": nil,
"name": "multiVar",
"multi": true,
"current": map[string]interface{}{
"text": "All",
"value": []interface{}{"All"},
},
},
},
},
},
description: "When value is already an array, text should remain as string to match frontend behavior",
},
}
runMigrationTests(t, tests, schemaversion.V23)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dashboard := map[string]interface{}{
"schemaVersion": 22,
}
// Copy templating from input
if templating, ok := tt.input["templating"]; ok {
dashboard["templating"] = templating
}
err := V23(context.Background(), dashboard)
if err != nil {
t.Fatalf("V23 migration failed: %v", err)
}
if dashboard["schemaVersion"] != 23 {
t.Errorf("Expected schemaVersion to be 23, got %v", dashboard["schemaVersion"])
}
// Verify templating structure
templating, ok := dashboard["templating"].(map[string]interface{})
if !ok {
t.Fatalf("Expected templating to be a map")
}
list, ok := templating["list"].([]interface{})
if !ok || len(list) == 0 {
t.Fatalf("Expected templating.list to be a non-empty array")
}
variable, ok := list[0].(map[string]interface{})
if !ok {
t.Fatalf("Expected variable to be a map")
}
// Check current property alignment
expectedTemplating := tt.expected["templating"].(map[string]interface{})
expectedList := expectedTemplating["list"].([]interface{})
expectedVariable := expectedList[0].(map[string]interface{})
actualCurrent := variable["current"].(map[string]interface{})
expectedCurrent := expectedVariable["current"].(map[string]interface{})
if !compareValues(actualCurrent["text"], expectedCurrent["text"]) {
t.Errorf("Text alignment failed. Expected: %v, Got: %v", expectedCurrent["text"], actualCurrent["text"])
}
if !compareValues(actualCurrent["value"], expectedCurrent["value"]) {
t.Errorf("Value alignment failed. Expected: %v, Got: %v", expectedCurrent["value"], actualCurrent["value"])
}
t.Logf("✓ %s: %s", tt.name, tt.description)
})
}
}
// Helper function to compare values
func compareValues(actual, expected interface{}) bool {
if actual == nil && expected == nil {
return true
}
if actual == nil || expected == nil {
return false
}
actualSlice, actualOk := actual.([]interface{})
expectedSlice, expectedOk := expected.([]interface{})
if actualOk && expectedOk {
if len(actualSlice) != len(expectedSlice) {
return false
}
for i, expectedValue := range expectedSlice {
if actualSlice[i] != expectedValue {
return false
}
}
return true
}
return actual == expected
}
@@ -236,21 +236,19 @@ func tablePanelChangedHandler(panel map[string]interface{}) error {
overrides = []interface{}{}
}
panel["transformations"] = transformations
// Only add transformations if they're not empty - frontend omits empty arrays
if len(transformations) > 0 {
panel["transformations"] = transformations
}
panel["fieldConfig"] = map[string]interface{}{
"defaults": defaults,
"overrides": overrides,
}
// Add default table panel options to match frontend behavior
// Add minimal table panel options to match frontend behavior
// Frontend doesn't add default footer options, so we don't either
panel["options"] = map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
}
@@ -259,6 +257,9 @@ func tablePanelChangedHandler(panel map[string]interface{}) error {
delete(panel, "transform")
delete(panel, "columns")
// Remove legend property - frontend table panel migration doesn't preserve it
delete(panel, "legend")
return nil
}
@@ -394,12 +395,7 @@ func migrateTableStyleToOverride(style map[string]interface{}) map[string]interf
}
// Add decimals
if decimals, ok := style["decimals"].(float64); ok {
properties = append(properties, map[string]interface{}{
"id": "decimals",
"value": int(decimals),
})
} else if decimals, ok := style["decimals"].(int); ok {
if decimals := GetIntValue(style, "decimals", -1); decimals != -1 {
properties = append(properties, map[string]interface{}{
"id": "decimals",
"value": decimals,
@@ -456,9 +452,11 @@ func migrateTableStyleToOverride(style map[string]interface{}) map[string]interf
// Handle alignment
if align, ok := style["align"].(string); ok && align != "" {
alignValue := align
var alignValue interface{}
if align == "auto" {
alignValue = ""
alignValue = nil // Frontend sets to null and filters it out
} else {
alignValue = align
}
properties = append(properties, map[string]interface{}{
"id": "custom.align",
@@ -514,7 +512,7 @@ func migrateDefaults(prevDefaults map[string]interface{}) map[string]interface{}
defaults["thresholds"] = map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"color": "green"},
map[string]interface{}{"color": "green", "value": (*float64)(nil)},
map[string]interface{}{"color": "red", "value": 80},
},
}
@@ -524,22 +522,24 @@ func migrateDefaults(prevDefaults map[string]interface{}) map[string]interface{}
return defaults
}
if unit, ok := prevDefaults["unit"].(string); ok && unit != "" {
if unit := GetStringValue(prevDefaults, "unit"); unit != "" {
defaults["unit"] = unit
}
if decimals, ok := prevDefaults["decimals"].(float64); ok {
defaults["decimals"] = int(decimals)
if decimals := GetIntValue(prevDefaults, "decimals", -1); decimals != -1 {
defaults["decimals"] = decimals
}
if alias, ok := prevDefaults["alias"].(string); ok && alias != "" {
if alias, ok := prevDefaults["alias"].(string); ok {
defaults["displayName"] = alias
}
if align, ok := prevDefaults["align"].(string); ok && align != "" {
alignValue := align
var alignValue interface{}
if align == "auto" {
alignValue = ""
alignValue = nil // Frontend sets to null and filters it out
} else {
alignValue = align
}
defaults["custom"].(map[string]interface{})["align"] = alignValue
}
@@ -576,19 +576,11 @@ func generateThresholds(thresholds []interface{}, colors []interface{}) []interf
steps = append(steps, map[string]interface{}{
"color": baseColor,
"value": nil,
"value": (*float64)(nil),
})
// Add threshold steps
for i, threshold := range thresholds {
var color interface{}
// Use colors[i+1] for the i-th threshold (colors[0] was used for base step)
if i+1 < len(colors) && colors[i+1] != nil {
color = colors[i+1]
} else {
color = "red"
}
var value float64
switch v := threshold.(type) {
case string:
@@ -601,10 +593,17 @@ func generateThresholds(thresholds []interface{}, colors []interface{}) []interf
value = float64(v)
}
steps = append(steps, map[string]interface{}{
"color": color,
step := map[string]interface{}{
"value": value,
})
}
// Only add color if there's a corresponding color in the colors array
// This matches the frontend behavior where colors[idx] might be undefined
if i+1 < len(colors) && colors[i+1] != nil {
step["color"] = colors[i+1]
}
steps = append(steps, step)
}
return steps
@@ -1,851 +1,85 @@
package schemaversion_test
package schemaversion
import (
"context"
"testing"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
)
const (
// The pluginVersion to set after simulating auto-migrate for angular panels
pluginVersionForAutoMigrate = "12.1.0"
)
func TestV24(t *testing.T) {
tests := []migrationTestCase{
func TestV24TablePanelMigration(t *testing.T) {
tests := []struct {
name string
input map[string]interface{}
expected map[string]interface{}
description string
}{
{
name: "should migrate basic Angular table with defaults",
name: "preserve_empty_display_name",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
"type": "table",
"styles": []interface{}{
map[string]interface{}{
"id": 1,
"type": "table",
"title": "Basic Table",
"legend": true,
"styles": []interface{}{
map[string]interface{}{
"thresholds": []interface{}{"10", "20", "30"},
"colors": []interface{}{"red", "yellow", "green"},
"pattern": "/.*/",
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"alias": "",
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "table",
"title": "Basic Table",
"legend": true,
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"align": "auto",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"value": nil, "color": "red"},
map[string]interface{}{"value": float64(10), "color": "yellow"},
map[string]interface{}{"value": float64(20), "color": "green"},
map[string]interface{}{"value": float64(30), "color": "red"},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
"type": "table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"displayName": "",
},
},
},
description: "Empty displayName values should be preserved when migrating from empty alias in table panel styles",
},
{
name: "should migrate table with complex defaults and overrides",
name: "do_not_add_empty_transformations",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 2,
"type": "table",
"title": "Complex Table",
"styles": []interface{}{
// Default style
map[string]interface{}{
"pattern": "/.*/",
"unit": "bytes",
"decimals": float64(2),
"align": "center",
"colorMode": "cell",
"thresholds": []interface{}{"100", "500"},
"colors": []interface{}{"green", "yellow", "red"},
},
// Column-specific override with exact name
map[string]interface{}{
"pattern": "Status",
"alias": "Current Status",
"unit": "short",
"decimals": float64(0),
"colorMode": "value",
"align": "left",
},
// Column-specific override with regex pattern
map[string]interface{}{
"pattern": "/Error.*/",
"link": true,
"linkUrl": "http://example.com/errors",
"linkTooltip": "View error details",
"linkTargetBlank": true,
"colorMode": "row",
"colors": []interface{}{"red", "orange"},
},
// Date column
map[string]interface{}{
"pattern": "Time",
"type": "date",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"alias": "Timestamp",
},
// Hidden column
map[string]interface{}{
"pattern": "Hidden",
"type": "hidden",
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
"type": "table",
"title": "Test Table",
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 2,
"type": "table",
"title": "Complex Table",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "bytes",
"decimals": 2,
"custom": map[string]interface{}{
"align": "center",
"cellOptions": map[string]interface{}{
"type": "color-background",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"value": nil, "color": "green"},
map[string]interface{}{"value": float64(100), "color": "yellow"},
map[string]interface{}{"value": float64(500), "color": "red"},
},
},
},
"overrides": []interface{}{
map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byName",
"options": "Status",
},
"properties": []interface{}{
map[string]interface{}{"id": "displayName", "value": "Current Status"},
map[string]interface{}{"id": "unit", "value": "short"},
map[string]interface{}{"id": "decimals", "value": 0},
map[string]interface{}{"id": "custom.cellOptions", "value": map[string]interface{}{"type": "color-text"}},
map[string]interface{}{"id": "custom.align", "value": "left"},
},
},
map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byRegexp",
"options": "/Error.*/",
},
"properties": []interface{}{
map[string]interface{}{
"id": "links",
"value": []interface{}{
map[string]interface{}{
"title": "View error details",
"url": "http://example.com/errors",
"targetBlank": true,
},
},
},
map[string]interface{}{"id": "custom.cellOptions", "value": map[string]interface{}{"type": "color-background"}},
},
},
map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byName",
"options": "Time",
},
"properties": []interface{}{
map[string]interface{}{"id": "displayName", "value": "Timestamp"},
map[string]interface{}{"id": "unit", "value": "time: YYYY-MM-DD HH:mm:ss"},
},
},
map[string]interface{}{
"matcher": map[string]interface{}{
"id": "byName",
"options": "Hidden",
},
"properties": []interface{}{
map[string]interface{}{"id": "custom.hideFrom.viz", "value": true},
},
},
},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
},
},
{
name: "should migrate table with timeseries_aggregations transform",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 3,
"type": "table",
"title": "Table with Aggregations",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"unit": "percent",
"decimals": float64(1),
},
},
"transform": "timeseries_aggregations",
"columns": []interface{}{
map[string]interface{}{"value": "avg", "text": "Average"},
map[string]interface{}{"value": "max", "text": "Maximum"},
map[string]interface{}{"value": "min", "text": "Minimum"},
map[string]interface{}{"value": "total", "text": "Total"},
map[string]interface{}{"value": "current", "text": "Current"},
map[string]interface{}{"value": "count", "text": "Count"},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 3,
"type": "table",
"title": "Table with Aggregations",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "percent",
"decimals": 1,
"custom": map[string]interface{}{
"align": "auto",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"color": "green"},
map[string]interface{}{"color": "red", "value": 80},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{
map[string]interface{}{
"id": "reduce",
"options": map[string]interface{}{
"reducers": []interface{}{"mean", "max", "min", "sum", "lastNotNull", "count"},
"includeTimeField": false,
},
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
},
},
{
name: "should migrate table with timeseries_to_rows transform",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 4,
"type": "table",
"title": "Table with Rows Transform",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"unit": "short",
},
},
"transform": "timeseries_to_rows",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 4,
"type": "table",
"title": "Table with Rows Transform",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "short",
"custom": map[string]interface{}{
"align": "auto",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"color": "green"},
map[string]interface{}{"color": "red", "value": 80},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{
map[string]interface{}{
"id": "seriesToRows",
"options": map[string]interface{}{
"reducers": []interface{}{},
},
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
},
},
{
name: "should migrate table with timeseries_to_columns transform",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 5,
"type": "table",
"title": "Table with Columns Transform",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"unit": "bytes",
},
},
"transform": "timeseries_to_columns",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 5,
"type": "table",
"title": "Table with Columns Transform",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "bytes",
"custom": map[string]interface{}{
"align": "auto",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"color": "green"},
map[string]interface{}{"color": "red", "value": 80},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{
map[string]interface{}{
"id": "seriesToColumns",
"options": map[string]interface{}{
"reducers": []interface{}{},
},
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
},
},
{
name: "should migrate table with table merge transform",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 6,
"type": "table",
"title": "Table with Merge Transform",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"align": "auto",
},
},
"transform": "table",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 6,
"type": "table",
"title": "Table with Merge Transform",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"align": "",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"color": "green"},
map[string]interface{}{"color": "red", "value": 80},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{
map[string]interface{}{
"id": "merge",
"options": map[string]interface{}{
"reducers": []interface{}{},
},
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
},
},
{
name: "should migrate table with existing transformations",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 7,
"type": "table",
"title": "Table with Existing Transformations",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"unit": "short",
},
},
"transformations": []interface{}{
map[string]interface{}{
"id": "filterFieldsByName",
"options": map[string]interface{}{
"include": map[string]interface{}{
"names": []interface{}{"field1", "field2"},
},
},
},
},
"transform": "timeseries_to_rows",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 7,
"type": "table",
"title": "Table with Existing Transformations",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "short",
"custom": map[string]interface{}{
"align": "auto",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"color": "green"},
map[string]interface{}{"color": "red", "value": 80},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{
map[string]interface{}{
"id": "filterFieldsByName",
"options": map[string]interface{}{
"include": map[string]interface{}{
"names": []interface{}{"field1", "field2"},
},
},
},
map[string]interface{}{
"id": "seriesToRows",
"options": map[string]interface{}{
"reducers": []interface{}{},
},
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
},
},
{
name: "should not migrate angular table without styles",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 8,
"type": "table",
"title": "Table without styles",
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 8,
"type": "table",
"title": "Table without styles",
},
},
},
},
{
name: "should not migrate react table (table2)",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 9,
"type": "table",
"table": "table2",
"title": "React table",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"unit": "short",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 9,
"type": "table",
"table": "table2",
"title": "React table",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"unit": "short",
},
},
},
},
},
},
{
name: "should not migrate non-table panels",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 10,
"type": "graph",
"title": "Graph panel",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
map[string]interface{}{
"id": 11,
"type": "singlestat",
"title": "Singlestat panel",
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 10,
"type": "graph",
"title": "Graph panel",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
map[string]interface{}{
"id": 11,
"type": "singlestat",
"title": "Singlestat panel",
},
},
},
},
{
name: "should handle mixed numeric and string thresholds",
input: map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{
map[string]interface{}{
"id": 12,
"type": "table",
"title": "Mixed threshold types",
"styles": []interface{}{
map[string]interface{}{
"pattern": "/.*/",
"thresholds": []interface{}{10, "20", 30.5},
"colors": []interface{}{"green", "yellow", "orange", "red"},
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 24,
"panels": []interface{}{
map[string]interface{}{
"id": 12,
"type": "table",
"title": "Mixed threshold types",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"custom": map[string]interface{}{
"align": "auto",
"cellOptions": map[string]interface{}{
"type": "auto",
},
"footer": map[string]interface{}{
"reducers": []interface{}{},
},
"inspect": false,
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{"value": nil, "color": "green"},
map[string]interface{}{"value": float64(10), "color": "yellow"},
map[string]interface{}{"value": float64(20), "color": "orange"},
map[string]interface{}{"value": float64(30.5), "color": "red"},
},
},
},
"overrides": []interface{}{},
},
"options": map[string]interface{}{
"cellHeight": "sm",
"footer": map[string]interface{}{
"countRows": false,
"fields": "",
"reducer": []interface{}{"sum"},
"show": false,
},
"showHeader": true,
},
"transformations": []interface{}{},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"pluginVersion": pluginVersionForAutoMigrate,
},
},
"type": "table",
"title": "Test Table",
},
description: "V24 migration should not add empty transformations arrays to table panels",
},
}
runMigrationTests(t, tests, schemaversion.V24)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dashboard := map[string]interface{}{
"schemaVersion": 23,
"panels": []interface{}{tt.input},
}
err := V24(context.Background(), dashboard)
if err != nil {
t.Fatalf("V24 migration failed: %v", err)
}
if dashboard["schemaVersion"] != 24 {
t.Errorf("Expected schemaVersion to be 24, got %v", dashboard["schemaVersion"])
}
panels, ok := dashboard["panels"].([]interface{})
if !ok || len(panels) == 0 {
t.Fatalf("Expected panels array with at least one panel")
}
panel, ok := panels[0].(map[string]interface{})
if !ok {
t.Fatalf("Expected panel to be a map")
}
// Check that transformations array is not added if it wasn't in input
if _, hasTransformations := tt.input["transformations"]; !hasTransformations {
if _, exists := panel["transformations"]; exists {
t.Errorf("Empty transformations array should not be added")
}
}
t.Logf("✓ %s: %s", tt.name, tt.description)
})
}
}
@@ -161,9 +161,8 @@ func migrateConstantVariable(variable map[string]interface{}) {
variable["options"] = options
// Convert to textbox if hide is 0 (dontHide) or 1 (hideLabel)
if hide, ok := variable["hide"].(float64); ok {
if hide == 0 || hide == 1 {
variable["type"] = "textbox"
}
hide := GetIntValue(variable, "hide", -1)
if hide == 0 || hide == 1 {
variable["type"] = "textbox"
}
}
+295 -164
View File
@@ -88,17 +88,17 @@ func processPanels(panels []interface{}) error {
continue
}
// Migrate singlestat panels
if p["type"] == "singlestat" || p["type"] == "grafana-singlestat-panel" {
// Migrate singlestat panels (including those already auto-migrated to stat)
if p["type"] == "singlestat" || p["type"] == "grafana-singlestat-panel" ||
p["autoMigrateFrom"] == "singlestat" || p["autoMigrateFrom"] == "grafana-singlestat-panel" {
if err := migrateSinglestatPanel(p); err != nil {
return err
}
}
// Normalize existing stat panels to ensure they have current default options
if p["type"] == "stat" {
normalizeStatPanel(p)
}
// Note: Panel defaults (including options object) are already applied
// by applyPanelDefaults() in the main migration flow for ALL panels
// No need for stat-specific normalization
}
return nil
@@ -121,9 +121,12 @@ func migrateSinglestatPanel(panel map[string]interface{}) error {
// panel.changePlugin(gaugePanelPlugin)
// Store original type for migration context (only for stat/gauge migration)
// This matches the frontend behavior where autoMigrateFrom is set in PanelModel.restoreModel
// Set autoMigrateFrom to track the original type for proper migration logic
originalType := panel["type"].(string)
panel["autoMigrateFrom"] = panel["type"]
// Only set autoMigrateFrom if it doesn't already exist (preserve frontend defaults)
if _, exists := panel["autoMigrateFrom"]; !exists {
panel["autoMigrateFrom"] = originalType
}
panel["type"] = targetType
panel["pluginVersion"] = pluginVersionForAutoMigrate
@@ -133,39 +136,15 @@ func migrateSinglestatPanel(panel map[string]interface{}) error {
return nil
}
// normalizeStatPanel ensures existing stat panels have all current default options
func normalizeStatPanel(panel map[string]interface{}) {
if panel["options"] == nil {
panel["options"] = map[string]interface{}{}
}
options := panel["options"].(map[string]interface{})
// Apply missing default options that might not be present in older stat panels
if _, exists := options["percentChangeColorMode"]; !exists {
options["percentChangeColorMode"] = "standard"
}
// Ensure other critical defaults are present
if _, exists := options["justifyMode"]; !exists {
options["justifyMode"] = "auto"
}
if _, exists := options["textMode"]; !exists {
options["textMode"] = "auto"
}
if _, exists := options["wideLayout"]; !exists {
options["wideLayout"] = true
}
if _, exists := options["showPercentChange"]; !exists {
options["showPercentChange"] = false
}
}
// migrateSinglestatOptions handles the complete migration of singlestat panel options and field config
func migrateSinglestatOptions(panel map[string]interface{}, originalType string) {
// Preserve important panel-level properties that should not be removed
// These properties are preserved by the frontend's getSaveModel() method
var maxDataPoints interface{}
if mdp, exists := panel["maxDataPoints"]; exists {
maxDataPoints = mdp
}
// Initialize field config if not present
if panel["fieldConfig"] == nil {
panel["fieldConfig"] = map[string]interface{}{
@@ -178,7 +157,13 @@ func migrateSinglestatOptions(panel map[string]interface{}, originalType string)
defaults := fieldConfig["defaults"].(map[string]interface{})
// Migrate from angular singlestat configuration using appropriate strategy
if originalType == "grafana-singlestat-panel" {
// Use autoMigrateFrom if available, otherwise use originalType
migrationType := originalType
if autoMigrateFrom, exists := panel["autoMigrateFrom"].(string); exists {
migrationType = autoMigrateFrom
}
if migrationType == "grafana-singlestat-panel" {
migrateGrafanaSinglestatPanel(panel, defaults)
} else {
migratetSinglestat(panel, defaults)
@@ -187,106 +172,73 @@ func migrateSinglestatOptions(panel map[string]interface{}, originalType string)
// Apply shared migration logic
applySharedSinglestatMigration(defaults)
// Apply complete stat panel defaults (matches frontend getPanelOptionsWithDefaults)
// The frontend applies these defaults after migration via applyPluginOptionDefaults
applyCompleteStatPanelDefaults(panel)
// Create proper fieldConfig structure from defaults
createFieldConfigFromDefaults(panel, defaults)
// Restore preserved panel-level properties
if maxDataPoints != nil {
panel["maxDataPoints"] = maxDataPoints
}
// Clean up old angular properties after migration
cleanupAngularProperties(panel)
}
// getDefaultStatOptions returns the default options structure for stat panels
// This matches the frontend's stat panel defaultOptions exactly
func getDefaultStatOptions() map[string]interface{} {
// For now, return the explicit defaults until we integrate the centralized system
return map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"mean"},
"fields": "",
"values": false,
},
"orientation": "horizontal",
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
"reduceOptions": map[string]interface{}{
"calcs": []string{"lastNotNull"}, // Matches frontend: ReducerID.lastNotNull
"fields": "",
"values": false,
},
"orientation": "auto",
}
}
// migratetSinglestat handles explicit migration from 'singlestat' panels
// Based on explicit migration logic in DashboardMigrator.ts
// Based on frontend migrateFromAngularSinglestat function
func migratetSinglestat(panel map[string]interface{}, defaults map[string]interface{}) {
angularOpts := extractAngularOptions(panel)
// Explicit migration uses standard stat panel defaults
options := getDefaultStatOptions()
// Explicit migration: always set a reducer with fallback
// Extract valueName for reducer mapping (matches frontend migrateFromAngularSinglestat)
var valueName string
if vn, ok := angularOpts["valueName"].(string); ok {
valueName = vn
}
// Set calcs based on valueName (matches frontend: calcs: [reducer ? reducer.id : ReducerID.mean])
var calcs []string
if reducer := getReducerForValueName(valueName); reducer != "" {
options["reduceOptions"].(map[string]interface{})["calcs"] = []string{reducer}
calcs = []string{reducer}
} else {
// Explicit migration fallback: use mean for invalid reducers
options["reduceOptions"].(map[string]interface{})["calcs"] = []string{"mean"}
// Use mean as fallback (matches frontend migrateFromAngularSinglestat: ReducerID.mean)
calcs = []string{"mean"}
}
// Migrate thresholds FIRST (consolidated: both panel types create DEFAULT_THRESHOLDS for empty strings)
migrateThresholds(angularOpts, defaults)
// If no thresholds were set from angular migration, add default stat panel thresholds
// This matches the behavior of frontend pluginLoaded which adds default thresholds
if _, hasThresholds := defaults["thresholds"]; !hasThresholds {
defaults["thresholds"] = map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
}
}
// Apply common angular option migrations (value mappings can now use threshold colors)
applyCommonAngularMigration(panel, defaults, options, angularOpts)
panel["options"] = options
}
// migrateGrafanaSinglestatPanel handles auto-migration from 'grafana-singlestat-panel'
// Based on frontend changePlugin() and sharedSingleStatPanelChangedHandler logic
func migrateGrafanaSinglestatPanel(panel map[string]interface{}, defaults map[string]interface{}) {
angularOpts := extractAngularOptions(panel)
// Auto-migration uses different defaults (matches frontend changePlugin behavior)
// Create options exactly like frontend migrateFromAngularSinglestat
options := map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"lastNotNull"}, // Auto-migration default
"calcs": calcs,
"fields": "",
"values": false,
},
"orientation": "auto", // Auto-migration uses auto
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
"orientation": "horizontal", // Matches frontend migrateFromAngularSinglestat: VizOrientation.Horizontal
}
// Auto-migration: only override if valid, otherwise keep default "lastNotNull"
var valueName string
if vn, ok := angularOpts["valueName"].(string); ok {
valueName = vn
}
if reducer := getReducerForValueName(valueName); reducer != "" {
options["reduceOptions"].(map[string]interface{})["calcs"] = []string{reducer}
}
// No fallback - keeps the auto-migration default "lastNotNull"
// Migrate thresholds FIRST (consolidated: both panel types create DEFAULT_THRESHOLDS for empty strings)
migrateThresholds(angularOpts, defaults)
@@ -298,7 +250,7 @@ func migrateGrafanaSinglestatPanel(panel map[string]interface{}, defaults map[st
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
"value": (*float64)(nil),
},
map[string]interface{}{
"color": "red",
@@ -311,7 +263,21 @@ func migrateGrafanaSinglestatPanel(panel map[string]interface{}, defaults map[st
// Apply common angular option migrations (value mappings can now use threshold colors)
applyCommonAngularMigration(panel, defaults, options, angularOpts)
panel["options"] = options
// Merge new options with existing panel options to preserve properties like maxDataPoints
if existingOptions, exists := panel["options"].(map[string]interface{}); exists {
for key, value := range options {
existingOptions[key] = value
}
} else {
panel["options"] = options
}
}
// migrateGrafanaSinglestatPanel handles auto-migration from 'grafana-singlestat-panel'
// Uses the same migration logic as singlestat panels since the frontend applies
// migrateFromAngularSinglestat to both panel types.
func migrateGrafanaSinglestatPanel(panel map[string]interface{}, defaults map[string]interface{}) {
migratetSinglestat(panel, defaults)
}
// migrateThresholds handles threshold migration for both singlestat panel types
@@ -329,7 +295,7 @@ func migrateThresholds(angularOpts map[string]interface{}, defaults map[string]i
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
"value": (*float64)(nil), // Use pointer to ensure field is present in JSON
},
map[string]interface{}{
"color": "red",
@@ -350,8 +316,7 @@ func applyCommonAngularMigration(panel map[string]interface{}, defaults map[stri
options["reduceOptions"].(map[string]interface{})["fields"] = "/^" + tableColumn + "$/"
}
// Migrate format to unit
// Based on sharedSingleStatPanelChangedHandler line ~130: defaults.unit = prevPanel.format
// Migrate unit from format property (matches frontend sharedSingleStatPanelChangedHandler)
if format, ok := angularOpts["format"].(string); ok {
defaults["unit"] = format
}
@@ -361,10 +326,11 @@ func applyCommonAngularMigration(panel map[string]interface{}, defaults map[stri
defaults["decimals"] = decimals
}
// Migrate null point mode
if nullPointMode, ok := angularOpts["nullPointMode"]; ok {
defaults["nullValueMode"] = nullPointMode
}
// Note: Frontend migrateFromAngularSinglestat does migrate nullPointMode to nullValueMode
// but the frontend's getSaveModel() method removes it, so we don't add it here
// if nullPointMode, ok := angularOpts["nullPointMode"]; ok {
// defaults["nullValueMode"] = nullPointMode
// }
// Migrate null text
if nullText, ok := angularOpts["nullText"].(string); ok {
@@ -376,19 +342,10 @@ func applyCommonAngularMigration(panel map[string]interface{}, defaults map[stri
migrateValueMappings(angularOpts, defaults, valueMaps)
// Migrate sparkline configuration
// Based on statPanelChangedHandler lines ~25-35: sparkline migration logic
// Based on statPanelChangedHandler lines ~20-23: sparkline migration logic
if sparkline, ok := angularOpts["sparkline"].(map[string]interface{}); ok {
if show, ok := sparkline["show"].(bool); ok && show {
options["graphMode"] = "area"
// Handle sparkline color
// Based on statPanelChangedHandler lines ~30-35: sparkline lineColor handling
if lineColor, ok := sparkline["lineColor"].(string); ok {
defaults["color"] = map[string]interface{}{
"mode": "fixed",
"fixedColor": lineColor,
}
}
} else {
options["graphMode"] = "none"
}
@@ -398,13 +355,13 @@ func applyCommonAngularMigration(panel map[string]interface{}, defaults map[stri
}
// Migrate color configuration
// Based on statPanelChangedHandler lines ~35-45: colorBackground and colorValue migration
if colorBackground, ok := angularOpts["colorBackground"].(bool); ok && colorBackground {
options["colorMode"] = "background"
} else if colorValue, ok := angularOpts["colorValue"].(bool); ok && colorValue {
options["colorMode"] = "value"
} else {
options["colorMode"] = "none"
// Based on statPanelChangedHandler lines ~25-38: colorBackground and colorValue migration
colorMode := determineColorMode(angularOpts)
options["colorMode"] = colorMode
// Sparkline color migration only happens when colorMode is "none"
if colorMode == "none" {
migrateSparklineColor(angularOpts, defaults, options)
}
// Migrate text mode
@@ -419,6 +376,27 @@ func applyCommonAngularMigration(panel map[string]interface{}, defaults map[stri
}
}
// applyCompleteStatPanelDefaults applies the complete stat panel defaults
// This matches the frontend's getPanelOptionsWithDefaults behavior after migration
func applyCompleteStatPanelDefaults(panel map[string]interface{}) {
// Get or create options object
options, exists := panel["options"].(map[string]interface{})
if !exists {
options = map[string]interface{}{}
panel["options"] = options
}
defaultOptions := getDefaultStatOptions()
// Merge defaults with existing options, but don't override existing values
// This matches the frontend's getPanelOptionsWithDefaults behavior
for key, defaultValue := range defaultOptions {
if _, exists := options[key]; !exists {
options[key] = defaultValue
}
}
}
// applySharedSinglestatMigration applies shared migration logic for all singlestat panels
// Based on sharedSingleStatMigrationHandler in packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts
func applySharedSinglestatMigration(defaults map[string]interface{}) {
@@ -482,6 +460,7 @@ func getReducerForValueName(valueName string) string {
"min": "min",
"max": "max",
"mean": "mean",
"avg": "mean", // avg maps to mean
"median": "median",
"sum": "sum",
"count": "count",
@@ -512,7 +491,10 @@ func migrateThresholdsAndColors(defaults map[string]interface{}, thresholdsStr s
}
if i == 0 {
step["value"] = nil
// Frontend expects explicit null value for first step, not omitted field
// Use a pointer to ensure the field is present in JSON with null value
var nullValue *float64
step["value"] = nullValue
} else if i-1 < len(thresholdValues) {
if val, err := strconv.ParseFloat(strings.TrimSpace(thresholdValues[i-1]), 64); err == nil {
step["value"] = val
@@ -532,10 +514,19 @@ func migrateValueMappings(panel map[string]interface{}, defaults map[string]inte
mappings := []interface{}{}
mappingType := panel["mappingType"]
if mappingType == nil {
if panel["valueMaps"] != nil && len(panel["valueMaps"].([]interface{})) > 0 {
// Check for inconsistent mapping configuration
// If panel has rangeMaps but mappingType is 1, or vice versa, fix it
hasValueMaps := panel["valueMaps"] != nil && IsArray(panel["valueMaps"]) && len(panel["valueMaps"].([]interface{})) > 0
hasRangeMaps := panel["rangeMaps"] != nil && IsArray(panel["rangeMaps"]) && len(panel["rangeMaps"].([]interface{})) > 0
if hasRangeMaps && mappingType == float64(1) {
mappingType = 2
} else if hasValueMaps && mappingType == float64(2) {
mappingType = 1
} else if mappingType == nil {
if hasValueMaps {
mappingType = 1
} else if panel["rangeMaps"] != nil && len(panel["rangeMaps"].([]interface{})) > 0 {
} else if hasRangeMaps {
mappingType = 2
}
}
@@ -575,9 +566,10 @@ func upgradeOldAngularValueMapping(old map[string]interface{}, thresholds interf
newMappings := []interface{}{}
// Use the color we would have picked from thresholds
// Frontend uses old.text to determine color, not old.value
var color interface{}
if value, ok := old["value"]; ok {
if numeric, err := parseNumericValue(value); err == nil {
if text, ok := old["text"].(string); ok {
if numeric, err := parseNumericValue(text); err == nil {
if thresholdsMap, ok := thresholds.(map[string]interface{}); ok {
if steps, ok := thresholdsMap["steps"].([]interface{}); ok {
level := getActiveThreshold(numeric, steps)
@@ -714,34 +706,113 @@ func parseNumericValue(value interface{}) (float64, error) {
}
}
// createFieldConfigFromDefaults creates the proper fieldConfig structure from defaults
// and removes all legacy properties from the panel
func createFieldConfigFromDefaults(panel map[string]interface{}, defaults map[string]interface{}) {
// Ensure fieldConfig exists
if panel["fieldConfig"] == nil {
panel["fieldConfig"] = map[string]interface{}{
"defaults": map[string]interface{}{},
"overrides": []interface{}{},
}
}
fieldConfig := panel["fieldConfig"].(map[string]interface{})
fieldDefaults := fieldConfig["defaults"].(map[string]interface{})
// Copy all defaults to fieldConfig.defaults
for key, value := range defaults {
fieldDefaults[key] = value
}
// Note: Frontend doesn't add these extra fieldConfig defaults
// Color is handled in sparkline migration logic
// nullValueMode and unit are not added by frontend
// Remove all legacy properties from the panel
legacyProperties := []string{
"colors", "thresholds", "valueMaps", "grid", "legend", "mappingTypes", "gauge",
"autoMigrateFrom", "colorBackground", "colorValue", "format", "mappingType",
"nullPointMode", "postfix", "postfixFontSize", "prefix",
"prefixFontSize", "rangeMaps", "sparkline", "tableColumn", "valueFontSize",
"valueName", "aliasYAxis", "bars", "dashLength", "dashes", "fill", "fillGradient",
"lineInterpolation", "lineWidth", "pointRadius", "points", "spaceLength",
"stack", "steppedLine", "xAxis", "yAxes", "yAxis", "zIndex",
}
for _, prop := range legacyProperties {
delete(panel, prop)
}
}
// cleanupAngularProperties removes old angular properties after migration
// Based on PanelModel.clearPropertiesBeforePluginChange in public/app/features/dashboard/state/PanelModel.ts
// This function removes ALL properties except those in mustKeepProps to match frontend behavior exactly
func cleanupAngularProperties(panel map[string]interface{}) {
// Remove PanelModel's autoMigrateFrom property
delete(panel, "autoMigrateFrom")
// Properties that must be kept (matching frontend mustKeepProps)
mustKeepProps := map[string]bool{
"id": true, "gridPos": true, "type": true, "title": true, "scopedVars": true,
"repeat": true, "repeatPanelId": true, "repeatDirection": true, "repeatedByRow": true,
"minSpan": true, "collapsed": true, "panels": true, "targets": true, "datasource": true,
"timeFrom": true, "timeShift": true, "hideTimeOverride": true, "description": true,
"links": true, "fullscreen": true, "isEditing": true, "isViewing": true,
"hasRefreshed": true, "events": true, "cacheTimeout": true, "queryCachingTTL": true,
"cachedPluginOptions": true, "transparent": true, "pluginVersion": true,
"fieldConfig": true, "options": true, // These are set by migration
"maxDataPoints": true, "interval": true, // Panel-level properties preserved by frontend
"autoMigrateFrom": true, // Preserve autoMigrateFrom for proper migration logic
}
// Remove angular singlestat properties
delete(panel, "valueName")
delete(panel, "format")
delete(panel, "decimals")
delete(panel, "thresholds")
delete(panel, "colors")
delete(panel, "gauge")
delete(panel, "sparkline")
delete(panel, "colorBackground")
delete(panel, "colorValue")
delete(panel, "nullPointMode")
delete(panel, "nullText")
delete(panel, "valueMaps")
delete(panel, "tableColumn")
delete(panel, "angular")
// Remove legacy options properties
if options, ok := panel["options"].(map[string]interface{}); ok {
delete(options, "valueOptions")
delete(options, "thresholds")
delete(options, "valueMaps")
delete(options, "minValue")
delete(options, "maxValue")
// Remove ALL properties except those in mustKeepProps (matching frontend behavior)
for key := range panel {
if !mustKeepProps[key] {
delete(panel, key)
}
}
// Ensure all targets have refIds (matching frontend ensureQueryIds behavior)
ensureTargetRefIds(panel)
}
// ensureTargetRefIds assigns refIds to targets that don't have them
// This matches the frontend PanelModel.ensureQueryIds() behavior
func ensureTargetRefIds(panel map[string]interface{}) {
targets, ok := panel["targets"].([]interface{})
if !ok || len(targets) == 0 {
return
}
// Find existing refIds
existingRefIds := make(map[string]bool)
for _, targetInterface := range targets {
if target, ok := targetInterface.(map[string]interface{}); ok {
if refId, ok := target["refId"].(string); ok {
existingRefIds[refId] = true
}
}
}
// Assign refIds to targets that don't have them
letters := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
letterIndex := 0
for _, targetInterface := range targets {
if target, ok := targetInterface.(map[string]interface{}); ok {
refId, hasRefId := target["refId"].(string)
if !hasRefId || refId == "" {
// Find next available refId
for letterIndex < len(letters) {
refId := string(letters[letterIndex])
if !existingRefIds[refId] {
target["refId"] = refId
existingRefIds[refId] = true
break
}
letterIndex++
}
letterIndex++
}
}
}
}
@@ -750,7 +821,67 @@ func cleanupAngularProperties(panel map[string]interface{}) {
func removeDeprecatedVariableProperties(variable map[string]interface{}) {
// Remove deprecated properties
delete(variable, "tags")
delete(variable, "tagsQuery")
delete(variable, "tagValuesQuery")
delete(variable, "useTags")
// Only remove tagsQuery if it's a non-empty string (matches frontend behavior)
if tagsQuery, exists := variable["tagsQuery"]; exists {
if str, ok := tagsQuery.(string); ok && str != "" {
delete(variable, "tagsQuery")
}
}
// Only remove tagValuesQuery if it's a non-empty string (matches frontend behavior)
if tagValuesQuery, exists := variable["tagValuesQuery"]; exists {
if str, ok := tagValuesQuery.(string); ok && str != "" {
delete(variable, "tagValuesQuery")
}
}
// Only remove useTags if it's a truthy boolean (matches frontend behavior)
if useTags, exists := variable["useTags"]; exists {
if val, ok := useTags.(bool); ok && val {
delete(variable, "useTags")
}
}
}
// determineColorMode determines the color mode based on angular options
func determineColorMode(angularOpts map[string]interface{}) string {
if colorBackground, ok := angularOpts["colorBackground"].(bool); ok && colorBackground {
return "background"
}
if colorValue, ok := angularOpts["colorValue"].(bool); ok && colorValue {
return "value"
}
return "none"
}
// migrateSparklineColor migrates sparkline color configuration when colorMode is "none"
// Based on statPanelChangedHandler lines 31-38
func migrateSparklineColor(angularOpts map[string]interface{}, defaults map[string]interface{}, options map[string]interface{}) {
sparkline, ok := angularOpts["sparkline"].(map[string]interface{})
if !ok {
return
}
show, ok := sparkline["show"].(bool)
if !ok || !show {
return
}
graphMode, ok := options["graphMode"].(string)
if !ok || graphMode != "area" {
return
}
lineColor, ok := sparkline["lineColor"].(string)
if !ok {
return
}
defaults["color"] = map[string]interface{}{
"mode": "fixed",
"fixedColor": lineColor,
}
}
@@ -1,750 +1,105 @@
package schemaversion_test
package schemaversion
import (
"context"
"testing"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
)
func TestV28(t *testing.T) {
tests := []migrationTestCase{
func TestV28SinglestatMigration(t *testing.T) {
tests := []struct {
name string
input map[string]interface{}
expected map[string]interface{}
description string
}{
{
name: "migrate angular singlestat to stat panel",
name: "migrate_range_maps_to_field_config_mappings",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
"type": "singlestat",
"rangeMaps": []interface{}{
map[string]interface{}{
"id": 1,
"type": "singlestat",
"valueName": "avg",
"format": "ms",
"decimals": 2,
"thresholds": "10,20,30",
"colors": []interface{}{"green", "yellow", "red"},
"gauge": map[string]interface{}{
"show": false,
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "var1",
"tags": []interface{}{"tag1"},
"tagsQuery": "query",
"tagValuesQuery": "values",
"useTags": true,
},
"from": "null",
"to": "N/A",
},
},
"mappingType": 1, // Inconsistent - should be 2 for rangeMaps
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"mean"},
"fields": "",
"values": false,
},
"orientation": "horizontal",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "ms",
"decimals": 2,
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "yellow",
"value": 10.0,
},
map[string]interface{}{
"color": "red",
"value": 20.0,
},
},
},
"mappings": []interface{}{},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "var1",
},
},
},
},
},
{
name: "migrate angular singlestat to stat panel with gauge options",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "singlestat",
"valueName": "current",
"format": "percent",
"gauge": map[string]interface{}{
"show": true,
"thresholdMarkers": true,
"thresholdLabels": false,
},
"sparkline": map[string]interface{}{
"show": true,
"lineColor": "#ff0000",
},
"colorBackground": true,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"lastNotNull"},
"fields": "",
"values": false,
},
"orientation": "horizontal",
"colorMode": "background",
"graphMode": "area",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "percent",
"min": 0,
"max": 100,
"color": map[string]interface{}{
"mode": "fixed",
"fixedColor": "#ff0000",
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "migrate grafana-singlestat-panel to stat panel",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "grafana-singlestat-panel",
"valueName": "current",
"format": "percent",
"gauge": map[string]interface{}{
"show": true,
"thresholdMarkers": true,
"thresholdLabels": false,
},
"sparkline": map[string]interface{}{
"show": true,
"lineColor": "#ff0000",
},
"colorBackground": true,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"lastNotNull"},
"fields": "",
"values": false,
},
"orientation": "auto",
"colorMode": "background",
"graphMode": "area",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "percent",
"min": 0,
"max": 100,
"color": map[string]interface{}{
"mode": "fixed",
"fixedColor": "#ff0000",
},
"mappings": []interface{}{},
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "migrate singlestat with empty thresholds to stat panel",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "singlestat",
"valueName": "min",
"format": "bytes",
"thresholds": "",
"colors": []interface{}{"green", "red"},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"min"},
"fields": "",
"values": false,
},
"orientation": "horizontal",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "bytes",
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
"mappings": []interface{}{},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "migrate grafana-singlestat-panel with empty thresholds to stat panel",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "grafana-singlestat-panel",
"valueName": "max",
"format": "short",
"thresholds": "",
"colors": []interface{}{"green", "red"},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"max"},
"fields": "",
"values": false,
},
"orientation": "auto",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "short",
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
"mappings": []interface{}{},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "migrate singlestat with value mappings and threshold colors",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "singlestat",
"valueName": "current",
"format": "short",
"thresholds": "50,80",
"colors": []interface{}{"green", "orange", "red"},
"valueMaps": []interface{}{
"type": "stat",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"mappings": []interface{}{
map[string]interface{}{
"value": "40",
"text": "Warning",
},
map[string]interface{}{
"value": "90",
"text": "Critical",
},
},
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"lastNotNull"},
"fields": "",
"values": false,
},
"orientation": "horizontal",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "short",
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "orange",
"value": 50.0,
},
map[string]interface{}{
"color": "red",
"value": 80.0,
},
},
},
"mappings": []interface{}{
map[string]interface{}{
"type": "value",
"options": map[string]interface{}{
"40": map[string]interface{}{
"text": "Warning",
"color": "green",
},
},
},
map[string]interface{}{
"type": "value",
"options": map[string]interface{}{
"90": map[string]interface{}{
"text": "Critical",
"color": "red",
},
},
},
},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "migrate singlestat with invalid valueName fallback to mean",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "singlestat",
"valueName": "invalid_reducer",
"format": "short",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"mean"},
"fields": "",
"values": false,
},
"orientation": "horizontal",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "short",
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
"mappings": []interface{}{},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "migrate grafana-singlestat-panel with invalid valueName keeps lastNotNull",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "grafana-singlestat-panel",
"valueName": "invalid_reducer",
"format": "short",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"lastNotNull"},
"fields": "",
"values": false,
},
"orientation": "auto",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "short",
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
"mappings": []interface{}{},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
{
name: "handle nested panels in rows",
input: map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "row",
"panels": []interface{}{
map[string]interface{}{
"id": 2,
"type": "singlestat",
"valueName": "sum",
"format": "bytes",
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"type": "row",
"panels": []interface{}{
map[string]interface{}{
"id": 2,
"type": "stat",
"options": map[string]interface{}{
"reduceOptions": map[string]interface{}{
"calcs": []string{"sum"},
"fields": "",
"values": false,
"match": "null",
"result": map[string]interface{}{
"text": "N/A",
},
"orientation": "horizontal",
"colorMode": "none",
"graphMode": "none",
"justifyMode": "auto",
"percentChangeColorMode": "standard",
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true,
},
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"unit": "bytes",
"thresholds": map[string]interface{}{
"mode": "absolute",
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
},
map[string]interface{}{
"color": "red",
"value": 80,
},
},
},
"mappings": []interface{}{},
},
"overrides": []interface{}{},
},
"pluginVersion": pluginVersionForAutoMigrate,
"targets": []interface{}{
map[string]interface{}{"refId": "A"},
},
"type": "special",
},
},
},
},
},
description: "RangeMaps should migrate to fieldConfig.mappings, and inconsistent mappingType should be fixed to 2 (RangeToText)",
},
{
name: "remove deprecated variable properties",
name: "migrate_sparkline_color_when_color_mode_none",
input: map[string]interface{}{
"schemaVersion": 27,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "var1",
"type": "query",
"tags": []interface{}{"tag1", "tag2"},
"tagsQuery": "SELECT * FROM tags",
"tagValuesQuery": "SELECT value FROM tag_values",
"useTags": true,
},
map[string]interface{}{
"name": "var2",
"type": "custom",
// No deprecated properties
},
},
"type": "singlestat",
"colorMode": "None",
"sparkline": map[string]interface{}{
"lineColor": "rgb(31, 120, 193)",
},
},
expected: map[string]interface{}{
"schemaVersion": 28,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "var1",
"type": "query",
},
map[string]interface{}{
"name": "var2",
"type": "custom",
"type": "stat",
"fieldConfig": map[string]interface{}{
"defaults": map[string]interface{}{
"color": map[string]interface{}{
"mode": "fixed",
"fixedColor": "rgb(31, 120, 193)",
},
},
},
},
description: "Sparkline lineColor should migrate to fieldConfig.defaults.color only when colorMode is None",
},
}
runMigrationTests(t, tests, schemaversion.V28)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dashboard := map[string]interface{}{
"schemaVersion": 27,
"panels": []interface{}{tt.input},
}
err := V28(context.Background(), dashboard)
if err != nil {
t.Fatalf("V28 migration failed: %v", err)
}
if dashboard["schemaVersion"] != 28 {
t.Errorf("Expected schemaVersion to be 28, got %v", dashboard["schemaVersion"])
}
panels, ok := dashboard["panels"].([]interface{})
if !ok || len(panels) == 0 {
t.Fatalf("Expected panels array with at least one panel")
}
panel, ok := panels[0].(map[string]interface{})
if !ok {
t.Fatalf("Expected panel to be a map")
}
// Verify panel type was changed to stat
if panel["type"] != "stat" {
t.Errorf("Expected panel type to be 'stat', got %v", panel["type"])
}
t.Logf("✓ %s: %s", tt.name, tt.description)
})
}
}
@@ -44,16 +44,12 @@ func V29(_ context.Context, dashboard map[string]interface{}) error {
continue
}
// Set refresh to 1 if not 1 or 2
refresh, hasRefresh := variable["refresh"]
refreshInt := 0
if r, ok := refresh.(int); ok {
refreshInt = r
}
if !hasRefresh || (refreshInt != 1 && refreshInt != 2) {
refreshInt := GetIntValue(variable, "refresh", 0)
if refreshInt != 1 && refreshInt != 2 {
variable["refresh"] = 1
}
// Clear options if present
if _, hasOptions := variable["options"]; hasOptions {
// Clear options if they have content (matches frontend behavior)
if options, hasOptions := variable["options"].([]interface{}); hasOptions && len(options) > 0 {
variable["options"] = []interface{}{}
}
}
@@ -269,8 +269,8 @@ func processLegacyMapping(mappingMap map[string]interface{}, thresholds map[stri
color := getColorFromThresholds(mappingMap, thresholds)
// Convert legacy type numbers to new format
if mappingType, ok := mappingMap["type"].(float64); ok {
switch int(mappingType) {
if mappingType := GetIntValue(mappingMap, "type", -1); mappingType != -1 {
switch mappingType {
case 1: // ValueToText
hasValueMappings = processValueToTextMapping(mappingMap, color, thresholds, valueMaps, newMappings, hasValueMappings)
case 2: // RangeToText
@@ -281,25 +281,16 @@ func processLegacyMapping(mappingMap map[string]interface{}, thresholds map[stri
return hasValueMappings
}
// getColorFromThresholds extracts color from thresholds based on mapping values
// getColorFromThresholds extracts color from thresholds based on mapping text (matches frontend behavior)
func getColorFromThresholds(mappingMap map[string]interface{}, thresholds map[string]interface{}) interface{} {
if thresholds == nil {
return nil
}
// Try to get color from threshold based on the mapping value
if value, ok := mappingMap["value"]; ok {
if valueStr, ok := value.(string); ok {
if numeric, err := strconv.ParseFloat(valueStr, 64); err == nil {
return getActiveThresholdColor(numeric, thresholds)
}
}
}
// For range mappings, use the 'from' value to determine color
if fromVal, ok := mappingMap["from"]; ok {
if fromStr, ok := fromVal.(string); ok {
if numeric, err := strconv.ParseFloat(fromStr, 64); err == nil {
// Try to get color from threshold based on the mapping text (matches frontend behavior)
if text, ok := mappingMap["text"]; ok {
if textStr, ok := text.(string); ok {
if numeric, err := strconv.ParseFloat(textStr, 64); err == nil {
return getActiveThresholdColor(numeric, thresholds)
}
}
@@ -325,19 +316,18 @@ func processValueToTextMapping(mappingMap map[string]interface{}, color interfac
// processNullValueMapping creates a special value mapping for null values
func processNullValueMapping(mappingMap map[string]interface{}, color interface{}, thresholds map[string]interface{}, newMappings *[]interface{}) {
// For null values, use the base threshold color (lowest step)
if thresholds != nil && color == nil {
color = getBaseThresholdColor(thresholds)
result := map[string]interface{}{
"text": mappingMap["text"],
}
if color != nil {
result["color"] = color
}
*newMappings = append(*newMappings, map[string]interface{}{
"type": "special",
"options": map[string]interface{}{
"match": "null",
"result": map[string]interface{}{
"text": mappingMap["text"],
"color": color,
},
"match": "null",
"result": result,
},
})
}
@@ -376,9 +366,13 @@ func processRangeToTextMapping(mappingMap map[string]interface{}, color interfac
})
}
// getActiveThresholdColor returns the color for a value based on thresholds
// getActiveThresholdColor returns the color for a value based on thresholds (matches frontend getActiveThreshold)
func getActiveThresholdColor(value float64, thresholds map[string]interface{}) interface{} {
if steps, ok := thresholds["steps"].([]interface{}); ok {
if len(steps) == 0 {
return nil
}
var activeStep map[string]interface{}
for _, step := range steps {
@@ -390,9 +384,11 @@ func getActiveThresholdColor(value float64, thresholds map[string]interface{}) i
continue
}
if stepNum, ok := stepValue.(float64); ok {
if stepNum := GetFloatValue(stepMap, "value", -1); stepNum != -1 {
if value >= stepNum {
activeStep = stepMap
} else {
break
}
}
}
@@ -407,24 +403,6 @@ func getActiveThresholdColor(value float64, thresholds map[string]interface{}) i
return nil
}
// getBaseThresholdColor returns the base threshold color (first step with null value)
func getBaseThresholdColor(thresholds map[string]interface{}) interface{} {
if steps, ok := thresholds["steps"].([]interface{}); ok {
for _, step := range steps {
if stepMap, ok := step.(map[string]interface{}); ok {
if stepValue, ok := stepMap["value"]; ok {
if stepValue == nil {
// This is the base color (null value step)
return stepMap["color"]
}
}
}
}
}
return nil
}
// migrateTooltipOptions renames tooltipOptions to tooltip for specific panel types
func migrateTooltipOptions(panel map[string]interface{}) {
panelType, ok := panel["type"].(string)
@@ -25,7 +25,7 @@ func TestV30(t *testing.T) {
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
"value": (*float64)(nil),
},
map[string]interface{}{
"color": "red",
@@ -99,7 +99,7 @@ func TestV30(t *testing.T) {
"steps": []interface{}{
map[string]interface{}{
"color": "green",
"value": nil,
"value": (*float64)(nil),
},
map[string]interface{}{
"color": "red",
@@ -112,12 +112,10 @@ func TestV30(t *testing.T) {
"type": "value",
"options": map[string]interface{}{
"1": map[string]interface{}{
"text": "Up",
"color": "green",
"text": "Up",
},
"0": map[string]interface{}{
"text": "Down",
"color": "green",
"text": "Down",
},
},
},
@@ -127,8 +125,7 @@ func TestV30(t *testing.T) {
"from": float64(10),
"to": float64(20),
"result": map[string]interface{}{
"text": "Medium",
"color": "green",
"text": "Medium",
},
},
},
@@ -137,8 +134,7 @@ func TestV30(t *testing.T) {
"options": map[string]interface{}{
"match": "null",
"result": map[string]interface{}{
"text": "Null Value",
"color": "green",
"text": "Null Value",
},
},
},
@@ -128,7 +128,9 @@ func processPanelsV31(panels []interface{}) {
}
}
// Update the panel with the new transformations
p["transformations"] = newTransformations
// Update the panel with the new transformations - only if not empty
if len(newTransformations) > 0 {
p["transformations"] = newTransformations
}
}
}
@@ -1,336 +1,91 @@
package schemaversion_test
package schemaversion
import (
"context"
"testing"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
)
func TestV31(t *testing.T) {
tests := []migrationTestCase{
func TestV31LabelsToFieldsMigration(t *testing.T) {
tests := []struct {
name string
input map[string]interface{}
expected map[string]interface{}
description string
}{
{
name: "panel with basic labelsToFields transformation gets merge transformation added",
name: "do_not_add_empty_transformations",
input: map[string]interface{}{
"title": "V31 LabelsToFields Migration Test Dashboard",
"schemaVersion": 30,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with basic labelsToFields",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{},
},
},
},
},
"type": "timeseries",
"title": "Test Panel",
},
expected: map[string]interface{}{
"title": "V31 LabelsToFields Migration Test Dashboard",
"schemaVersion": 31,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with basic labelsToFields",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "merge",
"options": map[string]interface{}{},
},
},
},
},
"type": "timeseries",
"title": "Test Panel",
},
description: "V31 migration should not add empty transformations arrays to panels",
},
{
name: "panel with labelsToFields options preserved during migration",
name: "preserve_existing_transformations",
input: map[string]interface{}{
"title": "V31 LabelsToFields Options Preservation Test Dashboard",
"schemaVersion": 30,
"panels": []interface{}{
"type": "timeseries",
"transformations": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with labelsToFields options",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{
"mode": "rows",
"keepLabels": []interface{}{"job", "instance"},
"valueLabel": "value",
},
},
"id": "labelsToFields",
"options": map[string]interface{}{
"keepLabels": []interface{}{"__name__"},
},
},
},
},
expected: map[string]interface{}{
"title": "V31 LabelsToFields Options Preservation Test Dashboard",
"schemaVersion": 31,
"panels": []interface{}{
"type": "timeseries",
"transformations": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with labelsToFields options",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{
"mode": "rows",
"keepLabels": []interface{}{"job", "instance"},
"valueLabel": "value",
},
},
map[string]interface{}{
"id": "merge",
"options": map[string]interface{}{},
},
"id": "labelsToFields",
"options": map[string]interface{}{
"keepLabels": []interface{}{"__name__"},
},
},
},
},
},
{
name: "panel with multiple labelsToFields transformations",
input: map[string]interface{}{
"title": "V31 Multiple LabelsToFields Migration Test Dashboard",
"schemaVersion": 30,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with multiple labelsToFields",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "organize",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "calculateField",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{
"mode": "rows",
},
},
},
},
},
},
expected: map[string]interface{}{
"title": "V31 Multiple LabelsToFields Migration Test Dashboard",
"schemaVersion": 31,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with multiple labelsToFields",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "organize",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "merge",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "calculateField",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{
"mode": "rows",
},
},
map[string]interface{}{
"id": "merge",
"options": map[string]interface{}{},
},
},
},
},
},
},
{
name: "panel with no transformations remains unchanged",
input: map[string]interface{}{
"title": "V31 No Transformations Test Dashboard",
"schemaVersion": 30,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with no transformations",
"id": 1,
},
},
},
expected: map[string]interface{}{
"title": "V31 No Transformations Test Dashboard",
"schemaVersion": 31,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with no transformations",
"id": 1,
},
},
},
},
{
name: "panel with transformations but no labelsToFields remains unchanged",
input: map[string]interface{}{
"title": "V31 Other Transformations Test Dashboard",
"schemaVersion": 30,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with other transformations",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "organize",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "reduce",
"options": map[string]interface{}{},
},
},
},
},
},
expected: map[string]interface{}{
"title": "V31 Other Transformations Test Dashboard",
"schemaVersion": 31,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Panel with other transformations",
"id": 1,
"transformations": []interface{}{
map[string]interface{}{
"id": "organize",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "reduce",
"options": map[string]interface{}{},
},
},
},
},
},
},
{
name: "nested panels in row with labelsToFields transformation",
input: map[string]interface{}{
"title": "V31 Nested Panels Test Dashboard",
"schemaVersion": 30,
"panels": []interface{}{
map[string]interface{}{
"type": "row",
"title": "Row with nested panels",
"id": 1,
"collapsed": false,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Nested panel with labelsToFields",
"id": 2,
"transformations": []interface{}{
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{},
},
},
},
map[string]interface{}{
"type": "timeseries",
"title": "Nested panel without labelsToFields",
"id": 3,
"transformations": []interface{}{
map[string]interface{}{
"id": "organize",
"options": map[string]interface{}{},
},
},
},
},
},
},
},
expected: map[string]interface{}{
"title": "V31 Nested Panels Test Dashboard",
"schemaVersion": 31,
"panels": []interface{}{
map[string]interface{}{
"type": "row",
"title": "Row with nested panels",
"id": 1,
"collapsed": false,
"panels": []interface{}{
map[string]interface{}{
"type": "timeseries",
"title": "Nested panel with labelsToFields",
"id": 2,
"transformations": []interface{}{
map[string]interface{}{
"id": "labelsToFields",
"options": map[string]interface{}{},
},
map[string]interface{}{
"id": "merge",
"options": map[string]interface{}{},
},
},
},
map[string]interface{}{
"type": "timeseries",
"title": "Nested panel without labelsToFields",
"id": 3,
"transformations": []interface{}{
map[string]interface{}{
"id": "organize",
"options": map[string]interface{}{},
},
},
},
},
},
},
},
},
{
name: "dashboard with no panels",
input: map[string]interface{}{
"title": "V31 No Panels Test Dashboard",
"schemaVersion": 30,
},
expected: map[string]interface{}{
"title": "V31 No Panels Test Dashboard",
"schemaVersion": 31,
},
description: "Existing labelsToFields transformations should be preserved and updated if needed",
},
}
runMigrationTests(t, tests, schemaversion.V31)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dashboard := map[string]interface{}{
"schemaVersion": 30,
"panels": []interface{}{tt.input},
}
err := V31(context.Background(), dashboard)
if err != nil {
t.Fatalf("V31 migration failed: %v", err)
}
if dashboard["schemaVersion"] != 31 {
t.Errorf("Expected schemaVersion to be 31, got %v", dashboard["schemaVersion"])
}
panels, ok := dashboard["panels"].([]interface{})
if !ok || len(panels) == 0 {
t.Fatalf("Expected panels array with at least one panel")
}
panel, ok := panels[0].(map[string]interface{})
if !ok {
t.Fatalf("Expected panel to be a map")
}
// Check that transformations array is not added if it wasn't in input
if _, hasTransformations := tt.input["transformations"]; !hasTransformations {
if _, exists := panel["transformations"]; exists {
t.Errorf("Empty transformations array should not be added")
}
}
t.Logf("✓ %s: %s", tt.name, tt.description)
})
}
}
@@ -1,420 +1,224 @@
package schemaversion_test
package schemaversion
import (
"context"
"testing"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
)
func TestV33(t *testing.T) {
// Pass the mock provider to V33
migration := schemaversion.V33(testutil.GetTestDataSourceProvider())
tests := []migrationTestCase{
{
name: "dashboard with no panels",
input: map[string]interface{}{
"schemaVersion": 32,
func TestV33DatasourceMigration(t *testing.T) {
// Create test datasource provider
dsProvider := &testDataSourceProvider{
datasources: []DataSourceInfo{
{
Default: true,
UID: "default-ds-uid",
Type: "prometheus",
APIVersion: "v1",
Name: "Default Test Datasource Name",
ID: 1,
},
expected: map[string]interface{}{
"schemaVersion": 33,
},
},
{
name: "panel with default datasource should return null",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "default",
"targets": []interface{}{
map[string]interface{}{
"datasource": "default",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"datasource": "default",
},
},
},
},
},
},
{
name: "panel with null datasource should return null",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"datasource": nil,
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"datasource": nil,
},
},
},
},
},
},
{
name: "panel with existing datasource reference should be preserved",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "existing-uid",
"type": "existing-type",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "target-uid",
"type": "target-type",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "existing-uid",
"type": "existing-type",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "target-uid",
"type": "target-type",
},
},
},
},
},
},
},
{
name: "panel with datasource by name should be migrated",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "Existing Target Name",
"targets": []interface{}{
map[string]interface{}{
"datasource": "Existing Target Name",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
},
},
},
},
},
{
name: "panel with datasource by UID should be migrated",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "existing-target-uid",
"targets": []interface{}{
map[string]interface{}{
"datasource": "existing-target-uid",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
},
},
},
},
},
{
name: "panel with unknown datasource should preserve as UID",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "unknown-datasource",
"targets": []interface{}{
map[string]interface{}{
"datasource": "unknown-datasource",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "unknown-datasource",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "unknown-datasource",
},
},
},
},
},
},
},
{
name: "panel with mixed datasources",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "Existing Target Name",
"targets": []interface{}{
map[string]interface{}{
"datasource": "default",
},
map[string]interface{}{
"datasource": "existing-target-uid",
},
map[string]interface{}{
"datasource": "unknown-ds",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": "default",
},
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "unknown-ds",
},
},
},
},
},
},
},
{
name: "panel without targets should not fail",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "Existing Target Name",
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
},
},
},
{
name: "nested panels in collapsed rows should be migrated",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"type": "row",
"collapsed": true,
"datasource": "Existing Target Name",
"panels": []interface{}{
map[string]interface{}{
"datasource": "default",
"targets": []interface{}{
map[string]interface{}{
"datasource": "existing-target-uid",
},
},
},
map[string]interface{}{
"datasource": "unknown-ds",
"targets": []interface{}{
map[string]interface{}{
"datasource": "Existing Target Name",
},
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"type": "row",
"collapsed": true,
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
},
},
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "unknown-ds",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
},
},
},
},
},
},
},
{
name: "targets with lowercase default keyword should not be updated",
input: map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
map[string]interface{}{
"datasource": "Existing Target Name",
"targets": []interface{}{
map[string]interface{}{
"datasource": "default",
},
map[string]interface{}{
"datasource": nil,
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 33,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"targets": []interface{}{
map[string]interface{}{
"datasource": "default",
},
map[string]interface{}{
"datasource": nil,
},
},
},
},
{
Default: false,
UID: "non-default-test-ds-uid",
Type: "loki",
APIVersion: "v1",
Name: "Non Default Test Datasource Name",
ID: 2,
},
},
}
runMigrationTests(t, tests, migration)
tests := []struct {
name string
input map[string]interface{}
expected map[string]interface{}
description string
}{
{
name: "empty_string_datasource_should_become_empty_object",
input: map[string]interface{}{
"datasource": "",
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": "",
},
},
},
expected: map[string]interface{}{
"datasource": map[string]interface{}{},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{},
},
},
},
description: "Empty string datasources should migrate to empty objects {} to match frontend behavior",
},
{
name: "null_datasource_should_remain_null",
input: map[string]interface{}{
"datasource": nil,
},
expected: map[string]interface{}{
"datasource": nil,
},
description: "Null datasources should remain null when returnDefaultAsNull is true",
},
{
name: "existing_object_datasource_should_remain_unchanged",
input: map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "existing-ref-uid",
"type": "prometheus",
},
},
expected: map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "existing-ref-uid",
"type": "prometheus",
},
},
description: "Existing datasource objects should remain unchanged",
},
{
name: "string_datasource_should_migrate_to_object",
input: map[string]interface{}{
"datasource": "Non Default Test Datasource Name",
},
expected: map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "non-default-test-ds-uid",
"type": "loki",
"apiVersion": "v1",
},
},
description: "String datasources should migrate to structured objects with uid, type, and apiVersion",
},
{
name: "default_datasource_should_become_null",
input: map[string]interface{}{
"datasource": "default",
},
expected: map[string]interface{}{
"datasource": nil,
},
description: "Default datasource should become null when returnDefaultAsNull is true",
},
{
name: "unknown_datasource_should_be_preserved_as_uid",
input: map[string]interface{}{
"datasource": "unknown-datasource",
},
expected: map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "unknown-datasource",
},
},
description: "Unknown datasource names should be preserved as UID-only reference",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create a dashboard with the test panel
dashboard := map[string]interface{}{
"schemaVersion": 32,
"panels": []interface{}{
tt.input,
},
}
// Run V33 migration
migration := V33(dsProvider)
err := migration(context.Background(), dashboard)
if err != nil {
t.Fatalf("V33 migration failed: %v", err)
}
// Verify schema version was updated
if dashboard["schemaVersion"] != 33 {
t.Errorf("Expected schemaVersion to be 33, got %v", dashboard["schemaVersion"])
}
// Get the migrated panel
panels, ok := dashboard["panels"].([]interface{})
if !ok || len(panels) == 0 {
t.Fatalf("Expected panels array with at least one panel")
}
panel, ok := panels[0].(map[string]interface{})
if !ok {
t.Fatalf("Expected panel to be a map")
}
// Verify panel datasource
if !compareDatasource(panel["datasource"], tt.expected["datasource"]) {
t.Errorf("Panel datasource mismatch.\nExpected: %v\nGot: %v", tt.expected["datasource"], panel["datasource"])
}
// Verify targets if they exist
if expectedTargets, hasTargets := tt.expected["targets"].([]interface{}); hasTargets {
actualTargets, ok := panel["targets"].([]interface{})
if !ok {
t.Fatalf("Expected targets array")
}
if len(actualTargets) != len(expectedTargets) {
t.Fatalf("Expected %d targets, got %d", len(expectedTargets), len(actualTargets))
}
for i, expectedTarget := range expectedTargets {
expectedTargetMap := expectedTarget.(map[string]interface{})
actualTargetMap := actualTargets[i].(map[string]interface{})
if !compareDatasource(actualTargetMap["datasource"], expectedTargetMap["datasource"]) {
t.Errorf("Target %d datasource mismatch.\nExpected: %v\nGot: %v", i, expectedTargetMap["datasource"], actualTargetMap["datasource"])
}
}
}
t.Logf("✓ %s: %s", tt.name, tt.description)
})
}
}
// Helper function to compare datasource objects
func compareDatasource(actual, expected interface{}) bool {
if actual == nil && expected == nil {
return true
}
if actual == nil || expected == nil {
return false
}
actualMap, actualOk := actual.(map[string]interface{})
expectedMap, expectedOk := expected.(map[string]interface{})
if !actualOk || !expectedOk {
return actual == expected
}
if len(actualMap) != len(expectedMap) {
return false
}
for key, expectedValue := range expectedMap {
actualValue, exists := actualMap[key]
if !exists || actualValue != expectedValue {
return false
}
}
return true
}
// Test datasource provider for testing
type testDataSourceProvider struct {
datasources []DataSourceInfo
}
func (p *testDataSourceProvider) GetDataSourceInfo(_ context.Context) []DataSourceInfo {
return p.datasources
}
@@ -58,28 +58,30 @@ import "context"
func V34(_ context.Context, dashboard map[string]interface{}) error {
dashboard["schemaVersion"] = int(34)
// Migrate panel queries if panels exist
panels, _ := dashboard["panels"].([]interface{})
for _, panel := range panels {
p, ok := panel.(map[string]interface{})
if !ok {
continue
}
migrateCloudWatchQueriesInPanel(p)
// Handle nested panels in collapsed rows
nestedPanels, hasNested := p["panels"].([]interface{})
if !hasNested {
continue
}
for _, nestedPanel := range nestedPanels {
np, ok := nestedPanel.(map[string]interface{})
// Migrate panel queries if panels exist and are an array
if panelsValue, exists := dashboard["panels"]; exists && IsArray(panelsValue) {
panels := panelsValue.([]interface{})
for _, panel := range panels {
p, ok := panel.(map[string]interface{})
if !ok {
continue
}
migrateCloudWatchQueriesInPanel(np)
migrateCloudWatchQueriesInPanel(p)
// Handle nested panels in collapsed rows
if !IsArray(p["panels"]) {
continue
}
nestedPanels := p["panels"].([]interface{})
for _, nestedPanel := range nestedPanels {
np, ok := nestedPanel.(map[string]interface{})
if !ok {
continue
}
migrateCloudWatchQueriesInPanel(np)
}
}
}
@@ -91,10 +93,10 @@ func V34(_ context.Context, dashboard map[string]interface{}) error {
// migrateCloudWatchQueriesInPanel migrates CloudWatch queries within a panel that use multiple statistics.
func migrateCloudWatchQueriesInPanel(panel map[string]interface{}) {
targets, ok := panel["targets"].([]interface{})
if !ok {
if !IsArray(panel["targets"]) {
return
}
targets := panel["targets"].([]interface{})
var newTargets []interface{}
var additionalTargets []interface{}
@@ -111,20 +113,17 @@ func migrateCloudWatchQueriesInPanel(panel map[string]interface{}) {
continue
}
// Add CloudWatch fields if missing
if _, exists := t["metricEditorMode"]; !exists {
t["metricEditorMode"] = 0
}
if _, exists := t["metricQueryType"]; !exists {
t["metricQueryType"] = 0
}
// Add CloudWatch fields if missing (set to 0 if not present)
t["metricEditorMode"] = GetIntValue(t, "metricEditorMode", 0)
t["metricQueryType"] = GetIntValue(t, "metricQueryType", 0)
// Get valid statistics (including null and empty strings)
validStats, isEmpty := getValidStatistics(t["statistics"])
// Handle empty array case (preserve it)
// Handle empty array case (delete statistics field like frontend)
if isEmpty {
// Keep empty array as-is
// Delete statistics field to match frontend behavior
delete(t, "statistics")
newTargets = append(newTargets, t)
continue
}
@@ -139,10 +138,8 @@ func migrateCloudWatchQueriesInPanel(panel map[string]interface{}) {
newTargets = append(newTargets, t)
case 1:
// Single statistic - set statistic field if not null
if validStats[0] != nil {
if statString, ok := validStats[0].(string); ok {
t["statistic"] = statString
}
if statString := GetStringValue(map[string]interface{}{"stat": validStats[0]}, "stat"); statString != "" {
t["statistic"] = statString
}
newTargets = append(newTargets, t)
default:
@@ -175,10 +172,10 @@ func migrateCloudWatchAnnotationQueries(dashboard map[string]interface{}) {
return
}
annotationsList, ok := annotations["list"].([]interface{})
if !ok {
if !IsArray(annotations["list"]) {
return
}
annotationsList := annotations["list"].([]interface{})
var additionalAnnotations []interface{}
@@ -193,14 +190,15 @@ func migrateCloudWatchAnnotationQueries(dashboard map[string]interface{}) {
}
// Get original name for suffix generation
originalName, _ := a["name"].(string)
originalName := GetStringValue(a, "name")
// Get valid statistics (including null and empty strings)
validStats, isEmpty := getValidStatistics(a["statistics"])
// Handle empty array case (preserve it)
// Handle empty array case (delete statistics field like frontend)
if isEmpty {
// Keep empty array as-is
// Delete statistics field to match frontend behavior
delete(a, "statistics")
annotationsList[i] = a
continue
}
@@ -214,10 +212,8 @@ func migrateCloudWatchAnnotationQueries(dashboard map[string]interface{}) {
case 1:
// Single statistic - set statistic field if not null
delete(a, "statistics")
if validStats[0] != nil {
if statString, ok := validStats[0].(string); ok {
a["statistic"] = statString
}
if statString := GetStringValue(map[string]interface{}{"stat": validStats[0]}, "stat"); statString != "" {
a["statistic"] = statString
}
annotationsList[i] = a
default:
@@ -460,7 +460,6 @@ func TestV34(t *testing.T) {
"namespace": "AWS/EC2",
"region": "us-east-1",
"metricName": "CPUUtilization",
"statistics": []interface{}{},
"metricEditorMode": 0,
"metricQueryType": 0,
},
@@ -58,7 +58,12 @@ func V35(_ context.Context, dashboard map[string]interface{}) error {
// applyXAxisVisibilityOverride adds a field override to ensure x-axis visibility
// when the panel's default axis placement is set to hidden.
func applyXAxisVisibilityOverride(panel map[string]interface{}) {
fieldConfig, _ := panel["fieldConfig"].(map[string]interface{})
fieldConfig, ok := panel["fieldConfig"].(map[string]interface{})
if !ok {
// Only process panels that already have fieldConfig (matches frontend behavior)
return
}
defaults, _ := fieldConfig["defaults"].(map[string]interface{})
custom, _ := defaults["custom"].(map[string]interface{})
@@ -1,6 +1,8 @@
package schemaversion
import "context"
import (
"context"
)
// V36 migrates dashboard datasource references from legacy string format to structured UID-based objects.
//
@@ -130,18 +132,18 @@ func migrateTemplateVariables(dashboard map[string]interface{}, datasources []Da
continue
}
varType, ok := varMap["type"].(string)
if !ok || varType != "query" {
varType := GetStringValue(varMap, "type")
if varType != "query" {
continue
}
ds, exists := varMap["datasource"]
// Handle null datasource variables by setting to default
// Handle null datasource variables by setting to default (matches frontend behavior)
if !exists || ds == nil {
varMap["datasource"] = GetDataSourceRef(defaultDS)
} else {
varMap["datasource"] = MigrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": false}, datasources)
}
// Note: Frontend v36 migration only converts null datasources to default objects
// It does NOT convert string datasources to objects, so we should not do that either
}
}
@@ -170,13 +172,18 @@ func migratePanels(dashboard map[string]interface{}, datasources []DataSourceInf
if !ok {
continue
}
migratePanelDatasources(np, datasources)
migratePanelDatasourcesInternal(np, datasources, true)
}
}
}
// migratePanelDatasources updates datasource references in a single panel and its targets
func migratePanelDatasources(panelMap map[string]interface{}, datasources []DataSourceInfo) {
migratePanelDatasourcesInternal(panelMap, datasources, false)
}
// migratePanelDatasourcesInternal updates datasource references with nesting awareness
func migratePanelDatasourcesInternal(panelMap map[string]interface{}, datasources []DataSourceInfo, isNested bool) {
// NOTE: Even though row panels don't technically need datasource or targets fields,
// we process them anyway to exactly match frontend behavior and avoid inconsistencies
// between frontend and backend migrations. The frontend DashboardMigrator processes
@@ -185,32 +192,42 @@ func migratePanelDatasources(panelMap map[string]interface{}, datasources []Data
defaultDS := GetDefaultDSInstanceSettings(datasources)
panelDataSourceWasDefault := false
// Handle targets - treat empty arrays same as missing targets (matches frontend behavior)
// Handle targets - only add default targets to top-level panels (matches frontend behavior)
targets, hasTargets := panelMap["targets"].([]interface{})
if !hasTargets || len(targets) == 0 {
targets = []interface{}{
map[string]interface{}{
"refId": "A",
},
if !isNested {
// Add default target to top-level panels only
targets = []interface{}{
map[string]interface{}{
"refId": "A",
},
}
panelMap["targets"] = targets
hasTargets = true
} else {
// Nested panels without targets are not processed
return
}
panelMap["targets"] = targets
hasTargets = true
}
// Handle panel datasource
ds, exists := panelMap["datasource"]
if !exists || ds == nil {
// Set to default if panel has targets (matches frontend logic)
panelMap["datasource"] = GetDataSourceRef(defaultDS)
panelDataSourceWasDefault = true
} else {
// Migrate existing non-null datasource (should be null after V33)
migrated := MigrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": true}, datasources)
if migrated == nil {
// If migration returned nil, set to default
// Set to default if panel has targets with length > 0 (matches frontend logic)
if len(targets) > 0 {
// Matches frontend: panel.datasource = getDataSourceRef(defaultDs)
panelMap["datasource"] = GetDataSourceRef(defaultDS)
panelDataSourceWasDefault = true
}
} else {
// Migrate existing non-null datasource
// Frontend preserves existing datasource objects as-is, so backend should too
// But don't override empty objects {} that were set by previous migrations (like V33)
if dsMap, ok := ds.(map[string]interface{}); ok && len(dsMap) == 0 {
// Keep empty object {} as-is (set by V33 migration for empty strings)
panelMap["datasource"] = ds
} else {
migrated := MigrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": false}, datasources)
panelMap["datasource"] = migrated
}
}
@@ -240,14 +257,21 @@ func migratePanelDatasources(panelMap map[string]interface{}, datasources []Data
}
if needsDefault {
// Use panel's datasource if it's not mixed
// Frontend: if (panel.datasource?.uid !== MIXED_DATASOURCE_NAME) { target.datasource = { ...panel.datasource }; }
panelDS, ok := panelMap["datasource"].(map[string]interface{})
if ok {
uid, hasUID := panelDS["uid"].(string)
if hasUID && uid != "-- Mixed --" {
targetMap["datasource"] = panelDS
uid := GetStringValue(panelDS, "uid")
isMixed := uid == "-- Mixed --"
if !isMixed {
// Spread the panel datasource properties (mimics frontend: { ...panel.datasource })
result := make(map[string]interface{})
for k, v := range panelDS {
result[k] = v
}
targetMap["datasource"] = result
} else {
// If panel is mixed, migrate target datasource independently
// Frontend: target.datasource = migrateDatasourceNameToRef(target.datasource, { returnDefaultAsNull: false });
targetMap["datasource"] = MigrateDatasourceNameToRef(ds, map[string]bool{"returnDefaultAsNull": false}, datasources)
}
}
@@ -260,8 +284,8 @@ func migratePanelDatasources(panelMap map[string]interface{}, datasources []Data
if panelDataSourceWasDefault {
targetDS, ok := targetMap["datasource"].(map[string]interface{})
if ok {
uid, ok := targetDS["uid"].(string)
if ok && uid != "__expr__" {
uid := GetStringValue(targetDS, "uid")
if uid != "" && uid != "__expr__" {
panelMap["datasource"] = targetDS
}
}
@@ -1,943 +1,10 @@
package schemaversion_test
package schemaversion
import (
"testing"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
"github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
)
func TestV36(t *testing.T) {
// Pass the mock provider to V36
migration := schemaversion.V36(testutil.GetTestDataSourceProvider())
tests := []migrationTestCase{
{
name: "dashboard with no datasources",
input: map[string]interface{}{
"schemaVersion": 35,
},
expected: map[string]interface{}{
"schemaVersion": 36,
},
},
{
name: "panel with null datasource and targets should get default datasource",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
},
},
},
{
name: "panel with null datasource and empty targets array should get default datasource and targets",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"id": 2,
"datasource": nil,
"targets": []interface{}{},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"id": 2,
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
},
},
},
{
name: "panel with null datasource and no targets property should get default datasource and targets",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"id": 3,
"datasource": nil,
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"id": 3,
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
},
},
},
{
name: "panel with mixed datasources should preserve target datasources",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "-- Mixed --",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": "existing-target-uid",
},
map[string]interface{}{
"refId": "B",
"datasource": "existing-ref-uid",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "-- Mixed --",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "existing-ref-uid",
"apiVersion": "v1",
},
},
},
},
},
},
},
{
name: "panel with specific datasource should apply to targets without datasource",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"datasource": "existing-ref-uid",
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": nil,
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": nil,
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "existing-ref-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "existing-ref-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "existing-ref-uid",
"apiVersion": "v1",
},
},
},
},
},
},
},
{
name: "panel with null datasource should inherit from target datasource (panelDataSourceWasDefault logic)",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": "existing-target-uid",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
},
},
},
},
},
{
name: "panel with expression queries should not inherit panel datasource from expression",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": "existing-target-uid",
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": "__expr__",
"type": "__expr__",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": "__expr__",
"type": "__expr__",
},
},
},
},
},
},
},
{
name: "panel with unknown datasource name should preserve as UID",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"datasource": "unknown-datasource",
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": "another-unknown-ds",
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"uid": "unknown-datasource",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "another-unknown-ds",
},
},
},
},
},
},
},
{
name: "nested panels in collapsed row should be migrated",
input: map[string]interface{}{
"schemaVersion": 35,
"panels": []interface{}{
map[string]interface{}{
"type": "row",
"panels": []interface{}{
map[string]interface{}{
"datasource": "existing-ref-uid",
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": nil,
},
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"panels": []interface{}{
map[string]interface{}{
"type": "row",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
"panels": []interface{}{
map[string]interface{}{
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "existing-ref-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "existing-ref-uid",
"apiVersion": "v1",
},
},
},
},
},
},
},
},
},
{
name: "annotations should migrate datasource references with returnDefaultAsNull: false",
input: map[string]interface{}{
"schemaVersion": 35,
"annotations": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "Default Annotation",
"datasource": "default",
},
map[string]interface{}{
"name": "Named Datasource Annotation",
"datasource": "Existing Target Name",
},
map[string]interface{}{
"name": "UID Datasource Annotation",
"datasource": "existing-target-uid",
},
map[string]interface{}{
"name": "Null Datasource Annotation",
"datasource": nil,
},
map[string]interface{}{
"name": "Unknown Datasource Annotation",
"datasource": "unknown-ds",
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"annotations": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "Default Annotation",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"name": "Named Datasource Annotation",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"name": "UID Datasource Annotation",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"name": "Null Datasource Annotation",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"name": "Unknown Datasource Annotation",
"datasource": map[string]interface{}{
"uid": "unknown-ds",
},
},
},
},
},
},
{
name: "template variables should migrate query variables only",
input: map[string]interface{}{
"schemaVersion": 35,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "query_var_null",
"datasource": nil,
},
map[string]interface{}{
"type": "query",
"name": "query_var_named",
"datasource": "Existing Target Name",
},
map[string]interface{}{
"type": "query",
"name": "query_var_uid",
"datasource": "existing-target-uid",
},
map[string]interface{}{
"type": "constant",
"name": "non_query_var",
"datasource": nil,
},
map[string]interface{}{
"type": "query",
"name": "query_var_unknown",
"datasource": "unknown-ds",
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"type": "query",
"name": "query_var_null",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"type": "query",
"name": "query_var_named",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"type": "query",
"name": "query_var_uid",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"type": "constant",
"name": "non_query_var",
"datasource": nil,
},
map[string]interface{}{
"type": "query",
"name": "query_var_unknown",
"datasource": map[string]interface{}{
"uid": "unknown-ds",
},
},
},
},
},
},
{
name: "comprehensive migration scenario matching integration test structure",
input: map[string]interface{}{
"schemaVersion": 35,
"title": "Datasource Reference Migration Test Dashboard",
"annotations": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "Default Annotation",
"datasource": "default",
},
map[string]interface{}{
"name": "Named Datasource Annotation",
"datasource": "Existing Target Name",
},
map[string]interface{}{
"name": "UID Datasource Annotation",
"datasource": "existing-target-uid",
},
map[string]interface{}{
"name": "Null Datasource Annotation",
"datasource": nil,
},
},
},
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "query_var_null",
"type": "query",
"datasource": nil,
},
map[string]interface{}{
"name": "query_var_named",
"type": "query",
"datasource": "Existing Target Name",
},
map[string]interface{}{
"name": "query_var_uid",
"type": "query",
"datasource": "existing-target-uid",
},
map[string]interface{}{
"name": "non_query_var",
"type": "constant",
"datasource": nil,
},
},
},
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"title": "Panel with Null Datasource and Targets",
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": nil,
},
},
},
map[string]interface{}{
"id": 2,
"title": "Panel with Null Datasource and Empty Targets",
"datasource": nil,
"targets": []interface{}{},
},
map[string]interface{}{
"id": 3,
"title": "Panel with No Targets Array",
"datasource": nil,
},
map[string]interface{}{
"id": 4,
"title": "Panel with Mixed Datasources",
"datasource": map[string]interface{}{
"uid": "-- Mixed --",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": nil,
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
},
},
},
map[string]interface{}{
"id": 5,
"title": "Panel with Existing Object Datasource",
"datasource": map[string]interface{}{
"uid": "existing-ref",
"type": "prometheus",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
"type": "loki",
},
},
},
},
map[string]interface{}{
"id": 7,
"title": "Panel with Expression Query",
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": "__expr__",
"type": "__expr__",
},
},
},
},
map[string]interface{}{
"id": 8,
"title": "Panel Inheriting from Target",
"datasource": nil,
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
},
},
},
},
},
expected: map[string]interface{}{
"schemaVersion": 36,
"title": "Datasource Reference Migration Test Dashboard",
"annotations": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "Default Annotation",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"name": "Named Datasource Annotation",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"name": "UID Datasource Annotation",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"name": "Null Datasource Annotation",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
"templating": map[string]interface{}{
"list": []interface{}{
map[string]interface{}{
"name": "query_var_null",
"type": "query",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"name": "query_var_named",
"type": "query",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"name": "query_var_uid",
"type": "query",
"datasource": map[string]interface{}{
"type": "elasticsearch",
"uid": "existing-target-uid",
"apiVersion": "v2",
},
},
map[string]interface{}{
"name": "non_query_var",
"type": "constant",
"datasource": nil,
},
},
},
"panels": []interface{}{
map[string]interface{}{
"id": 1,
"title": "Panel with Null Datasource and Targets",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
map[string]interface{}{
"id": 2,
"title": "Panel with Null Datasource and Empty Targets",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
map[string]interface{}{
"id": 3,
"title": "Panel with No Targets Array",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
},
},
map[string]interface{}{
"id": 4,
"title": "Panel with Mixed Datasources",
"datasource": map[string]interface{}{
"uid": "-- Mixed --",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"type": "prometheus",
"uid": "default-ds-uid",
"apiVersion": "v1",
},
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
},
},
},
map[string]interface{}{
"id": 5,
"title": "Panel with Existing Object Datasource",
"datasource": map[string]interface{}{
"uid": "existing-ref",
"type": "prometheus",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
"type": "loki",
},
},
},
},
map[string]interface{}{
"id": 7,
"title": "Panel with Expression Query",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
},
map[string]interface{}{
"refId": "B",
"datasource": map[string]interface{}{
"uid": "__expr__",
"type": "__expr__",
},
},
},
},
map[string]interface{}{
"id": 8,
"title": "Panel Inheriting from Target",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
"targets": []interface{}{
map[string]interface{}{
"refId": "A",
"datasource": map[string]interface{}{
"uid": "existing-target-uid",
},
},
},
},
},
},
},
}
runMigrationTests(t, tests, migration)
func TestV36DatasourceMigration(t *testing.T) {
// Test implementation will be added
t.Log("V36 migration tests - to be implemented")
}
@@ -115,10 +115,10 @@ func processPanelsV37(panels []interface{}) {
continue
}
displayMode, _ := legend["displayMode"].(string)
displayMode := GetStringValue(legend, "displayMode")
showLegend, hasShowLegend := legend["showLegend"].(bool)
// If displayMode is "hidden" OR showLegend is false, normalize to hidden legend
// If displayMode is "hidden" OR showLegend is explicitly false, normalize to hidden legend
if displayMode == "hidden" || (hasShowLegend && !showLegend) {
legend["displayMode"] = "list"
legend["showLegend"] = false
@@ -167,6 +167,12 @@ func migrateOverrides(fieldConfig map[string]interface{}) {
if valueStr, ok := value.(string); ok {
prop["value"] = migrateTableDisplayModeToCellOptions(valueStr)
}
} else {
// If no value exists, add empty cellOptions object to match frontend behavior
// Frontend always assigns a value even when original displayMode had no value
// See: public/app/features/dashboard/state/DashboardMigrator.ts:880
// override.properties[j].value = migrateTableDisplayModeToCellOptions(overrideDisplayMode);
prop["value"] = map[string]interface{}{}
}
}
}
@@ -37,8 +37,7 @@ import "context"
// refresh: "" // property added with empty string
func V40(_ context.Context, dash map[string]interface{}) error {
dash["schemaVersion"] = int(40)
if _, ok := dash["refresh"].(string); !ok {
dash["refresh"] = ""
}
// Ensure refresh is a string, set to empty string if missing or not a string
dash["refresh"] = GetStringValue(dash, "refresh")
return nil
}
@@ -77,7 +77,7 @@ func migrateHideFromForPanel(panel map[string]interface{}) {
}
// Check if this is a custom.hideFrom property
if id, ok := property["id"].(string); ok && id == "custom.hideFrom" {
if id := GetStringValue(property, "id"); id == "custom.hideFrom" {
if value, ok := property["value"].(map[string]interface{}); ok {
// If viz is true, also set tooltip to true
if GetBoolValue(value, "viz") {
@@ -0,0 +1,988 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [
{
"asDropdown": true,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"gdev",
"panel-tests"
],
"targetBlank": false,
"title": "Dropdown link",
"tooltip": "",
"type": "dashboards",
"url": ""
},
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [],
"targetBlank": false,
"title": "External link",
"tooltip": "localhost",
"type": "link",
"url": "localhost:3000"
}
],
"panels": [
{
"gridPos": {
"h": 3,
"w": 12,
"x": 0,
"y": 0
},
"id": 34,
"options": {
"content": "# All panels\n\nThis dashboard was created to quickly check accessiblity issues on a lot of panels at the same time ",
"mode": "markdown"
},
"pluginVersion": "8.1.0-pre",
"transparent": true,
"type": "text"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 9,
"x": 0,
"y": 0
},
"id": 62,
"options": {
"basemap": {
"config": {},
"type": "default"
},
"controls": {
"mouseWheelZoom": true,
"showAttribution": true,
"showDebug": false,
"showScale": false,
"showZoom": true
},
"layers": [
{
"config": {
"color": {
"field": "Price",
"fixed": "dark-green"
},
"fillOpacity": 0.4,
"shape": "circle",
"showLegend": true,
"size": {
"field": "Count",
"fixed": 5,
"max": 15,
"min": 2
}
},
"location": {
"gazetteer": "public/gazetteer/usa-states.json",
"lookup": "State",
"mode": "auto"
},
"type": "markers"
}
],
"view": {
"id": "coords",
"lat": 38.297683,
"lon": -99.228359,
"shared": true,
"zoom": 3.98
}
},
"targets": [
{
"csvFileName": "flight_info_by_state.csv",
"refId": "A",
"scenarioId": "csv_file"
}
],
"title": "Size, color mapped to different fields + share view",
"type": "geomap"
},
{
"gridPos": {
"h": 3,
"w": 12,
"x": 12,
"y": 0
},
"id": 35,
"options": {
"content": "# Another text panel\n\nBecause why not",
"mode": "markdown"
},
"pluginVersion": "8.1.0-pre",
"transparent": true,
"type": "text"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 3
},
"id": 32,
"panels": [],
"title": "Row title",
"type": "row"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"fillOpacity": 70,
"lineWidth": 1
},
"mappings": [
{
"options": {
"CRITICAL": {
"color": "red",
"index": 3
},
"HIGH": {
"color": "orange",
"index": 2
},
"LOW": {
"color": "blue",
"index": 0
},
"NORMAL": {
"color": "green",
"index": 1
}
},
"type": "value"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 24,
"x": 0,
"y": 4
},
"id": 41,
"options": {
"alignValue": "left",
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"mergeValues": true,
"rowHeight": 0.99,
"showValue": "auto",
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "LOW,HIGH,NORMAL,NORMAL,NORMAL,LOW,LOW,NORMAL,HIGH,CRITICAL"
},
{
"refId": "B",
"scenarioId": "csv_metric_values",
"stringInput": "NORMAL,LOW,LOW,CRITICAL,CRITICAL,LOW,LOW,NORMAL,HIGH,CRITICAL"
},
{
"refId": "C",
"scenarioId": "csv_metric_values",
"stringInput": "NORMAL,NORMAL,NORMAL,NORMAL,CRITICAL,LOW,NORMAL,NORMAL,NORMAL,LOW"
}
],
"title": "State timeline",
"type": "state-timeline"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"fillOpacity": 80,
"gradientMode": "hue",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 1
},
"links": [
{
"title": "Data link",
"url": "/"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 13
},
"id": 4,
"options": {
"bucketOffset": 0,
"combine": false,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
}
},
"title": "Histogram",
"type": "histogram"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 21
},
"id": 28,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"refId": "A",
"scenarioId": "logs"
}
],
"title": "Logs",
"type": "logs"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 21
},
"id": 8,
"options": {
"maxItems": 10,
"query": "",
"showHeadings": true,
"showRecentlyViewed": true,
"showSearch": true,
"showStarred": true,
"tags": []
},
"pluginVersion": "8.1.0-pre",
"title": "Dashboard list",
"type": "dashlist"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 29
},
"id": 6,
"options": {
"alertName": "",
"dashboardAlerts": false,
"maxItems": 20,
"showInstances": false,
"sortOrder": 1,
"stateFilter": {
"firing": true,
"inactive": false,
"pending": true
}
},
"title": "Alert list",
"type": "alertlist"
},
{
"cards": {},
"color": {
"cardColor": "#b4ff00",
"colorScale": "sqrt",
"colorScheme": "interpolateOranges",
"exponent": 0.5,
"mode": "spectrum"
},
"dataFormat": "timeseries",
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 37
},
"heatmap": {},
"hideZeroBuckets": false,
"highlightCards": true,
"id": 26,
"legend": {
"show": false
},
"reverseYBuckets": false,
"targets": [
{
"refId": "A",
"scenarioId": "exponential_heatmap_bucket_data"
}
],
"title": "Heatmap",
"tooltip": {
"show": true,
"showHistogram": false
},
"type": "heatmap",
"xAxis": {
"show": true
},
"yAxis": {
"format": "short",
"logBase": 1,
"show": true
},
"yBucketBound": "auto"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 37
},
"id": 20,
"options": {
"displayMode": "gradient",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"text": {}
},
"pluginVersion": "8.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 10
}
],
"title": "Bar gauge",
"type": "bargauge"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 45
},
"id": 24,
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 6
}
],
"title": "Pie chart",
"type": "piechart"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 45
},
"id": 18,
"options": {
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true,
"showValue": "auto",
"text": {}
},
"pluginVersion": "8.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 3
}
],
"title": "Gauge",
"type": "gauge"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 53
},
"id": 22,
"options": {
"showHeader": true
},
"pluginVersion": "8.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "table_static"
}
],
"title": "Tabel",
"type": "table"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 53
},
"id": 10,
"options": {
"limit": 10,
"navigateAfter": "10m",
"navigateBefore": "10m",
"onlyFromThisDashboard": false,
"onlyInTimeRange": false,
"showTags": true,
"showTime": true,
"showUser": true
},
"title": "Annotation list",
"type": "annolist"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 61
},
"id": 16,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"text": {},
"textMode": "auto"
},
"pluginVersion": "8.1.0-pre",
"title": "Stat",
"type": "stat"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 61
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 4,
"spread": 120
}
],
"title": "Graph NG",
"type": "timeseries"
},
{
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 1
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 69
},
"id": 14,
"options": {
"barWidth": 0.97,
"groupWidth": 0.7,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"csvContent": "Series, Value\nBar 2, 20\nBar 3, 25\nBar 3, 55.4",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Bar chart",
"type": "barchart"
},
{
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 77
},
"id": 12,
"options": {
"showImage": true
},
"title": "News panel",
"type": "news"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"panel-tests",
"all-panels"
],
"templating": {
"list": [
{
"current": {},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "query0",
"options": [],
"query": {
"query": "*",
"refId": "StandardVariableQuery"
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
},
{
"current": {
"selected": true,
"text": "7",
"value": "7"
},
"hide": 0,
"includeAll": false,
"multi": false,
"name": "query1",
"options": [
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "5",
"value": "5"
},
{
"selected": false,
"text": "6",
"value": "6"
},
{
"selected": true,
"text": "7",
"value": "7"
}
],
"query": "1,5,6,7",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": false,
"text": "",
"value": ""
},
"description": "This is some descriptive text",
"hide": 0,
"label": "Plain text",
"name": "text",
"options": [
{
"selected": true,
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Panel tests - All panels",
"uid": "n1jR8vnnz",
"weekStart": ""
}
@@ -0,0 +1,427 @@
{
"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"
},
{
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"enable": true,
"filter": {
"exclude": false,
"ids": [
1
]
},
"iconColor": "red",
"name": "Red, only panel 1",
"target": {
"lines": 4,
"refId": "Anno",
"scenarioId": "annotations"
}
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"enable": true,
"filter": {
"exclude": true,
"ids": [
1
]
},
"iconColor": "yellow",
"name": "Yellow - all except 1",
"target": {
"lines": 5,
"refId": "Anno",
"scenarioId": "annotations"
}
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"enable": true,
"filter": {
"exclude": false,
"ids": [
3,
4
]
},
"iconColor": "dark-purple",
"name": "Purple only panel 3+4",
"target": {
"lines": 6,
"refId": "Anno",
"scenarioId": "annotations"
}
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 119,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"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": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel one",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel two",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel three",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel four",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"annotations"
],
"templating": {
"list": []
},
"time": {
"from": "now-30m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Annotation filtering",
"uid": "ed155665",
"weekStart": ""
}
@@ -0,0 +1,213 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": true,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-influxdb1-influxql"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 6,
"w": 24,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": false,
"total": false,
"values": false
},
"lines": false,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Count",
"datasource": {
"uid": "gdev-influxdb1-influxql"
},
"groupBy": [
{
"params": [
"1m"
],
"type": "time"
},
{
"params": [
"null"
],
"type": "fill"
}
],
"measurement": "t_logs",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"message"
],
"type": "field"
},
{
"params": [],
"type": "count"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeRegions": [],
"title": "Log messages over time",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"uid": "gdev-influxdb1-influxql"
},
"gridPos": {
"h": 18,
"w": 24,
"x": 0,
"y": 6
},
"id": 2,
"options": {
"showLabels": false,
"showTime": true,
"sortOrder": "Descending",
"wrapLogMessage": true
},
"targets": [
{
"datasource": {
"uid": "gdev-influxdb1-influxql"
},
"groupBy": [],
"measurement": "t_logs",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "table",
"select": [
[
{
"params": [
"message"
],
"type": "field"
}
]
],
"tags": []
}
],
"title": "Logs",
"type": "logs"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"influxdb",
"datasource-test"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Datasource tests - InfluxDB Logs",
"uid": "yjRroGsWk",
"weekStart": ""
}
@@ -0,0 +1,331 @@
{
"annotations": {
"enable": false,
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"aliasColors": {},
"annotate": {
"enable": false
},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-influxdb1-influxql"
},
"editable": true,
"error": false,
"fill": 2,
"grid": {},
"gridPos": {
"h": 9,
"w": 24,
"x": 0,
"y": 0
},
"id": 1,
"interval": "$summarize",
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"resolution": 100,
"scale": 1,
"seriesOverrides": [],
"spaceLength": 10,
"stack": true,
"steppedLine": false,
"targets": [
{
"alias": "$tag_hostname",
"datasource": {
"uid": "gdev-influxdb1-influxql"
},
"dsType": "influxdb",
"groupBy": [
{
"params": [
"auto"
],
"type": "time"
},
{
"params": [
"hostname"
],
"type": "tag"
}
],
"measurement": "logins.count",
"policy": "default",
"query": "SELECT mean(\"value\") FROM \"logins.count\" WHERE \"hostname\" =~ /$Hostname$/ AND $timeFilter GROUP BY time($interval), \"hostname\"",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"value"
],
"type": "field"
},
{
"params": [],
"type": "mean"
}
]
],
"tags": [
{
"key": "datacenter",
"operator": "=~",
"value": "/^$datacenter$/"
},
{
"condition": "AND",
"key": "hostname",
"operator": "=~",
"value": "/^$host$/"
}
],
"target": ""
}
],
"thresholds": [],
"timeRegions": [],
"title": "Selected Servers",
"tooltip": {
"msResolution": false,
"query_as_alias": true,
"shared": false,
"sort": 0,
"value_type": "cumulative"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
},
"zerofill": true
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"datasource-test",
"influxdb"
],
"templating": {
"list": [
{
"current": {
"text": "America",
"value": "America"
},
"datasource": "gdev-influxdb1-influxql",
"definition": "",
"hide": 0,
"includeAll": false,
"multi": false,
"name": "datacenter",
"options": [],
"query": "SHOW TAG VALUES WITH KEY = \"datacenter\" ",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query",
"useTags": false
},
{
"allFormat": "regex values",
"current": {
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": "gdev-influxdb1-influxql",
"definition": "",
"hide": 0,
"includeAll": true,
"multi": true,
"multiFormat": "regex values",
"name": "host",
"options": [],
"query": "SHOW TAG VALUES WITH KEY = \"hostname\" WHERE \"datacenter\" =~ /^$datacenter$/",
"refresh": 1,
"refresh_on_load": false,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query",
"useTags": false
},
{
"allFormat": "glob",
"auto": true,
"auto_count": 5,
"auto_min": "10s",
"current": {
"text": "1m",
"value": "1m"
},
"hide": 0,
"includeAll": false,
"label": "",
"name": "summarize",
"options": [
{
"selected": false,
"text": "auto",
"value": "$__auto_interval_summarize"
},
{
"selected": true,
"text": "1m",
"value": "1m"
},
{
"selected": false,
"text": "10m",
"value": "10m"
},
{
"selected": false,
"text": "30m",
"value": "30m"
},
{
"selected": false,
"text": "1h",
"value": "1h"
},
{
"selected": false,
"text": "6h",
"value": "6h"
},
{
"selected": false,
"text": "12h",
"value": "12h"
},
{
"selected": false,
"text": "1d",
"value": "1d"
},
{
"selected": false,
"text": "7d",
"value": "7d"
},
{
"selected": false,
"text": "14d",
"value": "14d"
},
{
"selected": false,
"text": "30d",
"value": "30d"
}
],
"query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
"refresh": 2,
"refresh_on_load": false,
"skipUrlSync": false,
"type": "interval"
},
{
"datasource": "gdev-influxdb1-influxql",
"filters": [],
"hide": 0,
"name": "adhoc",
"skipUrlSync": false,
"type": "adhoc"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"collapse": false,
"enable": true,
"notice": false,
"now": true,
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"status": "Stable",
"type": "timepicker"
},
"timezone": "browser",
"title": "Datasource tests - InfluxDB Templated",
"uid": "000000002",
"weekStart": ""
}
@@ -0,0 +1,428 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 203,
"links": [],
"liveNow": false,
"panels": [
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 7,
"panels": [],
"title": "Logs",
"type": "row"
},
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 1
},
"id": 2,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": true,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"editorMode": "builder",
"expr": "{place=\"$place\"} |= ``",
"maxLines": 60,
"queryType": "range",
"refId": "A"
}
],
"title": "(Variable) $place logs",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 1
},
"id": 3,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": true,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"editorMode": "builder",
"expr": "{place=\"$place\"} |= `error`",
"maxLines": 60,
"queryType": "range",
"refId": "A"
}
],
"title": "(Variable) $place errors",
"type": "logs"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 10
},
"id": 9,
"panels": [],
"title": "Time Series",
"type": "row"
},
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineStyle": {
"fill": "solid"
},
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 24,
"x": 0,
"y": 11
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "9.4.0-pre",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"editorMode": "builder",
"expr": "count_over_time({place=\"$place\"} [5m])",
"legendFormat": "{{place}}",
"maxLines": 60,
"queryType": "range",
"refId": "A"
}
],
"title": "(Variable) No. of $place logs over the last 5m",
"type": "timeseries"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 17
},
"id": 11,
"panels": [],
"title": "Stats",
"type": "row"
},
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 18
},
"id": 20,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.4.0-pre",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"editorMode": "code",
"expr": "count_over_time({place=\"moon\"} [5m])",
"legendFormat": "{{place}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Moon Log count over 5m",
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"fieldConfig": {
"defaults": {
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 18
},
"id": 19,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.4.0-pre",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"editorMode": "code",
"expr": "count_over_time({place=\"luna\"} [5m])",
"legendFormat": "{{place}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Luna Log count over 5m",
"type": "stat"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"loki",
"datasource-test"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "luna",
"value": "luna"
},
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Place",
"multi": false,
"name": "place",
"options": [],
"query": {
"label": "place",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "",
"type": 1
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
},
{
"datasource": {
"type": "loki",
"uid": "PDDA8E780A17E7EF1"
},
"filters": [],
"hide": 0,
"label": "Ad-hoc",
"name": "adhoc",
"skipUrlSync": false,
"type": "adhoc"
}
]
},
"time": {
"from": "now-5m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Datasource tests - Loki",
"uid": "22mq9eSVz",
"weekStart": ""
}
@@ -0,0 +1,592 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": false,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Annotations \u0026 Alerts",
"showIn": 0,
"type": "dashboard"
},
{
"datasource": {
"uid": "gdev-mssql"
},
"enable": false,
"hide": false,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Single",
"rawQuery": "SELECT TOP 1\n createdAt as time,\n 'single' as text,\n hostname as tags\nFROM\n grafana_metric\nWHERE\n $__timeFilter(createdAt)\nORDER BY time\n",
"showIn": 0,
"tags": [],
"type": "tags"
},
{
"datasource": {
"uid": "gdev-mssql"
},
"enable": false,
"hide": false,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Region",
"rawQuery": "SELECT TOP 1\n DATEADD(MINUTE, 1, createdAt) as time,\n DATEADD(MINUTE, 6, createdAt) as timeend,\n 'region' as text,\n hostname as tags\nFROM\n grafana_metric\nWHERE\n $__timeFilter(createdAt)\nORDER BY time",
"showIn": 0,
"tags": [],
"type": "tags"
}
]
},
"description": "A dashboard visualizing data generated from grafana/fake-data-gen",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"aliasColors": {
"total avg": "#6ed0e0"
},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-mssql"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [
{
"alias": "total avg",
"fill": 0,
"pointradius": 3,
"points": true
}
],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mssql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time,\n avg(value) as value,\n hostname as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'logins.count' AND\n hostname IN($host)\nGROUP BY $__timeGroup(createdAt,'$summarize'), hostname\nORDER BY 1",
"refId": "A"
},
{
"alias": "",
"datasource": {
"uid": "gdev-mssql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time,\n min(value) as value,\n 'total avg' as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'logins.count'\nGROUP BY $__timeGroup(createdAt,'$summarize')\nORDER BY 1",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Average logins / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-mssql"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 18,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 8,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mssql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time,\n avg(value) as value,\n 'started' as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'payment.started'\nGROUP BY $__timeGroup(createdAt,'$summarize')\nORDER BY 1",
"refId": "A"
},
{
"alias": "",
"datasource": {
"uid": "gdev-mssql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time,\n avg(value) as value,\n 'ended' as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'payment.ended'\nGROUP BY $__timeGroup(createdAt,'$summarize')\nORDER BY 1",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Average payments started/ended / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-mssql"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"hiddenSeries": false,
"id": 6,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mssql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time,\n max(value) as value,\n hostname as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'cpu' AND\n hostname IN($host)\nGROUP BY $__timeGroup(createdAt,'$summarize'), hostname\nORDER BY 1",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Max CPU / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"uid": "gdev-mssql"
},
"fieldConfig": {
"defaults": {
"custom": {
"cellOptions": {
"type": "auto"
},
"footer": {
"reducers": []
},
"inspect": false
},
"decimals": 2,
"displayName": "",
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Time"
},
"properties": [
{
"id": "displayName",
"value": "Time"
},
{
"id": "unit",
"value": "time: YYYY-MM-DD HH:mm:ss"
},
{
"id": "custom.align"
}
]
}
]
},
"gridPos": {
"h": 10,
"w": 24,
"x": 0,
"y": 18
},
"id": 4,
"options": {
"cellHeight": "sm",
"showHeader": true
},
"pluginVersion": "12.1.0",
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mssql"
},
"format": "table",
"rawSql": "SELECT createdAt as Time, source, datacenter, hostname, value FROM grafana_metric WHERE hostname in($host)",
"refId": "A"
}
],
"title": "Values",
"transformations": [
{
"id": "merge",
"options": {
"reducers": []
}
}
],
"type": "table"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"mssql",
"datasource-test"
],
"templating": {
"list": [
{
"current": {
"text": "Africa",
"value": "Africa"
},
"datasource": "gdev-mssql",
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Datacenter",
"multi": false,
"name": "datacenter",
"options": [],
"query": "SELECT DISTINCT datacenter FROM grafana_metric",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": "gdev-mssql",
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
"multi": true,
"name": "host",
"options": [],
"query": "SELECT DISTINCT hostname FROM grafana_metric WHERE datacenter='$datacenter'",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"auto": false,
"auto_count": 30,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
"hide": 0,
"label": "Summarize",
"name": "summarize",
"options": [
{
"selected": false,
"text": "1s",
"value": "1s"
},
{
"selected": false,
"text": "10s",
"value": "10s"
},
{
"selected": false,
"text": "30s",
"value": "30s"
},
{
"selected": true,
"text": "1m",
"value": "1m"
},
{
"selected": false,
"text": "5m",
"value": "5m"
},
{
"selected": false,
"text": "10m",
"value": "10m"
},
{
"selected": false,
"text": "30m",
"value": "30m"
},
{
"selected": false,
"text": "1h",
"value": "1h"
},
{
"selected": false,
"text": "6h",
"value": "6h"
},
{
"selected": false,
"text": "12h",
"value": "12h"
},
{
"selected": false,
"text": "1d",
"value": "1d"
},
{
"selected": false,
"text": "7d",
"value": "7d"
},
{
"selected": false,
"text": "14d",
"value": "14d"
},
{
"selected": false,
"text": "30d",
"value": "30d"
}
],
"query": "1s,10s,30s,1m,5m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
"refresh": 2,
"skipUrlSync": false,
"type": "interval"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Datasource tests - MSSQL",
"uid": "86Js1xRmk",
"weekStart": ""
}
@@ -0,0 +1,595 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": false,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
},
{
"datasource": {
"uid": "gdev-mysql"
},
"enable": false,
"hide": false,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Single",
"rawQuery": "SELECT\n createdAt as time,\n 'single' as text,\n hostname as tags\nFROM\n grafana_metric\nWHERE\n $__timeFilter(createdAt)\nORDER BY time\nLIMIT 1\n",
"showIn": 0,
"tags": [],
"type": "tags"
},
{
"datasource": {
"uid": "gdev-mysql"
},
"enable": false,
"hide": false,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Region",
"rawQuery": "SELECT\n ADDTIME(createdAt, '00:01:00') as time,\n ADDTIME(createdAt, '00:06:00') as timeend,\n 'region' as text,\n hostname as tags\nFROM\n grafana_metric\nWHERE\n $__timeFilter(createdAt)\nORDER BY time\nLIMIT 1\n",
"showIn": 0,
"tags": [],
"type": "tags"
}
]
},
"description": "A dashboard visualizing data generated from grafana/fake-data-gen",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"aliasColors": {
"total avg": "#6ed0e0"
},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-mysql"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [
{
"alias": "total avg",
"fill": 0,
"pointradius": 3,
"points": true
}
],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mysql"
},
"format": "time_series",
"hide": false,
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time_sec,\n avg(value) as value,\n hostname as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'logins.count' AND\n hostname IN($host)\nGROUP BY 1, 3\nORDER BY 1",
"refId": "A",
"target": ""
},
{
"alias": "",
"datasource": {
"uid": "gdev-mysql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time_sec,\n min(value) as value,\n 'total avg' as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'logins.count'\nGROUP BY 1\nORDER BY 1",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Average logins / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-mysql"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 18,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mysql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time_sec,\n avg(value) as value,\n 'started' as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'payment.started'\nGROUP BY 1, 3\nORDER BY 1",
"refId": "A",
"target": ""
},
{
"alias": "",
"datasource": {
"uid": "gdev-mysql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time_sec,\n avg(value) as value,\n 'ended' as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'payment.ended'\nGROUP BY 1, 3\nORDER BY 1",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Average payments started/ended / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-mysql"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"hiddenSeries": false,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mysql"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(createdAt,'$summarize') as time_sec,\n max(value) as value,\n hostname as metric\nFROM \n grafana_metric\nWHERE\n $__timeFilter(createdAt) AND\n measurement = 'cpu' AND\n hostname IN($host)\nGROUP BY 1, 3\nORDER BY 1",
"refId": "A",
"target": ""
}
],
"thresholds": [],
"timeRegions": [],
"title": "Max CPU / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"uid": "gdev-mysql"
},
"fieldConfig": {
"defaults": {
"custom": {
"cellOptions": {
"type": "auto"
},
"footer": {
"reducers": []
},
"inspect": false
},
"decimals": 2,
"displayName": "",
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Time"
},
"properties": [
{
"id": "displayName",
"value": "Time"
},
{
"id": "unit",
"value": "time: YYYY-MM-DD HH:mm:ss"
},
{
"id": "custom.align"
}
]
}
]
},
"gridPos": {
"h": 9,
"w": 24,
"x": 0,
"y": 18
},
"id": 6,
"options": {
"cellHeight": "sm",
"showHeader": true
},
"pluginVersion": "12.1.0",
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-mysql"
},
"format": "table",
"rawSql": "SELECT createdAt as Time, source, datacenter, hostname, value FROM grafana_metric WHERE hostname in($host)",
"refId": "A",
"target": ""
}
],
"title": "Values",
"transformations": [
{
"id": "merge",
"options": {
"reducers": []
}
}
],
"type": "table"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"mysql",
"datasource-tags"
],
"templating": {
"list": [
{
"current": {
"text": "America",
"value": "America"
},
"datasource": "gdev-mysql",
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Datacenter",
"multi": false,
"name": "datacenter",
"options": [],
"query": "SELECT DISTINCT datacenter FROM grafana_metric",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": "gdev-mysql",
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
"multi": true,
"name": "host",
"options": [],
"query": "SELECT DISTINCT hostname FROM grafana_metric WHERE datacenter='$datacenter'",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"auto": false,
"auto_count": 5,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
"hide": 0,
"label": "Summarize",
"name": "summarize",
"options": [
{
"selected": false,
"text": "1s",
"value": "1s"
},
{
"selected": false,
"text": "10s",
"value": "10s"
},
{
"selected": false,
"text": "30s",
"value": "30s"
},
{
"selected": true,
"text": "1m",
"value": "1m"
},
{
"selected": false,
"text": "5m",
"value": "5m"
},
{
"selected": false,
"text": "10m",
"value": "10m"
},
{
"selected": false,
"text": "30m",
"value": "30m"
},
{
"selected": false,
"text": "1h",
"value": "1h"
},
{
"selected": false,
"text": "6h",
"value": "6h"
},
{
"selected": false,
"text": "12h",
"value": "12h"
},
{
"selected": false,
"text": "1d",
"value": "1d"
},
{
"selected": false,
"text": "7d",
"value": "7d"
},
{
"selected": false,
"text": "14d",
"value": "14d"
},
{
"selected": false,
"text": "30d",
"value": "30d"
}
],
"query": "1s,10s,30s,1m,5m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
"refresh": 2,
"skipUrlSync": false,
"type": "interval"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Datasource tests - MySQL",
"uid": "DGsCac3kz",
"weekStart": ""
}
@@ -0,0 +1,223 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-opentsdb"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"datasource": {
"uid": "gdev-opentsdb"
},
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"metric": "cpu",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-opentsdb"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"datasource": {
"uid": "gdev-opentsdb"
},
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"metric": "logins.count",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Login Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"datasource-test",
"gdev",
"opentsdb"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Datasource tests - OpenTSDB",
"uid": "tFU1mQyWz",
"weekStart": ""
}
@@ -0,0 +1,250 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 3151,
"links": [],
"panels": [
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-opentsdb-v2.3"
},
"fieldConfig": {
"defaults": {
"links": []
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "8.1.0-pre",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_hostname",
"currentFilterGroupBy": false,
"currentFilterKey": "",
"currentFilterType": "literal_or",
"currentFilterValue": "",
"datasource": {
"uid": "gdev-opentsdb-v2.3"
},
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"explicitTags": false,
"filters": [
{
"filter": "*",
"groupBy": true,
"tagk": "hostname",
"type": "wildcard"
}
],
"metric": "cpu",
"refId": "A",
"shouldComputeRate": false
}
],
"thresholds": [],
"timeRegions": [],
"title": "CPU per host",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-opentsdb-v2.3"
},
"fieldConfig": {
"defaults": {
"links": []
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "8.1.0-pre",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_hostname",
"currentFilterGroupBy": false,
"currentFilterKey": "",
"currentFilterType": "literal_or",
"currentFilterValue": "",
"datasource": {
"uid": "gdev-opentsdb-v2.3"
},
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"filters": [
{
"filter": "*",
"groupBy": true,
"tagk": "hostname",
"type": "wildcard"
}
],
"metric": "logins.count",
"refId": "A"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Login Count per host",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Datasource tests - OpenTSDB v2.3",
"uid": "rZRUGik7k",
"weekStart": ""
}
@@ -0,0 +1,637 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": false,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
},
{
"datasource": {
"uid": "gdev-postgres"
},
"enable": false,
"hide": false,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Single",
"rawQuery": "SELECT\n \"createdAt\" as time,\n 'single' as text,\n hostname as tags\nFROM\n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\")\nORDER BY time\nLIMIT 1\n",
"showIn": 0,
"tags": [],
"type": "tags"
},
{
"datasource": {
"uid": "gdev-postgres"
},
"enable": false,
"hide": false,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Region",
"rawQuery": "SELECT\n \"createdAt\" + (interval '1 minute') as time,\n \"createdAt\" + (6 * interval '1 minute') as timeend,\n 'region' as text,\n hostname as tags\nFROM\n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\")\nORDER BY time\nLIMIT 1\n",
"showIn": 0,
"tags": [],
"type": "tags"
}
]
},
"description": "A dashboard visualizing data generated from grafana/fake-data-gen",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"panels": [
{
"aliasColors": {
"total avg": "#6ed0e0"
},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-postgres"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [
{
"alias": "total avg",
"fill": 0,
"pointradius": 3,
"points": true
}
],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-postgres"
},
"format": "time_series",
"group": [],
"hide": false,
"metricColumn": "none",
"rawQuery": true,
"rawSql": "SELECT\n $__timeGroup(\"createdAt\",'$summarize'),\n avg(value) as \"value\",\n hostname as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\") AND\n measurement = 'logins.count' AND\n hostname IN($host)\nGROUP BY time, metric\nORDER BY time",
"refId": "A",
"select": [
[
{
"params": [
"value"
],
"type": "column"
}
]
],
"target": "",
"timeColumn": "time",
"where": [
{
"name": "$__timeFilter",
"params": [],
"type": "macro"
}
]
},
{
"alias": "",
"datasource": {
"uid": "gdev-postgres"
},
"format": "time_series",
"group": [],
"metricColumn": "none",
"rawQuery": true,
"rawSql": "SELECT\n $__timeGroup(\"createdAt\",'$summarize'),\n min(value) as \"value\",\n 'total avg' as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\") AND\n measurement = 'logins.count'\nGROUP BY time\nORDER BY time",
"refId": "B",
"select": [
[
{
"params": [
"value"
],
"type": "column"
}
]
],
"timeColumn": "time",
"where": [
{
"name": "$__timeFilter",
"params": [],
"type": "macro"
}
]
}
],
"thresholds": [],
"timeRegions": [],
"title": "Average logins / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-postgres"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 18,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-postgres"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(\"createdAt\",'$summarize'),\n avg(value) as \"value\",\n 'started' as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\") AND\n measurement = 'payment.started'\nGROUP BY time, metric\nORDER BY time",
"refId": "A",
"target": ""
},
{
"alias": "",
"datasource": {
"uid": "gdev-postgres"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(\"createdAt\",'$summarize'),\n avg(value) as \"value\",\n 'ended' as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\") AND\n measurement = 'payment.ended'\nGROUP BY time, metric\nORDER BY time",
"refId": "B"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Average payments started/ended / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"uid": "gdev-postgres"
},
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"hiddenSeries": false,
"id": 3,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-postgres"
},
"format": "time_series",
"rawSql": "SELECT\n $__timeGroup(\"createdAt\",'$summarize'),\n max(value) as \"value\",\n hostname as \"metric\"\nFROM \n grafana_metric\nWHERE\n $__timeFilter(\"createdAt\") AND\n measurement = 'cpu' AND\n hostname IN($host)\nGROUP BY time, metric\nORDER BY time",
"refId": "A",
"target": ""
}
],
"thresholds": [],
"timeRegions": [],
"title": "Max CPU / $summarize",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"uid": "gdev-postgres"
},
"fieldConfig": {
"defaults": {
"custom": {
"cellOptions": {
"type": "auto"
},
"footer": {
"reducers": []
},
"inspect": false
},
"decimals": 2,
"displayName": "",
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Time"
},
"properties": [
{
"id": "displayName",
"value": "Time"
},
{
"id": "unit",
"value": "time: YYYY-MM-DD HH:mm:ss"
},
{
"id": "custom.align"
}
]
}
]
},
"gridPos": {
"h": 9,
"w": 24,
"x": 0,
"y": 18
},
"id": 6,
"options": {
"cellHeight": "sm",
"showHeader": true
},
"pluginVersion": "12.1.0",
"targets": [
{
"alias": "",
"datasource": {
"uid": "gdev-postgres"
},
"format": "table",
"rawSql": "SELECT \"createdAt\" as \"Time\", source, datacenter, hostname, value FROM grafana_metric WHERE hostname in($host)",
"refId": "A",
"target": ""
}
],
"title": "Values",
"transformations": [
{
"id": "merge",
"options": {
"reducers": []
}
}
],
"type": "table"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"postgres",
"datasource-test"
],
"templating": {
"list": [
{
"current": {
"text": "America",
"value": "America"
},
"datasource": "gdev-postgres",
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Datacenter",
"multi": false,
"name": "datacenter",
"options": [],
"query": "SELECT DISTINCT datacenter FROM grafana_metric",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": "gdev-postgres",
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
"multi": true,
"name": "host",
"options": [],
"query": "SELECT DISTINCT hostname FROM grafana_metric WHERE datacenter='$datacenter'",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 1,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"auto": false,
"auto_count": 5,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
"hide": 0,
"label": "Summarize",
"name": "summarize",
"options": [
{
"selected": false,
"text": "1s",
"value": "1s"
},
{
"selected": false,
"text": "10s",
"value": "10s"
},
{
"selected": false,
"text": "30s",
"value": "30s"
},
{
"selected": true,
"text": "1m",
"value": "1m"
},
{
"selected": false,
"text": "5m",
"value": "5m"
},
{
"selected": false,
"text": "10m",
"value": "10m"
},
{
"selected": false,
"text": "30m",
"value": "30m"
},
{
"selected": false,
"text": "1h",
"value": "1h"
},
{
"selected": false,
"text": "6h",
"value": "6h"
},
{
"selected": false,
"text": "12h",
"value": "12h"
},
{
"selected": false,
"text": "1d",
"value": "1d"
},
{
"selected": false,
"text": "7d",
"value": "7d"
},
{
"selected": false,
"text": "14d",
"value": "14d"
},
{
"selected": false,
"text": "30d",
"value": "30d"
}
],
"query": "1s,10s,30s,1m,5m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
"refresh": 2,
"skipUrlSync": false,
"type": "interval"
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Datasource tests - Postgres",
"uid": "JYola5qzz",
"weekStart": ""
}
@@ -0,0 +1,802 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 32,
"w": 9,
"x": 0,
"y": 0
},
"id": 4,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "red"
},
{
"color": "yellow",
"value": 50
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"labels": "",
"refId": "H",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "I",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"labels": "",
"refId": "O",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "P",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "Q",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 11,
"w": 8,
"x": 9,
"y": 0
},
"id": 3,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "purple",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 33,
"w": 7,
"x": 17,
"y": 0
},
"id": 6,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "green"
},
{
"color": "blue",
"value": 50
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "P",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "Q",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "R",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "S",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "T",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "U",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "V",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "W",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "X",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 11,
"w": 8,
"x": 9,
"y": 11
},
"id": 7,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "purple",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 11,
"w": 8,
"x": 9,
"y": 22
},
"id": 8,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "purple",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "bargauge"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"demo"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Bar Gauge Demo Unfilled",
"uid": "xMsQdBfWz",
"weekStart": ""
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,537 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 44,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Orphan non-repeating panel",
"type": "timeseries"
},
{
"collapsed": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 8
},
"id": 2,
"panels": [],
"repeat": "row",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Row title $row",
"type": "row"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 9
},
"id": 9,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "horizontal",
"repeatDirection": "h",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Horizontal repeating $horizontal",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 17
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Non-repeating panel",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 8,
"y": 17
},
"id": 22,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "vertical",
"repeatDirection": "v",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Vertical repeating $vertical",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "vertical",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "horizontal",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "row",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "Repeating Kitchen Sink",
"uid": "hxQwTjpnk",
"weekStart": ""
}
@@ -0,0 +1,210 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 95,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "horizontal",
"repeatDirection": "h",
"title": "Panel Title $horizontal",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "vertical",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "horizontal",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "Templating - Repeating a panel horizontally",
"uid": "WVpf2jp7z",
"weekStart": ""
}
@@ -0,0 +1,215 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "vertical",
"repeatDirection": "v",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Panel Title $vertical",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "vertical",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"1"
],
"value": [
"1"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "horizontal",
"options": [
{
"selected": false,
"text": "All",
"value": "$__all"
},
{
"selected": true,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "Repeating a panel vertically",
"uid": "OY8Ghjt7k",
"weekStart": ""
}
@@ -0,0 +1,284 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"collapsed": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"panels": [],
"repeat": "row",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Row title $row",
"type": "row"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 8,
"x": 0,
"y": 1
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "horizontal",
"repeatDirection": "h",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Panel Title $horizontal",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "vertical",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "horizontal",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "row",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "Repeating a row with a repeating horizontal panel",
"uid": "0OmtTCtnk",
"weekStart": ""
}
@@ -0,0 +1,283 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"collapsed": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"panels": [],
"repeat": "row",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Row title $row",
"type": "row"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 1
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "vertical",
"repeatDirection": "v",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A"
}
],
"title": "Panel Title $vertical",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "vertical",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "horizontal",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "row",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "Repeating a row with a repeating vertical panel",
"uid": "I0YIojp7z",
"weekStart": ""
}
@@ -0,0 +1,198 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"collapsed": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"panels": [],
"repeat": "row",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Row title $row",
"type": "row"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "vertical",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "horizontal",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "row",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "1",
"value": "1"
},
{
"selected": false,
"text": "2",
"value": "2"
},
{
"selected": false,
"text": "3",
"value": "3"
}
],
"query": "1,2,3",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "utc",
"title": "Repeating an empty row",
"uid": "dtpl2Ctnk",
"weekStart": ""
}
@@ -0,0 +1,337 @@
{
"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": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Link with one query",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 8
},
"id": 6,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"showRowNums": false
},
"pluginVersion": "10.1.0-55406pre",
"title": "No extensions",
"type": "table"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 6,
"y": 8
},
"id": 4,
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 4
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"hide": false,
"refId": "B",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Link with new name",
"type": "piechart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 16
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"hide": false,
"refId": "B",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "Link with defaults",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Link Extensions (onClick)",
"uid": "dbfb47c5-e5e5-4d28-8ac7-35f349b95946",
"weekStart": ""
}
@@ -0,0 +1,233 @@
{
"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,
"id": 1,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 0
},
"id": 6,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"showRowNums": false
},
"pluginVersion": "9.5.0-53420pre",
"title": "No extensions",
"type": "table"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 6,
"y": 0
},
"id": 4,
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"pieType": "pie",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 4
}
],
"title": "Link with new name",
"type": "piechart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": 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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 6,
"x": 0,
"y": 8
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Link with defaults",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Link Extensions (path)",
"uid": "d1fbb077-cd44-4738-8c8a-d4e66748b719",
"weekStart": ""
}
@@ -0,0 +1,850 @@
{
"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,
"id": 1267,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 3,
"w": 24,
"x": 0,
"y": 0
},
"id": 8,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "* `__all_variables`=${__all_variables}\n* `__url_time_range`=${__url_time_range}",
"mode": "markdown"
},
"pluginVersion": "9.5.0-pre",
"title": "Panel Title",
"type": "text"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"links": [
{
"targetBlank": true,
"title": "value=${__value.raw}\u0026time=${__value.time}\u0026__value:percentencode=${__value:percentencode}\u0026text=${__value.text}",
"url": "value=${__value.raw}\u0026time=${__value.time}justvalue=${__value:percentencode}\u0026text=${__value.text}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 3
},
"id": 2,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"showRowNums": false
},
"pluginVersion": "9.5.0-pre",
"title": "DataLink: with __value.raw=\u0026__value.time=\u0026__value:percentencode=",
"type": "table"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"links": [
{
"targetBlank": true,
"title": "Value link",
"url": "value=${__value.raw}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 3
},
"id": 3,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 5
}
],
"title": "Stat panel with __value.raw ",
"type": "stat"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "continuous-GrYlRd"
},
"links": [
{
"title": "${__value.raw}",
"url": "${__value.raw}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 10
},
"id": 6,
"options": {
"displayMode": "basic",
"minVizHeight": 10,
"minVizWidth": 0,
"orientation": "horizontal",
"reduceOptions": {
"calcs": [],
"fields": "",
"values": true
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"csvFileName": "browser_marketshare.csv",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_file"
}
],
"title": "data link __value.raw",
"transformations": [
{
"id": "limit",
"options": {
"limitField": 5
}
}
],
"type": "bargauge"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "Since this is using getFrameDisplayName it works kind badly (especially with testdata) and only returns the `Series (refId)`. \n\nSo this should show:\n* Series (Query1)\n* Series (Query2)",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"displayName": "${__series.name}",
"links": [
{
"targetBlank": true,
"title": "Value link",
"url": "value=${__calc}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 10
},
"id": 12,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"alias": "",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "Query1",
"scenarioId": "random_walk",
"seriesCount": 1
},
{
"alias": "",
"datasource": {
"type": "grafana-testdata-datasource"
},
"hide": false,
"refId": "Query2",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "${series.name} in display name",
"type": "stat"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"links": [
{
"title": "__data.refId=${__data.refId}\u0026__data.fields[0]=${__data.fields[0]}\u0026cluster=${__field.labels.cluster}",
"url": "refId=${__data.refId}\u0026__data.fields[0]=${__data.fields[0]}\u0026cluster=${__field.labels.cluster}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 17
},
"id": 11,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"showRowNums": false
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"labels": "cluster=US",
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "DataLink: refId=${__data.refId}\u0026__data.fields[0]=${__data.fields[0]}\u0026cluster=${__field.labels.cluster}",
"type": "table"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"links": [
{
"title": "${__value.raw}",
"url": "${__value.raw}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 17
},
"id": 10,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"alias": "10,20,30,40",
"csvContent": "Time, value, test\n\"2023-03-24T17:12:12.347Z\", 10,hello\n\"2023-03-24T17:22:12.347Z\", 20,asd\n\"2023-03-24T17:32:12.347Z\", 30,asd2\n\"2023-03-24T17:42:12.347Z\", 40,as34\n",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
},
{
"alias": "5,6,7",
"csvContent": "Time, value, test\n\"2023-03-24T17:12:12.347Z\", 5,hello\n\"2023-03-24T17:22:12.347Z\", 6,asd\n\"2023-03-24T17:42:12.347Z\", 7,as34\n",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "B",
"scenarioId": "csv_content"
}
],
"title": "Data links with ${__value.raw}",
"transformations": [
{
"id": "joinByField",
"options": {}
}
],
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"links": [
{
"title": "__field.name=${__field.name}\u0026__field.labels.cluster=${__field.labels.cluster}",
"url": "__field.name=${__field.name}\u0026__field.labels.cluster=${__field.labels.cluster}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 24
},
"id": 13,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"showRowNums": false
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"labels": "cluster=US",
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "DataLink: __field.name=\u0026__field.labels.cluster",
"type": "table"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "The stat display names should be \n* Stockholm = Bad\n* New York = Good \n",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"displayName": "$__cell_0 = $__cell_2",
"links": [],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 24
},
"id": 14,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": true
},
"textMode": "auto"
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"alias": "",
"csvContent": "name, value, name2\nStockholm, 10, Good\nNew York, 15, Bad",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "DisplayName with __cell_0 = __cell_2",
"type": "stat"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "The stat display names should be \n* Stockholm = Bad\n* New York = Good \n",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"displayName": "${__field.name}",
"links": [
{
"targetBlank": true,
"title": "Value link",
"url": "value=${__calc}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 31
},
"id": 15,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"showRowNums": false
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"alias": "",
"csvContent": "name, value, name2\nStockholm, 10, Good\nNew York, 15, Bad",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "DisplayName: __field.name",
"type": "table"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "The stat display names should be \n* Stockholm = Bad\n* New York = Good \n",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"displayName": "${__data.fields[0]} = ${__data.fields[2]}",
"links": [
{
"targetBlank": true,
"title": "__data.fields[0] = ${__data.fields[0]} = __value.raw = ${__value.raw}",
"url": "__data.fields[0] = ${__data.fields[0]} = __value.raw = ${__value.raw}"
}
],
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 31
},
"id": 16,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": true
},
"textMode": "auto"
},
"pluginVersion": "9.5.0-pre",
"targets": [
{
"alias": "",
"csvContent": "name, value, name2\nStockholm, 10, Good\nNew York, 15, Bad",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "$__data.fields[0] = $__data.fields[2] with datalinks",
"type": "stat"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "A",
"value": "A"
},
"hide": 0,
"includeAll": false,
"multi": false,
"name": "customVar",
"options": [
{
"selected": true,
"text": "A",
"value": "A"
},
{
"selected": false,
"text": "B",
"value": "B"
},
{
"selected": false,
"text": "C",
"value": "C"
}
],
"query": "A,B,C",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "2023-03-24T17:12:12.347Z",
"to": "2023-03-24T17:42:12.347Z"
},
"timepicker": {},
"timezone": "",
"title": "Templating - Macros",
"uid": "e7c29343-6d1e-4167-9c13-803fe5be8c46",
"weekStart": ""
}
@@ -0,0 +1,132 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"gridPos": {
"h": 18,
"w": 24,
"x": 0,
"y": 0
},
"id": 11,
"options": {
"content": "## Global variables\n\n* `__dashboard` = `${__dashboard}`\n* `__dashboard.name` = `${__dashboard.name}`\n* `__dashboard.uid` = `${__dashboard.uid}`\n* `__org.name` = `${__org.name}`\n* `__org.id` = `${__org.id}`\n* `__user.id` = `${__user.id}`\n* `__user.login` = `${__user.login}`\n* `__user.email` = `${__user.email}`\n \n## Formats\n\n* `Server:raw` = `${Server:raw}`\n* `Server:regex` = `${Server:regex}`\n* `Server:lucene` = `${Server:lucene}`\n* `Server:glob` = `${Server:glob}`\n* `Server:pipe` = `${Server:pipe}`\n* `Server:distributed` = `${Server:distributed}`\n* `Server:csv` = `${Server:csv}`\n* `Server:html` = `${Server:html}`\n* `Server:json` = `${Server:json}`\n* `Server:percentencode` = `${Server:percentencode}`\n* `Server:singlequote` = `${Server:singlequote}`\n* `Server:doublequote` = `${Server:doublequote}`\n* `Server:sqlstring` = `${Server:sqlstring}`\n* `Server:date` = `${Server:date}`\n* `Server:text` = `${Server:text}`\n* `Server:queryparam` = `${Server:queryparam}`\n\n## Sanitization\n\n * `1 \u003c 2`\n\n## Link interpolation\n\n* [Example: ${__url_time_range}](https://example.com/?${__url_time_range})",
"mode": "markdown"
},
"pluginVersion": "7.1.0",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "Variable interpolation",
"type": "text"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": "All",
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "Server",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "A'A\"A",
"value": "A'A\"A"
},
{
"selected": false,
"text": "BB\\B",
"value": "BB\\B"
},
{
"selected": false,
"text": "CCC",
"value": "CCC"
}
],
"query": "A'A\"A,BB\\B,CCC",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Templating - Global variables and interpolation",
"uid": "HYaGDGIMk",
"weekStart": ""
}
@@ -0,0 +1,145 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"icon": "external link",
"includeVars": true,
"tags": [],
"title": "Grafana",
"tooltip": "",
"type": "link",
"url": "http://www.grafana.com"
},
{
"asDropdown": true,
"icon": "external link",
"includeVars": true,
"tags": [
"templating"
],
"title": "Link as DropDown",
"type": "dashboards"
},
{
"icon": "external link",
"includeVars": true,
"tags": [
"demo"
],
"type": "dashboards"
}
],
"panels": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"description": "",
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"content": "# ${custom.text}\n ",
"mode": "markdown"
},
"pluginVersion": "7.3.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "${custom.text}",
"type": "text"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "All",
"value": "$__all"
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "custom",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "p1",
"value": "p1"
},
{
"selected": false,
"text": "p2",
"value": "p2"
},
{
"selected": false,
"text": "p3",
"value": "p3"
}
],
"query": "p1,p2,p3",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Templating - Dashboard Links and Variables",
"uid": "yBCC3aKGk",
"weekStart": ""
}
@@ -0,0 +1,419 @@
{
"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": [],
"liveNow": false,
"panels": [
{
"gridPos": {
"h": 2,
"w": 24,
"x": 0,
"y": 0
},
"id": 15,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "\u003cdiv class=\"center-vh\"\u003e\n Horizontally repeated panel below\n\u003c/div\u003e",
"mode": "markdown"
},
"pluginVersion": "10.2.0-pre",
"type": "text"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 8,
"x": 0,
"y": 2
},
"id": 2,
"maxPerRow": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "server",
"repeatDirection": "h",
"targets": [
{
"alias": "server = $server",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "server=$server",
"type": "timeseries"
},
{
"gridPos": {
"h": 20,
"w": 16,
"x": 0,
"y": 12
},
"id": 10,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "### \n\nIt also has a variable with different value and text representations (A=1, B=2, etc). \nTo test that this works for the scoped variable. \n\nIn the title the text representation should be seen (A,B,C, etc). In the legend you\nshould see both the text and value (id). \n\n",
"mode": "markdown"
},
"pluginVersion": "10.2.0-pre",
"title": "Panel to the right is configured for vertical repeat",
"type": "text"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "blue",
"mode": "fixed"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 25,
"gradientMode": "hue",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "smooth",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 8,
"x": 16,
"y": 12
},
"id": 5,
"maxDataPoints": 50,
"maxPerRow": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "host",
"repeatDirection": "v",
"targets": [
{
"alias": "host = ${host:text} / id = $host",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "host_name = $host",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": [
"A",
"B",
"C"
],
"value": [
"A",
"B",
"C"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "server",
"options": [
{
"selected": false,
"text": "All",
"value": "$__all"
},
{
"selected": true,
"text": "A",
"value": "A"
},
{
"selected": true,
"text": "B",
"value": "B"
},
{
"selected": true,
"text": "C",
"value": "C"
},
{
"selected": false,
"text": "D",
"value": "D"
},
{
"selected": false,
"text": "E",
"value": "E"
},
{
"selected": false,
"text": "F",
"value": "F"
},
{
"selected": false,
"text": "E",
"value": "E"
},
{
"selected": false,
"text": "G",
"value": "G"
},
{
"selected": false,
"text": "H",
"value": "H"
},
{
"selected": false,
"text": "I",
"value": "I"
},
{
"selected": false,
"text": "J",
"value": "J"
},
{
"selected": false,
"text": "K",
"value": "K"
},
{
"selected": false,
"text": "L",
"value": "L"
}
],
"query": "A,B,C,D,E,F,E,G,H,I,J,K,L",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "host",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "A",
"value": "1"
},
{
"selected": false,
"text": "B",
"value": "2"
},
{
"selected": false,
"text": "C",
"value": "3"
},
{
"selected": false,
"text": "D",
"value": "4"
},
{
"selected": false,
"text": "E",
"value": "5"
}
],
"query": "A : 1, B : 2,C : 3, D : 4, E : 5",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Templating - Repeating Panels",
"uid": "templating-repeating-panels",
"weekStart": ""
}
@@ -0,0 +1,364 @@
{
"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": [],
"liveNow": false,
"panels": [
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 20,
"panels": [],
"title": "Row at the top - not repeated - saved expanded",
"type": "row"
},
{
"gridPos": {
"h": 2,
"w": 24,
"x": 0,
"y": 1
},
"id": 15,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "\u003cdiv class=\"center-vh\"\u003e\n Repeated row below. The row has \n a panel that is also repeated horizontally based\n on values in the $pod variable. \n\u003c/div\u003e",
"mode": "markdown"
},
"pluginVersion": "10.2.0-pre",
"type": "text"
},
{
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 3
},
"id": 16,
"panels": [],
"repeat": "server",
"repeatDirection": "h",
"title": "Row for server $server",
"type": "row"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 12,
"x": 0,
"y": 4
},
"id": 2,
"maxPerRow": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"repeat": "pod",
"repeatDirection": "h",
"targets": [
{
"alias": "server = $server, pod id = $pod ",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1
}
],
"title": "server = $server, pod = $pod",
"type": "timeseries"
},
{
"collapsed": true,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 21
},
"id": 25,
"panels": [
{
"gridPos": {
"h": 2,
"w": 24,
"x": 0,
"y": 22
},
"id": 30,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "\u003cdiv class=\"center-vh\"\u003e\n Just a panel\n\u003c/div\u003e",
"mode": "markdown"
},
"pluginVersion": "10.2.0-pre",
"type": "text"
}
],
"title": "Row at the bottom - not repeated - saved collapsed ",
"type": "row"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"templating",
"gdev"
],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": [
"A",
"B"
],
"value": [
"A",
"B"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "server",
"options": [
{
"selected": false,
"text": "All",
"value": "$__all"
},
{
"selected": true,
"text": "A",
"value": "A"
},
{
"selected": true,
"text": "B",
"value": "B"
},
{
"selected": false,
"text": "C",
"value": "C"
},
{
"selected": false,
"text": "D",
"value": "D"
},
{
"selected": false,
"text": "E",
"value": "E"
},
{
"selected": false,
"text": "F",
"value": "F"
},
{
"selected": false,
"text": "E",
"value": "E"
},
{
"selected": false,
"text": "G",
"value": "G"
},
{
"selected": false,
"text": "H",
"value": "H"
},
{
"selected": false,
"text": "I",
"value": "I"
},
{
"selected": false,
"text": "J",
"value": "J"
},
{
"selected": false,
"text": "K",
"value": "K"
},
{
"selected": false,
"text": "L",
"value": "L"
}
],
"query": "A,B,C,D,E,F,E,G,H,I,J,K,L",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": [
"Bob",
"Rob"
],
"value": [
"1",
"2"
]
},
"hide": 0,
"includeAll": true,
"multi": true,
"name": "pod",
"options": [
{
"selected": false,
"text": "All",
"value": "$__all"
},
{
"selected": true,
"text": "Bob",
"value": "1"
},
{
"selected": true,
"text": "Rob",
"value": "2"
},
{
"selected": false,
"text": "Sod",
"value": "3"
},
{
"selected": false,
"text": "Hod",
"value": "4"
},
{
"selected": false,
"text": "Cod",
"value": "5"
}
],
"query": "Bob : 1, Rob : 2,Sod : 3, Hod : 4, Cod : 5",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Repeating rows",
"uid": "Repeating-rows-uid",
"weekStart": ""
}
@@ -0,0 +1,91 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": {
"uid": "${DS_GDEV-TESTDATA}"
},
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"content": "# variable: ${text}\n ",
"mode": "markdown"
},
"pluginVersion": "7.4.0-pre",
"targets": [
{
"datasource": {
"uid": "${DS_GDEV-TESTDATA}"
},
"refId": "A"
}
],
"title": "Panel Title",
"type": "text"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "default value",
"value": "default value"
},
"hide": 0,
"name": "text",
"options": [
{
"selected": true,
"text": "default value",
"value": "default value"
}
],
"query": "default value",
"skipUrlSync": false,
"type": "textbox"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Templating - Textbox e2e scenarios",
"uid": "AejrN1AMz",
"weekStart": ""
}
@@ -0,0 +1,540 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"content": "## Data link variables overview\n\nThis dashboard presents variables that one can use when creating *data links*. All links redirect to this dashboard and this panel represents the values that were interpolated in the link that was clicked.\n\n\n#### Series variables\n1. **Name:** \u003cspan style=\"color: orange;\"\u003e$seriesName\u003c/span\u003e\n2. **label.datacenter:** \u003cspan style=\"color: orange;\"\u003e$labelDatacenter\u003c/span\u003e\n3. **label.datacenter.region:** \u003cspan style=\"color: orange;\"\u003e$labelDatacenterRegion\u003c/span\u003e\n\n#### Field variables\n1. **Name:** \u003cspan style=\"color: orange;\"\u003e$fieldName\u003c/span\u003e\n\n#### Value variables\n1. **Time:** \u003cspan style=\"color: orange;\"\u003e$valueTime\u003c/span\u003e\n2. **Numeric:** \u003cspan style=\"color: orange;\"\u003e$valueNumeric\u003c/span\u003e\n3. **Text:** \u003cspan style=\"color: orange;\"\u003e$valueText\u003c/span\u003e\n4. **Calc:** \u003cspan style=\"color: orange;\"\u003e$valueCalc\u003c/span\u003e\n\n",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 16,
"w": 6,
"x": 0,
"y": 0
},
"id": 8,
"mode": "markdown",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"transparent": true,
"type": "text"
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 9,
"x": 6,
"y": 0
},
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": [
{
"targetBlank": false,
"title": "Drill it down",
"url": "/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}\u0026var-labelDatacenter=${__field.labels.datacenter}\u0026var-labelDatacenterRegion=${__field.labels[\"datacenter.region\"]}\u0026var-valueTime=${__value.time}\u0026var-valueNumeric=${__value.numeric}\u0026var-valueText=${__value.text}"
}
]
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Foo datacenter",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"labels": "datacenter=foo,datacenter.region=us-east-1",
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "Bar datacenter",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"labels": "datacenter=bar,datacenter.region=us-east-2",
"refId": "B",
"scenarioId": "random_walk"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Multiple series",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 9,
"x": 15,
"y": 0
},
"id": 9,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": [
{
"targetBlank": false,
"title": "Drill it down",
"url": "/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}\u0026var-valueTime=${__value.time}\u0026var-valueNumeric=${__value.numeric}\u0026var-valueText=${__value.text}\u0026var-fieldName=${__field.name}"
}
]
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "Foo datacenter",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"labels": "datacenter=foo,datacenter.region=us-east-1",
"refId": "A",
"scenarioId": "random_walk_table",
"stringInput": ""
}
],
"thresholds": [],
"timeRegions": [],
"title": "Multiple fields",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
},
{
"datasource": {
"uid": "-- Dashboard --"
},
"gridPos": {
"h": 8,
"w": 9,
"x": 6,
"y": 8
},
"id": 6,
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": [
"last"
],
"defaults": {
"links": [
{
"targetBlank": true,
"title": "Drill it down!",
"url": "/d/wfTJJL5Wz/datalinks-source\n?var-fieldName=${__field.name}\n\u0026var-labelDatacenter=${__field.labels.datacenter}\n\u0026var-labelDatacenterRegion=${__field.labels[\"datacenter.region\"]}\n\u0026var-valueNumeric=${__value.numeric}\n\u0026var-valueText=${__value.text}\n\u0026var-valueCalc=${__value.calc}"
}
],
"mappings": [
{
"id": 0,
"op": "=",
"text": "N/A",
"type": 1,
"value": "null"
}
],
"max": 100,
"min": 0,
"nullValueMode": "connected",
"thresholds": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
],
"title": "${__series.name} - $__calc",
"unit": "none"
},
"override": {},
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.4.0-pre",
"targets": [
{
"datasource": {
"uid": "-- Dashboard --"
},
"panelId": 2,
"refId": "A"
}
],
"title": "Value reducers 1",
"type": "bargauge"
},
{
"datasource": {
"uid": "-- Dashboard --"
},
"gridPos": {
"h": 8,
"w": 9,
"x": 15,
"y": 8
},
"id": 4,
"options": {
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"links": [
{
"title": "Drill it down",
"url": "/d/wfTJJL5Wz/datalinks-source?var-fieldName=${__field.name}\u0026var-labelDatacenter=${__field.labels.datacenter}\u0026var-labelDatacenterRegion=${__field.labels[\"datacenter.region\"]}\u0026var-valueNumeric=${__value.numeric}\u0026var-valueText=${__value.text}\u0026var-valueCalc=${__value.calc}"
}
],
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
],
"title": "${__series.name} - $__calc"
},
"override": {},
"values": false
},
"orientation": "auto",
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "6.4.0-pre",
"targets": [
{
"datasource": {
"uid": "-- Dashboard --"
},
"panelId": 2,
"refId": "A"
}
],
"title": "Value reducers 2",
"type": "gauge"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"label": "Series name",
"name": "seriesName",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "labelDatacenter",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "labelDatacenterRegion",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "valueTime",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "valueNumeric",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "valueText",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "valueCalc",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"text": "",
"value": ""
},
"hide": 2,
"name": "fieldName",
"options": [
{
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Datalinks - variables",
"uid": "wfTJJL5Wz",
"weekStart": ""
}
@@ -0,0 +1,330 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"content": "## Data center = $datacenter\n\n### server = $server\n\n#### pod = $pod",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 6,
"w": 15,
"x": 0,
"y": 0
},
"id": 4,
"mode": "markdown",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "text"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "rgb(31, 120, 193)",
"mode": "fixed"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 9,
"x": 15,
"y": 0
},
"id": 6,
"links": [
{
"targetBlank": true,
"title": "Overview dashboard",
"url": "d/-Y-tnEDWk/dashboard-tests-nested-template-variables?orgId=1\u0026${__all_variables}\u0026${__url_time_range}"
}
],
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "horizontal",
"percentChangeColorMode": "standard",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.1.0",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "Panel drilldown link test",
"type": "stat"
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "grafana-testdata-datasource"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 13,
"w": 24,
"x": 0,
"y": 6
},
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "$datacenter.$server.$pod",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Panel Title",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"text": "A",
"value": [
"A"
]
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "datacenter",
"options": [],
"query": "*",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"text": "AA",
"value": [
"AA"
]
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "$datacenter.*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "server",
"options": [],
"query": "$datacenter.*",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"text": "All",
"value": [
"$__all"
]
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "$datacenter.$server.*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "pod",
"options": [],
"query": "$datacenter.$server.*",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Templating - Nested Variables Drilldown",
"uid": "O6GmNPvWk",
"weekStart": ""
}
@@ -0,0 +1,574 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"content": "## Data center = $datacenter\n\n### server = $server\n\n#### pod = $pod",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 4,
"mode": "markdown",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "Panel Title",
"type": "text"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "rgb(31, 120, 193)",
"mode": "fixed"
},
"mappings": [
{
"options": {
"match": "null",
"result": {
"text": "N/A"
}
},
"type": "special"
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 4,
"x": 12,
"y": 0
},
"id": 6,
"links": [
{
"targetBlank": true,
"title": "Drilldown detail dashboard",
"url": "d/O6GmNPvWk/dashboard-tests-nested-template-variables-drilldown?orgId=1\u0026${__all_variables}\u0026${__url_time_range}"
}
],
"maxDataPoints": 100,
"options": {
"colorMode": "none",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "horizontal",
"percentChangeColorMode": "standard",
"reduceOptions": {
"calcs": [
"mean"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "12.1.0",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "Panel drilldown link test",
"type": "stat"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {},
"links": [
{
"targetBlank": true,
"title": "Go to drilldown",
"url": "/d/O6GmNPvWk/dashboard-tests-nested-template-variables-drilldown?orgId=1\u0026${__all_variables}\u0026${__url_time_range}"
}
],
"mappings": [],
"max": 100,
"min": 0,
"nullValueMode": "connected",
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 4,
"x": 16,
"y": 0
},
"id": 8,
"options": {
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"mean"
],
"values": false
},
"showThresholdLabels": false,
"showThresholdMarkers": true
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "React gauge datalink",
"type": "gauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {},
"links": [
{
"targetBlank": true,
"title": "Go to drilldown",
"url": "/d/O6GmNPvWk/dashboard-tests-nested-template-variables-drilldown?orgId=1\u0026${__all_variables}\u0026${__url_time_range}"
}
],
"mappings": [],
"max": 100,
"min": 0,
"nullValueMode": "connected",
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 4,
"x": 20,
"y": 0
},
"id": 9,
"options": {
"displayMode": "basic",
"orientation": "vertical",
"reduceOptions": {
"calcs": [
"mean"
],
"values": false
},
"showUnfilled": true
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "React gauge datalink",
"type": "bargauge"
},
{
"datasource": {
"uid": "CsvData"
},
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "server"
},
"properties": [
{
"id": "links",
"value": [
{
"title": "filter",
"url": "http://localhost:3000/d/-Y-tnEDWk/templating-nested-template-variables?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}"
}
]
}
]
}
]
},
"gridPos": {
"h": 6,
"w": 24,
"x": 0,
"y": 9
},
"id": 11,
"options": {
"showHeader": true
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"data": [
{
"fields": [
{
"config": {},
"name": "datacenter",
"type": "string",
"values": [
"A",
"B",
"C"
]
},
{
"config": {},
"name": "server",
"type": "string",
"values": [
"AA",
"BB",
"CC"
]
}
]
}
],
"datasource": {
"uid": "CsvData"
},
"refId": "A"
}
],
"title": "Data links that filter update variables on current dashboard",
"type": "table"
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 13,
"w": 24,
"x": 0,
"y": 15
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "$datacenter.$server.$pod",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Panel Title",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": true,
"text": "A",
"value": [
"A"
]
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "datacenter",
"options": [],
"query": "*",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": true,
"text": "AA",
"value": [
"AA"
]
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "$datacenter.*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "server",
"options": [],
"query": "$datacenter.*",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"selected": true,
"text": "All",
"value": [
"$__all"
]
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "$datacenter.$server.*",
"hide": 0,
"includeAll": true,
"multi": true,
"name": "pod",
"options": [],
"query": "$datacenter.$server.*",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Templating - Nested Template Variables",
"uid": "-Y-tnEDWk",
"weekStart": ""
}
@@ -0,0 +1,138 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"content": "VariableUnderTest: $VariableUnderTest",
"mode": "markdown"
},
"pluginVersion": "8.4.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Panel Title",
"type": "text"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"id": 3,
"options": {
"content": "VariableUnderTestText: ${VariableUnderTest:text}",
"mode": "markdown"
},
"pluginVersion": "8.4.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Panel Title",
"type": "text"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 18
},
"id": 4,
"options": {
"content": "VariableUnderTestRaw: ${VariableUnderTest:raw}",
"mode": "markdown"
},
"pluginVersion": "8.4.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A"
}
],
"title": "Panel Title",
"type": "text"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Test variable output",
"uid": "kVi2Gex7z",
"weekStart": ""
}
@@ -0,0 +1,256 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": {
"uid": "CsvData"
},
"fieldConfig": {
"defaults": {
"custom": {},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Query"
},
"properties": [
{
"id": "links",
"value": [
{
"title": "Search",
"url": "/d/spVR9LSMk/templating-textbox-and-data-links?var-query=${__value.raw:percentencode}"
}
]
}
]
}
]
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"showHeader": true
},
"pluginVersion": "7.2.0-pre",
"targets": [
{
"data": [
{
"fields": [
{
"config": {},
"name": "Query",
"type": "string",
"values": [
"Contains+Plus",
"Contains\u0026Ampersand",
"Contains white space"
]
},
{
"config": {},
"name": " Test",
"type": "string",
"values": [
"asd",
"asd",
"asd"
]
}
]
}
],
"datasource": {
"uid": "CsvData"
},
"refId": "A"
}
],
"title": "Data",
"type": "table"
},
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"alertThreshold": true
},
"percentage": false,
"pluginVersion": "7.2.0-pre",
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "${query}",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Query: ${query}",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "asdasda+",
"value": "asdasda+"
},
"hide": 0,
"name": "query",
"options": [
{
"selected": true,
"text": "asdasda+",
"value": "asdasda+"
}
],
"query": "asdasda+",
"skipUrlSync": false,
"type": "textbox"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Templating - Textbox \u0026 data links",
"uid": "spVR9LSMk",
"weekStart": ""
}
@@ -0,0 +1,201 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": [
{
"aliasColors": {},
"autoMigrateFrom": "graph",
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 14,
"w": 19,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": true,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "updatesOnTime: $updatesOnTime",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "dependsOnFirst: $dependsOnFirst",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
}
],
"thresholds": [],
"timeRegions": [],
"title": "Panel Title",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "timeseries",
"xaxis": {
"mode": "time",
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"logBase": 1,
"show": true
},
{
"format": "short",
"logBase": 1,
"show": true
}
],
"yaxis": {
"align": false
}
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"templating"
],
"templating": {
"list": [
{
"current": {
"text": "value.1584434137814",
"value": "value.1584434137814"
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "value.$__from",
"hide": 0,
"includeAll": false,
"multi": false,
"name": "updatesOnTime",
"options": [],
"query": "value.$__from",
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"current": {
"text": "value.value.1584434072074",
"value": "value.value.1584434072074"
},
"datasource": {
"type": "grafana-testdata-datasource"
},
"definition": "value.$updatesOnTime",
"hide": 0,
"includeAll": false,
"multi": false,
"name": "dependsOnFirst",
"options": [],
"query": "value.$updatesOnTime",
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tagsQuery": "",
"type": "query",
"useTags": false
}
]
},
"time": {
"from": "now-30m",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Templating - Variables That Refresh On Time Change",
"uid": "HeUnbEuZk",
"weekStart": ""
}
@@ -0,0 +1,238 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 28,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 26,
"w": 6,
"x": 0,
"y": 0
},
"id": 7,
"options": {
"maxItems": 100,
"query": "",
"showHeadings": true,
"showRecentlyViewed": true,
"showSearch": false,
"showStarred": true,
"tags": []
},
"pluginVersion": "9.0.0-pre",
"tags": [],
"title": "Starred",
"type": "dashlist"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 13,
"w": 6,
"x": 6,
"y": 0
},
"id": 2,
"options": {
"maxItems": 1000,
"query": "",
"showHeadings": false,
"showRecentlyViewed": false,
"showSearch": true,
"showStarred": false,
"tags": [
"panel-tests"
]
},
"pluginVersion": "9.0.0-pre",
"tags": [
"panel-tests"
],
"title": "tag: panel-tests",
"type": "dashlist"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 13,
"w": 6,
"x": 12,
"y": 0
},
"id": 3,
"options": {
"maxItems": 1000,
"query": "",
"showHeadings": false,
"showRecentlyViewed": false,
"showSearch": true,
"showStarred": false,
"tags": [
"gdev",
"demo"
]
},
"pluginVersion": "9.0.0-pre",
"tags": [
"gdev",
"demo"
],
"title": "tag: dashboard-demo",
"type": "dashlist"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 26,
"w": 6,
"x": 18,
"y": 0
},
"id": 5,
"options": {
"maxItems": 1000,
"query": "",
"showHeadings": false,
"showRecentlyViewed": false,
"showSearch": true,
"showStarred": false,
"tags": [
"gdev",
"datasource-test"
]
},
"pluginVersion": "9.0.0-pre",
"tags": [
"gdev",
"datasource-test"
],
"title": "Data source tests",
"type": "dashlist"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 13,
"w": 6,
"x": 6,
"y": 13
},
"id": 4,
"options": {
"maxItems": 1000,
"query": "",
"showHeadings": false,
"showRecentlyViewed": false,
"showSearch": true,
"showStarred": false,
"tags": [
"templating",
"gdev"
]
},
"pluginVersion": "9.0.0-pre",
"tags": [
"templating",
"gdev"
],
"title": "tag: templating ",
"type": "dashlist"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 13,
"w": 6,
"x": 12,
"y": 13
},
"id": 8,
"options": {
"maxItems": 1000,
"query": "",
"showHeadings": false,
"showRecentlyViewed": false,
"showSearch": true,
"showStarred": false,
"tags": [
"gdev",
"transform"
]
},
"pluginVersion": "9.0.0-pre",
"tags": [
"gdev",
"demo"
],
"title": "tag: transforms",
"type": "dashlist"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Grafana Dev Overview \u0026 Home",
"uid": "j6T00KRZz",
"weekStart": ""
}
@@ -0,0 +1,373 @@
{
"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,
"id": 220,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"live-tests"
],
"targetBlank": false,
"title": "gdev live tests",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"liveNow": true,
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 2,
"w": 24,
"x": 0,
"y": 0
},
"id": 9,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "## Note the consistent refresh rate (liveNow = true)",
"mode": "markdown"
},
"pluginVersion": "11.1.0-pre",
"type": "text"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 11,
"x": 0,
"y": 2
},
"id": 2,
"options": {
"channel": {
"namespace": "devenv",
"path": "weather",
"scope": "stream"
},
"display": "none",
"json": {
"hello": "world"
},
"message": "weather,location=west,sensor=A temperature=82\nweather,location=east,sensor=A temperature=76",
"publish": "influx"
},
"title": "Enter weather data",
"type": "live"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 13,
"x": 11,
"y": 2
},
"id": 4,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"channel": "stream/devenv/weather",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Weather (values)",
"transformations": [
{
"id": "reduce",
"options": {
"includeTimeField": true,
"labelsToFields": false,
"mode": "reduceFields",
"reducers": [
"last"
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"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": 7,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "always",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 6
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "stream/devenv/weather",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Manually entered weather points",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"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": 7,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "always",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 13
},
"id": 10,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "plugin/testdata/random-flakey-stream",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Random flakey stream",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"live-tests"
],
"templating": {
"list": []
},
"time": {
"from": "now-30s",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Live flakey stream (w/ liveNow)",
"uid": "liveddluze",
"weekStart": ""
}
@@ -0,0 +1,373 @@
{
"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,
"id": 220,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"live-tests"
],
"targetBlank": false,
"title": "gdev live tests",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 2,
"w": 24,
"x": 0,
"y": 0
},
"id": 9,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "## Note the flakey refresh rate (liveNow = false). Also the time axis is not the same for all panels.",
"mode": "markdown"
},
"pluginVersion": "11.1.0-pre",
"type": "text"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 11,
"x": 0,
"y": 2
},
"id": 2,
"options": {
"channel": {
"namespace": "devenv",
"path": "weather",
"scope": "stream"
},
"display": "none",
"json": {
"hello": "world"
},
"message": "weather,location=west,sensor=A temperature=82\nweather,location=east,sensor=A temperature=76",
"publish": "influx"
},
"title": "Enter weather data",
"type": "live"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 13,
"x": 11,
"y": 2
},
"id": 4,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"channel": "stream/devenv/weather",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Weather (values)",
"transformations": [
{
"id": "reduce",
"options": {
"includeTimeField": true,
"labelsToFields": false,
"mode": "reduceFields",
"reducers": [
"last"
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"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": 7,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "always",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 6
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "stream/devenv/weather",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Manually entered weather points",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"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": 7,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "always",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 13
},
"id": 10,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "plugin/testdata/random-flakey-stream",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Random flakey stream",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"live-tests"
],
"templating": {
"list": []
},
"time": {
"from": "now-30s",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Live flakey stream",
"uid": "liveddluzy",
"weekStart": ""
}
@@ -0,0 +1,459 @@
{
"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,
"id": 209,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"live-tests"
],
"targetBlank": false,
"title": "gdev live tests",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"panels": [
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 2,
"w": 24,
"x": 0,
"y": 0
},
"id": 9,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "## This dashboard requires alpha panels to be enabled!",
"mode": "markdown"
},
"pluginVersion": "11.0.0-pre",
"type": "text"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 15,
"x": 0,
"y": 2
},
"id": 2,
"options": {
"channel": {
"namespace": "devenv",
"path": "weather",
"scope": "stream"
},
"display": "none",
"json": {
"hello": "world"
},
"message": "weather,location=west,sensor=A temperature=82\nweather,location=east,sensor=A temperature=76",
"publish": "influx"
},
"title": "Panel Title",
"type": "live"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 9,
"x": 15,
"y": 2
},
"id": 4,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": []
},
"pluginVersion": "11.0.0-pre",
"targets": [
{
"channel": "stream/devenv/weather",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "Weather (values)",
"transformations": [
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "time"
}
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 15,
"x": 0,
"y": 6
},
"id": 5,
"options": {
"channel": {
"namespace": "devenv",
"path": "weather",
"scope": "stream"
},
"display": "none",
"json": {
"hello": "world"
},
"message": "weather,location=west,sensor=A temperature=90\nweather,location=east,sensor=A temperature=80",
"publish": "influx"
},
"title": "Timeseries with multiple streaming queries",
"type": "live"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 10
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "stream/devenv/weather",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
},
{
"channel": "stream/devenv/weatherX",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"hide": false,
"queryType": "measurements",
"refId": "B"
}
],
"title": "Panel Title",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 15,
"x": 0,
"y": 17
},
"id": 6,
"options": {
"channel": {
"namespace": "devenv",
"path": "weather",
"scope": "stream"
},
"display": "none",
"json": {
"hello": "world"
},
"message": "weatherX,location=west,sensor=X temperature=82\nweatherX,location=east,sensor=X temperature=76",
"publish": "influx"
},
"title": "Panel Title",
"type": "live"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 9,
"x": 15,
"y": 17
},
"id": 7,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": []
},
"pluginVersion": "11.0.0-pre",
"targets": [
{
"channel": "stream/devenv/weatherX",
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"queryType": "measurements",
"refId": "A"
}
],
"title": "WeatherX (values)",
"transformations": [
{
"id": "sortBy",
"options": {
"fields": {},
"sort": [
{
"desc": true,
"field": "time"
}
]
}
}
],
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 15,
"x": 0,
"y": 21
},
"id": 8,
"options": {
"channel": {
"namespace": "devenv",
"path": "weather",
"scope": "stream"
},
"display": "none",
"json": {
"hello": "world"
},
"message": "weatherX,location=west,sensor=X temperature=90\nweatherX,location=east,sensor=X temperature=22",
"publish": "influx"
},
"title": "Panel Title",
"type": "live"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"live-tests"
],
"templating": {
"list": []
},
"time": {
"from": "now-1m",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Live publish test",
"uid": "addoomtlivedev",
"weekStart": ""
}
@@ -0,0 +1,780 @@
{
"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,
"id": 218,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"live-tests"
],
"targetBlank": false,
"title": "gdev live tests",
"tooltip": "",
"type": "dashboards",
"url": ""
}
],
"liveNow": true,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Value"
},
"properties": [
{
"id": "custom.lineWidth",
"value": 3
},
{
"id": "color",
"value": {
"fixedColor": "super-light-blue",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Max"
},
"properties": [
{
"id": "custom.fillBelowTo",
"value": "Min"
},
{
"id": "custom.fillOpacity",
"value": 72
},
{
"id": "color",
"value": {
"fixedColor": "dark-blue",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Min"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "dark-blue",
"mode": "fixed"
}
}
]
}
]
},
"gridPos": {
"h": 7,
"w": 13,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "random-20Hz-stream",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "live"
}
],
"title": "Random 20hs stream",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 7,
"x": 13,
"y": 0
},
"id": 5,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": [
{
"desc": true,
"displayName": "Time"
}
]
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 1,
"refId": "A"
}
],
"title": "Panel Title",
"transformations": [
{
"id": "filterFieldsByName",
"options": {
"include": {
"names": [
"Time",
"Value"
]
}
}
}
],
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "blue",
"mode": "fixed"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 4,
"x": 20,
"y": 0
},
"id": 3,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 1,
"refId": "A"
}
],
"title": "Stats",
"transformations": [
{
"id": "reduce",
"options": {
"reducers": [
"lastNotNull",
"min",
"max",
"count"
]
}
}
],
"type": "stat"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 13,
"x": 0,
"y": 7
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "random-2s-stream",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "live"
}
],
"title": "Random 2s stream",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 7,
"x": 13,
"y": 7
},
"id": 6,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": [
{
"desc": true,
"displayName": "Time"
}
]
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 2,
"refId": "A"
}
],
"title": "Panel Title",
"transformations": [
{
"id": "filterFieldsByName",
"options": {
"include": {
"names": [
"Time",
"Value"
]
}
}
}
],
"type": "table"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"fixedColor": "blue",
"mode": "fixed"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 4,
"x": 20,
"y": 7
},
"id": 4,
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showPercentChange": false,
"textMode": "auto",
"wideLayout": true
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 2,
"refId": "A"
}
],
"title": "Stats",
"transformations": [
{
"id": "reduce",
"options": {
"reducers": [
"lastNotNull",
"min",
"max",
"count"
]
}
}
],
"type": "stat"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"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"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 13,
"x": 0,
"y": 14
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"channel": "random-labeled-stream",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "live"
}
],
"title": "Random Labeled streams",
"type": "timeseries"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 11,
"x": 13,
"y": 14
},
"id": 8,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": [
{
"desc": true,
"displayName": "Time"
}
]
},
"pluginVersion": "11.1.0-pre",
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 7,
"refId": "A"
}
],
"title": "Labeled structure",
"type": "table"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"live-tests"
],
"templating": {
"list": []
},
"time": {
"from": "now-1m",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Live streaming examples",
"uid": "liveb94wbb",
"weekStart": ""
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,624 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 75,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 0
},
"id": 9,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.82,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Time,Name,Stat1,Stat2\n2020-01-01T00:00:00Z,Stockholm, 10, 15\n2020-01-01T00:00:00Z,New York, 19, 5\n2020-01-01T00:00:00Z,London, 10, 1\n2020-01-01T00:00:00Z,Negative, 15, -5\n2020-01-01T00:00:00Z,Long value, 15,10",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Auto sizing \u0026 auto show values",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "Should be smaller given the longer value",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"decimals": 2,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 0
},
"id": 15,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.82,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, 5\nLondon, 10, 1\nNegative, 15, -5\nLong value, 15,10",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Auto sizing \u0026 auto show values",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 8,
"x": 0,
"y": 10
},
"id": 16,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.89,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2,Stat3,Stat4,Stat5,Stat6,Stat7,Stat8,Stat9,Stat10\nA, 10, 15,8,3,4,12,14,1,5,10\nB, 19, 5,8,3,4,12,14,6,7,2\nC, 15, 5,8,3,4,10,4,6,7,2\n",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "auto show values \u0026 No room for value",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 8,
"x": 8,
"y": 10
},
"id": 17,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.89,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "auto",
"showValue": "always",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2,Stat3,Stat4,Stat5,Stat6,Stat7,Stat8,Stat9,Stat10\nA, 10, 15,8,3,4,12,14,1,5,10\nB, 19, 5,8,3,4,12,14,6,7,2\nC, 15, 5,8,3,4,10,4,6,7,2\n",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "auto show values \u0026 Always show value",
"type": "barchart"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 8,
"x": 16,
"y": 10
},
"id": 10,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 1,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {
"titleSize": 10,
"valueSize": 25
},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"panelId": 9,
"refId": "A"
}
],
"title": "Fixed value sizing",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"decimals": 7,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 12,
"x": 0,
"y": 21
},
"id": 18,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.82,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "horizontal",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, -5\nLondon, 10, 1\nLong value, 15,10",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Auto sizing \u0026 auto show values",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 12,
"x": 12,
"y": 21
},
"id": 19,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.89,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "horizontal",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2,Stat3,Stat4,Stat5,Stat6,Stat7,Stat8,Stat9,Stat10\nA, 10, 15,8,3,4,12,14,1,5,10\nB, 19, 5,8,3,4,12,14,6,7,2\nC, 15, 5,8,3,4,10,4,6,7,2\n",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "auto show values \u0026 little room",
"type": "barchart"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"panel-tests",
"barchart",
"graph-ng"
],
"templating": {
"list": []
},
"time": {
"from": "now-5m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "BarChart - Panel Tests - Value sizing",
"uid": "WFlOM-jM1",
"weekStart": ""
}
@@ -0,0 +1,316 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 530,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 1,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "decmbytes"
},
"overrides": []
},
"gridPos": {
"h": 14,
"w": 11,
"x": 0,
"y": 0
},
"id": 2,
"maxDataPoints": 30,
"options": {
"barRadius": 0,
"barWidth": 0.97,
"groupWidth": 0.7,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "vertical",
"showValue": "auto",
"stacking": "none",
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelMaxLength": 6,
"xTickLabelRotation": 45,
"xTickLabelSpacing": 100
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"fields\": [\n {\n \"name\": \"label\",\n \"type\": \"string\",\n \"typeInfo\": {\n \"frame\": \"string\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 600000\n }\n },\n {\n \"name\": \"A-series\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {},\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n \"acquisition\",\n \"extension\",\n \"conductor\",\n \"authorise\",\n \"architect\",\n \"illusion\",\n \"congress\",\n \"highlight\",\n \"partnership\",\n \"understanding\",\n \"disagreement\",\n \"personality\",\n \"commerce\",\n \"systematic\",\n \"hesitate\",\n \"business\",\n \"manufacture\",\n \"incredible\",\n \"constitutional\",\n \"prevalence\",\n \"professor\",\n \"entitlement\",\n \"cooperation\",\n \"sickness\",\n \"contrast\",\n \"reference\",\n \"audience\",\n \"discount\",\n \"apparatus\",\n \"disturbance\",\n \"automatic\",\n \"refrigerator\",\n \"elaborate\",\n \"sympathetic\",\n \"integration\",\n \"president\"\n ],\n [\n 306.78931659492116,\n 200.00696051101917,\n 164.90889283973593,\n 518.9385023737021,\n 999.9040675564702,\n 613.9689830172349,\n 773.2337077340269,\n 317.47395634701644,\n 748.3318338316539,\n 606.8039493787173,\n 426.27771317792866,\n 376.47735643253924,\n 66.30635081800493,\n 401.70654338415505,\n 108.86259550477234,\n 182.40284186231278,\n 867.7047958572101,\n 959.3957783599242,\n 396.7606089549935,\n 455.9625595614323,\n 685.4792456298062,\n 368.6567303946707,\n 157.06596562976327,\n 59.54120602048763,\n 406.72723615743973,\n 440.18247585615575,\n 516.0267558264891,\n 258.76006051667315,\n 952.966531725171,\n 554.8746357628739,\n 86.7279280805682,\n 781.2422516386563,\n 754.2723802427706,\n 435.0305712850233,\n 384.43181614983,\n 459.04164596738127\n ]\n ]\n }\n }\n]",
"refId": "A",
"scenarioId": "raw_frame"
}
],
"title": "Panel Title",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"decimals": 7,
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 14,
"w": 13,
"x": 11,
"y": 0
},
"id": 5,
"options": {
"barRadius": 0,
"barWidth": 1,
"groupWidth": 0.82,
"legend": {
"calcs": [
"max"
],
"displayMode": "list",
"placement": "right",
"showLegend": true
},
"orientation": "horizontal",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 45,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, -5\nLondon, 10, 1\nLong value, 15,10",
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Auto sizing \u0026 auto show values",
"type": "barchart"
},
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 1,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
},
"unit": "decmbytes"
},
"overrides": []
},
"gridPos": {
"h": 18,
"w": 24,
"x": 0,
"y": 14
},
"id": 3,
"maxDataPoints": 20,
"options": {
"barRadius": 0,
"barWidth": 0.97,
"groupWidth": 0.7,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "horizontal",
"showValue": "auto",
"stacking": "none",
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelMaxLength": 5,
"xTickLabelRotation": 45,
"xTickLabelSpacing": 100
},
"targets": [
{
"datasource": {
"type": "datasource",
"uid": "-- Dashboard --"
},
"panelId": 2,
"refId": "A"
}
],
"title": "Panel Title",
"type": "barchart"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"panel-tests",
"barchart",
"graph-ng"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "BarChart - Label Rotation \u0026 Skipping",
"uid": "xCmMwXdVz",
"weekStart": ""
}
@@ -0,0 +1,402 @@
{
"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"
}
]
},
"description": "",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 271,
"links": [],
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 6,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"barRadius": 0,
"barWidth": 1,
"fullHighlight": false,
"groupWidth": 0.82,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1\nStockholm, 10\nNew York, 19\nLondon, 10\nNegative, 15\nLong value, 15",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "One series",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 6,
"x": 6,
"y": 0
},
"id": 2,
"options": {
"barRadius": 0,
"barWidth": 0.97,
"fullHighlight": false,
"groupWidth": 0.7,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "none",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, 5\nLondon, 10, 1\nNegative, 15, 5\nLong value, 15,10",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Two series",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 6,
"x": 0,
"y": 11
},
"id": 3,
"options": {
"barRadius": 0,
"barWidth": 1,
"fullHighlight": false,
"groupWidth": 0.82,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "normal",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, 5\nLondon, 10, 1\nNegative, 15, 5\nLong value, 15,10",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Two series",
"type": "barchart"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"axisSoftMin": 0,
"fillOpacity": 80,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"scaleDistribution": {
"type": "linear"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 6,
"x": 6,
"y": 11
},
"id": 4,
"options": {
"barRadius": 0,
"barWidth": 0.7,
"fullHighlight": false,
"groupWidth": 0.7,
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"orientation": "auto",
"showValue": "auto",
"stacking": "normal",
"text": {},
"tooltip": {
"mode": "single",
"sort": "none"
},
"xTickLabelRotation": 0,
"xTickLabelSpacing": 0
},
"targets": [
{
"csvContent": "Name,Stat1,Stat2\nStockholm, 10, 15\nNew York, 19, 5\nLondon, 10, 1\nNegative, 15, 5\nLong value, 15,10",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "csv_content"
}
],
"title": "Two series",
"type": "barchart"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"panel-tests",
"barchart",
"graph-ng"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "BarChart - Panel Tests - Series toggle / bar widths",
"uid": "adoero0hbka9sf",
"weekStart": ""
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,867 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 7501,
"links": [],
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 7,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"max": 100,
"min": 0,
"unit": "decgbytes"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "green",
"index": 0
},
{
"color": "orange",
"index": 1,
"value": 60
},
{
"color": "red",
"index": 2,
"value": 80
}
],
"values": false
},
"orientation": "vertical"
},
"targets": [
{
"alias": "sda1",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "sda2",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"alias": "sda3",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"alias": "sda4",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"alias": "sda5",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"alias": "sda6",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"alias": "sda7",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"alias": "sda8",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "H",
"scenarioId": "random_walk"
},
{
"alias": "sda9",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "I",
"scenarioId": "random_walk"
},
{
"alias": "sda10",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"alias": "sda11",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"alias": "sda12",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"alias": "sda13",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"alias": "sda14",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"alias": "sda15",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"alias": "sda16",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "P",
"scenarioId": "random_walk"
}
],
"transparent": true,
"type": "bargauge"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 10,
"w": 16,
"x": 0,
"y": 7
},
"id": 4,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"max": 100,
"min": 0,
"unit": "celsius"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "blue",
"index": 0
},
{
"color": "green",
"index": 1,
"value": 20
},
{
"color": "orange",
"index": 2,
"value": 40
},
{
"color": "red",
"index": 3,
"value": 80
}
],
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"alias": "Inside",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "Area B",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"alias": "Basement",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"alias": "Garage",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "D",
"scenarioId": "random_walk"
}
],
"title": "Gradient mode",
"type": "bargauge"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 10,
"w": 6,
"x": 16,
"y": 7
},
"id": 6,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"max": 100,
"min": 0,
"unit": "watt"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "blue",
"index": 0
},
{
"color": "green",
"index": 1,
"value": 42.5
},
{
"color": "orange",
"index": 2,
"value": 80
},
{
"color": "red",
"index": 3,
"value": 90
}
],
"values": false
},
"orientation": "horizontal"
},
"pluginVersion": "6.2.0-pre",
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "P",
"scenarioId": "random_walk"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "Q",
"scenarioId": "random_walk"
}
],
"title": "Basic",
"type": "bargauge"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 22,
"w": 2,
"x": 22,
"y": 7
},
"id": 8,
"options": {
"displayMode": "lcd",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"max": 100,
"min": 0
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "red",
"index": 0
},
{
"color": "red",
"index": 1,
"value": 90
}
],
"values": false
},
"orientation": "vertical"
},
"targets": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
}
],
"title": "Completion",
"type": "bargauge"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 12,
"w": 22,
"x": 0,
"y": 17
},
"id": 10,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"max": 100,
"min": 0,
"unit": "decgbytes"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "blue",
"index": 0
},
{
"color": "green",
"index": 1,
"value": 30
},
{
"color": "orange",
"index": 2,
"value": 60
},
{
"color": "red",
"index": 3,
"value": 80
}
],
"values": false
},
"orientation": "vertical"
},
"targets": [
{
"alias": "sda1",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "sda2",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"alias": "sda3",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"alias": "sda4",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"alias": "sda5",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"alias": "sda6",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"alias": "sda7",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"alias": "sda8",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "H",
"scenarioId": "random_walk"
},
{
"alias": "sda9",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "I",
"scenarioId": "random_walk"
},
{
"alias": "sda10",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"alias": "sda11",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"alias": "sda12",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"alias": "sda13",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"alias": "sda14",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"alias": "sda15",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"alias": "sda16",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "P",
"scenarioId": "random_walk"
}
],
"type": "bargauge"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 29
},
"id": 11,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"max": 100,
"min": 0,
"unit": "decgbytes"
},
"mappings": [],
"override": {},
"thresholds": [
{
"color": "blue",
"index": 0
},
{
"color": "green",
"index": 1,
"value": 30
},
{
"color": "orange",
"index": 2,
"value": 60
},
{
"color": "red",
"index": 3,
"value": 80
}
],
"values": false
},
"orientation": "vertical"
},
"targets": [
{
"alias": "sda1",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "sda2",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"alias": "sda3",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"alias": "sda4",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"alias": "sda5",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "E",
"scenarioId": "random_walk"
},
{
"alias": "sda6",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"alias": "sda7",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "G",
"scenarioId": "random_walk"
},
{
"alias": "sda8",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "H",
"scenarioId": "random_walk"
},
{
"alias": "sda9",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "I",
"scenarioId": "random_walk"
},
{
"alias": "sda10",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"alias": "sda11",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"alias": "sda12",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"alias": "sda13",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"alias": "sda14",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"alias": "sda15",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"alias": "sda16",
"datasource": {
"type": "grafana-testdata-datasource"
},
"refId": "P",
"scenarioId": "random_walk"
}
],
"type": "bargauge"
}
],
"refresh": "10s",
"schemaVersion": 42,
"tags": [
"gdev",
"demo"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"2s",
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Bar Gauge Demo",
"uid": "vmie2cmWz",
"weekStart": ""
}
@@ -0,0 +1,751 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"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": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 0
},
"id": 8,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "green"
},
{
"color": "purple",
"value": 50
},
{
"color": "blue",
"value": 70
}
],
"unit": "watt"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": false
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "D",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "I",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "P",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "Q",
"scenarioId": "random_walk"
}
],
"title": "Basic vertical ",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 0
},
"id": 22,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "green"
},
{
"color": "blue",
"value": 25
},
{
"color": "orange",
"value": 37.5
},
{
"color": "purple",
"value": 43.75
},
{
"color": "red",
"value": 50
}
],
"unit": "watt"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "J",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "K",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "L",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "M",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "N",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "O",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "P",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "Q",
"scenarioId": "random_walk"
}
],
"title": "Basic vertical (Unfilled)",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 10
},
"id": 12,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "green",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "celsius"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": false
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"alias": "Inside",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
}
],
"title": "Gradient ",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 10
},
"id": 23,
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "green",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "celsius"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"alias": "Inside",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
}
],
"title": "Gradient (Unfilled)",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 6,
"w": 12,
"x": 0,
"y": 19
},
"id": 21,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "green",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "celsius"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": false
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"alias": "Inside",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
}
],
"title": "Title to left of bar",
"type": "bargauge"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"gridPos": {
"h": 6,
"w": 12,
"x": 12,
"y": 19
},
"id": 24,
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": [
"mean"
],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue"
},
{
"color": "green",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "celsius"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"alias": "Inside",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "A",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "F",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "B",
"scenarioId": "random_walk"
},
{
"datasource": {
"apiVersion": "v1",
"type": "grafana-testdata-datasource",
"uid": "testdata-type-uid"
},
"refId": "C",
"scenarioId": "random_walk"
}
],
"title": "Title to left of bar (Filled)",
"type": "bargauge"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"panel-tests"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
]
},
"timezone": "",
"title": "Panel Tests - Bar Gauge 2",
"uid": "sRrEibfZk",
"weekStart": ""
}

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