Compare commits

..

124 Commits

Author SHA1 Message Date
Dominik Prokop
05025c5495 DataLinks: Make data links input grow again (#21499)
(cherry picked from commit 2355d0901a)
2020-01-15 10:36:39 +01:00
Andrej Ocenas
57315ae08d Release 6.5.3 version changes 2020-01-15 10:36:39 +01:00
Erik Sundell
4e73140963 CloudWatch: dimension_values templating fix (#21401)
* Handle dimension value if passed as array

* Break out dimension value loading into its own func

(cherry picked from commit cf2dd51827)
2020-01-15 10:36:39 +01:00
Leonard Gram
f86e4e39fd Build: package all binaries for enterprise (#21381)
(cherry picked from commit 1c71637d11)
2020-01-15 10:36:39 +01:00
Torkel Ödegaard
1a057dac84 Cloudwatch: Fixed crash when switching from cloudwatch data source (#21376)
(cherry picked from commit f774c4a076)
2020-01-15 10:36:39 +01:00
Boris Granveaud
89f040fb03 Rendering: Fix panel PNG rendering when using sub url & serve_from_sub_path = true (#21306)
* Rendering: fix dashboard rendering when using sub url

* rollback on render.go: no need to add sub-path

(cherry picked from commit b8b618241e)
2020-01-15 10:36:39 +01:00
Ryan McKinley
54044155a5 Units: support farenheit (existing misspelling) (#21249)
(cherry picked from commit af2cd77655)
2020-01-15 10:36:39 +01:00
vikkyomkar
a8707bbc0e Docs: fixed broken doc link for graph and table panels (#21238)
* fixed  broken doc link

* fixed broken doc link

(cherry picked from commit bc10a69626)
2020-01-15 10:36:39 +01:00
vikkyomkar
5bc2f9eb1e Docs: fix of broken doc link in the dashlist panel's help section (#21230)
* fixed the broker link of dashlist panel docs

* fixed broken document link

(cherry picked from commit 68f73b18fb)
2020-01-15 10:36:39 +01:00
mpursley
f903c43106 Docs: Update the link to docs for singlestat (#21225)
(cherry picked from commit bf79b97b6e)
2020-01-15 10:36:39 +01:00
Hugo Häggmark
50ad07c14c Table: Matches column names with unescaped regex characters (#21164)
* Table: Matches column names with unescaped regex characters
Fixes #21106

* Chore: Cleans up unused code

(cherry picked from commit 05cb85feba)
2020-01-15 10:36:39 +01:00
Dominik Prokop
6307f53a32 DataLinks: Sanitize data/panel link URLs (#21140)
* Sanitize html in panel links

* Add sanitize-url package

* Enable config mocking

* Sanitize datalinks urls

* Update public/app/core/config.ts

* Minor test update

* Remove sanitize-url dependency

* Remove typings

* Review update

* Revert "Remove sanitize-url dependency"

This reverts commit c4f38e6de6.

* Revert "Remove typings"

This reverts commit 676d47e8c2.

* Sanitaze, don't escape html when sanitizing URL

(cherry picked from commit 26aa1f0cca)
2020-01-15 10:36:39 +01:00
Sofia Papagiannaki
aa9d3f6a79 API: Validate redirect_to cookie has valid (Grafana) url (#21057)
* Restrict redirect_to to valid relative paths

* Add tests

(cherry picked from commit b12dc890b8)
2020-01-15 10:36:39 +01:00
Hugo Häggmark
50be540a19 Prometheus: Prevents validation of inputs when clicking in them without changing the value (#21059)
Fixes #21056

(cherry picked from commit a187500c0e)
2020-01-15 10:36:39 +01:00
Hugo Häggmark
7247f0f213 Prometheus: Fixes so user can change HTTP Method in config (#21055)
Fixes #21004

(cherry picked from commit e69ec6ca53)
2020-01-15 10:36:39 +01:00
Hugo Häggmark
e2699f5e5e Templating: Fixes default visibility for submenu to same as dashboard (#21050)
(cherry picked from commit 8fd1931e1c)
2020-01-15 10:36:39 +01:00
Hugo Häggmark
77f85f9ed6 Fix: Shows SubMenu when filtering directly from table (#21017)
* Fix: Shows SubMenu when filtering from table
Fixes #20270

* Tests: Updates snapshots

* Refactor: Changes after PR comments

* Refactor: Changes template

(cherry picked from commit 8495af4c52)
2020-01-15 10:36:39 +01:00
Ivana Huckova
27b8cce24f Elastic: Fix multiselect variable interpolation for logs (#20894)
(cherry picked from commit 827688f152)
2020-01-15 10:36:39 +01:00
Marcus Andersson
742d165968 release 6.5.2 2019-12-11 13:41:26 +01:00
David
bb4b4a251f Prometheus: removes metric syntax (#21003)
* Prometheus: removes metric syntax

* Removed unused constant
2019-12-11 13:41:26 +01:00
Torkel Ödegaard
2c3e9ec887 MixedDatasources: Do not filter out all mixed data sources in add mixed query dropdown (#20990)
(cherry picked from commit 72ee1b9a94)
2019-12-11 13:41:26 +01:00
Leonard Gram
0b37efa96a build: adds IANA timezone info to windows build (#21001)
(cherry picked from commit 67d83d1ffc)
2019-12-11 13:41:26 +01:00
Erik Sundell
c48548c9b4 Make sure datasource variable is being used everywhere (#20917)
(cherry picked from commit 93ab0532c7)
2019-12-11 13:41:26 +01:00
Torkel Ödegaard
a36e320d8b Alerting: Improve alert threshold handle dragging behavior (#20922)
(cherry picked from commit fc00d8336f)
2019-12-11 13:41:26 +01:00
Andrej Ocenas
1c5df83102 Prometheus: Refactor labels caching (#20898)
(cherry picked from commit a7f4e4c56a)
2019-12-11 13:41:26 +01:00
Sofia Papagiannaki
1bff4b50e0 Elasticsearch: set default port to 9200 in ConfigEditor (#20948)
(cherry picked from commit 4ad8b6f030)
2019-12-11 13:41:26 +01:00
David
d3fa0bf4a4 Cloudwatch: Defined explore query editor for cloudwatch (#20909)
* Defined explore query editor for cloudwatch

* Fix types

(cherry picked from commit ab3df98523)
2019-12-11 13:41:26 +01:00
Erik Sundell
fa897fca76 Remove escaping of \ ( ) characters (#20915)
(cherry picked from commit a533e00622)
2019-12-11 13:41:26 +01:00
Torkel Ödegaard
45abe478cb AngularPanels: Check for digest cycle on root scope (#20919)
(cherry picked from commit 2a44cbd137)
2019-12-11 13:41:26 +01:00
Erik Sundell
e43aecd194 Remove false positive error message for expression and id field (#20864)
(cherry picked from commit 9d9f0e1b8c)
2019-12-11 13:41:26 +01:00
Torkel Ödegaard
dc2ac41fdc AngularPanels: Fixed loading spinner being stuck in some rare cases (#20878)
(cherry picked from commit 62f0aca3e6)
2019-12-11 13:41:26 +01:00
Hendrik van Huyssteen
ea07f7fe8e TeamPicker: Increase size limit from 10 to 100 (#20882)
(cherry picked from commit 9a7a1b86ee)
2019-12-11 13:41:26 +01:00
Marcus Andersson
7f41446083 GraphTooltip: added boundaries so we never render tooltip outside window. (#20874)
(cherry picked from commit 5f72bfe6e7)
2019-12-11 13:41:26 +01:00
Dominik Prokop
327558c890 Graphite: Use data frames when procesing annotation query in graphite ds (#20857)
* Use data frames when procesing annotation query in graphite ds

* Remove destruct

(cherry picked from commit ad33d95dd3)
2019-12-11 13:41:26 +01:00
Marcus Andersson
45278bac28 Gauge/BarGauge: Added support for value mapping of "no data"-state to text/value (#20842)
* FieldDisplay: added support for value mapping of no data state.

 Committer: Marcus Andersson <marcus.andersson@grafana.com>

* FieldDisplay: fixed issue when switching between modes and display numeric was null.

* ValueMapping: introduced a private function for checking null values.

* FieldDisplay: refactoring of test setup to reduce duplication.

* Docs: added info about new 'no data' value to text mapping.

* Docs: improved according to feedback. Reverted prettier formatting changes.

* FieldDisplay: removed unused import.

(cherry picked from commit 7a710737ae)
2019-12-11 13:41:26 +01:00
Arve Knudsen
dccd0c2f2d Server: Return 404 when non-pending invite is requested (#20863)
Server API: Return 404 when non-pending invite is requested

(cherry picked from commit abc7893fdc)
2019-12-11 13:41:26 +01:00
Milan Pavlik
5be4bf742c Update README.md (#20820)
(cherry picked from commit fd2b39a3e9)
2019-12-11 13:41:26 +01:00
Arve Knudsen
c059fedcb3 Server: Fail when unable to create log directory (#20804)
(cherry picked from commit b1af28122b)
2019-12-11 13:41:26 +01:00
Adam Zegelin
dbc231fdaf Units: Remove SI prefix symbol from new milli/microSievert(/h) (#20650)
(cherry picked from commit fcde26e2db)
2019-12-11 13:41:26 +01:00
Peter Holmberg
418bba81db Navigation: Fix navigation when new password is chosen (#20747)
(cherry picked from commit b3816a2727)
2019-12-11 13:41:26 +01:00
Andrej Ocenas
c48999edd6 Prometheus: Fix caching for default labels request (#20718)
(cherry picked from commit f2574f4944)
2019-12-11 13:41:26 +01:00
Hugo Häggmark
1763a0fd80 Release 6.5.1 2019-11-28 08:43:49 +01:00
Sofia Papagiannaki
8e7f6cd454 SQLStore: Rewrite system statistics query to count users once (#20711)
Fix system statistics query to count only once users that are
part of several organisations.

Fixes #20681

(cherry picked from commit 02d7d00560)
2019-11-28 08:43:49 +01:00
Erik Sundell
e3db87d27a CloudWatch: Region template query fix (#20661)
* Make region an optional parameter

* Test region template query

(cherry picked from commit 116b6188a6)
2019-11-28 08:43:49 +01:00
Hans-Peter Schadler
89f6dd2348 Documentation: Add missing blank in docker run command (#20705)
(cherry picked from commit 616e2eb29f)
2019-11-28 08:43:49 +01:00
Arve Knudsen
ccebda73d4 Server: Defer wg.Done call to ensure it's called (#20700)
(cherry picked from commit 3c7cfbebe8)
2019-11-28 08:43:49 +01:00
Hugo Häggmark
83dbc4c7c7 Fix: Fixes templateSrv is undefined for plugins that do not use @@ngInject (#20696)
Fixes #20662

(cherry picked from commit 1751770394)
2019-11-28 08:43:49 +01:00
Arve Knudsen
3dd33b7ac0 Server: Clean up startup logic/error checking (#20679)
* Server: Clean up startup logic/error checking

(cherry picked from commit 29d27fbaf0)
2019-11-28 08:43:49 +01:00
Erik Sundell
fc248d8941 CloudWatch: Annotations query editor loading fix (#20687)
* Re-adding lost import

* Make sure wildcard is not in annotations editor

(cherry picked from commit 2929649fd4)
2019-11-28 08:43:49 +01:00
Marcus Efraimsson
24a5d2fe8b release 6.5.0 2019-11-25 12:01:36 +01:00
Sofia Papagiannaki
4a536f231e Chore: Improve grafana-server profiling and tracing (#20593)
Profiling and tracing can now be enabled/disabled separately.
Adds argument for trace file path.
Support overriding profiling and tracing argument using
environment variables.
Update docs.

Fixes #20576
(cherry picked from commit b16cb92b32)
2019-11-25 12:01:36 +01:00
Marcus Efraimsson
0ebfd921cf prettier format fix 2019-11-25 12:01:36 +01:00
Torkel Ödegaard
210a0beca8 BarGauge/Gauge: Add back missing title option field display options (#20616)
Fixes #20615
(cherry picked from commit 6c50feb252)
2019-11-25 12:01:36 +01:00
Erik Sundell
3858c3bc18 Docs: CloudWatch docs fixes (#20609)
* Updates after feedback

* docs: remove br tag in whats new

(cherry picked from commit 161f481f12)
2019-11-25 12:01:36 +01:00
Erik Sundell
f927502908 Cloudwatch: Docs improvements (#20100)
* Add Service Quota part

* Update docs after pr feedback

* Describing new features

* Divide into subheaders

* Changes after feedback

* cloudwatch: add min time interval section to docs

* docs: json format fix

* cloudwatch: move min time interval section in docs

* cloudwatch: docs fix

* docs: cloudwatch fixes

* docs: s/you are/you're

* docs: Cloudwatch - escapes underscores in tables

(cherry picked from commit de94298d3a)
2019-11-25 12:01:36 +01:00
Marcus Efraimsson
5e294f321d CloudWatch: Fix high CPU load (#20579)
* Cache decrypted securejsondata
* Models: Add datasource cache tests

(cherry picked from commit 3fc5f4552a)
2019-11-25 12:01:36 +01:00
Ivana Huckova
15f8fb5004 Explore: UI changes for split view and live tailing (#20516)
(cherry picked from commit 29b46f7a28)
2019-11-25 12:01:36 +01:00
Ivana Huckova
28399a1d85 Explore: Keep logQL filters when selecting labels in log row details (#20570)
(cherry picked from commit c6a9a83bf3)
2019-11-25 12:01:36 +01:00
Jon Gyllenswärd
875431c7b0 Instrumentation: Edition and license info to usage stats (#20589)
* Added edition and licensing info to usage stats

(cherry picked from commit bccc5397f6)
2019-11-25 12:01:36 +01:00
Ryan McKinley
3e0969397e grafana/toolkit: Smaller output after successful upload (#20580)
After toolkit uploads a report successfully, it should only show the
response data, not the whole request info.
(cherry picked from commit d9abf01ce1)
2019-11-25 12:01:36 +01:00
Ryan McKinley
a2e3ad166d Table: Use the configured field formatter if it exists (#20584)
This PR lets the alpha Table component use a Fields configured
formatter rather than the super hacky ColumnStyle.
(cherry picked from commit f78b3b1329)
2019-11-25 12:01:36 +01:00
Torkel Ödegaard
af22094e5d TextPanel: Fixes issue with template variable value not properly html escaped (#20588)
* sanitize html after replacing variables

* TextPanel: Always html escape variable values

(cherry picked from commit f47759b98e)
2019-11-25 12:01:36 +01:00
Ivana Huckova
5842818a38 Docs: Update Explore docs for 6.5 (time-sync button & log details) (#20390)
(cherry picked from commit 11304b14b6)
2019-11-25 12:01:36 +01:00
Ivana Huckova
4cd912c3ba Explore: UI changes for derived fields (#20557)
(cherry picked from commit 569c81d07e)
2019-11-25 12:01:36 +01:00
Marcus Efraimsson
b9ab181f63 Docker: Custom dockerfiles, docker and image rendering docs update (#20492)
Adds support for using custom dockerfiles to pre-install image
renderer plugins.
Updates docs for docker and image rendering.

Fixes #20241

Co-Authored-By: Leonard Gram <leo@xlson.com>

(cherry picked from commit 2484b24c75)
2019-11-25 12:01:36 +01:00
Dominik Prokop
a41233dd7e Tooltip: Fix issue with tooltip throwing an error when retrieving values (#20565)
(cherry picked from commit caff9146ea)
2019-11-25 12:01:36 +01:00
Erik Sundell
ac98c4dc71 Changelog: Reference a few more issues that were fixed (#20562)
* Reference a few more issues that were fixed

* Remove dashboard entry - it will be added automatically

(cherry picked from commit 83fa91b1f4)
2019-11-25 12:01:36 +01:00
Dominik Prokop
cc5205260b Enable theme context mocking in tests (#20519)
* Enable theme context mocking in tests

* Expose mockThemeContext from grafana/ui

* Add docs

* Update contribute/style-guides/themes.md

Co-Authored-By: Marcus Olsson <olsson.e.marcus@gmail.com>

* Update packages/grafana-ui/src/themes/ThemeContext.tsx

Co-Authored-By: Marcus Olsson <olsson.e.marcus@gmail.com>

* Update contribute/style-guides/themes.md

Co-Authored-By: Marcus Olsson <olsson.e.marcus@gmail.com>

* Docs update

* Update contribute/style-guides/themes.md

Co-Authored-By: Marcus Olsson <olsson.e.marcus@gmail.com>

(cherry picked from commit bff08ab99f)
2019-11-25 12:01:36 +01:00
Lukas Siatka
281dfe980e Explore: updates responsive button to pass all the div element props
(cherry picked from commit 4ddb113b79)
2019-11-25 12:01:36 +01:00
Łukasz Siatka
8cf07ca15e Explore: fixes explore responsive button ref
(cherry picked from commit 013179eebc)
2019-11-25 12:01:36 +01:00
Łukasz Siatka
e657dea9ab Explore: adds a ref to responsive button
(cherry picked from commit 1cc1e545a0)
2019-11-25 12:01:36 +01:00
Łukasz Siatka
716e12f9fb Explore: updates responsive button to forward ref
(cherry picked from commit 231e620f95)
2019-11-25 12:01:36 +01:00
Ivana Huckova
cc797a86e8 Explore: UI fixes for log details (#20485)
(cherry picked from commit c9645a96c6)
2019-11-25 12:01:36 +01:00
Mitsuhiro Tanda
367503e6bd CloudWatch: enable min_interval (#20260)
(cherry picked from commit e33cf32b97)
2019-11-25 12:01:36 +01:00
Leonard Gram
8ae9ccd308 CI: fix release script remove filtering (#20552)
(cherry picked from commit 65bacf2df6)
2019-11-25 12:01:36 +01:00
Erik Sundell
a0de783f84 Update dashboards (#20486)
(cherry picked from commit 22edacd4a8)
2019-11-25 12:01:36 +01:00
Leonard Gram
7357110acf CI: Build all platforms for Enterprise (#20389)
* CI: Build all platforms for Enterprise

* CI: publishes new enterprise builds to grafana.com

(cherry picked from commit d630ac4b68)
2019-11-25 12:01:36 +01:00
Sofia Papagiannaki
dc46be5169 Alerting: Propagate failures to delete dashboard alerts (#20507)
* Propagate failures to delete dashboard alerts

(cherry picked from commit ea7ccda647)
2019-11-25 12:01:36 +01:00
Erik Sundell
8e2a725d86 Cloudwatch: Fix LaunchTime attribute tag bug (#20237)
* Cast tags of type Time to string

* Fig go lint issue

(cherry picked from commit 359416b89f)
2019-11-25 12:01:36 +01:00
Hugo Häggmark
3477f1e4b2 Fix: Prevents crash when searchFilter is non string (#20526)
(cherry picked from commit e03d702d0c)
2019-11-25 12:01:36 +01:00
Marcus Efraimsson
99d89eace2 docs: what's new fixes (#20535)
What's new in v6.5 fixes.
(cherry picked from commit 2079386a7d)
2019-11-25 12:01:36 +01:00
Erik Sundell
3dfe957589 What's new in 6.5 - adding CloudWatch topics (#20497)
* Adding cloudwatch related stuff - images will come later on

* Changes after pr feedback

* Add images

* Update image path

* Remove react migration part - might not be so interesting for our users

* Removing part about curated dashboards since it's not released yet - will be re-added later on

(cherry picked from commit 49685a92fd)
2019-11-25 12:01:36 +01:00
Dominik Prokop
dde6cbf8f6 grafana/ui: Expose Icon component (#20524)
(cherry picked from commit 9f94e059cf)
2019-11-25 12:01:36 +01:00
Peter Holmberg
c5a28d8cb3 MySql: Fix tls auth settings in config page (#20501)
(cherry picked from commit d3d595a776)
2019-11-25 12:01:36 +01:00
Erik Sundell
af4cf3f451 CloudWatch: Remove HighResolution toggle since it's not being used (#20440)
* Remove highres flag since it's not being used

* Remove not used code. Init id field correctly

* Fix broken tests

* Remove GMS related calculations

* Rename period field

* Add breaking changes to changelog. Also update upgrading docs

* Update snapshot

* Update docs after feedback

* Changes after feedback

(cherry picked from commit ec18e2bfc3)
2019-11-25 12:01:36 +01:00
Jon Gyllenswärd
6781a63897 Image-rendering: Cleanup of rendering code (#20496)
(cherry picked from commit 1b38d94537)
2019-11-25 12:01:36 +01:00
Torkel Ödegaard
b8da278bd1 TimePicker: Fixed update issue after plugin uses getLocationSrv().update (#20466)
* TimePicker: Fixed update issue after plugin uses getLocationSrv().update

* comment fix

* don't mess with the text panel

(cherry picked from commit 322c110b89)
2019-11-25 12:01:36 +01:00
Ivana Huckova
a718dac6bf Docs: Add explore images to What's new in v6.5 (#20442)
(cherry picked from commit c2e401667c)
2019-11-25 12:01:36 +01:00
Mitsuhiro Tanda
e904b6a206 handle PartialData status (#20459)
(cherry picked from commit af35e081c2)
2019-11-25 12:01:36 +01:00
Erik Sundell
ee896b8341 CloudWatch: Make sure period variable is being interpreted correctly (#20447)
* Make sure variable is interpreted before parsing int

* Use correct datatype in tests

(cherry picked from commit 38d5abfadb)
2019-11-25 12:01:36 +01:00
Torkel Ödegaard
239d491a0b UsersPage: Removed icon in external button (#20441)
(cherry picked from commit 785584a690)
2019-11-25 12:01:36 +01:00
Gabriel Kent
5bc748cb56 Dashboard Migrator: persist thresholds param if already set (#20458)
(cherry picked from commit 836cf8e639)
2019-11-25 12:01:36 +01:00
Jon Gyllenswärd
64e294c586 Reporting: Handle timeouts in rendering (#20415)
* Added timeout in grpc call to plugins for rendering

(cherry picked from commit 7a8c6a9b54)
2019-11-25 12:01:36 +01:00
Andrej Ocenas
62b61f98cc Provisioning: Fix unmarshaling nested jsonData values (#20399)
Problem was that yaml unmarshal returned nested maps as
 map[interface{}]interface{} which are then not marshal-able
to json because of that interface{} key type. This adds explicit
casting of the keys in the yaml value types to string which
then makes the values marshal-able to JSON in DB.

Fixes: #11537
(cherry picked from commit 3f144bdd05)
2019-11-25 12:01:36 +01:00
Arve Knudsen
80e5b8318c Fail when server is unable to bind port (#20409)
* Server: Return error when unable to bind port
* Server: Exit if a service fails
* Build: Remove graceful kill from Bra config
(cherry picked from commit 82f4fc2783)
2019-11-25 12:01:36 +01:00
Dominik Prokop
1b21695b7e Packages: stable release tags update (#20417)
* Update next npm tag when publishing stable release

* shellcheck fix

(cherry picked from commit de9ea829a4)
2019-11-25 12:01:36 +01:00
Marcus Efraimsson
bcd2dcb0ee Chore: Log actual error when oauth pass thru fails (#20419)
Logs the actual error when failing to retreive access token
when OAuth pass true is enabled for a datasource.

Ref: #20407
(cherry picked from commit dfa2f3d2fb)
2019-11-25 12:01:36 +01:00
Emil Tullstedt
b0f26bf253 NavLinks: Make ordering in navigation configurable (#20382)
The ordering of links in the navigation bar is currently based the order of the slice containing the navigation tree. Since Grafana supports adding more links to the navigation bar with `RunIndexDataHooks` which runs at the very end of the function this means that any link registered through a hook will be placed last in the slice and be displayed last in the menu. With this PR the ordering can be specified with a weight which allows for placing links created by extensions in a more intuitive place where applicable.

Stable sorting is used to ensure that the current FIFO ordering is preserved when either no weight is set or two items shares the same weight.
(cherry picked from commit d4e013fd44)
2019-11-25 12:01:36 +01:00
Dominik Prokop
a97b126633 Fix flot overriding onselectstart/ondrag events (#20381)
(cherry picked from commit d602da20f6)
2019-11-25 12:01:36 +01:00
Marcus Efraimsson
96e4ae839d Docs: What's new in Grafana v6.5 Draft (#20368)
Fixes incorrect auth proxy link.
Update index page to link to v6.4 (currently latest).
Adds What's new in v6.5 draft article.
(cherry picked from commit 073e9ef9e7)
2019-11-25 12:01:36 +01:00
Erik Sundell
12000ef4e4 Update changelog for v6.5.0-beta1 (#20350)
Updates changelog for v6.5 including breaking changes
 and docs/upgrading to v6.5 notes.
(cherry picked from commit 771ee549fb)
2019-11-25 12:01:36 +01:00
Dominik Prokop
899a4f0700 grafana/ui: Add Icon component (#20353)
* Add Icon component

* Add missing Icon types

* Polish icon story

* Update packages/grafana-ui/src/components/Icon/Icon.mdx

(cherry picked from commit 17fe704ae8)
2019-11-25 12:01:36 +01:00
Sofia Papagiannaki
ab9c0da30e MySql: Fix password regression in MySQL datasource (#20376)
(cherry picked from commit 2ca1cc5645)
2019-11-14 08:33:19 -05:00
Erik Sundell
1f3c557dfd CloudWatch: Datasource improvements (#20268)
* CloudWatch: Datasource improvements

* Add statistic as template variale

* Add wildcard to list of values

* Template variable intercept dimension key

* Return row specific errors when transformation error occured

* Add meta feedback

* Make it possible to retrieve values without known metrics

* Add curated dashboard for EC2

* Fix broken tests

* Use correct dashboard name

* Display alert in case multi template var is being used for some certain props in the cloudwatch query

* Minor fixes after feedback

* Update dashboard json

* Update snapshot test

* Make sure region default is intercepted in cloudwatch link

* Update dashboards

* Include ec2 dashboard in ds

* Do not include ec2 dashboard in beta1

* Display actual region

(cherry picked from commit 00bef917ee)
2019-11-14 08:33:19 -05:00
Ryan McKinley
6686611369 grafana/toolkit: remove aws-sdk and upload to grafana.com API endpoint (#20372)
* remove aws-sdk and upload directly

* remove unused imports

* put the plugin file in the root directory

(cherry picked from commit 1f018adbf3)
2019-11-14 08:33:19 -05:00
Leonard Gram
e19d43ef2d LDAP: last org admin can login but wont be removed (#20326)
* LDAP: last org admin (that's going to be removed) can login
Previously, if you tried to login with LDAP but were that last org admin
of an org that you would no longer be an admin of after sync (which
happens at login), you wouldn't be able to login due to an error.

(cherry picked from commit e9668fd251)
2019-11-14 08:33:19 -05:00
Šimon Podlipský
a8f13bb0c1 DataFrame processing: Require table rows to be array (#20357)
(cherry picked from commit 4260cd548f)
2019-11-14 08:33:19 -05:00
Marcus Efraimsson
0773ae80ea Telegram: Check error before adding defer close of image (#20331)
Properly handles file opening error and returns before deferring 
close of file.

Fixes #20156

(cherry picked from commit 5b42bb58f6)
2019-11-14 08:33:19 -05:00
Lukas Siatka
79bfdcb122 Explore: updates breakpoint used to collapse datasource picker
(cherry picked from commit adc84c6ac5)
2019-11-14 08:33:19 -05:00
Ivana Huckova
4d7edd3cd8 Elastic: Fix Elastic template variables interpolation when redirecting to Explore (#20314)
(cherry picked from commit 822b0b2708)
2019-11-14 08:33:19 -05:00
Torkel Ödegaard
8fa29f2497 Links: Updated links to grafana.com (#20320)
* Links: Updated links to grafana.com

* Updated snapshot

(cherry picked from commit 6959cf77ca)
2019-11-14 08:33:19 -05:00
Arve Knudsen
8cb1af2b21 Avatar: Don't log failure to add existing item to cache (#19947)
Checks if avatar was found in cache before trying to add it to cache.

Fixes #19946

(cherry picked from commit 3a8cd7b76c)
2019-11-14 08:33:19 -05:00
Arve Knudsen
33d84abf2c Build: Fix Docker builds (#20312)
(cherry picked from commit 08fcff107d)
2019-11-14 08:33:19 -05:00
Arve Knudsen
9a584bc798 Build: Build Ubuntu based Docker images also for ARM (#20267)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
(cherry picked from commit ff47238b26)
2019-11-14 08:33:19 -05:00
Torkel Ödegaard
fd491c39a3 Prometheus: Adds hint support to dashboard and fixes prometheus link in query editor (#20275)
* Prometheus: moved hints into query editor, and fixed missing refIds in responses

* Minor fix

* Removed unused type import

(cherry picked from commit b756aa0bb1)
2019-11-14 08:33:19 -05:00
Ivana Huckova
47a199a731 Explore: Fix always disabled QueryField for InfluxDB (#20299)
(cherry picked from commit 78520ac3d1)
2019-11-14 08:33:19 -05:00
Andrej Ocenas
4647c48427 Explore: Fix interpolation of error message (#20301)
(cherry picked from commit a08c2c43db)
2019-11-14 08:33:19 -05:00
Torkel Ödegaard
d6f352cdf5 PanelLinks: fixed issue with old panel links and grafana behind a subpath (#20298)
(cherry picked from commit 6f3f0bf3e0)
2019-11-14 08:33:19 -05:00
Dominik Prokop
7b517bcb10 ColorPicker: Fixes issue with ColorPicker disappearing too quickly (#20289)
(cherry picked from commit 422a94707d)
2019-11-14 08:33:19 -05:00
Torkel Ödegaard
6243776004 Templating: Made default template variable query editor field a text area with dynamic automatic height (#20288)
(cherry picked from commit dd6f5efabe)
2019-11-14 08:33:19 -05:00
Torkel Ödegaard
0cc17c384a PanelData: Support showing data and errors in angular panels (#20286)
(cherry picked from commit 767c672a2f)
2019-11-14 08:33:19 -05:00
gotjosh
1033687df6 Fix: URL Encode Groupd IDs for external team sync (#20280)
* Fix: URL Encode Group IDs for external team sync

External Group IDs can have special characters. Encode them to make them
URL-safe.

(cherry picked from commit 7e96a57c37)
2019-11-14 08:33:19 -05:00
Lukas Siatka
3abca7a820 Datasource: fixes prometheus metrics query query field definition (#20273)
* Datasource: fixes prometheus metrics query query field definition

* Fix query editor for panels

(cherry picked from commit 26c030667a)
2019-11-14 08:33:19 -05:00
Arve Knudsen
ece9015afe Start version 6.5
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
2019-11-08 11:42:32 +01:00
6352 changed files with 1201081 additions and 247804 deletions

View File

@@ -1,19 +1,19 @@
[run]
init_cmds = [
["go", "run", "build.go", "-dev", "build-cli"],
["go", "run", "build.go", "-dev", "build-server"],
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
["go", "run", "-mod=vendor", "build.go", "-dev", "build-cli"],
["go", "run", "-mod=vendor", "build.go", "-dev", "build-server"],
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
]
watch_all = true
follow_symlinks = true
watch_dirs = [
"$WORKDIR/pkg",
"$WORKDIR/public/views",
"$WORKDIR/conf",
"$WORKDIR/pkg",
"$WORKDIR/public/views",
"$WORKDIR/conf",
]
watch_exts = [".go", ".ini", ".toml", ".template.html"]
build_delay = 1500
cmds = [
["go", "run", "build.go", "-dev", "build-server"],
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
["go", "run", "-mod=vendor", "build.go", "-dev", "build-server"],
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
]

File diff suppressed because it is too large Load Diff

View File

@@ -16,9 +16,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{js,ts,tsx,scss}]
quote_type = single
[*.md]
trim_trailing_whitespace = false

View File

@@ -1,4 +0,0 @@
{
"extends": ["@grafana/eslint-config"],
"root": true
}

23
.github/CODEOWNERS vendored
View File

@@ -1,23 +0,0 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
# More details are here: https://help.github.com/articles/about-codeowners/
# The '*' pattern is global owners.
# Order is important. The last matching pattern has the most precedence.
# The folders are ordered as follows:
# In each subsection folders are ordered first by depth, then alphabetically.
# This should make it easy to add new rules without breaking existing ones.
# Documentation owner: Diana Payton
/docs/ @oddlittlebird
/contribute/ @oddlittlebird @marcusolsson
# @grafana/ui component documentation
*.mdx @marcusolsson @jessover9000
# Backend code
*.go @grafana/backend-platform
go.mod @grafana/backend-platform
go.sum @grafana/backend-platform

14
.github/ISSUE_TEMPLATE/4-question.md vendored Normal file
View File

@@ -0,0 +1,14 @@
---
name: Support request
about: 'Question or support request relating to using Grafana'
title: ''
labels: ''
assignees: ''
---
STOP -- PLEASE READ!
GitHub is not the right place for questions and support requests.
Please ask questions on our community site: [https://community.grafana.com/](https://community.grafana.com/)

View File

@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Questions & Help
url: https://community.grafana.com
about: Please ask and answer questions here.

View File

@@ -1,7 +0,0 @@
FROM alpine
RUN apk update
RUN apk add rsync git bash
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019 Sean Middleditch
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,60 +0,0 @@
publish-to-git
==============
[GitHub Action](https://github.com/features/actions) for publishing a directory
and its contents to another git repository.
This can be especially useful for publishing static website, such as with
[GitHub Pages](https://pages.github.com/), from built files in other job
steps, such as [Doxygen](http://www.doxygen.nl/) generated HTML files.
**NOTE**: GitHub currently requires the use of a Personal Access Token for
pushing to other repositories. Pushing to the current repository should work
with the always-available GitHub Token (available via
`{{ secrets.GITHUB_TOKEN }}`. If pushing to another repository, a Personal
Access Token will need to be [created](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) and assigned to the
workflow [secrets](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables).
Inputs
------
- `repository`: Destination repository (default: current repository).
- `branch`: Destination branch (required).
- `host`: Destination git host (default: `github.com`).
- `github_token`: GitHub Token (required; use `secrets.GITHUB_TOKEN`).
- `github_pat`: Personal Access Token or other https credentials.
- `source_folder`: Source folder in workspace to copy (default: workspace root).
- `target_folder`: Target folder in destination branch to copy to (default: repository root).
- `commit_author`: Override commit author (default: `{github.actor}@users.noreply.github.com`).
- `commit_message`: Set commit message (default: `[workflow] Publish from [repository]:[branch]/[folder]`).
- `dry_run`: Does not push if non-empty (default: empty).
- `working_directory`: Location to checkout repository (default: random location in `${HOME}`)
Outputs
-------
- `commit_hash`: SHA hash of the new commit.
- `working_directory`: Working directory of git clone of repository.
License
-------
MIT License. See [LICENSE](LICENSE) for details.
Usage Example
-------------
```yaml
jobs:
publish:
- uses: actions/checkout@master
- run: |
sh scripts/build-doxygen-html.sh --out static/html
- uses: seanmiddleditch/gha-publish-to-git@master
with:
branch: gh-pages
github_token: '${{ secrets.GITHUB_TOKEN }}'
github_pat: '${{ secrets.GH_PAT }}'
source_folder: static/html
if: success() && github.event == 'push'
```

View File

@@ -1,60 +0,0 @@
---
name: publish-to-git
description: 'Publish files to a git repository'
branding:
icon: 'git-commit'
color: 'blue'
inputs:
repository:
description: 'Destination repository (default: current repository)'
default: ''
branch:
description: 'Destination branch'
required: true
host:
description: 'Destination git host'
default: 'github.com'
github_token:
description: 'GitHub Token (use `secrets.GITHUB_TOKEN`)'
required: true
github_pat:
description: 'Personal Access Token or other https credentials'
default: ''
source_folder:
description: 'Source folder in workspace to copy (default: workspace root)'
defaault: ''
target_folder:
description: 'Target folder in destination branch to copy to (default: repository root)'
default: ''
commit_author:
description: 'User Name <email@address> (default: [github.actor]@users.noreply.github.com)'
default: ''
commit_message:
description: 'Commit message (default: [workflow] Publish from [repository]:[branch]/[folder])'
default: ''
dry_run:
description: 'Do not push to repository (set to non-empty string to make dry-run)'
default: ''
working_directory:
description: 'Working directory for clone (default: random location in `${HOME}`)'
default: ''
outputs:
commit_hash:
description: 'Hash of the new commit'
working_directory:
description: 'Working directory of temporary repository'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.repository }}
- ${{ inputs.branch }}
- ${{ inputs.host }}
- ${{ inputs.github_token }}
- ${{ inputs.github_pat }}
- ${{ inputs.source_folder }}
- ${{ inputs.target_folder }}
- ${{ inputs.commit_author }}
- ${{ inputs.commit_message }}
- ${{ inputs.dry_run }}
- ${{ inputs.working_directory }}

View File

@@ -1,99 +0,0 @@
#/bin/bash
# Name the Docker inputs.
#
INPUT_REPOSITORY="$1"
INPUT_BRANCH="$2"
INPUT_HOST="$3"
INPUT_GITHUB_TOKEN="$4"
INPUT_GITHUB_PAT="$5"
INPUT_SOURCE_FOLDER="$6"
INPUT_TARGET_FOLDER="$7"
INPUT_COMMIT_AUTHOR="$8"
INPUT_COMMIT_MESSAGE="$9"
INPUT_DRYRUN="${10}"
INPUT_WORKDIR="${11}"
# Check for required inputs.
#
[ -z "$INPUT_BRANCH" ] && echo >&2 "::error::'branch' is required" && exit 1
[ -z "$INPUT_GITHUB_TOKEN" -a -z "$INPUT_GITHUB_PAT" ] && echo >&2 "::error::'github_token' or 'github_pat' is required" && exit 1
# Set state from inputs or defaults.
#
REPOSITORY="${INPUT_REPOSITORY:-${GITHUB_REPOSITORY}}"
BRANCH="${INPUT_BRANCH}"
HOST="${INPUT_GIT_HOST:-github.com}"
TOKEN="${INPUT_GITHUB_PAT:-${INPUT_GITHUB_TOKEN}}"
REMOTE="${INPUT_REMOTE:-https://${TOKEN}@${HOST}/${REPOSITORY}.git}"
SOURCE_FOLDER="${INPUT_SOURCE_FOLDER:-.}"
TARGET_FOLDER="${INPUT_TARGET_FOLDER}"
REF="${GITHUB_BASE_REF:-${GITHUB_REF}}"
REF_BRANCH=$(echo "${REF}" | rev | cut -d/ -f1 | rev)
[ -z "$REF_BRANCH" ] && echo 2>&1 "No ref branch" && exit 1
COMMIT_AUTHOR="${INPUT_AUTHOR:-${GITHUB_ACTOR} <${GITHUB_ACTOR}@users.noreply.github.com>}"
COMMIT_MESSAGE="${INPUT_COMMIT_MESSAGE:-[${GITHUB_WORKFLOW}] Publish from ${GITHUB_REPOSITORY}:${REF_BRANCH}/${SOURCE_FOLDER}}"
# Calculate the real source path.
#
SOURCE_PATH="$(realpath "${SOURCE_FOLDER}")"
[ -z "${SOURCE_PATH}" ] && exit 1
echo "::debug::SOURCE_PATH=${SOURCE_PATH}"
# Let's start doing stuff.
echo "Publishing ${SOURCE_FOLDER} to ${REMOTE}:${BRANCH}/${TARGET_FOLDER}"
# Create a working directory; the workspace may be filled with other important
# files.
#
WORK_DIR="${INPUT_WORKDIR:-$(mktemp -d "${HOME}/gitrepo.XXXXXX")}"
[ -z "${WORK_DIR}" ] && echo >&2 "::error::Failed to create temporary working directory" && exit 1
cd "${WORK_DIR}"
# Initialize git repo and configure for remote access.
#
echo "Initializing repository with remote ${REMOTE}"
git init || exit 1
git config --local user.email "${GITHUB_ACTOR}@users.noreply.github.com" || exit 1
git config --local user.name "${GITHUB_ACTOR}" || exit 1
git remote add origin "${REMOTE}" || exit 1
git remote -v
# Fetch initial (current contents).
#
echo "Fetching ${REMOTE}:${BRANCH}"
git fetch --depth 1 origin "${BRANCH}" || exit 1
git checkout -b "${BRANCH}" || exit 1
git pull origin "${BRANCH}" || exit 1
# Create the target directory (if necessary) and copy files from source.
#
TARGET_PATH="${WORK_DIR}/${TARGET_FOLDER}"
echo "Populating ${TARGET_PATH}"
mkdir -p "${TARGET_PATH}" || exit 1
rsync -a --quiet --delete "${SOURCE_PATH}/" "${TARGET_PATH}" || exit 1
# Create commit with changes.
#
echo "Creating commit"
git add "${TARGET_PATH}" || exit 1
git commit -m "${COMMIT_MESSAGE}" --author "${COMMIT_AUTHOR}" || exit 1
COMMIT_HASH="$(git rev-parse HEAD)"
echo "Created commit ${COMMIT_HASH}"
# Publish output variables.
#
echo "::set-output name=commit_hash::${COMMIT_HASH}"
echo "::set-output name=working_directory::${WORK_DIR}"
# Push if not a dry-run.
#
if [ -z "${INPUT_DRYRUN}" ] ; then
echo "Pushing to ${REMOTE}:${BRANCH}"
git push origin "${BRANCH}" || exit 1
else
echo "[DRY-RUN] Not pushing to ${REMOTE}:${BRANCH}"
fi

47
.github/stale.yml vendored
View File

@@ -1,47 +0,0 @@
# Configuration for probot-stale - https://github.com/probot/stale
# General configuration
# Label to use when marking as stale
staleLabel: stale
# Pull request specific configuration
pulls:
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 14
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 30
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This pull request has been automatically marked as stale because it has not had
activity in the last 2 weeks. It will be closed in 30 days if no further activity occurs. Please
feel free to give a status update now, ping for review, or re-open when it's ready.
Thank you for your contributions!
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This pull request has been automatically closed because it has not had
activity in the last 30 days. Please feel free to give a status update now, ping for review, or re-open when it's ready.
Thank you for your contributions!
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 1
exemptLabels:
- help wanted
- type/bug
- type/feature-request
- Epic
- no stalebot
# Issue specific configuration
issues:
limitPerRun: 1
daysUntilStale: 100000
daysUntilClose: 100000
markComment: >
This issue has been automatically marked as stale because it has not had activity in the
last 100 days. It will be closed in the next 100 days if no activity occurs.
Thank you for your contributions.
closeComment: >
This issue has been automatically closed because it has not had activity in the
last month and a half. If this issue is still valid, please ping a maintainer and ask them to check this again.
Thank you for your contributions.

View File

@@ -1,30 +0,0 @@
name: publish_docs
on:
push:
branches:
- master
paths:
- 'docs/sources/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: publish-to-git
uses: ./.github/actions/gha-publish-to-git
id: publish
with:
repository: grafana/website
branch: master
host: github.com
github_pat: '${{ secrets.GH_BOT_ACCESS_TOKEN }}'
source_folder: docs/sources
target_folder: content/docs/grafana/latest
- shell: bash
run: |
test -n "${{ steps.publish.outputs.commit_hash }}"
test -n "${{ steps.publish.outputs.working_directory }}"

30
.gitignore vendored
View File

@@ -10,19 +10,13 @@ awsconfig
/public/views/index.html
/public/views/error.html
/emails/dist
/reports
/e2e/tmp
.yarnrc
.yarn/
vendor/
# Enterprise emails
/emails/templates/enterprise_*
/public/emails/enterprise_*
# Enterprise devenv
/devenv/docker/blocks/grafana-enterprise
/public_gen
/public/vendor/npm
/tmp
tools/phantomjs/phantomjs
tools/phantomjs/phantomjs.exe
@@ -67,8 +61,7 @@ profile.cov
/pkg/cmd/grafana-cli/grafana-cli
/pkg/cmd/grafana-server/grafana-server
/pkg/cmd/grafana-server/debug
/pkg/extensions/*
!/pkg/extensions/main.go
/pkg/extensions
/public/app/extensions
debug.test
/examples/*/dist
@@ -88,8 +81,6 @@ debug.test
/devenv/bulk-dashboards/*.json
/devenv/bulk_alerting_dashboards/*.json
/devenv/datasources_bulk.yaml
/devenv/bulk_alerting_dashboards/bulk_alerting_datasources.yaml
/scripts/build/release_publisher/release_publisher
*.patch
@@ -98,22 +89,11 @@ debug.test
/packages/**/dist
/packages/**/compiled
/packages/**/.rpt2_cache
/packages/**/tsdoc-metadata.json
theOutput/
# Ignore go local build dependencies
/scripts/go/bin/**
# Ignore compilation stats from `yarn stats`
compilation-stats.json
# e2e tests
/packages/grafana-e2e/cypress/screenshots
/packages/grafana-e2e/cypress/videos
/packages/grafana-e2e/cypress/logs
/e2e/server.log
/e2e/**/screenshots
!/e2e/**/screenshots/expeced/*
/e2e/**/videos/*
# report dumping the whole system env
/report.*.json

View File

@@ -1,3 +0,0 @@
module.exports = {
...require('@grafana/toolkit/src/config/prettier.plugin.config.json'),
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,12 @@
FROM node:12.16.3-alpine3.11 as js-builder
WORKDIR /usr/src/app/
COPY package.json yarn.lock ./
COPY packages packages
RUN yarn install --pure-lockfile --no-progress
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
COPY public public
COPY tools tools
COPY scripts scripts
COPY emails emails
ENV NODE_ENV production
RUN ./node_modules/.bin/grunt build
FROM golang:1.14.2-alpine3.11 as go-builder
# Golang build container
FROM golang:1.13.1-alpine
RUN apk add --no-cache gcc g++
WORKDIR $GOPATH/src/github.com/grafana/grafana
COPY go.mod go.sum ./
COPY vendor vendor
RUN go mod verify
@@ -31,8 +15,36 @@ COPY build.go package.json ./
RUN go run build.go build
# Final stage
FROM alpine:3.11
# Node build container
FROM node:10.14.2-alpine
# PhantomJS
RUN apk add --no-cache curl &&\
cd /tmp && curl -Ls https://github.com/dustinblackman/phantomized/releases/download/2.1.1/dockerized-phantomjs.tar.gz | tar xz &&\
cp -R lib lib64 / &&\
cp -R usr/lib/x86_64-linux-gnu /usr/lib &&\
cp -R usr/share /usr/share &&\
cp -R etc/fonts /etc &&\
curl -k -Ls https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 | tar -jxf - &&\
cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
WORKDIR /usr/src/app/
COPY package.json yarn.lock ./
COPY packages packages
RUN yarn install --pure-lockfile --no-progress
COPY Gruntfile.js tsconfig.json tslint.json .browserslistrc ./
COPY public public
COPY scripts scripts
COPY emails emails
ENV NODE_ENV production
RUN ./node_modules/.bin/grunt build
# Final container
FROM alpine:3.10
LABEL maintainer="Grafana team <hello@grafana.com>"
@@ -50,7 +62,7 @@ ENV PATH="/usr/share/grafana/bin:$PATH" \
WORKDIR $GF_PATHS_HOME
RUN apk add --no-cache ca-certificates bash tzdata && \
apk add --no-cache --upgrade openssl musl-utils
apk add --no-cache --upgrade --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main openssl musl-utils
COPY conf ./conf
@@ -68,9 +80,18 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
COPY --from=go-builder /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-server /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-cli ./bin/
COPY --from=js-builder /usr/src/app/public ./public
COPY --from=js-builder /usr/src/app/tools ./tools
# PhantomJS
COPY --from=1 /tmp/lib /lib
COPY --from=1 /tmp/lib64 /lib64
COPY --from=1 /tmp/usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
COPY --from=1 /tmp/usr/share /usr/share
COPY --from=1 /tmp/etc/fonts /etc/fonts
COPY --from=1 /usr/local/bin/phantomjs /usr/local/bin
COPY --from=0 /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-server /go/src/github.com/grafana/grafana/bin/linux-amd64/grafana-cli ./bin/
COPY --from=1 /usr/src/app/public ./public
COPY --from=1 /usr/src/app/tools ./tools
COPY tools/phantomjs/render.js ./tools/phantomjs/render.js
EXPOSE 3000

View File

@@ -1,26 +1,9 @@
FROM node:12.16.3-slim AS js-builder
WORKDIR /usr/src/app/
COPY package.json yarn.lock ./
COPY packages packages
RUN yarn install --pure-lockfile
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
COPY public public
COPY tools tools
COPY scripts scripts
COPY emails emails
ENV NODE_ENV production
RUN ./node_modules/.bin/grunt build
FROM golang:1.14.2 AS go-builder
FROM golang:1.13.1 AS go-builder
WORKDIR /src/grafana
COPY go.mod go.sum ./
COPY vendor vendor/
RUN go mod verify
@@ -29,7 +12,29 @@ COPY pkg pkg/
RUN go run build.go build
FROM ubuntu:20.04
FROM node:10.17 AS js-builder
# PhantomJS
RUN apt-get update && apt-get install -y curl &&\
curl -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 | tar xj &&\
cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
WORKDIR /usr/src/app/
COPY package.json yarn.lock ./
COPY packages packages
RUN yarn install --pure-lockfile
COPY Gruntfile.js tsconfig.json tslint.json .browserslistrc ./
COPY public public
COPY scripts scripts
COPY emails emails
ENV NODE_ENV production
RUN ./node_modules/.bin/grunt build
FROM ubuntu:18.10
LABEL maintainer="Grafana team <hello@grafana.com>"
EXPOSE 3000
@@ -49,8 +54,8 @@ WORKDIR $GF_PATHS_HOME
COPY conf conf
# curl should be part of the image
RUN apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates curl
# We need font libs for phantomjs, and curl should be part of the image
RUN apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates libfontconfig1 curl
RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
addgroup --system --gid $GF_GID grafana && \
@@ -66,11 +71,14 @@ RUN mkdir -p "$GF_PATHS_HOME/.aws" && \
chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
# PhantomJS
COPY --from=js-builder /usr/local/bin/phantomjs /usr/local/bin/
COPY --from=go-builder /src/grafana/bin/linux-amd64/grafana-server /src/grafana/bin/linux-amd64/grafana-cli bin/
COPY --from=js-builder /usr/src/app/public public
COPY --from=js-builder /usr/src/app/tools tools
COPY tools/phantomjs/render.js tools/phantomjs/
COPY packaging/docker/run.sh /
USER grafana

View File

@@ -35,6 +35,7 @@ module.exports = function (grunt) {
config.libc = grunt.option('libc');
}
config.phjs = grunt.option('phjsToRelease');
config.pkg.version = grunt.option('pkgVer') || config.pkg.version;
console.log('Version', config.pkg.version);

View File

@@ -4,7 +4,7 @@
-include local/Makefile
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go gosec revive golangci-lint go-vet test-go test-js test run run-frontend clean devenv devenv-down revive-alerting protobuf help
.PHONY: all deps-go deps-js deps build-go build-server build-cli build-js build build-docker-dev build-docker-full lint-go gosec revive golangci-lint go-vet test-go test-js test run clean devenv devenv-down revive-alerting help
GO = GO111MODULE=on go
GO_FILES ?= ./pkg/...
@@ -52,9 +52,6 @@ scripts/go/bin/bra: scripts/go/go.mod
run: scripts/go/bin/bra ## Build and run web server on filesystem changes.
@GO111MODULE=on scripts/go/bin/bra run
run-frontend: deps-js ## Fetch js dependencies and watch frontend for rebuild
yarn start
##@ Testing
test-go: ## Run tests for backend.
@@ -84,10 +81,7 @@ revive-alerting: scripts/go/bin/revive
@echo "lint alerting via revive"
@scripts/go/bin/revive \
-formatter stylish \
-config ./scripts/go/configs/revive-strict.toml \
./pkg/services/alerting/... \
./pkg/services/provisioning/datasources/... \
./pkg/services/provisioning/dashboards/...
./pkg/services/alerting/...
scripts/go/bin/golangci-lint: scripts/go/go.mod
@cd scripts/go; \
@@ -161,16 +155,6 @@ devenv-down: ## Stop optional services.
##@ Helpers
# We separate the protobuf generation because most development tasks on
# Grafana do not involve changing protobuf files and protoc is not a
# go-gettable dependency and so getting it installed can be inconvenient.
#
# If you are working on changes to protobuf interfaces you may either use
# this target or run the individual scripts below directly.
protobuf: ## Compile protobuf definitions
bash scripts/protobuf-check.sh
bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh
clean: ## Clean up intermediate build artifacts.
@echo "cleaning"
rm -rf node_modules

View File

@@ -15,15 +15,6 @@ Grafana allows you to query, visualize, alert on and understand your metrics no
- **Alerting:** Visually define alert rules for your most important metrics. Grafana will continuously evaluate and send notifications to systems like Slack, PagerDuty, VictorOps, OpsGenie.
- **Mixed Data Sources:** Mix different data sources in the same graph! You can specify a data source on a per-query basis. This works for even custom datasources.
### Grafana 7.0 and GrafanaCONline
- Grafana 7.0 Beta is [available for download](https://grafana.com/grafana/download).
- Read [what's is new](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v7-0/).
Want to learn more about Grafana 7 and more? Sign up for our online conference!
[![GrafanaCONline](public/img/grafanaconline.png)](https://grafana.com/about/events/grafanacon/2020/?source=grafana-readme)
## Get started
- [Get Grafana](https://grafana.com/get)

View File

@@ -20,6 +20,8 @@ Upgrading Go or Node.js requires making changes in many different files. See bel
The Grafana project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.11 or greater installed.
All dependencies are vendored in the `vendor/` directory.
_Note:_ Since most developers of Grafana still use the `GOPATH` we need to specify `GO111MODULE=on` to make `go mod` and `got get` work as intended. If you have setup Grafana outside of the `GOPATH` on your machine you can skip `GO111MODULE=on` when running the commands below.
To add or update a new dependency, use the `go get` command:
@@ -33,14 +35,16 @@ GO111MODULE=on go get example.com/some/module/pkg
GO111MODULE=on go get example.com/some/module/pkg@vX.Y.Z
```
Tidy up the `go.mod` and `go.sum` files:
Tidy up the `go.mod` and `go.sum` files and copy the new/updated dependency to the `vendor/` directory:
```bash
# The GO111MODULE variable can be omitted when the code isn't located in GOPATH.
GO111MODULE=on go mod tidy
GO111MODULE=on go mod vendor
```
You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request.
You have to commit the changes to `go.mod`, `go.sum` and the `vendor/` directory before submitting the pull request.
## Node.js dependencies

View File

@@ -1,38 +0,0 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts",
"bundledPackages": [],
"compiler": {},
"apiReport": {
"enabled": false
},
"docModel": {
"enabled": true,
"apiJsonFilePath": "<projectFolder>/../../reports/docs/<unscopedPackageName>.api.json"
},
"dtsRollup": {
"enabled": false
},
"tsdocMetadata": {},
"messages": {
"compilerMessageReporting": {
"default": {
"logLevel": "warning"
}
},
"extractorMessageReporting": {
"default": {
"logLevel": "warning"
},
"ae-internal-missing-underscore": {
"logLevel": "none",
"addToApiReportFile": false
}
},
"tsdocMessageReporting": {
"default": {
"logLevel": "warning"
}
}
}
}

View File

@@ -40,6 +40,7 @@ var (
linuxPackageVersion string = "v1"
linuxPackageIteration string = ""
race bool
phjsToRelease string
workingDir string
includeBuildId bool = true
buildId string = "0"
@@ -51,6 +52,7 @@ var (
skipRpmGen bool = false
skipDebGen bool = false
printGenVersion bool = false
modVendor bool = true
)
func main() {
@@ -67,7 +69,9 @@ func main() {
flag.StringVar(&libc, "libc", "", "LIBC")
flag.BoolVar(&cgo, "cgo-enabled", cgo, "Enable cgo")
flag.StringVar(&pkgArch, "pkg-arch", "", "PKG ARCH")
flag.StringVar(&phjsToRelease, "phjs", "", "PhantomJS binary")
flag.BoolVar(&race, "race", race, "Use race detector")
flag.BoolVar(&modVendor, "modVendor", modVendor, "Go modules use vendor folder")
flag.BoolVar(&includeBuildId, "includeBuildId", includeBuildId, "IncludeBuildId in package name")
flag.BoolVar(&enterprise, "enterprise", enterprise, "Build enterprise version of Grafana")
flag.StringVar(&buildIdRaw, "buildId", "0", "Build ID from CI system")
@@ -385,6 +389,7 @@ func createPackage(options linuxPackageOptions) {
if enterprise {
description += " Enterprise"
}
args = append(args, "--vendor", description)
if !enterprise {
args = append(args, "--license", "\"Apache 2.0\"")
@@ -454,6 +459,9 @@ func gruntBuildArg(task string) []string {
if libc != "" {
args = append(args, fmt.Sprintf("--libc=%s", libc))
}
if phjsToRelease != "" {
args = append(args, fmt.Sprintf("--phjsToRelease=%v", phjsToRelease))
}
if enterprise {
args = append(args, "--enterprise")
}
@@ -501,6 +509,9 @@ func build(binaryName, pkg string, tags []string) {
if race {
args = append(args, "-race")
}
if modVendor {
args = append(args, "-mod=vendor")
}
args = append(args, "-o", binary)
args = append(args, pkg)

View File

@@ -179,7 +179,7 @@ disable_brute_force_login_protection = false
# set to true if you host Grafana behind HTTPS. default is false.
cookie_secure = false
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict" and "none"
cookie_samesite = lax
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
@@ -230,10 +230,6 @@ snapshot_remove_expired = true
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
versions_to_keep = 20
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
min_refresh_interval = 5s
#################################### Users ###############################
[users]
# disable user signup / registration
@@ -298,9 +294,6 @@ signout_redirect_url =
# This setting is ignored if multiple OAuth providers are configured.
oauth_auto_login = false
# OAuth state max age cookie duration. Defaults to 60 seconds.
oauth_state_cookie_max_age = 60
# limit of api_key seconds to live before expiration
api_key_max_seconds_to_live = -1
@@ -325,7 +318,6 @@ scopes = user:email,read:org
auth_url = https://github.com/login/oauth/authorize
token_url = https://github.com/login/oauth/access_token
api_url = https://api.github.com/user
allowed_domains =
team_ids =
allowed_organizations =
@@ -339,7 +331,6 @@ scopes = api
auth_url = https://gitlab.com/oauth/authorize
token_url = https://gitlab.com/oauth/token
api_url = https://gitlab.com/api/v4
allowed_domains =
allowed_groups =
#################################### Google Auth #########################
@@ -373,34 +364,6 @@ client_secret = some_secret
scopes = user:email
allowed_organizations =
#################################### Azure AD OAuth #######################
[auth.azuread]
name = Azure AD
enabled = false
allow_sign_up = true
client_id = some_client_id
client_secret = some_client_secret
scopes = openid email profile
auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
allowed_domains =
allowed_groups =
#################################### Okta OAuth #######################
[auth.okta]
name = Okta
enabled = false
allow_sign_up = true
client_id = some_id
client_secret = some_secret
scopes = openid profile email groups
auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
token_url = https://<tenant-id>.okta.com/oauth2/v1/token
api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
allowed_domains =
allowed_groups =
role_attribute_path =
#################################### Generic OAuth #######################
[auth.generic_oauth]
name = OAuth
@@ -411,17 +374,58 @@ client_secret = some_secret
scopes = user:email
email_attribute_name = email:primary
email_attribute_path =
role_attribute_path =
role_attribute_path =
auth_url =
token_url =
api_url =
allowed_domains =
team_ids =
allowed_organizations =
tls_skip_verify_insecure = false
tls_client_cert =
tls_client_key =
tls_client_ca =
send_client_credentials_via_post = false
#################################### SAML Auth ###########################
[auth.saml] # Enterprise only
# Defaults to false. If true, the feature is enabled
enabled = false
# Base64-encoded public X.509 certificate. Used to sign requests to the IdP
certificate =
# Path to the public X.509 certificate. Used to sign requests to the IdP
certificate_path =
# Base64-encoded private key. Used to decrypt assertions from the IdP
private_key =
# Path to the private key. Used to decrypt assertions from the IdP
private_key_path =
# Base64-encoded IdP SAML metadata XML. Used to verify and obtain binding locations from the IdP
idp_metadata =
# Path to the SAML metadata XML. Used to verify and obtain binding locations from the IdP
idp_metadata_path =
# URL to fetch SAML IdP metadata. Used to verify and obtain binding locations from the IdP
idp_metadata_url =
# Duration, since the IdP issued a response and the SP is allowed to process it. Defaults to 90 seconds
max_issue_delay = 90s
# Duration, for how long the SP's metadata should be valid. Defaults to 48 hours
metadata_valid_duration = 48h
# Friendly name or name of the attribute within the SAML assertion to use as the user's name
assertion_attribute_name = displayName
# Friendly name or name of the attribute within the SAML assertion to use as the user's login handle
assertion_attribute_login = mail
# Friendly name or name of the attribute within the SAML assertion to use as the user's email
assertion_attribute_email = mail
#################################### Basic Auth ##########################
[auth.basic]
@@ -433,7 +437,6 @@ enabled = false
header_name = X-WEBAUTH-USER
header_property = username
auto_sign_up = true
# Deprecated, use sync_ttl instead
ldap_sync_ttl = 60
sync_ttl = 60
whitelist =
@@ -587,8 +590,6 @@ notification_timeout_seconds = 30
# Default setting for max attempts to sending alert notifications. Default value is 3
max_attempts = 3
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
min_interval_seconds = 1
#################################### Explore #############################
[explore]
@@ -613,7 +614,6 @@ basic_auth_password =
address =
prefix = prod.grafana.%(instance_name)s.
#################################### Grafana.com integration ##########################
[grafana_net]
url = https://grafana.com
@@ -644,13 +644,10 @@ disable_shared_zipkin_spans = false
#################################### External Image Storage ##############
[external_image_storage]
# Used for uploading images to public servers so they can be included in slack/email messages.
# You can choose between (s3, webdav, gcs, azure_blob, local)
provider =
[external_image_storage.s3]
endpoint =
path_style_access =
bucket_url =
bucket =
region =
@@ -683,9 +680,6 @@ container_name =
server_url =
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
callback_url =
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
concurrent_render_request_limit = 30
[panels]
# here for to support old env variables, can remove after a few months
@@ -695,68 +689,6 @@ disable_sanitize_html = false
[plugins]
enable_alpha = false
app_tls_skip_verify_insecure = false
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
allow_loading_unsigned_plugins =
#################################### Grafana Image Renderer Plugin ##########################
[plugin.grafana-image-renderer]
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
# See ICUs metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
# timezone IDs. Fallbacks to TZ environment variable if not set.
rendering_timezone =
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
rendering_language =
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
rendering_viewport_device_scale_factor =
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
# the security risk it's not recommended to ignore HTTPS errors.
rendering_ignore_https_errors =
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
# [log].filter = rendering:debug.
rendering_verbose_logging =
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
# Default is false. This can be useful to enable (true) when troubleshooting.
rendering_dumpio =
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
rendering_args =
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
# compatible with the plugin.
rendering_chrome_bin =
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
rendering_mode =
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
# and will cluster using browser instances.
# Mode 'context' will cluster using incognito pages.
rendering_clustering_mode =
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
rendering_clustering_max_concurrency =
# Limit the maxiumum viewport width, height and device scale factor that can be requested.
rendering_viewport_max_width =
rendering_viewport_max_height =
rendering_viewport_max_device_scale_factor =
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
# a port not in use.
grpc_host =
grpc_port =
[enterprise]
license_path =

View File

@@ -46,7 +46,7 @@
# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
;root_url = http://localhost:3000
# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons.
;serve_from_sub_path = false
@@ -87,11 +87,6 @@
# For "postgres" only, either "disable", "require" or "verify-full"
;ssl_mode = disable
;ca_cert_path =
;client_key_path =
;client_cert_path =
;server_cert_name =
# For "sqlite3" only, path relative to data_path setting
;path = grafana.db
@@ -180,7 +175,7 @@
# set to true if you host Grafana behind HTTPS. default is false.
;cookie_secure = false
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled"
# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict" and "none"
;cookie_samesite = lax
# set to true if you want to allow browsers to render Grafana in a <frame>, <iframe>, <embed> or <object>. default is false.
@@ -229,10 +224,6 @@
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
;versions_to_keep = 20
# Minimum dashboard refresh interval. When set, this will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
;min_refresh_interval = 5s
#################################### Users ###############################
[users]
# disable user signup / registration
@@ -244,15 +235,9 @@
# Set to true to automatically assign new users to the default organization (id 1)
;auto_assign_org = true
# Set this value to automatically add new users to the provided organization (if auto_assign_org above is set to true)
;auto_assign_org_id = 1
# Default role new users will be automatically assigned (if disabled above is set to true)
;auto_assign_org_role = Viewer
# Require email validation before sign up completes
;verify_email_enabled = false
# Background text for the user field on the login page
;login_hint = email or username
;password_hint = password
@@ -297,12 +282,6 @@
# This setting is ignored if multiple OAuth providers are configured.
;oauth_auto_login = false
# OAuth state max age cookie duration. Defaults to 60 seconds.
;oauth_state_cookie_max_age = 60
# limit of api_key seconds to live before expiration
;api_key_max_seconds_to_live = -1
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
@@ -324,23 +303,9 @@
;auth_url = https://github.com/login/oauth/authorize
;token_url = https://github.com/login/oauth/access_token
;api_url = https://api.github.com/user
;allowed_domains =
;team_ids =
;allowed_organizations =
#################################### GitLab Auth #########################
[auth.gitlab]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = api
;auth_url = https://gitlab.com/oauth/authorize
;token_url = https://gitlab.com/oauth/token
;api_url = https://gitlab.com/api/v4
;allowed_domains =
;allowed_groups =
#################################### Google Auth ##########################
[auth.google]
;enabled = false
@@ -352,44 +317,6 @@
;token_url = https://accounts.google.com/o/oauth2/token
;api_url = https://www.googleapis.com/oauth2/v1/userinfo
;allowed_domains =
;hosted_domain =
#################################### Grafana.com Auth ####################
[auth.grafana_com]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =
#################################### Azure AD OAuth #######################
[auth.azuread]
;name = Azure AD
;enabled = false
;allow_sign_up = true
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = openid email profile
;auth_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize
;token_url = https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token
;allowed_domains =
;allowed_groups =
#################################### Okta OAuth #######################
[auth.okta]
;name = Okta
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = openid profile email groups
;auth_url = https://<tenant-id>.okta.com/oauth2/v1/authorize
;token_url = https://<tenant-id>.okta.com/oauth2/v1/token
;api_url = https://<tenant-id>.okta.com/oauth2/v1/userinfo
;allowed_domains =
;allowed_groups =
;role_attribute_path =
#################################### Generic OAuth ##########################
[auth.generic_oauth]
@@ -404,7 +331,6 @@
;auth_url = https://foo.bar/login/oauth/authorize
;token_url = https://foo.bar/login/oauth/access_token
;api_url = https://foo.bar/user
;allowed_domains =
;team_ids =
;allowed_organizations =
;role_attribute_path =
@@ -413,9 +339,59 @@
;tls_client_key =
;tls_client_ca =
#################################### Basic Auth ##########################
[auth.basic]
;enabled = true
; Set to true to enable sending client_id and client_secret via POST body instead of Basic authentication HTTP header
; This might be required if the OAuth provider is not RFC6749 compliant, only supporting credentials passed via POST payload
;send_client_credentials_via_post = false
#################################### SAML Auth ###########################
[auth.saml] # Enterprise only
# Defaults to false. If true, the feature is enabled.
;enabled = false
# Base64-encoded public X.509 certificate. Used to sign requests to the IdP
;certificate =
# Path to the public X.509 certificate. Used to sign requests to the IdP
;certificate_path =
# Base64-encoded private key. Used to decrypt assertions from the IdP
;private_key =
;# Path to the private key. Used to decrypt assertions from the IdP
;private_key_path =
# Base64-encoded IdP SAML metadata XML. Used to verify and obtain binding locations from the IdP
;idp_metadata =
# Path to the SAML metadata XML. Used to verify and obtain binding locations from the IdP
;idp_metadata_path =
# URL to fetch SAML IdP metadata. Used to verify and obtain binding locations from the IdP
;idp_metadata_url =
# Duration, since the IdP issued a response and the SP is allowed to process it. Defaults to 90 seconds.
;max_issue_delay = 90s
# Duration, for how long the SP's metadata should be valid. Defaults to 48 hours.
;metadata_valid_duration = 48h
# Friendly name or name of the attribute within the SAML assertion to use as the user's name
;assertion_attribute_name = displayName
# Friendly name or name of the attribute within the SAML assertion to use as the user's login handle
;assertion_attribute_login = mail
# Friendly name or name of the attribute within the SAML assertion to use as the user's email
;assertion_attribute_email = mail
#################################### Grafana.com Auth ####################
[auth.grafana_com]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =
#################################### Auth Proxy ##########################
[auth.proxy]
@@ -429,6 +405,10 @@
# Read the auth proxy docs for details on what the setting below enables
;enable_login_token = false
#################################### Basic Auth ##########################
[auth.basic]
;enabled = true
#################################### Auth LDAP ##########################
[auth.ldap]
;enabled = false
@@ -457,7 +437,6 @@
[emails]
;welcome_email_on_sign_up = false
;templates_pattern = emails/*.html
#################################### Logging ##########################
[log]
@@ -516,41 +495,6 @@
# Syslog tag. By default, the process' argv[0] is used.
;tag =
#################################### Usage Quotas ########################
[quota]
; enabled = false
#### set quotas to -1 to make unlimited. ####
# limit number of users per Org.
; org_user = 10
# limit number of dashboards per Org.
; org_dashboard = 100
# limit number of data_sources per Org.
; org_data_source = 10
# limit number of api_keys per Org.
; org_api_key = 10
# limit number of orgs a user can create.
; user_org = 10
# Global limit of users.
; global_user = -1
# global limit of orgs.
; global_org = -1
# global limit of dashboards
; global_dashboard = -1
# global limit of api_keys
; global_api_key = -1
# global limit on number of logged in users.
; global_session = -1
#################################### Alerting ############################
[alerting]
# Disable alerting engine & UI features
@@ -578,9 +522,6 @@
# Default setting for max attempts to sending alert notifications. Default value is 3
;max_attempts = 3
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
;min_interval_seconds = 1
#################################### Explore #############################
[explore]
# Enable the Explore section
@@ -591,14 +532,11 @@
[metrics]
# Disable / Enable internal metrics
;enabled = true
# Graphite Publish interval
;interval_seconds = 10
# Disable total stats (stat_totals_*) metrics to be generated
;disable_total_stats = false
#If both are set, basic auth will be required for the metrics endpoint.
; basic_auth_username =
; basic_auth_password =
# Publish interval
;interval_seconds = 10
# Send internal metrics to Graphite
[metrics.graphite]
@@ -606,11 +544,6 @@
;address =
;prefix = prod.grafana.%(instance_name)s.
#################################### Grafana.com integration ##########################
# Url used to import dashboards directly from Grafana.com
[grafana_com]
;url = https://grafana.com
#################################### Distributed tracing ############
[tracing.jaeger]
# Enable by setting the address sending traces to jaeger (ex localhost:6831)
@@ -633,6 +566,11 @@
# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
;disable_shared_zipkin_spans = false
#################################### Grafana.com integration ##########################
# Url used to import dashboards directly from Grafana.com
[grafana_com]
;url = https://grafana.com
#################################### External image storage ##########################
[external_image_storage]
# Used for uploading images to public servers so they can be included in slack/email messages.
@@ -640,8 +578,6 @@
;provider =
[external_image_storage.s3]
;endpoint =
;path_style_access =
;bucket =
;region =
;path =
@@ -673,9 +609,10 @@
;server_url =
# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
;callback_url =
# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
# which this setting can help protect against by only allowing a certain amount of concurrent requests.
;concurrent_render_request_limit = 30
[enterprise]
# Path to a valid Grafana Enterprise license.jwt file
;license_path =
[panels]
# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
@@ -684,73 +621,3 @@
[plugins]
;enable_alpha = false
;app_tls_skip_verify_insecure = false
# Enter a comma-separated list of plugin identifiers to identify plugins that are allowed to be loaded even if they lack a valid signature.
;allow_loading_unsigned_plugins =
#################################### Grafana Image Renderer Plugin ##########################
[plugin.grafana-image-renderer]
# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
# See ICUs metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
# timezone IDs. Fallbacks to TZ environment variable if not set.
;rendering_timezone =
# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
;rendering_language =
# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
;rendering_viewport_device_scale_factor =
# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
# the security risk it's not recommended to ignore HTTPS errors.
;rendering_ignore_https_errors =
# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
# only capture and log error messages. When enabled, debug messages are captured and logged as well.
# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
# [log].filter = rendering:debug.
;rendering_verbose_logging =
# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
# Default is false. This can be useful to enable (true) when troubleshooting.
;rendering_dumpio =
# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
;rendering_args =
# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
# compatible with the plugin.
;rendering_chrome_bin =
# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
;rendering_mode =
# When rendering_mode = clustered you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
# and will cluster using browser instances.
# Mode 'context' will cluster using incognito pages.
;rendering_clustering_mode =
# When rendering_mode = clustered you can define maximum number of browser instances/incognito pages that can execute concurrently..
;rendering_clustering_max_concurrency =
# Limit the maxiumum viewport width, height and device scale factor that can be requested.
;rendering_viewport_max_width =
;rendering_viewport_max_height =
;rendering_viewport_max_device_scale_factor =
# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
# a port not in use.
;grpc_host =
;grpc_port =
[enterprise]
# Path to a valid Grafana Enterprise license.jwt file
;license_path =
[feature_toggles]
# enable features, separated by spaces
;enable =

View File

@@ -72,7 +72,7 @@ if err := s.bus.Dispatch(cmd); err != nil {
### Handle commands
Let other parts of the application dispatch commands to a service, by registering a _command handler_:
Let others parts of the application dispatch commands to a service, by registering a _command handler_:
To handle a command, register a command handler in the `Init` function.
@@ -91,7 +91,7 @@ func (s *MyService) SendStickers(cmd *models.SendStickersCommand) error {
## Queries
A command handler can optionally populate the command sent to it. This pattern is commonly used to implement _queries_.
A command handler can optionally populate the command sent it. This pattern is commonly used to implement _queries_.
### Making a query

View File

@@ -32,7 +32,7 @@ The `Init` method is used to initialize and configure the service to make it rea
Every service needs to be registered with the application for it to be included in the service graph.
To register a service, call the `registry.RegisterService` function in an `init` function within your package.
To register a service, call the `registry.RegisterService` function in a `init` function within your package.
```go
func init() {

View File

@@ -4,12 +4,13 @@ This guide helps you get started developing Grafana.
Before you begin, you might want to read [How to contribute to Grafana as a junior dev](https://medium.com/@ivanahuckova/how-to-contribute-to-grafana-as-junior-dev-c01fe3064502) by [Ivana Huckova](https://medium.com/@ivanahuckova).
## Dependencies
Make sure you have the following dependencies installed before setting up your developer environment:
- [Git](https://git-scm.com/)
- [Go](https://golang.org/dl/) (see [go.mod](../go.mod#L3) for minimum required version)
- [Go](https://golang.org/dl/)
- [Node.js (Long Term Support)](https://nodejs.org)
- [Yarn](https://yarnpkg.com)
@@ -20,7 +21,7 @@ We recommend using [Homebrew](https://brew.sh/) for installing any missing depen
```
brew install git
brew install go
brew install node@12
brew install node
npm install -g yarn
```
@@ -51,7 +52,7 @@ After the command has finished, we can start building our source code:
yarn start
```
Once `yarn start` has built the assets, it will continue to do so whenever any of the files change. This means you don't have to manually build the assets every time you change the code.
Once `yarn start` has built the assets, it will continue to do so whenever any of the files change. This means you don't have to manually build the assets whenever every time you change the code.
Next, we'll build the web server that will serve the frontend assets we just built.
@@ -71,10 +72,6 @@ Log in using the default credentials:
When you log in for the first time, Grafana asks you to change your password.
#### Building on Windows
The Grafana backend includes Sqlite3 which requires GCC to compile. So in order to compile Grafana on Windows you need to install GCC. We recommend [TDM-GCC](http://tdm-gcc.tdragon.net/download).
## Test Grafana
The test suite consists of three types of tests: _Frontend tests_, _backend tests_, and _end-to-end tests_.
@@ -97,35 +94,27 @@ go test -v ./pkg/...
### Run end-to-end tests
The end to end tests in Grafana use [Cypress](https://www.cypress.io/) to run automated scripts in a headless Chromium browser. Read more about our [e2e framework](/contribute/style-guides/e2e.md).
To run the tests:
The end-to-end tests in Grafana uses [puppeteer](https://github.com/GoogleChrome/puppeteer) to run automated scripts in a headless Chrome browser. To run the tests:
```
yarn e2e
yarn e2e-tests
```
By default, the end-to-end tests starts a Grafana instance listening on `localhost:3001`. To use a specific URL, set the `BASE_URL` environment variable:
By default, the end-to-end tests assumes Grafana is available on `localhost:3000`. To use a specific URL, set the `BASE_URL` environment variable:
```
BASE_URL=http://localhost:3333 yarn e2e
BASE_URL=http://localhost:3333 yarn e2e-tests
```
To follow the tests in the browser while they're running, use the `yarn e2e:debug`.
To follow the tests in the browser while they're running, add the `BROWSER` and `SLOWMO` environment variables:
```
yarn e2e:debug
```
If you want to pick a test first, use the `yarn e2e:dev`, to pick a test and follow the test in the browser while it runs.
```
yarn e2e:dev
BROWSER=1 SLOWMO=1 yarn e2e-tests
```
## Configure Grafana for development
The default configuration, `grafana.ini`, is located in the `conf` directory.
The default configuration, `grafana.ini`, is located in the `conf` directory.
To override the default configuration, create a `custom.ini` file in the `conf` directory. You only need to add the options you wish to override.
@@ -135,6 +124,7 @@ Enable the development mode, by adding the following line in your `custom.ini`:
app_mode = development
```
### Add data sources
By now, you should be able to build and test a change you've made to the Grafana source code. In most cases, you need to add at least one data source to verify the change.
@@ -176,7 +166,7 @@ The resulting image will be tagged as grafana/grafana:dev.
1. Build the frontend: `go run build.go build-frontend`.
1. Build the Docker image: `make build-docker-dev`.
**Note:** If you are using Docker for macOS, be sure to set the memory limit to be larger than 2 GiB. Otherwise, `grunt build` may fail. The memory limit settings are available under **Docker Desktop** -> **Preferences** -> **Advanced**.
**Note:** If you are using Docker for macOS, be sure to set the memory limit to be larger than 2 GiB. Otherwise `grunt build` may fail. The memory limit settings are available under **Docker Desktop** -> **Preferences** -> **Advanced**.
## Troubleshooting
@@ -184,7 +174,7 @@ Are you having issues with setting up your environment? Here are some tips that
### Too many open files when running `make run`
Depending on your environment, you may have to increase the maximum number of open files allowed. For the rest of this section, we will assume you are on a Unix like OS (e.g. Linux/MacOS), where you can control the maximum number of open files through the [ulimit](https://ss64.com/bash/ulimit.html) shell command.
Depending on your environment, you may have to increase the maximum number of open files allowed.
To see how many open files are allowed, run:
@@ -204,28 +194,7 @@ The number of files needed may be different on your environment. To determine th
find ./conf ./pkg ./public/views | wc -l
```
Another alternative is to limit the files being watched. The directories that are watched for changes are listed in the `.bra.toml` file in the root directory.
To retain your `ulimit` configuration, i.e. so it will be remembered for future sessions, you need to commit it to your command line shell initialization file. Which file this will be depends on the shell you are using, here are some examples:
* zsh -> ~/.zshrc
* bash -> ~/.bashrc
Commit your ulimit configuration to your shell initialization file as follows ($LIMIT being your chosen limit and $INIT_FILE being the initialization file for your shell):
```
echo ulimit -S -n $LIMIT >> $INIT_FILE
```
Your command shell should read the initialization file in question every time it gets started, and apply your `ulimit` command.
For some people, typically using the bash shell, ulimit fails with an error similar to the following:
```
ulimit: open files: cannot modify limit: Operation not permitted
```
If that happens to you, chances are you've already set a lower limit and your shell won't let you set a higher one. Try looking in your shell initalization files (~/.bashrc typically), if there's already a ulimit command that you can tweak.
Another alternative is to limit the files being watched. The directories that are watched for changes are listed in the `.bra.toml` file in the root directory.
## Next steps

View File

@@ -39,3 +39,7 @@ Tests must use the standard library, `testing`. For assertions, prefer using [te
The majority of our tests uses [GoConvey](http://goconvey.co/) but that's something we want to avoid going forward.
In the `sqlstore` package we do database operations in tests and while some might say that's not suited for unit tests. We think they are fast enough and provide a lot of value.
## General guidelines
- Avoid using import aliases, e.g. `import m "github.com/grafana/grafana/pkg/models"`.

View File

@@ -1,209 +0,0 @@
# Guidelines for code comments in grafana-* packages
This document aims to give you some recommendation on how to add code comments to the exported code in the grafana packages.
## Table of Contents
1. [Add package description](#add-package-description)
1. [Set stability of an API](#set-stability-of-an-api)
1. [Deprecate an API](#deprecate-an-api)
1. [Specify parameters](#specify-parameters)
1. [Set return values](#set-return-values)
____
## Add package description
Each package has an overview explaining the overall responsibility and usage of the package.
You can document this description with [`@packageDocumentation`](https://api-extractor.com/pages/tsdoc/tag_packagedocumentation/) tag.
Add this tag to the `<packageRoot>/src/index.ts` entry file to have one place for the package description.
## Set stability of an API
All `exported` apis from the package should have a release tag to indicate its stability.
- [`@alpha`](https://api-extractor.com/pages/tsdoc/tag_alpha/) - early draft of api and will probably change.
- [`@beta`](https://api-extractor.com/pages/tsdoc/tag_beta/) - close to being stable but might change.
- [`@public`](https://api-extractor.com/pages/tsdoc/tag_public/) - ready for useage in production.
- [`@internal`](https://api-extractor.com/pages/tsdoc/tag_internal/) - for internal use only.
### Main stability of APIs
Add a tag to mark the stability of the whole exported `class/interface/function/type` etc.
Please place the `release tag` at the bottom of the comment to make it consistent among files and easier to read.
**Do:**
```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
*
* @public
**/
export class DataFrameFactory {
create(): DataFrame { }
}
```
**Don't**
```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @public
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
**/
export class DataFrameFactory {
create(): DataFrame { }
}
```
### Partial stability of APIs
Add the main stability of the API at the top according to [Main stability of API](#main-stability-of-api).
Then override the non-stable parts of the API with the proper [release tag](#release-tags). This should also be place at the bottom of the comment block.
**Do:**
```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
*
* @public
**/
export class DataFrameFactory {
create(): DataFrame { }
/**
* @beta
**/
createMany(): DataFrames[] {}
}
```
**Don't**
```typescript
/**
* Will help to create DataFrame objects and handle
* the heavy lifting of creating a complex object.
*
* @example
* ```typescript
* const dataFrame = factory.create();
* ```
**/
export class DataFrameFactory {
/**
* @public
**/
create(): DataFrame { }
/**
* @beta
**/
createMany(): DataFrame[] {}
}
```
## Deprecate an API
If you want to mark an API as deprecated to signal that this API will be removed in the future, then add the [`@deprecated`](https://api-extractor.com/pages/tsdoc/tag_deprecated/) tag.
If applicable add a reason why the API is deprecated directly after the `@deprecated tag`.
## Specify parameters
If you want to specify the possible parameters that can be passed to an API, then add the [`@param`](https://api-extractor.com/pages/tsdoc/tag_param/) tag.
This attribute can be skipped if the type provided by `typescript` and the function comment or the function name is enough to explain what the parameters are.
**Do:**
```typescript
/**
* Will help to create a resource resovler depending
* on the current execution context.
*
* @param context - The current execution context.
* @returns FileResolver if executed on the server otherwise a HttpResolver.
* @public
**/
export const factory = (context: Context): IResolver => {
if (context.isServer) {
return new FileResolver();
}
return new HttpResolver();
}
```
**Don't**
```typescript
/**
* Will compare two numbers to see if they are equal to each others.
*
* @param x - The first number
* @param y - The second number
* @public
**/
export const isEqual = (x: number, y: number): boolean => {
return x === y;
}
```
## Set return values
If you want to specify the return value from a function you can use the [`@returns`](https://api-extractor.com/pages/tsdoc/tag_returns/) tag.
This attribute can be skipped if the type provided by `typescript` and the function comment or the function name is enough to explain what the function returns.
**Do:**
```typescript
/**
* Will help to create a resource resovler depending
* on the current execution context.
*
* @param context - The current execution context.
* @returns FileResolver if executed on the server otherwise a HttpResolver.
* @public
**/
export const factory = (context: Context): IResolver => {
if (context.isServer) {
return new FileResolver();
}
return new HttpResolver();
}
```
**Don't**
```typescript
/**
* Will compare two numbers to see if they are equal to each others.
*
* @returns true if values are equal
* @public
**/
export const isEqual = (x: number, y: number): boolean => {
return x === y;
}
```

View File

@@ -1,144 +0,0 @@
# Markdown style guide
This guide for Markdown style helps keep contributions consistent across all documentation
created for Grafana products. Refer to the guide and update its sections as needed when a
Subject Matter Expert answers a question on Markdown style, or a decision is made about
how to apply Markdown.
## Headers
In Markdown, the number of "#" symbols creates different heading levels, similar to
HTML heading levels:
**Example**
* \# is \<h1>.
* \#\# is \<h2>.
* \#\#\# is \<h3>.
Start your document with a single ``#`` for the title of the page. Add the sub-headings with two ``##``.
## Bold and emphasis
* Make text **bold** using two asterisks.
**Example:** It is ``**important**`` to use Github Flavored Markdown emoji consistently.
* Make text ``*emphasized*`` using single `` _underscores_`` or a single asterisk.
**Example:** Github Flavored Markdown emoji should _only_ appear in specific cases.
## Links and references
Create links to other website by wrapping the display text in square brackets, and
the web URL in curved brackets.
\[text to display](www.website.com)
**Example:** For more information on including emoji in Github flavored Markdown, refer to the [webfx page on emoji](https://www.webfx.com/tools/emoji-cheat-sheet/) for a list of emoji.
## Block quotes
Include Block quotes inside text using right-facing arrows:
**Example**
> Any important information
> about emoji can be separated into
> a blockquote.
## Code blocks
Code blocks written with markdown can show off syntax highlighting specific
to different languages. Use three back tics to create a code block:
```
function testNum(a) {
if (a > 0) {
return "positive";
} else {
return "NOT positive";
}
}
```
Write the name of the language after the first set of back tics, no spaces,
to show specific syntax highlighting. For example; "\```javascript" produces the following:
```javascript
function testNum(a) {
if (a > 0) {
return "positive";
} else {
return "NOT positive";
}
}
```
## Tables
Construct a table by typing the table headings, and separating them with
a "|" character. Then, add a second line of dashes ("-") separated by
another "|" character. When constructing the table cells, separate each cell data with another
"|".
**Example**
Heading one | Heading two
\------------|------------
Cell one data| Cell two data
Will publish as:
Heading one | Heading two
------------|------------
Cell one data| Cell two data
## Lists
### Numbered lists
To avoid inconsistent list numbering, use repetitive list numbering:
\1. First
\1. Second
\1. Third
The list above will always display as:
1. First
2. Second
3. Third
### Unordered lists
Build a list of points - an unordered or unnumbered list - by
using "\*" characters.
**Example**
* First
* Another item
* The last list item
## Images
Include images in a document using the following syntax:
**Example** \!\[Grafana Logo](/link/to/grafanalogo/logo.png)
This follows the format of "!", alt text wrapped in "[]" and the link URL wrapped in "()".
## Comments
You can include comments that will not appear in published markdown using the
following syntax:
\[comment]: <> (Comment text to display)
The word "comment" wrapped in "[]" followed by a ":", a space, "<>", and then
the comment itself wrapped in "()".

View File

@@ -2,10 +2,6 @@
This style guide applies to all documentation created for Grafana products.
For information about how to write technical documentation, we suggest reviewing the content of the [Google Technical Writing courses](https://developers.google.com/tech-writing).
The [Divio documentation system](https://documentation.divio.com/) site is also a good resource.
## Contributing
The *Documentation style guide* is a living document. Add to it whenever a style decision is made or a question is answered regarding style, grammar, or word choice.
@@ -33,7 +29,6 @@ The following sections provide general guidelines on topics specific to Grafana
- Use: The panel opens. Grafana opens the panel.
* Do not use an ampersand (&) as an abbreviation for "and."
- **Exceptions:** If an ampersand is used in the Grafana UI, then match the UI.
* Avoid using internal slang and jargon in technical documentation.
### File naming conventions
@@ -86,43 +81,11 @@ Always give the reader some idea of what to expect in the reference. Avoid blind
When possible, use the exact title of the page or section you are linking to as the link text.
**Example**
Refer to the [Documentation style guide](documentation-style-guide.md) for information about word usage and capitalization guidelines.
### Command line examples
* Do not assume everyone is using Linux. Make sure instructions include enough information for Windows and Mac users to successfully complete procedures.
* Do not add `$` before commands. Make it easy for users to copy and paste commands.
* **Wrong:** `$ sudo yum install grafana`
* **Right:** `sudo yum install grafana`
* Include `sudo` before commands that require `sudo` to work.
For terminal examples and Grafana configuration, use a `bash` code block:
```bash
sudo yum install grafana
```
For HTTP request/response, use an `http` code block:
```http
GET /api/dashboards/id/1/permissions HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
```
* Refer to the [Documentation style guide](documentation-style-guide.md) for information about word usage and capitalization guidelines.
### Word usage
Grafana products has some words, abbreviations, and terms particular to the Grafana discourse community.
#### checkout, check out
Two words if used as a verb, one word if used as a noun.
**Examples**
* Check out these new features!
* Proceed to checkout.
Grafana products has some words, abbreviations, and slang particular to this discourse community.
#### data source
@@ -131,6 +94,7 @@ Two words, not one
**Exceptions:**
* "datasource" used as an identifier
* "datasource" in a URL
* "Open source" should be hyphenated when used as an adjective, e.g. *open-source software*. The open form should be preferred when used as a noun, e.g. *Grafana is open source*.
* Use "data source" instead of "datasource" unless used as an identifier, in code, or as part of a URL.
* Spell out "repository" and avoid the shorter "repo."
* Use "Unix" as the preferred spelling (as opposed to "UNIX", or "unix") when referring to the family of operating systems.
@@ -142,21 +106,9 @@ Two words, not one
* Correct, but passive voice: Your list of active alarms is displayed.
* Incorrect: The list of active alarms displays.
#### drawer
Do not use. This is developer jargon that refers to a UI panel. Refer to the panel or feature by its proper name.
#### intro, introduction
"Introduction" is the preferred word. Use "intro" if there are space constraints (like on the side menu) or you are specifically trying for a less formal, more conversational tone.
#### metadata
One word, not two.
#### open source, open-source
Do not hyphenate when used as an adjective unless the lack of hyphen would cause confusion. For example: _Open source software design is the most open open-source system I can imagine._
Hyphenate when used as an adjective. For example: _open-source software._
Do not hyphenate when it is used as a noun. For example: _Open source is the best way to develop software._

View File

@@ -1,209 +0,0 @@
# End to end test framework
Grafana Labs uses a minimal home grown solution built on top of Cypress for our end to end (e2e) tests.
## Commands
- `yarn e2e` Creates an isolated grafana-server home under `<repo-root>/e2e/tmp` with provisioned data sources and dashboards. This
copies locally build binary and frontend assets from your repo root so you need to have a built backend and frontend
for this to run locally. The server starts on port 3001 so it does not conflict with your normal dev server.
- `yarn e2e:debug` Same as above but runs the tests in chrome and does not shutdown after completion.
- `yarn e2e:dev` Same as above but does not run any tests on startup. It lets you pick a test first.
If you already have a Grafana instance running, you can provide a specific URL by setting the `BASE_URL` environment variable:
```
BASE_URL=http://172.0.10.2:3333 yarn e2e
```
The above commands use some utils scripts under `<repo-root>/e2e` that can also be used for more control.
- `./e2e/start-server` This creates a fresh new grafana server working dir, setup's config and starts the server. It
will also kill any previously started server that is still running using pid file at `<repo-root>/e2e/tmp/pid`.
- `./e2e/wait-for-grafana` waits for `$HOST` and `$PORT` to be available. Per default localhost and 3001.
- `./e2e/run-suite <debug|dev|noarg>` Starts cypress in different modes.
## Test Suites
All the integration tests are located at `e2e/suite<x>/specs`. The page objects and reusable flows are in the
`packages/grafana-e2e` package.
## Basic concepts
Here is a good introduction to e2e best practices: https://martinfowler.com/bliki/PageObject.html.
- `Selector`: A unique identifier that is used from the e2e framework to retrieve an element from the Browser
- `Page`: An abstraction for an object that contains one or more `Selectors` with `visit` function to navigate to the page.
- `Component`: An abstraction for an object that contains one or more `Selectors` but without `visit` function
- `Flow`: An abstraction that contains a sequence of actions on one or more `Pages` that can be reused and shared between tests
## Basic example
Let's start with a simple example with a single selector. For simplicity, all examples are in JSX.
In our example app, we have an input that we want to type some text into during our e2e test.
```jsx harmony
<div>
<input type="text" className="gf-form-input login-form-input" />
</div>
```
We could define a selector using `JQuery` [type selectors](https://api.jquery.com/category/selectors/) with a string like `'.gf-form-input.login-form-input'` but that would be brittle as style changes occur frequently. Furthermore there is nothing that signals to future developers that this input is part of an e2e test.
At Grafana, we use `aria-label` as our preferred way of defining selectors instead of `data-*` attributes. This also aids in accessibility.
Let's add a descriptive `aria-label` to our simple example.
```jsx harmony
<div>
<input type="text" className="gf-form-input login-form-input" aria-label="Username input field" />
</div>
```
Now that we added the `aria-label` we suddenly get more information about this particular field. It's an input field that represents a username, but there it's still not really signaling that it's part of an e2e test.
The next step is to create a `Page` representation in our e2e test framework to glue the test with the real implementation using the `pageFactory` function. For that function we can supply a `url` and `selectors` like in the example below:
```typescript
export const Login = {
url: "/login", // used when called from Login.visit()
username: "Username input field", // used when called from Login.username().type('Hello World')
};
```
The next step is to add the `Login` page to the exported const `Pages` in `packages/grafana-e2e-selectors/src/selectors/pages.ts` so that it appears when we type `e2e.pages` in our IDE.
```ecmascript 6
export const Pages = {
Login,
...,
...,
...,
};
```
Now that we have a `Page` called `Login` in our `Pages` const we can use that to add a selector in our html like shown below and now this really signals to future developers that it is part of an e2e test.
```jsx harmony
<div>
<input type="text" className="gf-form-input login-form-input" aria-label={selectors.pages.Login.username} />
</div>
```
The last step in our example is to use our `Login` page as part of a test.
- The `url` property is used whenever we call the `visit` function and is equivalent to the Cypress function [cy.visit()](https://docs.cypress.io/api/commands/visit.html#Syntax).
> Best practice after calling `visit` is to always call `should` on a selector to prevent flaky tests when you try to access an element that isn't ready. For more information, refer to [Commands vs. assertions](https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions).
- Any defined selector can be accessed from the `Login` page by invoking it. This is equivalent to the result of the Cypress function [cy.get(...)](https://docs.cypress.io/api/commands/get.html#Syntax).
```ecmascript 6
describe('Login test', () => {
it('Should pass', () => {
e2e.pages.Login.visit();
// To prevent flaky tests, always do a .should on any selector that you expect to be in the DOM.
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
e2e.pages.Login.username().should('be.visible');
e2e.pages.Login.username().type('admin');
});
});
```
## Advanced example
Let's take a look at an example that uses the same `selector` for multiple items in a list for instance. In this example app we have a list of data sources that we want to click on during an e2e test.
```jsx harmony
<ul>
{dataSources.map(dataSource => (
<li className="card-item-wrapper" key={dataSource.id}>
<a className="card-item" href={`datasources/edit/${dataSource.id}`}>
<div className="card-item-name">{dataSource.name}</div>
</a>
</li>
))}
</ul>
```
````
Just as before in the basic example we'll start by creating a page abstraction using the `pageFactory` function:
```typescript
export const DataSources = {
url: '/datasources',
dataSources: (dataSourceName: string) => `Data source list item ${dataSourceName}`,
};
````
You might have noticed that instead of a simple `string` as the `selector`, we're using a `function` that takes a string parameter as an argument and returns a formatted string using the argument.
Just as before we need to add the `DataSources` page to the exported const `Pages` in `packages/grafana-e2e-selectors/src/selectors/pages.ts`.
The next step is to use the `dataSources` selector function as in our example below:
```jsx harmony
<ul>
{dataSources.map(dataSource => (
<li className="card-item-wrapper" key={dataSource.id}>
<a className="card-item" href={`datasources/edit/${dataSource.id}`}>
<div className="card-item-name" aria-label={selectors.pages.DataSources.dataSources(dataSource.name)}>
{dataSource.name}
</div>
</a>
</li>
))}
</ul>
```
When this list is rendered with the data sources with names `A`, `B`, `C` the resulting html would become:
```jsx harmony
<div class="card-item-name" aria-label="Data source list item A">
A
</div>
...
<div class="card-item-name" aria-label="Data source list item B">
B
</div>
...
<div class="card-item-name" aria-label="Data source list item C">
C
</div>
```
Now we can write our test. The one thing that differs from the `Basic example` is that we pass in which data source we want to click on as an argument to the selector function:
> Best practice after calling `visit` is to always call `should` on a selector to prevent flaky tests when you try to access an element that isn't ready. For more information, refer to [Commands vs. assertions](https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions).
```ecmascript 6
describe('List test', () => {
it('Clicking on data source named B', () => {
e2e.pages.DataSources.visit();
// To prevent flaky tests, always do a .should on any selector that you expect to be in the DOM.
// Read more here: https://docs.cypress.io/guides/core-concepts/retry-ability.html#Commands-vs-assertions
e2e.pages.DataSources.dataSources('B').should('be.visible');
e2e.pages.DataSources.dataSources('B').click();
});
});
```
## Debugging PhantomJS image rendering
### Common Error
The most common error with PhantomJs image rendering is when a PR introduces an import that has functionality that's not supported by PhantomJs. To quickly identify which new import causes this you can use a tool like `es-check`.
1. Run > `npx es-check es5 './public/build/*.js'`
2. Check the output for files that break es5 compatibility.
3. Lazy load the failing imports if possible.
### Debugging
There is no easy or comprehensive way to debug PhantomJS smoke test (image rendering) failures. However, PhantomJS exposes remote debugging interface which can give you a sense of what is going wrong in the smoke test. Before performing the steps described below make sure your local Grafana instance is running:
1. Go to `tools/phantomjs` directory
2. Execute `phantomjs` binary against `render.js` file: `./phantomjs --remote-debugger-port=9009 --remote-debugger-autorun=yes ./render.js url="http://localhost:3000"`
3. In your browser navigate to `http://localhost:9009/`
4. Select `http://localhost:3000/login` from the list. You will get access to Webkit's inspector to see the console's output from the smoke test.
The method described above is not perfect, but is helpful to evaluate smoke tests breaking due to bundle errors.

View File

@@ -7,277 +7,31 @@ Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/jav
- [Frontend Style Guide](#frontend-style-guide)
- [Table of Contents](#table-of-contents)
- [Basic rules](#basic-rules)
- [Naming conventions](#naming-conventions)
- [File and directory naming conventions](#file-and-directory-naming-conventions)
- [Code organization](#code-organization)
- [Exports](#exports)
- [Comments](#comments)
- [React](#react)
- [Props](#props)
- [Organization](#organization)
- [Props](#props)
- [State management](#state-management)
## Basic rules
- Try to keep files small and focused.
- Break large components up into sub-components.
- Use spaces for indentation.
### Naming conventions
## Organization
#### Use `PascalCase` for:
- Components and types that needs to be used by external plugins needs to go into @grafana/ui
- Components should get their own folder under features/xxx/components
- Sub components can live in that component folders, so small component do not need their own folder
- Place test next to their component file (same dir)
- Component sass should live in the same folder as component code
- State logic & domain models should live in features/xxx/state
- Containers (pages) can live in feature root features/xxx
- up for debate?
##### Typescript class names
## Props
```typescript
// bad
class dataLink {
//...
}
// good
class DataLink {
//...
}
```
##### Types and interfaces
```
// bad
interface buttonProps {
//...
}
// bad
interface button_props {
//...
}
// bad
interface IButtonProps {
//...
}
// good
interface ButtonProps {
//...
}
// bad
type requestInfo = ...
// bad
type request_info = ...
// good
type RequestInfo = ...
```
##### Enums
```
// bad
enum buttonVariant {
//...
}
// good
enum ButtonVariant {
//...
}
```
#### Use `camelCase` for:
##### Functions
```typescript
// bad
const CalculatePercentage = () => { ... }
// bad
const calculate_percentage = () => { ... }
// good
const calculatePercentage = () => { ... }
```
##### Methods
```typescript
class DateCalculator {
// bad
CalculateTimeRange () {...}
}
class DateCalculator {
// bad
calculate_timee_range () {...}
}
class DateCalculator {
// good
calculateTimeRange () {...}
}
```
##### Variables
```typescript
// bad
const QueryTargets = [];
// bad
const query_targets = [];
// good
const queryTargets = [];
```
##### React state and properties
```typescript
interface ModalState {
// bad
IsActive: boolean;
// bad
is_active: boolean;
// good
isActive: boolean;
}
```
##### Emotion class names
```typescript
const getStyles = = () => ({
// bad
ElementWraper: css`...`,
// bad
["element-wrapper"]: css`...`,
// good
elementWrapper: css`...`,
});
```
#### Use `ALL_CAPS` for constants.
```typescript
// bad
const constantValue = "This string won't change";
// bad
const constant_value = "This string won't change";
// good
const CONSTANT_VALUE = "This string won't change";
```
#### Use [BEM](http://getbem.com/) convention for SASS styles.
_SASS styles are deprecated. Please migrate to Emotion whenever you need to modify SASS styles._
### Typing
In general, you should let Typescript infer the types so that there's no need to explicitly define type for each variable.
There are some exceptions to this:
```typescript
// Typescript needs to know type of arrays or objects otherwise it would infer it as array of any
// bad
const stringArray = [];
// good
const stringArray: string[] = [];
```
Specify function return types explicitly in new code. This improves readability by being able to tell what a function returns just by looking at the signature. It also prevents errors when a function's return type is broader than expected by the author.
> Note: We don't have linting for this enabled because of lots of old code that needs to be fixed first.
```typescript
// bad
function transform(value?: string) {
if (!value) {
return undefined
}
return applyTransform(value)
};
// good
function transform(value?: string): TransformedValue | undefined {
if (!value) {
return undefined
}
return applyTransform(value)
};
```
### File and directory naming conventions
Name files according to the primary export:
- When the primary export is a class or React component, use PascalCase.
- When the primary export is a function, use camelCase.
For files exporting multiple utility functions, use the name that describes the responsibility of grouped utilities. For example, a file exporting math utilities should be named `math.ts`.
- Use `constants.ts` for files exporting constants.
- Use `actions.ts` for files exporting Redux actions.
- Use `reducers.ts` Redux reducers.
- Use `*.test.ts(x)` for test files.
### Code organization
Organize your code in a directory that encloses feature code:
- Put Redux state and domain logic code in `state` directory (i.e. `features/my-feature/state/actions.ts`).
- Put React components in `components` directory (i.e. `features/my-feature/components/ButtonPeopleDreamOf.tsx`).
- Put test files next to the test subject.
- Put containers (pages) in feature root (i.e. `features/my-feature/DashboardPage.tsx`).
- Subcomponents can live in the component folders. Small component do not need their own folder.
- Component SASS styles should live in the same folder as component code.
For code that needs to be used by external plugin:
- Put components and types in `@grafana/ui`.
- Put data models and data utilities in `@grafana/data`.
- Put runtime services interfaces in `@grafana/runtime`.
#### Exports
- Use named exports for all code you want to export from a file.
- Use declaration exports (i.e. `export const foo = ...`).
- Export only the code that is meant to be used outside the module.
### Comments
- Use [TSDoc](https://github.com/microsoft/tsdoc) comments to document your code.
- Use [react-docgen](https://github.com/reactjs/react-docgen) comments (`/** ... */`) for props documentation.
- Use inline comments for comments inside functions, classes etc.
- Please try to follow the [code comment guidelines](./code-comments.md) when adding comments.
### Linting
Linting is performed using [@grafana/eslint-config](https://github.com/grafana/eslint-config-grafana).
## React
Use the following conventions when implementing React components:
### Props
##### Name callback props and handlers with an "on" prefix.
- Name callback props and handlers with an "on" prefix.
```tsx
// bad
handleChange = () => {
};
render() {
return (
<MyComponent changed={this.handleChange} />
);
}
// good
onChange = () => {
@@ -289,36 +43,46 @@ render() {
);
}
// bad
handleChange = () => {
};
render() {
return (
<MyComponent changed={this.handleChange} />
);
}
```
##### React Component definitions
- React Component definitions
```jsx
// bad
export class YourClass extends PureComponent { ... }
// good
export class YourClass extends PureComponent<{},{}> { ... }
// bad
export class YourClass extends PureComponent { ... }
```
##### React Component constructor
- React Component constructor
```typescript
// good
constructor(props:Props) {...}
// bad
constructor(props) {...}
// good
constructor(props: Props) {...}
```
##### React Component defaultProps
- React Component defaultProps
```typescript
// bad
static defaultProps = { ... }
// good
static defaultProps: Partial<Props> = { ... }
// bad
static defaultProps = { ... }
```
## State management

View File

@@ -1,15 +1,129 @@
# Redux framework
Grafana uses [Redux Toolkit](https://redux-toolkit.js.org/) to handle Redux boilerplate code.
> Some of our Reducers are used by Angular and therefore state is to be considered as mutable for those reducers.
To reduce the amount of boilerplate code used to create a strongly typed redux solution with actions, action creators, reducers and tests we've introduced a small framework around Redux.
## Test functionality
`+` Much less boilerplate code
`-` Non Redux standard api
## New core functionality
### actionCreatorFactory
Used to create an action creator with the following signature
```typescript
{ type: string , (payload: T): {type: string; payload: T;} }
```
where the `type` string will be ensured to be unique and `T` is the type supplied to the factory.
#### Example
```typescript
export const someAction = actionCreatorFactory<string>('SOME_ACTION').create();
// later when dispatched
someAction('this rocks!');
```
```typescript
// best practices, always use an interface as type
interface SomeAction {
data: string;
}
export const someAction = actionCreatorFactory<SomeAction>('SOME_ACTION').create();
// later when dispatched
someAction({ data: 'best practices' });
```
```typescript
// declaring an action creator with a type string that has already been defined will throw
export const someAction = actionCreatorFactory<string>('SOME_ACTION').create();
export const theAction = actionCreatorFactory<string>('SOME_ACTION').create(); // will throw
```
### reducerFactory
Fluent API used to create a reducer. (same as implementing the standard switch statement in Redux)
#### Example
```typescript
interface ExampleReducerState {
data: string[];
}
const intialState: ExampleReducerState = { data: [] };
export const someAction = actionCreatorFactory<string>('SOME_ACTION').create();
export const otherAction = actionCreatorFactory<string[]>('Other_ACTION').create();
export const exampleReducer = reducerFactory<ExampleReducerState>(intialState)
// addMapper is the function that ties an action creator to a state change
.addMapper({
// action creator to filter out which mapper to use
filter: someAction,
// mapper function where the state change occurs
mapper: (state, action) => ({ ...state, data: state.data.concat(action.payload) }),
})
// a developer can just chain addMapper functions until reducer is done
.addMapper({
filter: otherAction,
mapper: (state, action) => ({ ...state, data: action.payload }),
})
.create(); // this will return the reducer
```
#### Typing limitations
There is a challenge left with the mapper function that I can not solve with TypeScript. The signature of a mapper is
```typescript
<State, Payload>(state: State, action: ActionOf<Payload>) => State;
```
If you would to return an object that is not of the state type like the following mapper
```typescript
mapper: (state, action) => ({ nonExistingProperty: ''}),
```
Then you would receive the following compile error
```shell
[ts] Property 'data' is missing in type '{ nonExistingProperty: string; }' but required in type 'ExampleReducerState'. [2741]
```
But if you return an object that is spreading state and add a non existing property type like the following mapper
```typescript
mapper: (state, action) => ({ ...state, nonExistingProperty: ''}),
```
Then you would not receive any compile error.
If you want to make sure that never happens you can just supply the State type to the mapper callback like the following mapper:
```typescript
mapper: (state, action): ExampleReducerState => ({ ...state, nonExistingProperty: 'kalle' }),
```
Then you would receive the following compile error
```shell
[ts]
Type '{ nonExistingProperty: string; data: string[]; }' is not assignable to type 'ExampleReducerState'.
Object literal may only specify known properties, and 'nonExistingProperty' does not exist in type 'ExampleReducerState'. [2322]
```
## New test functionality
### reducerTester
Fluent API that simplifies the testing of reducers
#### Usage
#### Example
```typescript
reducerTester()
@@ -17,32 +131,3 @@ reducerTester()
.whenActionIsDispatched(someAction('reducer tests'))
.thenStateShouldEqual({ ...initialState, data: 'reducer tests' });
```
#### Complex usage
Sometimes you encounter a `resulting state` that contains properties that are hard to compare, such as `Dates`, but you still want to compare that other props in state are correct.
Then you can use `thenStatePredicateShouldEqual` function on `reducerTester` that will return the `resulting state` so that you can expect upon individual properties..
```typescript
reducerTester()
.givenReducer(someReducer, initialState)
.whenActionIsDispatched(someAction('reducer tests'))
.thenStatePredicateShouldEqual(resultingState => {
expect(resultingState.data).toEqual('reducer tests');
return true;
});
```
### thunkTester
Fluent API that simplifies the testing of thunks.
#### Usage
```typescript
const dispatchedActions = await thunkTester(initialState)
.givenThunk(someThunk)
.whenThunkIsDispatched(arg1, arg2, arg3);
expect(dispatchedActions).toEqual([someAction('reducer tests')]);
```

View File

@@ -1,182 +0,0 @@
# Storybook
[Storybook](https://storybook.js.org/) is a tool which we use to manage our design system and the components which are a part of it. Storybook consists of _stories:_ each story represents a component and a case in which it is used. To show a wide variety of use cases is good both documentation wise and for troubleshooting -- it might be possible to reproduce a bug for an edge case in a story.
Storybook is:
- A good way to publish our design system with its implementations
- Used as a tool for documentation
- Used for debugging and displaying edge cases
## How to create stories
Stories for a component should be placed next to the component file. The Storybook file requires the same name as the component file. For example, a story for `SomeComponent.tsx` will have the file name `SomeComponent.story.tsx`. If a story should be internal, not visible in production, name the file `SomeComponent.story.internal.tsx`.
### Writing stories
When writing stories, we use the [CSF format](https://storybook.js.org/docs/formats/component-story-format/). For more in-depth information on writing stories, see [Storybooks documentation on writing stories](https://storybook.js.org/docs/basics/writing-stories/).
With the CSF format, the default export defines some general information about the stories in the file:
- `title`: Where the component is going to live in the hierarchy
- `decorators`: A list which can contain wrappers or provide context, such as theming
```jsx
// In MyComponent.story.tsx
import MyComponent from './MyComponent';
export default {
title: 'General/MyComponent',
component: MyComponent,
decorators: [ ... ],
}
```
When it comes to writing the actual stories, you continue in the same file with named exports. The exports are turned into the story name.
```jsx
// Will produce a story name “some story”
export const someStory = () => <MyComponent />;
```
If you want to write cover cases with different values for props, then using knobs is usually enough. You dont need to create a new story. This will be covered further down.
### Categorization
We currently have these categories:
- **Docs Overview** - Guidelines and information regarding the design system
- **Forms** - Components commonly used in forms such as different kind of inputs
- **General** - Components which can be used in a lot of different places
- **Visualizations** - Data visualizations
- **Panel** - Components belonging to panels and panel editors
## Writing MDX documentation
An MDX file is basically a markdown file with the possibility to add jsx. These files are used by Storybook to create a “docs” tab.
### Link the MDX file to a components stories
To link a components stories with an MDX file you have to do this:
```jsx
// In TabsBar.story.tsx
import { TabsBar } from "./TabsBar";
// Import the MDX file
import mdx from "./TabsBar.mdx";
export default {
title: "General/Tabs/TabsBar",
component: TabsBar,
parameters: {
docs: {
// This is the reference required for the MDX file
page: mdx,
},
},
};
```
### MDX file structure
There are some things that the MDX file should contain:
- When and why the component should be used
- Best practices - dos and donts for the component
- Usage examples with code. It is possible to use the `Preview` element to show live examples in MDX
- Props table. This can be generated by doing the following:
```jsx
// In MyComponent.mdx
import { Props } from "@storybook/addon-docs/blocks";
import { MyComponent } from "./MyComponent";
<Props of={MyComponent} />;
```
### MDX file without a relationship to a component
An MDX file can exist by itself without any connection to a story. This can be good for writing things such as a general guidelines page. Two things are required for this to work:
- The file needs to be named `*.story.mdx`
- A `Meta` tag must exist that says where in the hierarchy the component lives. It can look like this:
```jsx
<Meta title="Docs Overview/Color Palettes"/>
# Guidelines for using colors
...
```
You can add parameters to the Meta tag. This example shows how to hide the tools:
```jsx
<Meta title="Docs Overview/Color Palettes" parameters={{ options: { isToolshown: false }}}/>
# Guidelines for using colors
...
```
## Documenting component properties
A quick way to get an overview of what a component does is by looking at its properties. That's why it is important that we document these in a good way.
### Comments
When writing the props interface for a component, it is possible to add a comment to that specific property, which will end up in the Props table in the MDX file. The comments are generated by [react-docgen](https://github.com/reactjs/react-docgen) and are formatted by writing `/** */`.
```jsx
interface MyProps {
/** Sets the initial values, which are overridden when the query returns a value*/
defaultValues: Array<T>;
}
```
### Knobs
Knobs is an [addon to Storybook](https://github.com/storybookjs/storybook/tree/master/addons/knobs) which can be used to easily switch values in the UI. A good use case for it is to try different props for the component. Using knobs is easy. Grafana is set up so knobs can be used straight out of the box. Here is an example of how you might use it.
```jsx
// In MyComponent.story.tsx
import { number, text } from "@storybook/addon-knobs";
export const basicStory = () => (
<MyComponent
max={number("Max value", 10)}
min={number("Min value", -10)}
title={text("Title", "Look at the value!")}
/>
);
```
The general convention is that the first parameter of the knob is its name and the second is the default value. There are some more types:
| Knob | Description |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `text` | Any text field |
| `number` | Any number input. Also [available as range](https://github.com/storybookjs/storybook/tree/master/addons/knobs#number-bound-by-range) |
| `boolean` | A switch between true/false |
| `color` | Color picker |
| `object` | JSON input or array. Good to use if the property requires more complex data structures. |
| `array` | Array of strings separated by a comma |
| `select` | Select a value from an options object. Good for trying different test cases. |
| `options` | Configurable UI for selecting a range of options |
| `files` | File selector |
| `date` | Select date as stringified Unix timestamp |
| `button` | Has a handler which is called when clicked |
## Best practices
- When creating a new component or writing documentation for an existing one, always cover the basic use case it was intended for with a code example.
- Use stories and knobs to create edge cases. If you are trying to solve a bug, try to reproduce it with a story.
- Do not create stories in the MDX, always create them in the `*.story.tsx` file.

View File

@@ -1,55 +1,48 @@
# Styling Grafana
## Emotion
[Emotion](https://emotion.sh/docs/introduction) is our default-to-be approach to styling React components. It provides a way for styles to be a consequence of properties and state of a component.
## Usage
### Usage
### Basic styling
#### Basic styling
For styling components, use [Emotion's `css` function](https://emotion.sh/docs/emotion#css).
For styling components use Emotion's `css` function
```tsx
import React from 'react';
import { css } from 'emotion';
import { css } from 'emotion';
const ComponentA = () => (
<div
className={css`
background: red;
`}
>
As red as you can get
</div>
);
const ComponentA = () => {
return (
<div className={css`background: red;`}>
As red as you can ge
</div>
);
}
```
### Styling complex components
#### Styling complex components
In more complex cases, especially when you need to style multiple DOM elements in one component, or when using styles that depend on properties and/or state, you should create a helper function that returns an object of styles. This function should also be wrapped in the `stylesFactory` helper function, which will provide basic memoization.
In more complex cases, especially when you need to style multiple DOM elements in one component or when your styles that depend on properties and/or state, you should create a helper function that returns an object with desired stylesheet. This function should also be wrapped in `stylesFactory` helper function that will provide basic memoization.
Let's say you need to style a component that has a different background depending on the theme:
Let's say you need to style a component that has different background depending on the theme:
```tsx
import React from 'react';
import { css } from 'emotion';
import { GrafanaTheme } from '@grafana/data';
import { selectThemeVariant, stylesFactory, useTheme } from '@grafana/ui';
import { css, cx } from 'emotion';
import { GrafanaTheme, useTheme, selectThemeVariant, stylesFactory } from '@grafana/ui';
const getStyles = stylesFactory((theme: GrafanaTheme) => {
const backgroundColor = selectThemeVariant(
{ light: theme.colors.red, dark: theme.colors.blue },
theme.type
);
const backgroundColor = selectThemeVariant({ light: theme.colors.red, dark: theme.colors.blue }, theme.type);
return {
wrapper: css`
background: ${backgroundColor};
`,
icon: css`
font-size: ${theme.typography.size.sm};
`,
icon: css`font-size:${theme.typography.size.sm}`;
};
});
}
const ComponentA = () => {
const theme = useTheme();
@@ -61,18 +54,18 @@ const ComponentA = () => {
<i className={styles.icon} />
</div>
);
};
});
```
For more information about themes at Grafana please see the [themes guide](./themes.md).
For more information about themes at Grafana please see [themes guide](./themes.md)
### Composing class names
#### Composing class names
For class composition, use [Emotion's `cx` function](https://emotion.sh/docs/emotion#cx).
For class composition use Emotion's `cx` function
```tsx
import React from 'react';
import { css, cx } from 'emotion';
import { css, cx } from 'emotion';
interface Props {
className?: string;
@@ -81,11 +74,13 @@ interface Props {
const ComponentA: React.FC<Props> = ({ className }) => {
const finalClassName = cx(
className,
css`
background: red;
`
);
css`background: red`,
)
return <div className={finalClassName}>As red as you can ge</div>;
};
return (
<div className={finalClassName}>
As red as you can ge
</div>
);
}
```

View File

@@ -2,22 +2,11 @@
## Overview
**Themes are implemented in Typescript.** That's because our goal is to share variables between Grafana TypeScript and [Sass](https://sass-lang.com/) code. Theme definitions are located in the following files:
- [packages/grafana-ui/src/themes/dark.ts](../../packages/grafana-ui/src/themes/dark.ts)
- [packages/grafana-ui/src/themes/default.ts](../../packages/grafana-ui/src/themes/default.ts)
- [packages/grafana-ui/src/themes/light.ts](../../packages/grafana-ui/src/themes/light.ts)
The `default.ts` file holds common variables like typography and spacing definitions, while `[light|dark].ts` primarily specify colors used in themes.
**Themes are implemented in Typescript.** That's because our goal is to share variables between Grafana Typescript code and SASS files. Theme definitions are located in `packages/grafana-ui/src/themes/[default|dark|light].ts` files. `default.ts` file holds common variables like typography and spacing definitions, while `[light|dark].ts` primarily specify colors used in themes.
## Usage
This section provides usage guidelines.
### Using themes in React components
Here's how to use Grafana themes in React components.
#### Using `ThemeContext` directly
```tsx
@@ -37,11 +26,12 @@ const Foo: React.FunctionComponent<FooProps> = () => {
// Your component has access to the theme variables now
}
```
#### Using `withTheme` higher-order component (HOC)
With this method your component will be automatically wrapped in `ThemeContext.Consumer` and provided with current theme via `theme` prop. Components used with `withTheme` must implement the `Themeable` interface.
With this method your component will be automatically wrapped in `ThemeContext.Consumer` and provided with current theme via `theme` prop. Component used with `withTheme` must implement `Themeable` interface.
```ts
import { ThemeContext, Themeable } from '@grafana/ui';
@@ -53,7 +43,7 @@ const Foo: React.FunctionComponent<FooProps> = () => ...
export default withTheme(Foo);
```
### Test components that use `ThemeContext`
### Test components that use ThemeContext
When implementing snapshot tests for components that use the `withTheme` HOC, the snapshot will contain the entire theme object. Any change to the theme renders the snapshot outdated.
@@ -83,11 +73,9 @@ describe('MyComponent', () => {
});
```
### Using themes in [Storybook](https://storybook.js.org/)
### Using themes in Storybook
All stories are wrapped with `ThemeContext.Provider` using a global decorator. To render a `Themeable` component that isn't wrapped by a `withTheme` HOC, either create a new component in your story, or use the `renderComponentWithTheme` helper.
#### Create a new component:
All stories are wrapped with `ThemeContext.Provider` using global decorator. To render `Themeable` component that's not wrapped by `withTheme` HOC you either create a new component in your story:
```tsx
// Foo.story.tsx
@@ -98,7 +86,7 @@ FooStories.add('Story' () => {
});
```
#### Use `renderComponentWithTheme` helper:
or use `renderComponentWithTheme` helper:
```tsx
// Bar.story.tsx
@@ -110,42 +98,29 @@ BarStories.add('Story' () => {
### Using themes in Angular code
There should be very few cases where a theme would be used in an Angular context. For this purpose, there is a function available that retrieves the current theme:
There should be very few cases where theme would be used in Angular context. For this purpose there is a function available that retrieves current theme: `import { getCurrentTheme } from app/core/utils/ConfigProvider`. Angular components should be migrated to React, or if that's not possible at the moment, styled using SASS.
```ts
import { getCurrentTheme } from app/core/utils/ConfigProvider
```
Angular components should be migrated to React, or if that's not possible at the moment, styled using Sass.
## FAQ
This section provides insight into frequently-asked questions.
### How can I modify Sass variable files?
### How can I modify SASS variable files?
> For the following to apply you need to run `yarn dev` task.
`[_variables|_variables.dark|_variables.light].generated.scss` files are the ones that are referenced in the main Sass files for Sass variables to be available. **These files are automatically generated and should never be modified by hand!**
`[_variables|_variables.dark|_variables.light].generated.scss` files are the ones that are referenced in the main SASS files for SASS variables to be available. **These files are automatically generated and should never be modified by hand!**.
#### If you need to modify a *Sass variable value* you need to modify the corresponding Typescript file that is the source of the variables:
#### If you need to modify *SASS variable value* you need to modify corresponding Typescript file that is a source of the variables:
- `_variables.generated.scss` - modify `grafana-ui/src/themes/default.ts`
- `_variables.light.generated.scss` - modify `grafana-ui/src/themes/light.ts`
- `_variables.dark.generated.scss` - modify `grafana-ui/src/themes/dark.ts`
#### If you need to *add new variable* to Sass variables you need to modify corresponding template file:
#### If you need to *add new variable* to SASS variables you need to modify corresponding template file:
- `_variables.generated.scss` - modify `grafana-ui/src/themes/_variables.scss.tmpl.ts`
- `_variables.light.generated.scss` - modify `grafana-ui/src/themes/_variables.light.scss.tmpl.ts`
- `_variables.dark.generated.scss` - modify `grafana-ui/src/themes/_variables.dark.scss.tmpl.ts`
## Limitations
This section describes limitations with Grafana's theming system.
### You must ensure `ThemeContext` provider is available in a React tree
By default all react2angular directives have `ThemeContext.Provider` ensured. But, there are cases where we create another React tree via `ReactDOM.render`. This happens in the case of graph legend rendering and the `ReactContainer` directive. In such cases theme consumption will fail. To make sure theme context is available in such cases, you need to wrap your rendered component with ThemeContext.Provider using the `provideTheme` function:
### You must ensure ThemeContext provider is available in a React tree
By default all react2angular directives have `ThemeContext.Provider` ensured. But, there are cases where we create another React tree via `ReactDOM.render`. This happens in case of graph legend rendering and `ReactContainer` directive. In such cases theme consumption will fail. To make sure theme context is available in such cases, you need to wrap your rendered component with ThemeContext.Provider using `provideTheme` function:
```ts
// graph.ts

View File

@@ -1,57 +0,0 @@
# Templates
Templates are both a starting point and an instruction manual for writing something new. They are intended to make life easier by providing a jumping-off point, something besides a blank page to start from. They are not intended to be a limitation. If the template does not work perfectly for your use case, you can adjust or change it. We will work it out in code review.
## Create a template
Feel free to add templates to the `templates` folder. Try to make them as generic as possible and include clear instructions for when and how to use the template. Assume that the template user is a brand new contributor and write accordingly.
## Use a template
1. Read the template. Make sure you understand what it is for and how it is intended to be used.
1. Copy and rename the template. Move it to where you actually need it.
You might also want to copy the content of the template and paste it into a different file. This is acceptable use.
1. Replace the template content with your own. Delete whatever is unnecessary.
## Documentation templates
In an ideal world, each topic will correspond to an information *type* ([task](doc-task-template.md), [reference](doc-reference-template.md), [concept](doc-concept-template.md)) and contain only that type of information.
However, this is not always practical. For example, you have a series of short topics, you can group them into one topic.
Try to *chunk* your content. This means you should organize the document so that the same kinds of content are grouped together.
### Chunking example
If I was writing content for a site called *Doggie handbook*, I might organize it like this.
**Concept**
* What a dog is
* Brief history of dogs
* Why you might want a dog
* Tasks dogs can be trained to do
**Tasks**
* Feed the dog
* Groom the dog
* Train the dog
**Reference**
* List of dog equipment you will need
* Table of breeds that includes breed name, size range, short or long hair, and type of dog
### Audience
Write for an audience that is computer literate and has general technical knowledge, but is not necessarily familiar with Grafana or the finer points of observability.
Pretend you are explaining your topic to a brand new Grafana user or developer.
### Self-contained
Thanks to search engines, every page in the documentation might be a reader's entry point. This means that each page needs to be self-contained and make sense on its own. The reader should not need to read other topics in order to perform the task or understand the concept.
However, try to be helpful and link to related information. Using the *Doggie handbook* example, the concept topic that explains what dogs can be trained to do might link to the Train the dog task.
## Code templates
This is a placeholder for future templates.

View File

@@ -1,42 +0,0 @@
DELETE THIS LINE: If draft = false, then the document will not be built in the doc site. If the date is earlier than the build date, than the document will not show in the build site. Use these settings to control whether future content is shown in the doc site.
+++
draft = "false"
date = "yyyy-mm-dd"
title = "Title in sentence case"
description = "Description in title case"
keywords = ["grafana", "enter", "keywords", "here"]
type = "docs"
[menu.docs]
name = "Name of topic"
identifier = "identifier"
parent = "menu parent"
weight = 100
+++
# Concept
The title of the concept topic will generally be a noun or a gerund. Examples include Templates, Templating, Dashboards, and panels.
Concepts are topic types for any information that doesn't involve task lists or reference information. Ideally you use concept elements to explain concepts, ideas, overviews, workflows, and the like. In the intro section, this first paragraph or two, you should explain to the user what to expect in this topic or section.
[Permissions overview](https://grafana.com/docs/grafana/latest/permissions/overview/) is an example of a concept topic.
## Idea
Concept topics or sections explain *what* and *why*. They do not explain *how*. If you are a new user, you might look for concept information to learn about what Grafana is, why it might be useful to you, and what the general workflow is.
## Workflow
Continuing the example in the previous section, here is a sample Grafana workflow.
1. Install Grafana. <link to task for installing Grafana>
2. Set up data sources. <link to data sources concept topic, which links to data source task topics>
3. Create panels. <link to panel concept topic, which links to tasks>
4. Create dashboards. <link to panel concept topic, which links to tasks>
5. Enter queries. <link to query editor concept topic>
6. Add users. <link to user management concept topic, which links to tasks>
7. Create playlists. <link to Playlist topic that contains concept information and tasks>
## Next steps
Concept tasks often link to related information, including *tasks* related to the concept and *reference* topics related to the concept.

View File

@@ -1,75 +0,0 @@
DELETE THIS LINE: If draft = false, then the document will not be built in the doc site. If the date is earlier than the build date, than the document will not show in the build site. Use these settings to control whether future content is shown in the doc site.
+++
draft = "false"
date = "yyyy-mm-dd"
title = "Title in sentence case"
description = "Description in title case"
keywords = ["grafana", "enter", "keywords", "here"]
type = "docs"
[menu.docs]
name = "Name of topic"
identifier = "identifier"
parent = "menu parent"
weight = 100
+++
# Reference
The *reference* topic type is for storing reference information, such as extensive tables, lists, or other information that is used as support for a task. Reference topics are also designed for API information.
Often reference topics are linked from *task* topics, because they contain information the user needs in order to perform a task.
[Grafana CLI](https://grafana.com/docs/grafana/latest/administration/cli/) is one example of a reference topic.
## Lists
Lists of commands or parameters are often organized in reference topics. The information you need to present will dictate the format.
* They might
* be in
* unordered lists.
[Configuration](https://grafana.com/docs/grafana/latest/installation/configuration/) is an example of lists.
## Tables
If you have a large list of things to store in a table, then you are probably dealing with reference information. Hugo accepts either tables in Markdown or in HTML format, so use whichever is easier for you.
The [Glossary](https://grafana.com/docs/grafana/latest/guides/glossary/) provides an example of reference data in a table.
### Empty markdown table
While you might not need a heading for each table, headings are a good way to chunk information if you have several tables. They also make the content easy to skim. Use headings or intro paragraphs like this one to explain to the reader what the information in the table is used for.
| | | | | | |
|:---|:---|:--:|:--:|---:|---:|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
### Empty HTML table
And here is intro text, similar to the paragraph in the previous section. Do not add local styling to the table. The website CSS will take care of that for you.
<table>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
## API documentation
API documentation is always a reference topic rather than a task topic, but it has its own rules.

View File

@@ -1,57 +0,0 @@
+++
draft = "false"
date = "yyyy-mm-dd"
title = "Title in sentence case"
description = "Description in title case"
keywords = ["grafana", "enter", "keywords", "here"]
type = "docs"
[menu.docs]
name = "Name of topic"
identifier = "identifier"
parent = "menu parent"
weight = 100
+++
# Task
A *task* topic is intended for a procedure that describes how to accomplish a task. It lists a series of steps that users follow to produce an intended outcome. It tells the reader *how* to do something. [Install Grafana plugins](https://grafana.com/docs/grafana/latest/plugins/installation/) and [Playlist](https://grafana.com/docs/grafana/latest/reference/playlist/) are examples of task topics. Playlist includes a small amount of concept information in the introduction, which is appropriate.
Always include an introduction of a short paragraph or two to explain what the task is for, perhaps give the reader an idea of what the outcome will be.
In most cases, each topic should only contain one task. If you have several very short, related tasks, then you might combine them into one topic.
In the case of a long task, then you probably won't need any headings except for the h1 at the top of the page.
1. Start with step one.
1. Use second-person imperative tense.
1. Basically, "You, do this" with every sentence.
1. Do not use the third-person "user" for steps you want the reader ("you") to perform.
1. Write steps that contain one action, possibly two related actions, such as copy and paste a thing or save and quit the program.
If a sentence is not telling the reader to do something, then it is not a step. You can use nested images or paragraphs like this one to add information if necessary.
In many cases, you should tell the reader what the outcome should be so that they know when they are done.
## One-step task
Some tasks are so short, they only contain one step.
Write one-step tasks as simple sentences, not as unordered lists or numbered lists.
## Short task
Short tasks can be grouped. How short constitutes "short" is a judgment call based on number of steps and how long individual steps are.
1. Use your judgment.
2. Ask your coworkers or someone on the Comm team for advice if you aren't sure.
## Next steps
If the task you are writing leads naturally to one or more other tasks, then include links after the task to help the reader figure out where to go next.
Thanks to internet search engines, every page in the documentation could be page one. Pretend you are explaining your task to a new Grafana user who just walked in off the street.
## Testing
It is a good practice to have someone else test the task you have written. If they can successfully complete the task using *only* what the steps you have written, not guessing or using their inherent knowledge, then your task has passed the test. However, it is very common to find you have skipped steps, because *you* are very familiar with Grafana and the topic you are explaining.
New users or people from other teams are very helpful for these tests.

View File

@@ -36,14 +36,5 @@ make devenv sources=influxdb,prometheus2,elastic5
Some of the blocks support dynamic change of the image version used in the Docker file. The signature looks like this:
```bash
make devenv sources=postgres,openldap,grafana postgres_version=9.2 grafana_version=6.7.0-beta1
make devenv sources=postgres,openldap postgres_version=9.2
```
### Notes per block
#### Grafana
The grafana block is pre-configured with the dev-datasources and dashboards.
#### Jaeger
Jaeger block runs both Jaeger and Loki container. Loki container sends traces to Jaeger and also logs its own logs into itself so it is possible to setup derived field for traceID from Loki to Jaeger. You need to install a docker plugin for the self logging to work, without it the container won't start. See https://github.com/grafana/loki/tree/master/cmd/docker-driver#plugin-installation for installation instructions.

View File

@@ -0,0 +1,168 @@
{
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [
{
"alert": {
"conditions": [
{
"evaluator": {
"params": [
65
],
"type": "gt"
},
"operator": {
"type": "and"
},
"query": {
"params": [
"A",
"5m",
"now"
]
},
"reducer": {
"params": [],
"type": "avg"
},
"type": "query"
}
],
"executionErrorState": "alerting",
"frequency": "10s",
"handler": 1,
"name": "bulk alerting",
"noDataState": "no_data",
"notifications": []
},
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-prometheus",
"fill": 1,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"$$hashKey": "object:117",
"expr": "go_goroutines",
"format": "time_series",
"intervalFactor": 1,
"refId": "A"
}
],
"thresholds": [
{
"colorMode": "critical",
"fill": true,
"line": true,
"op": "gt",
"value": 50
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"schemaVersion": 16,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
"title": "New dashboard",
"uid": null,
"version": 0
}

View File

@@ -1,170 +0,0 @@
{
alertingDashboard(dashboardCounter, datasourceCounter):: {
title: "alerting-title-" + dashboardCounter,
editable: true,
gnetId: null,
graphTooltip: 0,
id: null,
links: [],
panels: [
{
alert: {
conditions: [
{
evaluator: {
params: [
65
],
type: "gt"
},
operator: {
type: "and"
},
query: {
params: [
"A",
"5m",
"now"
]
},
reducer: {
params: [],
type: "avg"
},
type: "query"
}
],
executionErrorState: "alerting",
frequency: "24h",
handler: 1,
name: "bulk alerting " + dashboardCounter,
noDataState: "no_data",
notifications: []
},
aliasColors: {},
bars: false,
dashLength: 10,
dashes: false,
datasource: "gfdev-bulkalerting-" + datasourceCounter,
fill: 1,
gridPos: {
h: 9,
w: 12,
x: 0,
y: 0
},
id: 1,
legend: {
avg: false,
current: false,
max: false,
min: false,
show: true,
total: false,
values: false
},
lines: true,
linewidth: 1,
nullPointMode: "null",
percentage: false,
pointradius: 5,
points: false,
renderer: "flot",
seriesOverrides: [],
spaceLength: 10,
stack: false,
steppedLine: false,
targets: [
{
expr: "go_goroutines",
format: "time_series",
intervalFactor: 1,
refId: "A"
}
],
thresholds: [
{
colorMode: "critical",
fill: true,
line: true,
op: "gt",
value: 50
}
],
timeFrom: null,
timeShift: null,
title: "Panel Title",
tooltip: {
shared: true,
sort: 0,
value_type: "individual"
},
type: "graph",
xaxis: {
buckets: null,
mode: "time",
name: null,
show: true,
values: []
},
yaxes: [
{
format: "short",
label: null,
logBase: 1,
max: null,
min: null,
show: true
},
{
format: "short",
label: null,
logBase: 1,
max: null,
min: null,
show: true
}
]
}
],
schemaVersion: 16,
style: "dark",
tags: [],
templating: {
list: []
},
time: {
from: "now-6h",
to: "now"
},
timepicker: {
refresh_intervals: [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
time_options: [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
timezone: "",
uid: null,
version: 0
},
}

View File

@@ -1,14 +0,0 @@
local arr = std.range(1, 100);
{
"apiVersion": 1,
"datasources": [
{
"name": 'gfdev-bulkalerting-' + counter,
"type": "prometheus",
"access": "proxy",
"url": "http://localhost:9090"
}
for counter in arr
],
}

View File

@@ -20,8 +20,8 @@ datasources:
url: http://localhost:3011
- name: gdev-testdata
isDefault: true
type: testdata
isDefault: true
- name: gdev-influxdb
type: influxdb
@@ -227,48 +227,10 @@ datasources:
authType: credentials
defaultRegion: eu-west-2
# Keep to test old /api/prom API
- name: gdev-loki-0.3
type: loki
access: proxy
url: http://localhost:3103
editable: false
# First version with new v1 API (remove once v1 is out)
- name: gdev-loki-0.4
type: loki
access: proxy
url: http://localhost:3104
editable: false
- name: gdev-loki
type: loki
access: proxy
url: http://localhost:3100
editable: false
jsonData:
derivedFields:
- name: "traceID"
matcherRegex: "traceID=(\\w+)"
url: "$${__value.raw}"
datasourceUid: gdev-jaeger
- name: "traceID"
matcherRegex: "traceID=(\\w+)"
url: "$${__value.raw}"
datasourceUid: gdev-zipkin
- name: gdev-jaeger
type: jaeger
uid: gdev-jaeger
access: proxy
url: http://localhost:16686
editable: false
- name: gdev-zipkin
type: zipkin
uid: gdev-zipkin
access: proxy
url: http://localhost:9411
editable: false

View File

@@ -1,248 +0,0 @@
apiVersion: 1
datasources:
- name: gdev-graphite
type: graphite
access: proxy
url: http://graphite11:80
jsonData:
graphiteVersion: "1.1"
- name: gdev-prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
- name: gdev-slow-prometheus
type: prometheus
access: proxy
url: http://prometheus:3011
- name: gdev-testdata
isDefault: true
type: testdata
- name: gdev-influxdb
type: influxdb
access: proxy
database: site
user: grafana
url: http://influxdb:8086
jsonData:
timeInterval: "15s"
secureJsonData:
password: grafana
- name: gdev-influxdb-telegraf
type: influxdb
access: proxy
database: telegraf
user: grafana
url: http://telegraf:8086
jsonData:
timeInterval: "10s"
secureJsonData:
password: grafana
- name: gdev-opentsdb
type: opentsdb
access: proxy
url: http://opentsdb:4242
jsonData:
tsdbResolution: 1
tsdbVersion: 1
- name: gdev-elasticsearch-v2-metrics
type: elasticsearch
access: proxy
database: "[metrics-]YYYY.MM.DD"
url: http://elasticsearch:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 2
- name: gdev-elasticsearch-v2-logs
type: elasticsearch
access: proxy
database: "[logs-]YYYY.MM.DD"
url: http://elasticsearch:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 2
- name: gdev-elasticsearch-v5-metrics
type: elasticsearch
access: proxy
database: "[metrics-]YYYY.MM.DD"
url: http://elasticsearch5:10200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 5
- name: gdev-elasticsearch-v5-logs
type: elasticsearch
access: proxy
database: "[logs-]YYYY.MM.DD"
url: http://elasticsearch5:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 5
- name: gdev-elasticsearch-v6-metrics
type: elasticsearch
access: proxy
database: "[metrics-]YYYY.MM.DD"
url: http://elasticsearch6:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 60
- name: gdev-elasticsearch-v6-logs
type: elasticsearch
access: proxy
database: "[logs-]YYYY.MM.DD"
url: http://elasticsearch6:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 60
- name: gdev-elasticsearch-v6-filebeat
type: elasticsearch
access: proxy
database: "[filebeat-]YYYY.MM.DD"
url: http://elasticsearch6:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 60
- name: gdev-elasticsearch-v7-metrics
type: elasticsearch
access: proxy
database: "[metrics-]YYYY.MM.DD"
url: http://elasticsearch7:9200
jsonData:
timeInterval: 10s
interval: Daily
timeField: "@timestamp"
esVersion: 70
- name: gdev-elasticsearch-v7-logs
type: elasticsearch
access: proxy
database: "[logs-]YYYY.MM.DD"
url: http://elasticsearch7:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 70
- name: gdev-elasticsearch-v7-filebeat
type: elasticsearch
access: proxy
database: "[filebeat-]YYYY.MM.DD"
url: http://elasticsearch7:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 70
timeInterval: "10s"
logMessageField: message
logLevelField: fields.level
- name: gdev-elasticsearch-v7-metricbeat
type: elasticsearch
access: proxy
database: "[metricbeat-]YYYY.MM.DD"
url: http://elasticsearch7:9200
jsonData:
interval: Daily
timeField: "@timestamp"
esVersion: 70
timeInterval: "10s"
- name: gdev-mysql
type: mysql
url: mysql:3306
database: grafana
user: grafana
secureJsonData:
password: password
- name: gdev-mysql-ds-tests
type: mysql
url: mysqltests:3306
database: grafana_ds_tests
user: grafana
secureJsonData:
password: password
- name: gdev-mssql
type: mssql
url: mssql:1433
database: grafana
user: grafana
secureJsonData:
password: Password!
- name: gdev-mssql-ds-tests
type: mssql
url: mssqltests:1433
database: grafanatest
user: grafana
secureJsonData:
password: Password!
- name: gdev-postgres
type: postgres
url: postgres:5432
database: grafana
user: grafana
secureJsonData:
password: password
jsonData:
sslmode: "disable"
- name: gdev-postgres-ds-tests
type: postgres
url: postgrestest:5432
database: grafanadstest
user: grafanatest
secureJsonData:
password: grafanatest
jsonData:
sslmode: "disable"
- name: gdev-cloudwatch
type: cloudwatch
editable: true
jsonData:
authType: credentials
defaultRegion: eu-west-2
# Keep to test old /api/prom API
- name: gdev-loki-0.3
type: loki
access: proxy
url: http://loki0.3:3100
editable: false
# First version with new v1 API (remove once v1 is out)
- name: gdev-loki-0.4
type: loki
access: proxy
url: http://loki0.4:3100
editable: false
- name: gdev-loki
type: loki
access: proxy
url: http://loki:3100
editable: false

View File

@@ -15,12 +15,10 @@
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"iteration": 1573479899663,
"links": [],
"panels": [
{
"alert": {
"alertRuleTags": {},
"conditions": [
{
"evaluator": {
@@ -54,14 +52,12 @@
"editable": true,
"error": false,
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 10,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"isNew": true,
"legend": {
@@ -77,9 +73,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -149,7 +142,6 @@
},
{
"alert": {
"alertRuleTags": {},
"conditions": [
{
"evaluator": {
@@ -173,7 +165,7 @@
"for": "900000h",
"frequency": "1m",
"handler": 1,
"name": "TestData - Always Pending",
"name": "Always Pending",
"noDataState": "no_data",
"notifications": []
},
@@ -185,14 +177,12 @@
"editable": true,
"error": false,
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 10,
"x": 10,
"y": 0
},
"hiddenSeries": false,
"id": 7,
"isNew": true,
"legend": {
@@ -208,9 +198,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -240,7 +227,7 @@
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Always Pending with For",
"title": "Always Alerting with For",
"tooltip": {
"msResolution": false,
"shared": true,
@@ -281,7 +268,6 @@
{
"dashboardFilter": "",
"dashboardTags": [],
"datasource": null,
"folderId": null,
"gridPos": {
"h": 20,
@@ -294,7 +280,6 @@
"links": [],
"nameFilter": "$namefilter",
"onlyAlertsOnDashboard": false,
"options": {},
"show": "current",
"sortOrder": 1,
"stateFilter": [],
@@ -305,7 +290,6 @@
},
{
"alert": {
"alertRuleTags": {},
"conditions": [
{
"evaluator": {
@@ -329,7 +313,7 @@
"for": "1m",
"frequency": "1m",
"handler": 1,
"name": "TestData - Always Alerting For",
"name": "TestData - Always Pending",
"noDataState": "no_data",
"notifications": []
},
@@ -341,14 +325,12 @@
"editable": true,
"error": false,
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 6,
"w": 10,
"x": 0,
"y": 7
},
"hiddenSeries": false,
"id": 6,
"isNew": true,
"legend": {
@@ -364,9 +346,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -467,14 +446,12 @@
"editable": true,
"error": false,
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 6,
"w": 10,
"x": 10,
"y": 7
},
"hiddenSeries": false,
"id": 3,
"isNew": true,
"legend": {
@@ -490,9 +467,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -597,14 +571,12 @@
"editable": true,
"error": false,
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 10,
"x": 0,
"y": 13
},
"hiddenSeries": false,
"id": 5,
"isNew": true,
"legend": {
@@ -620,9 +592,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -692,7 +661,7 @@
}
],
"revision": 2,
"schemaVersion": 21,
"schemaVersion": 18,
"style": "dark",
"tags": ["gdev", "alerting"],
"templating": {
@@ -742,5 +711,5 @@
"timezone": "browser",
"title": "Alerting with TestData",
"uid": "7MeksYbmk",
"version": 3
"version": 1
}

View File

@@ -1,191 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [
{
"aliasColors": {},
"bars": true,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-influxdb-telegraf",
"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",
"groupBy": [
{
"params": ["1m"],
"type": "time"
},
{
"params": ["null"],
"type": "fill"
}
],
"measurement": "logs",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": ["message"],
"type": "field"
},
{
"params": [],
"type": "count"
}
]
],
"tags": []
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Log messages over time",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"datasource": "gdev-influxdb-telegraf",
"gridPos": {
"h": 18,
"w": 24,
"x": 0,
"y": 6
},
"id": 2,
"options": {
"showLabels": false,
"showTime": true,
"sortOrder": "Descending",
"wrapLogMessage": true
},
"targets": [
{
"groupBy": [],
"measurement": "logs",
"orderByTime": "ASC",
"policy": "default",
"refId": "A",
"resultFormat": "table",
"select": [
[
{
"params": ["message"],
"type": "field"
}
]
],
"tags": []
}
],
"timeFrom": null,
"timeShift": null,
"title": "Logs",
"type": "logs"
}
],
"schemaVersion": 22,
"style": "dark",
"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",
"version": 4
}

View File

@@ -4,37 +4,11 @@
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": false,
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"limit": 100,
"name": "Annotations & Alerts",
"showIn": 0,
"type": "dashboard"
},
{
"datasource": "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": "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"
}
]
},
@@ -42,7 +16,7 @@
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"iteration": 1576251075020,
"iteration": 1532618661457,
"links": [],
"panels": [
{
@@ -54,14 +28,12 @@
"dashes": false,
"datasource": "gdev-mssql",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
@@ -76,9 +48,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -110,7 +79,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Average logins / $summarize",
"tooltip": {
@@ -157,14 +125,12 @@
"dashes": false,
"datasource": "gdev-mssql",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 18,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 8,
"legend": {
"avg": false,
@@ -179,9 +145,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -206,7 +169,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Average payments started/ended / $summarize",
"tooltip": {
@@ -252,14 +214,12 @@
"dashes": false,
"datasource": "gdev-mssql",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"hiddenSeries": false,
"id": 6,
"legend": {
"avg": false,
@@ -274,9 +234,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -295,7 +252,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Max CPU / $summarize",
"tooltip": {
@@ -346,7 +302,6 @@
},
"id": 4,
"links": [],
"options": {},
"pageSize": null,
"scroll": true,
"showHeader": true,
@@ -385,19 +340,15 @@
"type": "table"
}
],
"schemaVersion": 21,
"schemaVersion": 16,
"style": "dark",
"tags": ["gdev", "mssql", "datasource-test"],
"templating": {
"list": [
{
"allValue": null,
"current": {
"text": "Africa",
"value": "Africa"
},
"current": {},
"datasource": "gdev-mssql",
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Datacenter",
@@ -417,13 +368,8 @@
},
{
"allValue": null,
"current": {
"selected": false,
"text": "All",
"value": "$__all"
},
"current": {},
"datasource": "gdev-mssql",
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
@@ -446,7 +392,6 @@
"auto_count": 30,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
@@ -543,5 +488,5 @@
"timezone": "",
"title": "Datasource tests - MSSQL",
"uid": "86Js1xRmk",
"version": 2
"version": 1
}

View File

@@ -4,35 +4,11 @@
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": false,
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
},
{
"datasource": "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": "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"
}
]
},
@@ -40,7 +16,7 @@
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"iteration": 1576250298312,
"iteration": 1532620738041,
"links": [],
"panels": [
{
@@ -52,14 +28,12 @@
"dashes": false,
"datasource": "gdev-mysql",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
@@ -74,9 +48,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -110,7 +81,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Average logins / $summarize",
"tooltip": {
@@ -156,14 +126,12 @@
"dashes": false,
"datasource": "gdev-mysql",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 18,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
@@ -178,9 +146,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -206,7 +171,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Average payments started/ended / $summarize",
"tooltip": {
@@ -252,14 +216,12 @@
"dashes": false,
"datasource": "gdev-mysql",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"hiddenSeries": false,
"id": 3,
"legend": {
"avg": false,
@@ -274,9 +236,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -296,7 +255,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Max CPU / $summarize",
"tooltip": {
@@ -347,7 +305,6 @@
},
"id": 6,
"links": [],
"options": {},
"pageSize": null,
"scroll": true,
"showHeader": true,
@@ -389,8 +346,7 @@
"type": "table"
}
],
"refresh": false,
"schemaVersion": 21,
"schemaVersion": 16,
"style": "dark",
"tags": ["gdev", "mysql", "datasource-tags"],
"templating": {
@@ -402,7 +358,6 @@
"value": "America"
},
"datasource": "gdev-mysql",
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Datacenter",
@@ -423,12 +378,10 @@
{
"allValue": null,
"current": {
"selected": false,
"text": "All",
"value": "$__all"
},
"datasource": "gdev-mysql",
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
@@ -451,7 +404,6 @@
"auto_count": 5,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
@@ -548,5 +500,5 @@
"timezone": "",
"title": "Datasource tests - MySQL",
"uid": "DGsCac3kz",
"version": 2
"version": 8
}

View File

@@ -1,217 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "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",
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"metric": "cpu",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "CPU",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "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",
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"metric": "logins.count",
"refId": "A"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Login Count",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"schemaVersion": 22,
"style": "dark",
"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",
"version": 2
}

View File

@@ -4,35 +4,11 @@
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": false,
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
},
{
"datasource": "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": "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"
}
]
},
@@ -40,7 +16,7 @@
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"iteration": 1576249087264,
"iteration": 1532620601931,
"links": [],
"panels": [
{
@@ -52,14 +28,12 @@
"dashes": false,
"datasource": "gdev-postgres",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 0
},
"hiddenSeries": false,
"id": 2,
"legend": {
"avg": false,
@@ -74,9 +48,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -96,59 +67,20 @@
{
"alias": "",
"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"
}
]
"target": ""
},
{
"alias": "",
"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"
}
]
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Average logins / $summarize",
"tooltip": {
@@ -194,14 +126,12 @@
"dashes": false,
"datasource": "gdev-postgres",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 18,
"w": 12,
"x": 12,
"y": 0
},
"hiddenSeries": false,
"id": 4,
"legend": {
"avg": false,
@@ -216,9 +146,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -244,7 +171,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Average payments started/ended / $summarize",
"tooltip": {
@@ -290,14 +216,12 @@
"dashes": false,
"datasource": "gdev-postgres",
"fill": 2,
"fillGradient": 0,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 9
},
"hiddenSeries": false,
"id": 3,
"legend": {
"avg": false,
@@ -312,9 +236,6 @@
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
@@ -334,7 +255,6 @@
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Max CPU / $summarize",
"tooltip": {
@@ -385,7 +305,6 @@
},
"id": 6,
"links": [],
"options": {},
"pageSize": null,
"scroll": true,
"showHeader": true,
@@ -426,7 +345,7 @@
"type": "table"
}
],
"schemaVersion": 21,
"schemaVersion": 16,
"style": "dark",
"tags": ["gdev", "postgres", "datasource-test"],
"templating": {
@@ -438,7 +357,6 @@
"value": "America"
},
"datasource": "gdev-postgres",
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Datacenter",
@@ -459,12 +377,10 @@
{
"allValue": null,
"current": {
"selected": false,
"text": "All",
"value": "$__all"
},
"datasource": "gdev-postgres",
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
@@ -487,7 +403,6 @@
"auto_count": 5,
"auto_min": "10s",
"current": {
"selected": false,
"text": "1m",
"value": "1m"
},
@@ -584,5 +499,5 @@
"timezone": "",
"title": "Datasource tests - Postgres",
"uid": "JYola5qzz",
"version": 5
"version": 4
}

View File

@@ -1,491 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": null,
"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",
"value": null
},
{
"color": "yellow",
"value": 50
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"labels": "",
"refId": "H",
"scenarioId": "random_walk"
},
{
"refId": "I",
"scenarioId": "random_walk"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"labels": "",
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": null,
"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",
"value": null
},
{
"color": "purple",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"refId": "H",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": null,
"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",
"value": null
},
{
"color": "blue",
"value": 50
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "horizontal",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
},
{
"refId": "R",
"scenarioId": "random_walk"
},
{
"refId": "S",
"scenarioId": "random_walk"
},
{
"refId": "T",
"scenarioId": "random_walk"
},
{
"refId": "U",
"scenarioId": "random_walk"
},
{
"refId": "V",
"scenarioId": "random_walk"
},
{
"refId": "W",
"scenarioId": "random_walk"
},
{
"refId": "X",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": null,
"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",
"value": null
},
{
"color": "purple",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"refId": "H",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "bargauge"
},
{
"datasource": null,
"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",
"value": null
},
{
"color": "purple",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": true
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
},
{
"refId": "H",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "bargauge"
}
],
"schemaVersion": 21,
"style": "dark",
"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",
"version": 5
}

View File

@@ -66,7 +66,7 @@
{
"targetBlank": false,
"title": "Drill it down",
"url": "/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}"
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}"
}
]
},
@@ -164,7 +164,7 @@
{
"targetBlank": false,
"title": "Drill it down",
"url": "/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-fieldName=${__field.name}"
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source?var-seriesName=${__series.name}&var-valueTime=${__value.time}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-fieldName=${__field.name}"
}
]
},
@@ -246,7 +246,7 @@
{
"targetBlank": true,
"title": "Drill it down!",
"url": "/d/wfTJJL5Wz/datalinks-source\n?var-fieldName=${__field.name}\n&var-labelDatacenter=${__series.labels.datacenter}\n&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}\n&var-valueNumeric=${__value.numeric}\n&var-valueText=${__value.text}\n&var-valueCalc=${__value.calc}"
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source\n?var-fieldName=${__field.name}\n&var-labelDatacenter=${__series.labels.datacenter}\n&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}\n&var-valueNumeric=${__value.numeric}\n&var-valueText=${__value.text}\n&var-valueCalc=${__value.calc}"
}
],
"mappings": [
@@ -307,7 +307,7 @@
"links": [
{
"title": "Drill it down",
"url": "/d/wfTJJL5Wz/datalinks-source?var-fieldName=${__field.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-valueCalc=${__value.calc}"
"url": "http://localhost:3000/d/wfTJJL5Wz/datalinks-source?var-fieldName=${__field.name}&var-labelDatacenter=${__series.labels.datacenter}&var-labelDatacenterRegion=${__series.labels[\"datacenter.region\"]}&var-valueNumeric=${__value.numeric}&var-valueText=${__value.text}&var-valueCalc=${__value.calc}"
}
],
"mappings": [],

View File

@@ -222,7 +222,7 @@
"text": "A",
"value": ["A"]
},
"datasource": "gdev-testdata",
"datasource": "TestData DB-1",
"definition": "*",
"hide": 0,
"includeAll": true,
@@ -247,7 +247,7 @@
"text": "AA",
"value": ["AA"]
},
"datasource": "gdev-testdata",
"datasource": "TestData DB-1",
"definition": "$datacenter.*",
"hide": 0,
"includeAll": true,

View File

@@ -1,195 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"iteration": 1584435937931,
"links": [],
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": null,
"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",
"refId": "A",
"scenarioId": "random_walk"
},
{
"alias": "dependsOnFirst: $dependsOnFirst",
"refId": "B",
"scenarioId": "random_walk"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Panel Title",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"schemaVersion": 22,
"style": "dark",
"tags": ["gdev", "templating"],
"templating": {
"list": [
{
"allValue": null,
"current": {
"text": "value.1584434137814",
"value": "value.1584434137814"
},
"datasource": "gdev-testdata",
"definition": "value.$__from",
"hide": 0,
"includeAll": false,
"index": -1,
"label": null,
"multi": false,
"name": "updatesOnTime",
"options": [],
"query": "value.$__from",
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"tagsQuery": "",
"type": "query",
"useTags": false
},
{
"allValue": null,
"current": {
"text": "value.value.1584434072074",
"value": "value.value.1584434072074"
},
"datasource": "gdev-testdata",
"definition": "value.$updatesOnTime",
"hide": 0,
"includeAll": false,
"index": -1,
"label": null,
"multi": false,
"name": "dependsOnFirst",
"options": [
{
"selected": true,
"text": "value.value.1584434072074",
"value": "value.value.1584434072074"
}
],
"query": "value.$updatesOnTime",
"refresh": 0,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"tagValuesQuery": "",
"tags": [],
"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",
"variables": {
"list": []
},
"version": 13
}

View File

@@ -1,530 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": null,
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 0
},
"id": 8,
"links": [],
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "green",
"value": null
},
{
"color": "purple",
"value": 50
},
{
"color": "blue",
"value": 70
}
],
"unit": "watt"
},
"overrides": [],
"values": false
},
"orientation": "vertical",
"showUnfilled": false
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "I",
"scenarioId": "random_walk"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Basic vertical ",
"type": "bargauge"
},
{
"datasource": null,
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 0
},
"id": 22,
"links": [],
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "green",
"value": null
},
{
"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": [
{
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"refId": "J",
"scenarioId": "random_walk"
},
{
"refId": "K",
"scenarioId": "random_walk"
},
{
"refId": "L",
"scenarioId": "random_walk"
},
{
"refId": "M",
"scenarioId": "random_walk"
},
{
"refId": "N",
"scenarioId": "random_walk"
},
{
"refId": "O",
"scenarioId": "random_walk"
},
{
"refId": "P",
"scenarioId": "random_walk"
},
{
"refId": "Q",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Basic vertical (Unfilled)",
"type": "bargauge"
},
{
"datasource": null,
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 10
},
"id": 12,
"links": [],
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"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",
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Gradient ",
"type": "bargauge"
},
{
"datasource": null,
"gridPos": {
"h": 9,
"w": 12,
"x": 12,
"y": 10
},
"id": 23,
"links": [],
"options": {
"displayMode": "gradient",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"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",
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Gradient (Unfilled)",
"type": "bargauge"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 12,
"x": 0,
"y": 19
},
"id": 21,
"links": [],
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"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",
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Title to left of bar",
"type": "bargauge"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 12,
"x": 12,
"y": 19
},
"id": 24,
"links": [],
"options": {
"displayMode": "basic",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"decimals": null,
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"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",
"refId": "H",
"scenarioId": "csv_metric_values",
"stringInput": "100,100,100"
},
{
"alias": "Outhouse",
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Title to left of bar (Filled)",
"type": "bargauge"
}
],
"schemaVersion": 21,
"style": "dark",
"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"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
},
"timezone": "",
"title": "Panel Tests - Bar Gauge 2",
"uid": "sRrEibfZk",
"version": 5
}

View File

@@ -20,352 +20,142 @@
{
"datasource": null,
"gridPos": {
"h": 3,
"w": 24,
"h": 7,
"w": 20,
"x": 0,
"y": 0
},
"id": 6,
"interval": "6m",
"id": 2,
"interval": "10m",
"options": {
"colorMode": "background",
"colorMode": 0,
"displayMode": 2,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
]
},
"unit": "areaM2"
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"override": {},
"values": false
},
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.6.0-pre",
"pluginVersion": "6.5.0-pre",
"targets": [
{
"alias": "__house_locations",
"labels": "",
"min": 0,
"noise": 5,
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 6,
"spread": 100
}
],
"timeFrom": null,
"timeShift": null,
"title": "",
"type": "stat"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 24,
"x": 0,
"y": 3
},
"id": 10,
"interval": "7m",
"options": {
"colorMode": "background",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
]
},
"unit": "areaM2"
},
"overrides": [],
"values": false
"scenarioId": "random_walk"
},
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.6.0-pre",
"targets": [
{
"alias": "__house_locations",
"min": 0,
"noise": 10,
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 6,
"spread": 10
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "stat"
"type": "singlestat2"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 24,
"x": 0,
"y": 9
},
"id": 14,
"interval": "7m",
"options": {
"colorMode": "value",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
]
},
"unit": "areaM2"
},
"overrides": [],
"values": false
},
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.6.0-pre",
"targets": [
{
"alias": "__house_locations",
"min": 0,
"noise": 10,
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 6,
"spread": 10
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "stat"
},
{
"datasource": null,
"gridPos": {
"h": 14,
"w": 6,
"x": 0,
"y": 15
},
"id": 13,
"interval": "5m",
"options": {
"colorMode": "background",
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
]
},
"unit": "areaM2"
},
"overrides": [],
"values": false
},
"graphMode": "area",
"justifyMode": "auto",
"orientation": "horizontal",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.6.0-pre",
"targets": [
{
"alias": "__server_names",
"min": 0,
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 7,
"spread": 100
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "stat"
},
{
"datasource": null,
"gridPos": {
"h": 11,
"h": 20,
"w": 4,
"x": 6,
"y": 15
"x": 20,
"y": 0
},
"id": 8,
"interval": "10m",
"options": {
"colorMode": "background",
"colorMode": 0,
"displayMode": 2,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
]
},
"unit": "areaM2"
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"override": {},
"values": false
},
"graphMode": "line",
"justifyMode": "auto",
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.6.0-pre",
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
@@ -399,65 +189,60 @@
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "stat"
"type": "singlestat2"
},
{
"datasource": null,
"gridPos": {
"h": 9,
"w": 8,
"x": 10,
"y": 15
"h": 3,
"w": 20,
"x": 0,
"y": 7
},
"id": 12,
"id": 6,
"interval": "10m",
"options": {
"colorMode": "background",
"colorMode": 0,
"displayMode": 2,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
]
},
"unit": "areaM2"
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"overrides": [],
"override": {},
"values": false
},
"graphMode": "line",
"justifyMode": "auto",
"orientation": "horizontal",
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.6.0-pre",
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
@@ -491,10 +276,358 @@
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "stat"
"type": "singlestat2"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 20,
"x": 0,
"y": 10
},
"id": 3,
"interval": "10m",
"options": {
"colorMode": 0,
"displayMode": 3,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"override": {},
"values": false
},
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "singlestat2"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 20,
"x": 0,
"y": 16
},
"id": 4,
"interval": "10m",
"options": {
"colorMode": 0,
"displayMode": 0,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"override": {},
"values": false
},
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "singlestat2"
},
{
"datasource": null,
"gridPos": {
"h": 21,
"w": 4,
"x": 20,
"y": 20
},
"id": 9,
"interval": "10m",
"options": {
"colorMode": 0,
"displayMode": 0,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"override": {},
"values": false
},
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "singlestat2"
},
{
"datasource": null,
"gridPos": {
"h": 6,
"w": 20,
"x": 0,
"y": 22
},
"id": 5,
"interval": "10m",
"options": {
"colorMode": 0,
"displayMode": 1,
"fieldOptions": {
"calcs": ["mean"],
"defaults": {
"mappings": [],
"max": 100,
"min": 0,
"thresholds": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 10
},
{
"color": "purple",
"value": 20
},
{
"color": "orange",
"value": 40
},
{
"color": "red",
"value": 80
}
],
"unit": "percent"
},
"override": {},
"values": false
},
"orientation": "auto",
"sparkline": {
"show": true
}
},
"pluginVersion": "6.5.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk"
},
{
"refId": "B",
"scenarioId": "random_walk"
},
{
"refId": "C",
"scenarioId": "random_walk"
},
{
"refId": "D",
"scenarioId": "random_walk"
},
{
"refId": "E",
"scenarioId": "random_walk"
},
{
"refId": "F",
"scenarioId": "random_walk"
},
{
"refId": "G",
"scenarioId": "random_walk"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Panel Title",
"type": "singlestat2"
}
],
"schemaVersion": 22,
"schemaVersion": 20,
"style": "dark",
"tags": ["gdev", "panel-tests"],
"templating": {
@@ -508,5 +641,7 @@
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - Stat"
"title": "Panel Tests - Stat",
"uid": "jWWHNJpWz",
"version": 6
}

View File

@@ -1,602 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"links": [],
"panels": [
{
"datasource": null,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 7,
"title": "Cell styles",
"type": "row"
},
{
"datasource": "gdev-testdata",
"fieldConfig": {
"defaults": {
"custom": {
"align": "center",
"displayMode": "color-background"
},
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "blue",
"value": 20
},
{
"color": "orange",
"value": 60
},
{
"color": "red",
"value": 70
}
]
},
"unit": "degree"
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Max"
},
"properties": [
{
"id": "custom.width",
"value": 84
}
]
},
{
"matcher": {
"id": "byName",
"options": "Last"
},
"properties": [
{
"id": "custom.width",
"value": 78
}
]
},
{
"matcher": {
"id": "byName",
"options": "Mean"
},
"properties": [
{
"id": "custom.width",
"value": 74
}
]
},
{
"matcher": {
"id": "byName",
"options": "Field"
},
"properties": [
{
"id": "custom.align",
"value": "left"
}
]
}
]
},
"gridPos": {
"h": 16,
"w": 7,
"x": 0,
"y": 1
},
"id": 4,
"options": {
"showHeader": true,
"sortBy": [
{
"desc": true,
"displayName": "Last"
}
]
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 15,
"stringInput": ""
}
],
"timeFrom": null,
"timeShift": null,
"title": "Colored background",
"transformations": [
{
"id": "reduce",
"options": {
"reducers": ["max", "mean", "last"]
}
}
],
"type": "table"
},
{
"datasource": "gdev-testdata",
"fieldConfig": {
"defaults": {
"custom": {
"align": null
},
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "orange",
"value": null
},
{
"color": "red",
"value": 50
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Value"
},
"properties": [
{
"id": "custom.displayMode",
"value": "gradient-gauge"
}
]
},
{
"matcher": {
"id": "byName",
"options": "Info"
},
"properties": [
{
"id": "custom.width",
"value": 92
}
]
},
{
"matcher": {
"id": "byName",
"options": "Min"
},
"properties": [
{
"id": "custom.width",
"value": 76
}
]
},
{
"matcher": {
"id": "byName",
"options": "Max"
},
"properties": [
{
"id": "custom.width",
"value": 89
}
]
},
{
"matcher": {
"id": "byName",
"options": "Time"
},
"properties": [
{
"id": "custom.width",
"value": 165
}
]
}
]
},
"gridPos": {
"h": 16,
"w": 8,
"x": 7,
"y": 1
},
"id": 2,
"options": {
"showHeader": true,
"sortBy": [
{
"desc": false,
"displayName": "Min"
}
]
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk_table",
"stringInput": ""
}
],
"timeFrom": null,
"timeShift": null,
"title": "Bar gauge cells",
"transformations": [
{
"id": "organize",
"options": {
"excludeByName": {
"Time": true
},
"indexByName": {
"Info": 1,
"Max": 3,
"Min": 2,
"Time": 0,
"Value": 4
},
"renameByName": {}
}
}
],
"type": "table"
},
{
"datasource": "gdev-testdata",
"description": "",
"fieldConfig": {
"defaults": {
"custom": {
"align": null
},
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "blue",
"value": null
},
{
"color": "green",
"value": 50
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Value"
},
"properties": [
{
"id": "custom.displayMode",
"value": "lcd-gauge"
},
{
"id": "custom.align",
"value": "center"
}
]
}
]
},
"gridPos": {
"h": 16,
"w": 9,
"x": 15,
"y": 1
},
"id": 5,
"options": {
"showHeader": true,
"sortBy": []
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk_table",
"stringInput": ""
}
],
"timeFrom": null,
"timeShift": null,
"title": "Retro LCD cell",
"transformations": [
{
"id": "organize",
"options": {
"excludeByName": {
"Info": false,
"Max": true,
"Min": true,
"Time": false
},
"indexByName": {
"Info": 1,
"Max": 3,
"Min": 2,
"Time": 0,
"Value": 4
},
"renameByName": {}
}
}
],
"type": "table"
},
{
"collapsed": false,
"datasource": null,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 17
},
"id": 9,
"panels": [],
"title": "Data links",
"type": "row"
},
{
"datasource": "gdev-testdata",
"fieldConfig": {
"defaults": {
"custom": {
"align": "center",
"displayMode": "color-text"
},
"decimals": 2,
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "blue",
"value": 20
},
{
"color": "orange",
"value": 50
},
{
"color": "red",
"value": 70
}
]
},
"unit": "percent"
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Time"
},
"properties": [
{
"id": "custom.align",
"value": null
}
]
},
{
"matcher": {
"id": "byName",
"options": "{name=\"S1\", server=\"A\"}"
},
"properties": [
{
"id": "links",
"value": [
{
"title": "Details",
"url": "http://detail?serverLabel=${__field.labels.server}&valueNumeric=${__value.numeric}"
}
]
}
]
}
]
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 18
},
"id": 3,
"maxDataPoints": "10",
"options": {
"showHeader": true
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"alias": "S1",
"labels": "server=A",
"refId": "A",
"scenarioId": "random_walk",
"seriesCount": 1,
"stringInput": ""
},
{
"alias": "S2",
"labels": "server=B",
"refId": "B",
"scenarioId": "random_walk",
"seriesCount": 1,
"stringInput": ""
},
{
"alias": "S3",
"labels": "server=C",
"refId": "C",
"scenarioId": "random_walk",
"seriesCount": 1,
"stringInput": ""
}
],
"timeFrom": null,
"timeShift": null,
"title": "Data link with labels and numeric value",
"transformations": [
{
"id": "seriesToColumns",
"options": {}
}
],
"type": "table"
},
{
"datasource": "gdev-testdata",
"fieldConfig": {
"defaults": {
"custom": {
"align": "center",
"displayMode": "auto"
},
"mappings": [],
"thresholds": {
"mode": "percentage",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "blue",
"value": 20
},
{
"color": "orange",
"value": 60
},
{
"color": "red",
"value": 70
}
]
},
"unit": "degree"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 5,
"x": 12,
"y": 18
},
"id": 10,
"options": {
"showHeader": false,
"sortBy": [
{
"desc": true,
"displayName": "Last"
}
]
},
"pluginVersion": "7.1.0-pre",
"targets": [
{
"refId": "A",
"scenarioId": "random_walk_table",
"seriesCount": 5,
"stringInput": ""
}
],
"timeFrom": null,
"timeShift": null,
"title": "No header",
"transformations": [
{
"id": "organize",
"options": {
"excludeByName": {
"Min": true,
"Time": true,
"Value": true
},
"indexByName": {
"Info": 2,
"Max": 4,
"Min": 3,
"Time": 0,
"Value": 1
},
"renameByName": {}
}
}
],
"type": "table"
}
],
"schemaVersion": 25,
"style": "dark",
"tags": ["gdev", "panel-tests"],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
},
"timezone": "",
"title": "Panel Tests - React Table",
"uid": "U_bZIMRMk",
"version": 17
}

View File

@@ -1,695 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 28,
"links": [],
"panels": [
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-testdata",
"editable": true,
"error": false,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"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,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"refId": "A",
"scenario": "random_walk",
"scenarioId": "random_walk",
"target": ""
}
],
"thresholds": [],
"timeFrom": "2s",
"timeRegions": [],
"timeShift": null,
"title": "Millisecond res x-axis and tooltip",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-testdata",
"editable": true,
"error": false,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"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": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"refId": "A",
"scenario": "random_walk",
"scenarioId": "random_walk",
"target": ""
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Random walk series",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-testdata",
"editable": true,
"error": false,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 7
},
"hiddenSeries": false,
"id": 5,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [
{
"alias": "B-series",
"yaxis": 2
}
],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,0",
"target": ""
},
{
"refId": "B",
"scenarioId": "csv_metric_values",
"stringInput": "2000,3000,4000,1000,3000,10000",
"target": ""
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "2 yaxis and axis labels",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percent",
"label": "Perecent",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": "Pressure",
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-testdata",
"editable": true,
"error": false,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 7
},
"hiddenSeries": false,
"id": 9,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [
{
"alias": "B-series",
"zindex": -3
}
],
"spaceLength": 10,
"stack": true,
"steppedLine": false,
"targets": [
{
"hide": false,
"refId": "B",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,null,null,null,null,null,null,100,10,10,20,30,40,10",
"target": ""
},
{
"alias": "",
"hide": false,
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,10,20,30,40,40,40,100,10,20,20",
"target": ""
},
{
"alias": "",
"hide": false,
"refId": "C",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,10,20,30,40,40,40,100,10,20,20",
"target": ""
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Stacking value ontop of nulls",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-testdata",
"editable": true,
"error": false,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 0,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 15
},
"hiddenSeries": false,
"id": 21,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [
{
"alias": "C-series",
"steppedLine": true
}
],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"alias": "",
"hide": false,
"refId": "B",
"scenarioId": "csv_metric_values",
"stringInput": "1,null,40,null,90,null,null,100,null,null,100,null,null,80,null",
"target": ""
},
{
"alias": "",
"hide": false,
"refId": "C",
"scenarioId": "csv_metric_values",
"stringInput": "20,null40,null,null,50,null,70,null,100,null,10,null,30,null",
"target": ""
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Null between points",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "gdev-testdata",
"decimals": 3,
"fieldConfig": {
"defaults": {
"custom": {}
},
"overrides": []
},
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 15
},
"hiddenSeries": false,
"id": 16,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"show": true,
"total": true,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,0",
"target": ""
},
{
"refId": "B",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,0",
"target": ""
},
{
"refId": "C",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,0",
"target": ""
},
{
"refId": "D",
"scenarioId": "csv_metric_values",
"stringInput": "1,20,90,30,5,0",
"target": ""
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Legend Table No Scroll Visible",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
}
],
"refresh": false,
"revision": 8,
"schemaVersion": 25,
"style": "dark",
"tags": ["gdev", "panel-tests", "graph", "table"],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {
"refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
},
"timezone": "utc",
"title": "Panel Tests - Time zone support",
"uid": "5SdHCasdf",
"version": 1
}

View File

@@ -9,7 +9,7 @@
image: grafana/fake-data-gen
links:
- elasticsearch5
# network_mode: bridge
environment:
FD_SERVER: elasticsearch5
FD_DATASOURCE: elasticsearch
FD_PORT: 9200
FD_PORT: 10200

View File

@@ -9,12 +9,10 @@
fake-elastic6-data:
image: grafana/fake-data-gen
links:
- elasticsearch6
network_mode: bridge
environment:
FD_SERVER: elasticsearch6
FD_DATASOURCE: elasticsearch6
FD_PORT: 9200
FD_PORT: 11200
filebeat6:
image: docker.elastic.co/beats/filebeat-oss:6.7.1

View File

@@ -9,12 +9,10 @@
fake-elastic7-data:
image: grafana/fake-data-gen
links:
- elasticsearch7
network_mode: bridge
environment:
FD_SERVER: elasticsearch7
FD_DATASOURCE: elasticsearch7
FD_PORT: 9200
FD_PORT: 12200
filebeat7:
image: docker.elastic.co/beats/filebeat-oss:7.0.0
@@ -26,6 +24,7 @@
metricbeat7:
image: docker.elastic.co/beats/metricbeat-oss:7.0.0
network_mode: host
command: metricbeat -e -strict.perms=false
user: root
volumes:
@@ -36,7 +35,5 @@
image: docker.elastic.co/kibana/kibana-oss:7.0.0
ports:
- "5601:5601"
links:
- elasticsearch7
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch7:9200

View File

@@ -28,11 +28,11 @@ processors:
- add_cloud_metadata: ~
output.elasticsearch:
hosts: ["elasticsearch7:9200"]
hosts: ["localhost:12200"]
index: "metricbeat-%{+yyyy.MM.dd}"
setup.template.name: "metricbeat"
setup.template.pattern: "metricbeat-*"
setup.template.settings:
index.number_of_shards: 1
index.number_of_replicas: 1
index.number_of_replicas: 1

View File

@@ -1 +0,0 @@
grafana_version=6.6.2

View File

@@ -1,14 +0,0 @@
grafana:
image: grafana/grafana:${grafana_version}
ports:
- "3001:3000"
volumes:
- "./dashboards.yaml:/etc/grafana/provisioning/dashboards/dashboards.yaml"
- "./dev-dashboards:/usr/share/grafana/devenv/dev-dashboards"
- "./datasources_docker.yaml:/etc/grafana/provisioning/datasources/datasources.yaml"
environment:
GF_RENDERING_SERVER_URL: http://renderer:8081/render
GF_RENDERING_CALLBACK_URL: http://grafana:3000/
renderer:
image: grafana/grafana-image-renderer:latest

View File

@@ -1,32 +1,6 @@
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "6831:6831"
- "127.0.0.1:6831:6831/udp"
- "16686:16686"
# Additional loki to generate some traces
# datasource URL: http://localhost:3100/
loki:
image: grafana/loki:master
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
# For this to work you need to install the logging driver see https://github.com/grafana/loki/tree/master/cmd/docker-driver#plugin-installation
logging:
driver: loki
options:
loki-url: "http://localhost:3100/loki/api/v1/push"
# Optional jaeger tracing
environment:
- JAEGER_AGENT_HOST=jaeger
- JAEGER_AGENT_PORT=6831
- JAEGER_SAMPLER_TYPE=const
- JAEGER_SAMPLER_PARAM=1
promtail:
image: grafana/promtail:master
volumes:
- ./docker/blocks/loki/config.yaml:/etc/promtail/docker-config.yaml
- /var/log:/var/log
- ../data/log:/var/log/grafana
command:
-config.file=/etc/promtail/docker-config.yaml

View File

@@ -1,9 +1,9 @@
# datasource URL: http://localhost:3100/
loki:
image: grafana/loki:master
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:master
volumes:

View File

@@ -1,27 +0,0 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
client:
url: http://loki0.3:3100/api/prom/push
scrape_configs:
- job_name: system
entry_parser: raw
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
- job_name: grafana
entry_parser: raw
static_configs:
- targets:
- localhost
labels:
job: grafana
__path__: /var/log/grafana/*log

View File

@@ -1,15 +0,0 @@
# datasource URL: http://localhost:3103/
loki0.3:
image: grafana/loki:v0.3.0
ports:
- "3103:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail0.3:
image: grafana/promtail:v0.3.0
volumes:
- ./docker/blocks/loki0.3/config.yaml:/etc/promtail/docker-config.yaml
- /var/log:/var/log
- ../data/log:/var/log/grafana
command:
-config.file=/etc/promtail/docker-config.yaml

View File

@@ -1,27 +0,0 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
client:
url: http://loki0.4:3100/api/prom/push
scrape_configs:
- job_name: system
entry_parser: raw
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
- job_name: grafana
entry_parser: raw
static_configs:
- targets:
- localhost
labels:
job: grafana
__path__: /var/log/grafana/*log

View File

@@ -1,15 +0,0 @@
# datasource URL: http://localhost:3104/
loki0.4:
image: grafana/loki:v0.4.0
ports:
- "3104:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail0.4:
image: grafana/promtail:v0.4.0
volumes:
- ./docker/blocks/loki0.4/config.yaml:/etc/promtail/docker-config.yaml
- /var/log:/var/log
- ../data/log:/var/log/grafana
command:
-config.file=/etc/promtail/docker-config.yaml

View File

@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/mssql/server:2017-CU4-ubuntu
FROM microsoft/mssql-server-linux:2017-CU4
WORKDIR /usr/setup
COPY . /usr/setup
RUN chmod +x /usr/setup/setup.sh

View File

@@ -1,42 +0,0 @@
events { worker_connections 1024; }
http {
sendfile on;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
server {
listen 10080;
location /grafana/ {
################################################################
# Enable these settings to test with basic auth and an auth proxy header
# the htpasswd file contains an admin user with password admin and
# user1: grafana and user2: grafana
################################################################
################################################################
# To use the auth proxy header, set the following in custom.ini:
# [auth.proxy]
# enabled = true
# header_name = X-WEBAUTH-USER
# header_property = username
################################################################
location /grafana/login {
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/htpasswd;
proxy_set_header X-WEBAUTH-USER $remote_user;
proxy_pass http://host.docker.internal:3000/login;
}
proxy_set_header Authorization "";
proxy_pass http://host.docker.internal:3000/;
}
}
}

View File

@@ -1,4 +1,4 @@
postgres:
postgrestest:
image: postgres:${postgres_version}
environment:
POSTGRES_USER: grafana
@@ -7,11 +7,6 @@
ports:
- "5432:5432"
command: postgres -c log_connections=on -c logging_collector=on -c log_destination=stderr -c log_directory=/var/log/postgresql
healthcheck:
test: [ "CMD", "pg_isready", "-q", "-d", "$$POSTGRES_DATABASE", "-U", "$$POSTGRES_USER" ]
timeout: 45s
interval: 10s
retries: 10
fake-postgres-data:
image: grafana/fake-data-gen
@@ -19,6 +14,3 @@
environment:
FD_DATASOURCE: postgres
FD_PORT: 5432
depends_on:
postgres:
condition: service_healthy

View File

@@ -1,15 +1,18 @@
prometheus:
build: docker/blocks/prometheus
network_mode: host
ports:
- "9090:9090"
node_exporter:
image: prom/node-exporter
network_mode: host
ports:
- "9100:9100"
fake-prometheus-data:
image: grafana/fake-data-gen
network_mode: host
ports:
- "9091:9091"
environment:
@@ -17,10 +20,12 @@
alertmanager:
image: quay.io/prometheus/alertmanager
network_mode: host
ports:
- "9093:9093"
prometheus-random-data:
build: docker/blocks/prometheus_random_data
network_mode: host
ports:
- "8081:8080"

View File

@@ -15,7 +15,7 @@ alerting:
- scheme: http
static_configs:
- targets:
- "alertmanager:9093"
- "127.0.0.1:9093"
scrape_configs:
- job_name: 'prometheus'
@@ -24,16 +24,16 @@ scrape_configs:
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
- targets: ['127.0.0.1:9100']
- job_name: 'fake-data-gen'
static_configs:
- targets: ['fake-prometheus-data:9091']
- targets: ['127.0.0.1:9091']
- job_name: 'grafana'
static_configs:
- targets: ['grafana:3000']
- targets: ['127.0.0.1:3000']
- job_name: 'prometheus-random-data'
static_configs:
- targets: ['prometheus-random-data:8080']
- targets: ['127.0.0.1:8081']

View File

@@ -1,4 +1,3 @@
FROM prom/prometheus:v2.7.2
ADD prometheus.yml /etc/prometheus/
ADD recording.yml /etc/prometheus/
ADD alert.yml /etc/prometheus/
ADD alert.rules /etc/prometheus/

View File

@@ -0,0 +1,10 @@
# Alert Rules
ALERT AppCrash
IF process_open_fds > 0
FOR 15s
LABELS { severity="critical" }
ANNOTATIONS {
summary = "Number of open fds > 0",
description = "Just testing"
}

View File

@@ -1,11 +0,0 @@
groups:
- name: ALERT
rules:
- alert: AppCrash
expr: process_open_fds > 0
for: 15s
labels:
severity: critical
annotations:
summary: Number of open fds > 0
description: Just testing

View File

@@ -1,15 +1,18 @@
prometheus:
build: docker/blocks/prometheus2
network_mode: host
ports:
- "9090:9090"
node_exporter:
image: prom/node-exporter
network_mode: host
ports:
- "9100:9100"
fake-prometheus-data:
image: grafana/fake-data-gen
network_mode: host
ports:
- "9091:9091"
environment:
@@ -17,10 +20,12 @@
alertmanager:
image: quay.io/prometheus/alertmanager
network_mode: host
ports:
- "9093:9093"
prometheus-random-data:
build: docker/blocks/prometheus_random_data
network_mode: host
ports:
- "8081:8080"

View File

@@ -5,17 +5,17 @@ global:
# scrape_timeout is set to the global default (10s).
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
rule_files:
- "alert.yml"
- "recording.yml"
#rule_files:
# - "alert.rules"
# - "first.rules"
# - "second.rules"
alerting:
alertmanagers:
- scheme: http
static_configs:
- targets:
- "alertmanager:9093"
# alerting:
# alertmanagers:
# - scheme: http
# static_configs:
# - targets:
# - "127.0.0.1:9093"
scrape_configs:
- job_name: 'prometheus'
@@ -24,16 +24,16 @@ scrape_configs:
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
- targets: ['127.0.0.1:9100']
- job_name: 'fake-data-gen'
static_configs:
- targets: ['fake-prometheus-data:9091']
- targets: ['127.0.0.1:9091']
- job_name: 'grafana'
static_configs:
- targets: ['grafana:3000']
- targets: ['127.0.0.1:3000']
- job_name: 'prometheus-random-data'
static_configs:
- targets: ['prometheus-random-data:8080']
- targets: ['127.0.0.1:8081']

View File

@@ -1,16 +0,0 @@
groups:
- name: RECORDING_RULES
rules:
- record: instance_path:requests:rate5m
expr: rate(prometheus_http_requests_total{job="prometheus"}[5m])
- record: path:requests:rate5m
expr: sum without (instance)(instance_path:requests:rate5m{job="prometheus"})
- record: instance_path:reloads_failures:rate5m
expr: rate(prometheus_tsdb_reloads_failures_total{job="prometheus"}[5m])
- record: instance_path:reloads:rate5m
expr: rate(prometheus_tsdb_reloads_total{job="prometheus"}[5m])
- record: instance_path:request_failures_per_requests:ratio_rate5m
expr: |2
instance_path:reloads_failures:rate5m{job="prometheus"}
/
instance_path:reloads:rate5m{job="prometheus"}

View File

@@ -0,0 +1,3 @@
FROM prom/prometheus:v1.8.2
ADD prometheus.yml /etc/prometheus/
ADD alert.rules /etc/prometheus/

View File

@@ -0,0 +1,10 @@
# Alert Rules
ALERT AppCrash
IF process_open_fds > 0
FOR 15s
LABELS { severity="critical" }
ANNOTATIONS {
summary = "Number of open fds > 0",
description = "Just testing"
}

View File

@@ -0,0 +1,26 @@
prometheus:
build: docker/blocks/prometheus_mac
ports:
- "9090:9090"
node_exporter:
image: prom/node-exporter
ports:
- "9100:9100"
fake-prometheus-data:
image: grafana/fake-data-gen
ports:
- "9091:9091"
environment:
FD_DATASOURCE: prom
alertmanager:
image: quay.io/prometheus/alertmanager
ports:
- "9093:9093"
prometheus-random-data:
build: docker/blocks/prometheus_random_data
ports:
- "8081:8080"

View File

@@ -0,0 +1,39 @@
# my global config
global:
scrape_interval: 10s # By default, scrape targets every 15 seconds.
evaluation_interval: 10s # By default, scrape targets every 15 seconds.
# scrape_timeout is set to the global default (10s).
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
rule_files:
- "alert.rules"
# - "first.rules"
# - "second.rules"
alerting:
alertmanagers:
- scheme: http
static_configs:
- targets:
- "alertmanager:9093"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
- job_name: 'fake-data-gen'
static_configs:
- targets: ['fake-prometheus-data:9091']
- job_name: 'grafana'
static_configs:
- targets: ['host.docker.internal:3000']
- job_name: 'prometheus-random-data'
static_configs:
- targets: ['prometheus-random-data:8080']

View File

@@ -1,7 +1,7 @@
# This Dockerfile builds an image for a client_golang example.
# Builder image, where we build the example.
FROM golang:1.14.1 AS builder
FROM golang:1.13.0 AS builder
# Download prometheus/client_golang/examples/random first
RUN go get github.com/prometheus/client_golang/examples/random
WORKDIR /go/src/github.com/prometheus/client_golang

View File

@@ -1,19 +0,0 @@
http:
middlewares:
compress-response:
compress: {}
services:
grafana-subpath:
loadBalancer:
servers:
- url: 'http://grafana-subpath:3000/'
routers:
grafana-subpath:
entryPoints:
- web
middlewares:
- compress-response
rule: 'Path(`/grafana`) || PathPrefix(`/grafana/`)'
service: grafana-subpath

View File

@@ -1,19 +0,0 @@
version: '3'
services:
traefik:
image: traefik:v2.1
volumes:
- './traefik.yml:/etc/traefik/traefik.yml'
- './configs:/etc/traefik/configs'
ports:
- '80:80'
- '8080:8080'
links:
- grafana-subpath
grafana-subpath:
image: grafana/grafana:latest
environment:
- GF_SERVER_ROOT_URL=/grafana
- GF_SERVER_SERVE_FROM_SUB_PATH=true

View File

@@ -1,18 +0,0 @@
## traefik.yml
# Entrypoints enabled
entryPoints:
web:
address: ':80'
# API and dashboard configuration
api:
insecure: true
# Loggings
log: {}
# File configurations folder
providers:
file:
directory: /etc/traefik/configs

View File

@@ -1,6 +0,0 @@
# There is no data generator for this so easiest way to get some data here is run this example app
# https://github.com/openzipkin/zipkin-js-example/tree/master/web
zipkin:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"

View File

@@ -1,2 +1,2 @@
version: "2.1"
version: "2"
services:

View File

@@ -35,18 +35,6 @@ Run load test for 10 virtual users:
$ ./run.sh -v 10
```
Run load test and send the results to the database "myDb" in influxDB running locally on port 8086 (with no authentication):
```bash
$ ./run.sh -o influxdb=http://localhost:8086/myDb
```
Run auth token slow test (random query latency between 1 and 30 seconds):
```bash
$ ./run.sh -c auth_token_slow_test -s 30
```
Run auth proxy test:
```bash

View File

@@ -1,71 +0,0 @@
import { sleep, check, group } from 'k6';
import { createClient, createBasicAuthClient } from './modules/client.js';
import { createTestOrgIfNotExists, createTestdataDatasourceIfNotExists } from './modules/util.js';
export let options = {
noCookiesReset: true
};
let endpoint = __ENV.URL || 'http://localhost:3000';
const client = createClient(endpoint);
export const setup = () => {
const basicAuthClient = createBasicAuthClient(endpoint, 'admin', 'admin');
const orgId = createTestOrgIfNotExists(basicAuthClient);
const datasourceId = createTestdataDatasourceIfNotExists(basicAuthClient);
client.withOrgId(orgId);
return {
orgId: orgId,
datasourceId: datasourceId,
};
}
export default (data) => {
group("annotation by tag test", () => {
if (__ITER === 0) {
group("user authenticates thru ui with username and password", () => {
let res = client.ui.login('admin', 'admin');
check(res, {
'response status is 200': (r) => r.status === 200,
'response has cookie \'grafana_session\' with 32 characters': (r) => r.cookies.grafana_session[0].value.length === 32,
});
});
}
if (__ITER !== 0) {
group("batch tsdb requests with annotations by tag", () => {
const batchCount = 20;
const requests = [];
const payload = {
from: '1547765247624',
to: '1547768847624',
queries: [{
refId: 'A',
scenarioId: 'random_walk',
intervalMs: 10000,
maxDataPoints: 433,
datasourceId: data.datasourceId,
}]
};
requests.push({ method: 'GET', url: '/api/annotations?from=1580825186534&to=1580846786535' });
for (let n = 0; n < batchCount; n++) {
requests.push({ method: 'POST', url: '/api/tsdb/query', body: payload });
}
let responses = client.batch(requests);
for (let n = 0; n < batchCount; n++) {
check(responses[n], {
'response status is 200': (r) => r.status === 200,
});
}
});
}
});
sleep(5)
}
export const teardown = (data) => {}

View File

@@ -1,73 +0,0 @@
import { sleep, check, group } from 'k6';
import { createClient, createBasicAuthClient } from './modules/client.js';
import { createTestOrgIfNotExists, createTestdataDatasourceIfNotExists } from './modules/util.js';
export let options = {
noCookiesReset: true
};
let endpoint = __ENV.URL || 'http://localhost:3000';
const slowQuery = (__ENV.SLOW_QUERY && __ENV.SLOW_QUERY.length > 0) ? parseInt(__ENV.SLOW_QUERY, 10) : 5;
const client = createClient(endpoint);
export const setup = () => {
const basicAuthClient = createBasicAuthClient(endpoint, 'admin', 'admin');
const orgId = createTestOrgIfNotExists(basicAuthClient);
const datasourceId = createTestdataDatasourceIfNotExists(basicAuthClient);
client.withOrgId(orgId);
return {
orgId: orgId,
datasourceId: datasourceId,
};
}
export default (data) => {
group(`user auth token slow test (queries between 1 and ${slowQuery} seconds)`, () => {
if (__ITER === 0) {
group("user authenticates thru ui with username and password", () => {
let res = client.ui.login('admin', 'admin');
check(res, {
'response status is 200': (r) => r.status === 200,
'response has cookie \'grafana_session\' with 32 characters': (r) => r.cookies.grafana_session[0].value.length === 32,
});
});
}
if (__ITER !== 0) {
group('batch tsdb requests', () => {
const batchCount = 20;
const requests = [];
const payload = {
from: '1547765247624',
to: '1547768847624',
queries: [{
refId: 'A',
scenarioId: 'slow_query',
stringInput: `${Math.floor(Math.random() * slowQuery) + 1}s`,
intervalMs: 10000,
maxDataPoints: 433,
datasourceId: data.datasourceId,
}]
};
requests.push({ method: 'GET', url: '/api/annotations?dashboardId=2074&from=1548078832772&to=1548082432772' });
for (let n = 0; n < batchCount; n++) {
requests.push({ method: 'POST', url: '/api/tsdb/query', body: payload });
}
let responses = client.batch(requests);
for (let n = 0; n < batchCount; n++) {
check(responses[n], {
'response status is 200': (r) => r.status === 200,
});
}
});
}
});
sleep(5)
}
export const teardown = (data) => {}

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