mirror of
https://github.com/grafana/grafana.git
synced 2026-01-08 21:22:59 +08:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62b53c3eb7 | ||
|
|
4c305bf2e2 | ||
|
|
092e51408a | ||
|
|
3a2bfb7e38 | ||
|
|
80431256ca | ||
|
|
af364fb91d | ||
|
|
90fe6c5a9f | ||
|
|
399dd583da | ||
|
|
475a0baee1 | ||
|
|
f3e7f878d6 | ||
|
|
a364a86855 | ||
|
|
223f30c71f | ||
|
|
f53c6ebb65 | ||
|
|
bcbe45a745 | ||
|
|
1e32d7bced | ||
|
|
fed38ea617 | ||
|
|
e40dd982c6 | ||
|
|
443a0ba78e | ||
|
|
21bbb7530c | ||
|
|
3478088482 | ||
|
|
d17fb21ecc | ||
|
|
d94eaea64e | ||
|
|
45971205b0 | ||
|
|
3d95eea6ba | ||
|
|
54a092e0a1 | ||
|
|
4437f8af26 | ||
|
|
35213f192c | ||
|
|
1006650ae4 | ||
|
|
f1225330e2 | ||
|
|
4f888d9660 | ||
|
|
969c60e87c | ||
|
|
931dd93d91 | ||
|
|
34a172e133 | ||
|
|
9b764e3a20 | ||
|
|
23aa9b6e45 | ||
|
|
4ba8388f3a | ||
|
|
c3b3ad4380 | ||
|
|
bef64b046c | ||
|
|
4edafb7c8c | ||
|
|
3c0268d671 | ||
|
|
126296826b | ||
|
|
dd75bb67bb | ||
|
|
c31f39ca11 | ||
|
|
e17af53428 | ||
|
|
4d1617c1dd | ||
|
|
3cb8b896dd | ||
|
|
943f661a75 | ||
|
|
b2c1473e59 | ||
|
|
052ea8f63b | ||
|
|
38e88083a3 | ||
|
|
6232cfcdda | ||
|
|
aa7659d1dd | ||
|
|
199031a6e2 | ||
|
|
10d47ab095 |
@@ -1,7 +1,7 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["go", "run", "-mod=vendor", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "-mod=vendor", "build.go", "-dev", "build-server"],
|
||||
["go", "run", "build.go", "-dev", "build-cli"],
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
]
|
||||
watch_all = true
|
||||
@@ -14,6 +14,6 @@ watch_dirs = [
|
||||
watch_exts = [".go", ".ini", ".toml", ".template.html"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["go", "run", "-mod=vendor", "build.go", "-dev", "build-server"],
|
||||
["go", "run", "build.go", "-dev", "build-server"],
|
||||
["./bin/grafana-server", "-packaging=dev", "cfg:app_mode=development"]
|
||||
]
|
||||
|
||||
1650
.circleci/config.yml
1650
.circleci/config.yml
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
21
.github/CODEOWNERS
vendored
21
.github/CODEOWNERS
vendored
@@ -1,21 +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
|
||||
|
||||
# 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
14
.github/ISSUE_TEMPLATE/4-question.md
vendored
Normal 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/)
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -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.
|
||||
@@ -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"]
|
||||
21
.github/actions/gha-publish-to-git/LICENSE
vendored
21
.github/actions/gha-publish-to-git/LICENSE
vendored
@@ -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.
|
||||
60
.github/actions/gha-publish-to-git/README.md
vendored
60
.github/actions/gha-publish-to-git/README.md
vendored
@@ -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'
|
||||
```
|
||||
60
.github/actions/gha-publish-to-git/action.yml
vendored
60
.github/actions/gha-publish-to-git/action.yml
vendored
@@ -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 }}
|
||||
99
.github/actions/gha-publish-to-git/entrypoint.sh
vendored
99
.github/actions/gha-publish-to-git/entrypoint.sh
vendored
@@ -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
47
.github/stale.yml
vendored
@@ -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.
|
||||
30
.github/workflows/publish.yml
vendored
30
.github/workflows/publish.yml
vendored
@@ -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 }}"
|
||||
19
.gitignore
vendored
19
.gitignore
vendored
@@ -10,14 +10,13 @@ awsconfig
|
||||
/public/views/index.html
|
||||
/public/views/error.html
|
||||
/emails/dist
|
||||
/reports
|
||||
.yarnrc
|
||||
.yarn/
|
||||
|
||||
# Enterprise emails
|
||||
/emails/templates/enterprise_*
|
||||
/public/emails/enterprise_*
|
||||
|
||||
/public_gen
|
||||
/public/vendor/npm
|
||||
/tmp
|
||||
tools/phantomjs/phantomjs
|
||||
tools/phantomjs/phantomjs.exe
|
||||
@@ -62,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
|
||||
@@ -91,18 +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
|
||||
/public/e2e-test/screenShots/theOutput
|
||||
/public/e2e-tests/screenShots/theOutput/*.png
|
||||
/public/e2e-tests/videos
|
||||
|
||||
628
CHANGELOG.md
628
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
107
CONTRIBUTING.md
107
CONTRIBUTING.md
@@ -1,67 +1,98 @@
|
||||
# Contributing to Grafana
|
||||
# Contributing
|
||||
|
||||
Thank you for your interest in contributing to Grafana! We welcome all people who want to contribute in a healthy and constructive manner within our community. To help us create a safe and positive community experience for all, we require all participants to adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
Grafana uses GitHub to manage contributions.
|
||||
Contributions take the form of pull requests that will be reviewed by the core team.
|
||||
|
||||
This document is a guide to help you through the process of contributing to Grafana.
|
||||
- If you are a new contributor see: [Steps to Contribute](#steps-to-contribute).
|
||||
|
||||
## Become a contributor
|
||||
- If you have a trivial fix or improvement, go ahead and create a pull request.
|
||||
|
||||
You can contribute to Grafana in several ways. Here are some examples:
|
||||
- If you plan to do something more involved, discuss your idea on the respective [issue](https://github.com/grafana/grafana/issues) or create a [new issue](https://github.com/grafana/grafana/issues/new) if it does not exist. This will avoid unnecessary work and surely give you and us a good deal of inspiration.
|
||||
|
||||
- Contribute to the Grafana codebase.
|
||||
- Report and triage bugs.
|
||||
- Develop community plugins and dashboards.
|
||||
- Write technical documentation and blog posts, for users and contributors.
|
||||
- Organize meetups and user groups in your local area.
|
||||
- Help others by answering questions about Grafana.
|
||||
- Sign our [CLA](http://docs.grafana.org/contribute/cla/).
|
||||
|
||||
For more ways to contribute, check out the [Open Source Guides](https://opensource.guide/how-to-contribute/).
|
||||
- Make sure to follow the code style guides:
|
||||
- [Backend](https://github.com/grafana/grafana/tree/master/pkg)
|
||||
- [Frontend](https://github.com/grafana/grafana/tree/master/style_guides)
|
||||
|
||||
### Report bugs
|
||||
## Steps to contribute
|
||||
|
||||
Report a bug by submitting a [bug report](https://github.com/grafana/grafana/issues/new?labels=type%3A+bug&template=1-bug_report.md). Make sure that you provide as much information as possible on how to reproduce the bug.
|
||||
Should you wish to work on a GitHub issue, check first if it is not already assigned to someone. If it is free, you claim it by commenting on the issue that you want to work on it. This is to prevent duplicated efforts from contributors on the same issue.
|
||||
|
||||
Before submitting a new issue, try to make sure someone hasn't already reported the problem. Look through the [existing issues](https://github.com/grafana/grafana/issues) for similar issues.
|
||||
Please check the [`beginner friendly`](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) and [`help wanted`](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) labels to find issues that are good for getting started. If you have questions about one of the issues, with or without the tag, please comment on them and one of the core team or the original poster will clarify it.
|
||||
|
||||
#### Security issues
|
||||
To setup a local development environment we recommend reading [Building Grafana from source](http://docs.grafana.org/project/building_from_source/).
|
||||
|
||||
If you believe you've found a security vulnerability, please read our [security policy](https://github.com/grafana/grafana/security/policy) for more details.
|
||||
## Pull request checklist
|
||||
|
||||
### Suggest enhancements
|
||||
Whether you are contributing or doing code review, first read and understand https://google.github.io/eng-practices/review/reviewer/ for general engineering practices around code reviews that we also use.
|
||||
|
||||
If you have an idea of how to improve Grafana, submit an [enhancement request](https://github.com/grafana/grafana/issues/new?labels=type%3A+feature+request&template=2-feature_request.md).
|
||||
- Branch from the master branch and, if needed, rebase to the current master branch before submitting your pull request. If it doesn't merge cleanly with master you may be asked to rebase your changes.
|
||||
|
||||
We want to make Grafana accessible to even more people. Submit an [accessibility issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+accessibility&template=3-accessibility.md) to help us understand what we can improve.
|
||||
- If your patch is not getting reviewed or you need a specific person to review it, you can @-reply a reviewer asking for a review in the pull request or a comment.
|
||||
|
||||
### Triage issues
|
||||
- Add tests relevant to the fixed bug or new feature.
|
||||
|
||||
If you don't have the knowledge or time to code, consider helping with _issue triage_. The community will thank you for saving them time by spending some of yours.
|
||||
### High-level checks
|
||||
|
||||
Read more about the ways you can [Triage issues](/contribute/triage-issues.md).
|
||||
- [ ] The pull request adds value and the impact of the change is in line with [Backend](https://github.com/grafana/grafana/tree/master/pkg) or [Frontend](https://github.com/grafana/grafana/tree/master/style_guides).
|
||||
- [ ] The pull request works the way it says it should do.
|
||||
- [ ] The pull request closes one issue if possible and does not fix unrelated issues within the same pull request.
|
||||
- [ ] The pull request contains necessary tests.
|
||||
|
||||
### Answering questions
|
||||
### Low-level checks
|
||||
|
||||
If you have a question and you can't find the answer in the [documentation](https://grafana.com/docs/), the next step is to ask it on the [community site](https://community.grafana.com/).
|
||||
- [ ] The pull request contains a title that explains it. It follows [PR and commit messages guidelines](#Pull-Requests-titles-and-message).
|
||||
- [ ] The pull request contains necessary links to issues.
|
||||
- [ ] The pull request contains commits with messages that are small and understandable. It follows [PR and commit messages guidelines](#Pull-Requests-titles-and-message).
|
||||
- [ ] The pull request does not contain magic strings or numbers that could be replaced with an `Enum` or `const` instead.
|
||||
|
||||
It's important to us to help these users, and we'd love your help. Sign up to our [community site](https://community.grafana.com/), and start helping other Grafana users by answering their questions.
|
||||
#### Bug-specific checks
|
||||
|
||||
### Your first contribution
|
||||
- [ ] The pull request contains `Closes: #Issue` or `Fixes: #Issue` in pull request description.
|
||||
- [ ] The Pull Request adds tests that replicate the fixed bug and helps avoid regressions.
|
||||
|
||||
Unsure where to begin contributing to Grafana? Start by browsing issues labeled `beginner friendly` or `help wanted`.
|
||||
### Frontend-specific checks
|
||||
|
||||
- [Beginner-friendly](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) issues are generally straightforward to complete.
|
||||
- [Help wanted](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issues are problems we would like the community to help us with regardless of complexity.
|
||||
- [ ] The pull request does not increase the Angular code base.
|
||||
> We are in the process of migrating to React so any increment of Angular code is generally discouraged.
|
||||
- [ ] The pull request does not contain uses of `any` or `{}` without comments describing why.
|
||||
- [ ] The pull request does not contain large React components that could easily be split into several smaller components.
|
||||
- [ ] The pull request does not contain back end calls directly from components, use actions and Redux instead.
|
||||
- [ ] The pull request follows our [styling with Emotion convention](./style_guides/styling.md)
|
||||
> We still use a lot of SASS, but any new CSS work should be using or migrating existing code to Emotion
|
||||
|
||||
If you're looking to make a code change, see how to set up your environment for [local development](contribute/developer-guide.md).
|
||||
#### Redux specific checks (skip if your pull request does not contain Redux changes)
|
||||
|
||||
When you're ready to contribute, it's time to [Create a pull request](/contribute/create-pull-request.md).
|
||||
- [ ] The pull request does not contain code that mutates state in reducers or thunks.
|
||||
- [ ] The pull request uses helpers `actionCreatorFactory` and `reducerFactory` instead of traditional `switch statement` reducers in Redux. See [Redux framework](https://github.com/grafana/grafana/tree/master/style_guides/redux.md) for more details.
|
||||
- [ ] The pull request uses `reducerTester` to test reducers. See [Redux framework](https://github.com/grafana/grafana/tree/master/style_guides/redux.md) for more details.
|
||||
- [ ] The pull request does not contain code that accesses the reducers state slice directly, instead, the code uses state selectors to access state.
|
||||
|
||||
#### Contributor License Agreement (CLA)
|
||||
### Pull request titles and message
|
||||
|
||||
Before we can accept your pull request, you need to [sign our CLA](https://grafana.com/docs/contribute/cla/). If you haven't, our CLA assistant prompts you to when you create your pull request.
|
||||
Pull request titles should follow this format: `Area: Name of the change`.
|
||||
Titles are used to generate the changelog so they should be as descriptive as possible in one line.
|
||||
|
||||
## Where do I go from here?
|
||||
Good examples:
|
||||
|
||||
- Set up your [development environment](contribute/developer-guide.md).
|
||||
- Learn how to [contribute documentation](contribute/documentation.md).
|
||||
- Get started [developing plugins](https://grafana.com/docs/plugins/developing/development/) for Grafana.
|
||||
- `Explore: Adds Live option for supported datasources`
|
||||
- `GraphPanel: Don't sort series when legend table & sort column is not visible`
|
||||
- `Build: Support publishing MSI to grafana.com`
|
||||
|
||||
The message in the Pull requests should contain a reference so the issue if there is one. Ex `Closes #<issue number>`, `Fixes #<issue number>`, or `Ref #<issue number>` if the change is related to an issue but does not close it. Make sure to explain what problem the pull request is solving and why its implemented this way. As a new contributor its often better to overcommunicate to avoid back and forth communication, as it consumes time and energy.
|
||||
|
||||
### GIT commit formating.
|
||||
|
||||
Grafana Squash Pull requests when merging them into master. This means the maintainer will be responsible for the title in the git commit message.
|
||||
The commit message of the commits in the Pull Request can still be part of the git commit body. So it's always encouraged to write informative commit messages.
|
||||
|
||||
The Git commit title should be short, descriptive and include the Pull Request ID.
|
||||
|
||||
Good examples:
|
||||
|
||||
- `Explore: Live supprt in datasources (#12345)`
|
||||
- `GraphPanel: Fix legend sorting issues (#12345)`
|
||||
- `Build: Support publishing MSI to grafana.com (#12345)`
|
||||
|
||||
Its also good practice to include a reference to the issue in the git commit body when possible.
|
||||
|
||||
11
Dockerfile
11
Dockerfile
@@ -1,5 +1,5 @@
|
||||
# Golang build container
|
||||
FROM golang:1.13.4-alpine
|
||||
FROM golang:1.12.10-alpine
|
||||
|
||||
RUN apk add --no-cache gcc g++
|
||||
|
||||
@@ -11,12 +11,13 @@ COPY vendor vendor
|
||||
RUN go mod verify
|
||||
|
||||
COPY pkg pkg
|
||||
COPY build.go package.json ./
|
||||
COPY build.go build.go
|
||||
COPY package.json package.json
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
# Node build container
|
||||
FROM node:12.13.0-alpine
|
||||
FROM node:10.14.2-alpine
|
||||
|
||||
# PhantomJS
|
||||
RUN apk add --no-cache curl &&\
|
||||
@@ -35,7 +36,7 @@ COPY packages packages
|
||||
|
||||
RUN yarn install --pure-lockfile --no-progress
|
||||
|
||||
COPY Gruntfile.js tsconfig.json .eslintrc .editorconfig .browserslistrc ./
|
||||
COPY Gruntfile.js tsconfig.json tslint.json .browserslistrc ./
|
||||
COPY public public
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
@@ -51,7 +52,7 @@ LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
ARG GF_UID="472"
|
||||
ARG GF_GID="472"
|
||||
|
||||
ENV PATH="/usr/share/grafana/bin:$PATH" \
|
||||
ENV PATH=/usr/share/grafana/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
|
||||
GF_PATHS_DATA="/var/lib/grafana" \
|
||||
GF_PATHS_HOME="/usr/share/grafana" \
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
FROM golang:1.13.4 AS go-builder
|
||||
|
||||
WORKDIR /src/grafana
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
COPY vendor vendor/
|
||||
|
||||
RUN go mod verify
|
||||
|
||||
COPY build.go package.json ./
|
||||
COPY pkg pkg/
|
||||
|
||||
RUN go run build.go build
|
||||
|
||||
FROM node:12.13 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 .eslintrc .editorconfig .browserslistrc ./
|
||||
COPY public public
|
||||
COPY scripts scripts
|
||||
COPY emails emails
|
||||
|
||||
ENV NODE_ENV production
|
||||
RUN ./node_modules/.bin/grunt build
|
||||
|
||||
FROM ubuntu:19.10
|
||||
|
||||
LABEL maintainer="Grafana team <hello@grafana.com>"
|
||||
EXPOSE 3000
|
||||
|
||||
ARG GF_UID="472"
|
||||
ARG GF_GID="472"
|
||||
|
||||
ENV PATH="/usr/share/grafana/bin:$PATH" \
|
||||
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
|
||||
GF_PATHS_DATA="/var/lib/grafana" \
|
||||
GF_PATHS_HOME="/usr/share/grafana" \
|
||||
GF_PATHS_LOGS="/var/log/grafana" \
|
||||
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
|
||||
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"
|
||||
|
||||
WORKDIR $GF_PATHS_HOME
|
||||
|
||||
COPY conf conf
|
||||
|
||||
# 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 && \
|
||||
adduser --uid $GF_UID --system --ingroup grafana grafana && \
|
||||
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
|
||||
"$GF_PATHS_PROVISIONING/dashboards" \
|
||||
"$GF_PATHS_PROVISIONING/notifiers" \
|
||||
"$GF_PATHS_LOGS" \
|
||||
"$GF_PATHS_PLUGINS" \
|
||||
"$GF_PATHS_DATA" && \
|
||||
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
|
||||
cp conf/ldap.toml /etc/grafana/ldap.toml && \
|
||||
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
|
||||
ENTRYPOINT [ "/run.sh" ]
|
||||
@@ -10,7 +10,6 @@ module.exports = function (grunt) {
|
||||
tempDir: 'tmp',
|
||||
platform: process.platform.replace('win32', 'windows'),
|
||||
enterprise: false,
|
||||
libc: null,
|
||||
};
|
||||
|
||||
if (grunt.option('platform')) {
|
||||
@@ -31,10 +30,6 @@ module.exports = function (grunt) {
|
||||
}
|
||||
}
|
||||
|
||||
if (grunt.option('libc')) {
|
||||
config.libc = grunt.option('libc');
|
||||
}
|
||||
|
||||
config.phjs = grunt.option('phjsToRelease');
|
||||
config.pkg.version = grunt.option('pkgVer') || config.pkg.version;
|
||||
|
||||
@@ -47,7 +42,7 @@ module.exports = function (grunt) {
|
||||
grunt.loadTasks('./scripts/grunt');
|
||||
|
||||
// Utility function to load plugin settings into config
|
||||
function loadConfig(config, path) {
|
||||
function loadConfig(config,path) {
|
||||
require('glob').sync('*', {cwd: path}).forEach(function(option) {
|
||||
var key = option.replace(/\.js$/,'');
|
||||
// If key already exists, extend it. It is your responsibility to avoid naming collisions
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
# Triage issues
|
||||
Triaging of issues
|
||||
------------------
|
||||
|
||||
The main goal of issue triage is to categorize all incoming Grafana issues and make sure each issue has all basic information needed for anyone else to understand and be able to start working on it.
|
||||
Grafana being a popular open source project there are a lot of incoming issues. The main goal of issue triage is to categorize all incoming issues and make sure it has all basic information needed for anyone else to understand and/or being able to start working with it.
|
||||
|
||||
**Note:** This information is for Grafana project Maintainers, Owners, and Admins. If you are a Contributor, then you will not be able to perform most of the tasks in this topic.
|
||||
The core maintainers of the Grafana project is responsible for categorizing all incoming issues and delegate any critical and/or important issue to other maintainers. Currently there's one maintainer each week responsible. Besides that part, triage provides an important way to contribute to an open source project. Triage helps ensure issues resolve quickly by:
|
||||
|
||||
The core maintainers of the Grafana project are responsible for categorizing all incoming issues and delegating any critical or important issue to other maintainers. Currently one maintainer each week is responsible. Besides that part, triage provides an important way to contribute to an open source project.
|
||||
|
||||
Triage helps ensure issues resolve quickly by:
|
||||
|
||||
* Ensuring the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took.
|
||||
* Describing the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took.
|
||||
* Giving a contributor the information they need before they commit to resolving an issue.
|
||||
* Lowering the issue count by preventing duplicate issues.
|
||||
* Streamlining the development process by preventing duplicate discussions.
|
||||
* If you don't have the knowledge or time to code, consider helping with triage. The community will thank you for saving them time by spending some of yours.
|
||||
|
||||
If you don't have the knowledge or time to code, consider helping with triage. The community will thank you for saving them time by spending some of yours.
|
||||
|
||||
## Simplified flowchart diagram of the issue triage process
|
||||
|
||||
**Simplified flowchart diagram of the issue triage process:**
|
||||
<!-- https://textik.com/#610afa78553def29 -->
|
||||
```
|
||||
+--------------------------+
|
||||
@@ -58,6 +53,66 @@ If you don't have the knowledge or time to code, consider helping with triage. T
|
||||
+------------------+ +--------------+
|
||||
```
|
||||
|
||||
## How you can help
|
||||
|
||||
There are multiple ways that you can help with the Grafana project, especially without writing a single line of code. Everyone in the Grafana community will be greatly thankful you for helping out with any of the below tasks.
|
||||
|
||||
### Answer/ask questions
|
||||
|
||||
The [community site](https://community.grafana.com/) is the main channel to be used for asking and answering questions related to the Grafana project. This may be the first place a new or existing Grafana user look/ask for help after they found that the [documentation](https://grafana.com/docs) wasn't answering their questions. It's very important to help new and existing users so that these new users can find proper answers and eventually help out other users and by that keep growing the Grafana community.
|
||||
|
||||
Please signup to the Grafana [community site](https://community.grafana.com/) and start help other Grafana users by answering their questions and/or ask for help.
|
||||
|
||||
### Report documentation enhancements
|
||||
|
||||
If you visit the [documentation site](https://grafana.com/docs) and find typos/error/lack of information please report these by clicking on the `Request doc changes` link found on every page and/or contribute the changes yourself by clicking on `Edit this page` and open a pull request. Everyone in the community will greatly thank you for.
|
||||
|
||||
Please read about how documentation issues is triaged [below](#documentation-issue) to understand what kind of documentation may be suitable to request/add.
|
||||
|
||||
### Report a security vulnerability
|
||||
|
||||
Please review the [security policy](https://github.com/grafana/grafana/security/policy) for more details.
|
||||
|
||||
### Report bugs
|
||||
|
||||
Report a bug you found when using Grafana by [opening a new bug report](https://github.com/grafana/grafana/issues/new?labels=type%3A+bug&template=1-bug_report.md).
|
||||
|
||||
### Request enhancements/new features
|
||||
|
||||
Suggest an enhancement or new feature for the Grafana project by [opening a new enhancement issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+feature+request&template=2-feature_request.md).
|
||||
|
||||
Alternatively, help make Grafana be better at being accessible to all by [opening a new accessibility issue](https://github.com/grafana/grafana/issues/new?labels=type%3A+accessibility&template=3-accessibility.md).
|
||||
|
||||
### Report inaccurate issue information
|
||||
|
||||
If you find an issue that have a badly formatted title and/or description, bad language/grammar and/or wrong labels it's important to let the issue author or maintainers know so it can be fixed. See [good practices](#good-practices) regarding basic information for issues below.
|
||||
|
||||
### Request closing of issues
|
||||
|
||||
The Grafana project have a lot of open issues and the main goal is to only have issues open if their still relevant. If you find an issue that you think already have been resolved or no longer is relevant please report by adding a comment and explain why you think it should be closed including related issues (`#<issue number>`), if applicable, and optionally mention one of the maintainers.
|
||||
|
||||
### Investigate issues
|
||||
|
||||
See [investigation of issues](#investigation-of-issues).
|
||||
|
||||
### Vote on enhancements/bugs
|
||||
|
||||
Helping the Grafana project to know which issues are most important by users and the community is crucial for the success of the project. Read more about [prioritizing issues](#4-prioritization-of-issues) for details about how issues are being prioritized. The Grafana project use GitGub issues and reactions for collecting votes on enhancement and bugs.
|
||||
|
||||
**Please don't add `+1` issue comments or similar since that will notify everyone that have subscribed to an issue and it doesn't add any useful update, rather it creates a bad habit.**
|
||||
|
||||
If you want to show your interest or importance of an issue, please use [GitHub's reactions](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments).
|
||||
|
||||
### Report duplicates
|
||||
|
||||
If you find two issues describing the same bug/enhancement/feature please add a comment in one of the issue and explain which issues (`#<issue number>`) you think is a duplicate of another issue (`#<issue number>`).
|
||||
|
||||
### Suggest ideas for resolving bugs/enhancements
|
||||
|
||||
Related to how [issues are being prioritized](#4-prioritization-of-issues) it's important to help anyone that's interested in contributing code for resolving a bug or enhancement. This can be anything from getting started and setup the development environment to reference code and files where changes probably needs to be made and/or suggest ideas on how enhancements may function/be implemented.
|
||||
|
||||
Please read about how [help from the community](#5-requesting-help-from-the-community) may be requested when issues being triaged.
|
||||
|
||||
## 1. Find uncategorized issues
|
||||
|
||||
To get started with issue triage and finding issues that haven't been triaged you have two alternatives.
|
||||
@@ -135,7 +190,7 @@ If you receive a notification with additional information provided but you are n
|
||||
An issue can have multiple of the following labels. Typically, a properly categorized issue should at least have:
|
||||
|
||||
- One label identifying its type (`type/*`).
|
||||
- One or multiple labels identifying the functional areas of interest or component (`area/*`) and/or data source (`datasource/*`), if applicable.
|
||||
- One or multiple labels identifying the functional areas of interest or component (`area/*`) and/or datasource (`datasource/*`), if applicable.
|
||||
|
||||
Label | Description
|
||||
------- | --------
|
||||
@@ -148,7 +203,7 @@ Label | Description
|
||||
`type/works-as-intended` | A reported bug works as intended/by design.
|
||||
`type/build-packaging` | Build or packaging problem or enhancement.
|
||||
`area/*` | Subject is related to a functional area of interest or component.
|
||||
`datasource/*` | Subject is related to a core data source plugin.
|
||||
`datasource/*` | Subject is related to a core datasource plugin.
|
||||
|
||||
### Duplicate issue?
|
||||
|
||||
@@ -294,7 +349,7 @@ In many cases the issue author or community as a whole is more suitable to contr
|
||||
|
||||
When an issue has all basic information provided, but the triage responsible haven't been able to reproduce the reported problem at a first glance, the issue is labeled [Needs investigation](https://github.com/grafana/grafana/labels/needs%20investigation). Depending of the perceived severity and/or number of [upvotes](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments), the investigation will either be delegated to another maintainer for further investigation or either put on hold until someone else (maintainer or contributor) picks it up and eventually start investigating it.
|
||||
|
||||
Investigating issues can be a very time consuming task, especially for the maintainers given the huge number of combinations of plugins, data sources, platforms, databases, browsers, tools, hardware, integrations, versions and cloud services etc that are being used with Grafana. There are a certain amount of combinations that are more common than others and these are in general easier for maintainers to investigate.
|
||||
Investigating issues can be a very time consuming task, especially for the maintainers given the huge number of combinations of plugins, datasources, platforms, databases, browsers, tools, hardware, integrations, versions and cloud services etc that are being used with Grafana. There are a certain amount of combinations that are more common than others and these are in general easier for maintainers to investigate.
|
||||
|
||||
For some other combinations there may not be possible at all for a maintainer to setup a proper test environment for being able to investigate. In these cases we really appreciate any help we can get from the community. Otherwise the issue is highly likely to be closed.
|
||||
|
||||
|
||||
151
Makefile
151
Makefile
@@ -1,10 +1,6 @@
|
||||
## This is a self-documented Makefile. For usage information, run `make help`:
|
||||
##
|
||||
## For more information, refer to https://suva.sh/posts/well-documented-makefiles/
|
||||
|
||||
-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 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
|
||||
|
||||
GO = GO111MODULE=on go
|
||||
GO_FILES ?= ./pkg/...
|
||||
@@ -12,66 +8,76 @@ SH_FILES ?= $(shell find ./scripts -name *.sh)
|
||||
|
||||
all: deps build
|
||||
|
||||
##@ Dependencies
|
||||
|
||||
deps-go: ## Install backend dependencies.
|
||||
deps-go:
|
||||
$(GO) run build.go setup
|
||||
|
||||
deps-js: node_modules ## Install frontend dependencies.
|
||||
deps-js: node_modules
|
||||
|
||||
deps: deps-js ## Install all dependencies.
|
||||
deps: deps-js
|
||||
|
||||
node_modules: package.json yarn.lock ## Install node modules.
|
||||
@echo "install frontend dependencies"
|
||||
yarn install --pure-lockfile --no-progress
|
||||
|
||||
##@ Building
|
||||
|
||||
build-go: ## Build all Go binaries.
|
||||
build-go:
|
||||
@echo "build go files"
|
||||
$(GO) run build.go build
|
||||
|
||||
build-server: ## Build Grafana server.
|
||||
build-server:
|
||||
@echo "build server"
|
||||
$(GO) run build.go build-server
|
||||
|
||||
build-cli: ## Build Grafana CLI application.
|
||||
build-cli:
|
||||
@echo "build in CI environment"
|
||||
$(GO) run build.go build-cli
|
||||
|
||||
build-js: ## Build frontend assets.
|
||||
build-js:
|
||||
@echo "build frontend"
|
||||
yarn run build
|
||||
|
||||
build: build-go build-js ## Build backend and frontend.
|
||||
build: build-go build-js
|
||||
|
||||
build-docker-dev:
|
||||
@echo "build development container"
|
||||
@echo "\033[92mInfo:\033[0m the frontend code is expected to be built already."
|
||||
$(GO) run build.go -goos linux -pkg-arch amd64 ${OPT} build pkg-archive latest
|
||||
cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
cd packaging/docker && docker build --tag grafana/grafana:dev .
|
||||
|
||||
build-docker-full:
|
||||
@echo "build docker container"
|
||||
docker build --tag grafana/grafana:dev .
|
||||
|
||||
test-go:
|
||||
@echo "test backend"
|
||||
$(GO) test -v ./pkg/...
|
||||
|
||||
test-js:
|
||||
@echo "test frontend"
|
||||
yarn test
|
||||
|
||||
test: test-go test-js
|
||||
|
||||
clean:
|
||||
@echo "cleaning"
|
||||
rm -rf node_modules
|
||||
rm -rf public/build
|
||||
|
||||
node_modules: package.json yarn.lock
|
||||
@echo "install frontend dependencies"
|
||||
yarn install --pure-lockfile --no-progress
|
||||
|
||||
scripts/go/bin/revive: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/revive github.com/mgechev/revive
|
||||
|
||||
scripts/go/bin/gosec: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/gosec github.com/securego/gosec/cmd/gosec
|
||||
|
||||
scripts/go/bin/bra: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/bra github.com/unknwon/bra
|
||||
|
||||
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.
|
||||
@echo "test backend"
|
||||
$(GO) test -v ./pkg/...
|
||||
|
||||
test-js: ## Run tests for frontend.
|
||||
@echo "test frontend"
|
||||
yarn test
|
||||
|
||||
test: test-go test-js ## Run all tests.
|
||||
|
||||
##@ Linting
|
||||
|
||||
scripts/go/bin/revive: scripts/go/go.mod
|
||||
scripts/go/bin/golangci-lint: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/revive github.com/mgechev/revive
|
||||
$(GO) build -o ./bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
|
||||
revive: scripts/go/bin/revive
|
||||
@echo "lint via revive"
|
||||
@@ -86,9 +92,13 @@ revive-alerting: scripts/go/bin/revive
|
||||
-formatter stylish \
|
||||
./pkg/services/alerting/...
|
||||
|
||||
scripts/go/bin/golangci-lint: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
# TODO recheck the rules and leave only necessary exclusions
|
||||
gosec: scripts/go/bin/gosec
|
||||
@echo "lint via gosec"
|
||||
@scripts/go/bin/gosec -quiet \
|
||||
-exclude=G104,G107,G201,G202,G204,G301,G304,G401,G402,G501 \
|
||||
-conf=./scripts/go/configs/gosec.json \
|
||||
$(GO_FILES)
|
||||
|
||||
golangci-lint: scripts/go/bin/golangci-lint
|
||||
@echo "lint via golangci-lint"
|
||||
@@ -96,43 +106,19 @@ golangci-lint: scripts/go/bin/golangci-lint
|
||||
--config ./scripts/go/configs/.golangci.yml \
|
||||
$(GO_FILES)
|
||||
|
||||
scripts/go/bin/gosec: scripts/go/go.mod
|
||||
@cd scripts/go; \
|
||||
$(GO) build -o ./bin/gosec github.com/securego/gosec/cmd/gosec
|
||||
|
||||
# TODO recheck the rules and leave only necessary exclusions
|
||||
gosec: scripts/go/bin/gosec
|
||||
@echo "lint via gosec"
|
||||
@scripts/go/bin/gosec -quiet \
|
||||
-exclude=G104,G107,G108,G201,G202,G204,G301,G304,G401,G402,G501 \
|
||||
-conf=./scripts/go/configs/gosec.json \
|
||||
$(GO_FILES)
|
||||
|
||||
go-vet:
|
||||
@echo "lint via go vet"
|
||||
@$(GO) vet $(GO_FILES)
|
||||
|
||||
lint-go: go-vet golangci-lint revive revive-alerting gosec ## Run all code checks for backend.
|
||||
lint-go: go-vet golangci-lint revive revive-alerting gosec
|
||||
|
||||
# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts
|
||||
shellcheck: $(SH_FILES) ## Run checks for shell scripts.
|
||||
shellcheck: $(SH_FILES)
|
||||
@docker run --rm -v "$$PWD:/mnt" koalaman/shellcheck:stable \
|
||||
$(SH_FILES) -e SC1071 -e SC2162
|
||||
$(SH_FILES) -e SC1071
|
||||
|
||||
##@ Docker
|
||||
|
||||
build-docker-dev: ## Build Docker image for development (fast).
|
||||
@echo "build development container"
|
||||
@echo "\033[92mInfo:\033[0m the frontend code is expected to be built already."
|
||||
$(GO) run build.go -goos linux -pkg-arch amd64 ${OPT} build pkg-archive latest
|
||||
cp dist/grafana-latest.linux-x64.tar.gz packaging/docker
|
||||
cd packaging/docker && docker build --tag grafana/grafana:dev .
|
||||
|
||||
build-docker-full: ## Build Docker image for development.
|
||||
@echo "build docker container"
|
||||
docker build --tag grafana/grafana:dev .
|
||||
|
||||
##@ Services
|
||||
run: scripts/go/bin/bra
|
||||
@scripts/go/bin/bra run
|
||||
|
||||
# create docker-compose file with provided sources and start them
|
||||
# example: make devenv sources=postgres,openldap
|
||||
@@ -140,7 +126,7 @@ ifeq ($(sources),)
|
||||
devenv:
|
||||
@printf 'You have to define sources for this command \nexample: make devenv sources=postgres,openldap\n'
|
||||
else
|
||||
devenv: devenv-down ## Start optional services, e.g. postgres, prometheus, and elasticsearch.
|
||||
devenv: devenv-down
|
||||
$(eval targets := $(shell echo '$(sources)' | tr "," " "))
|
||||
|
||||
@cd devenv; \
|
||||
@@ -151,17 +137,8 @@ devenv: devenv-down ## Start optional services, e.g. postgres, prometheus, and e
|
||||
docker-compose up -d --build
|
||||
endif
|
||||
|
||||
devenv-down: ## Stop optional services.
|
||||
# drop down the envs
|
||||
devenv-down:
|
||||
@cd devenv; \
|
||||
test -f docker-compose.yaml && \
|
||||
docker-compose down || exit 0;
|
||||
|
||||
##@ Helpers
|
||||
|
||||
clean: ## Clean up intermediate build artifacts.
|
||||
@echo "cleaning"
|
||||
rm -rf node_modules
|
||||
rm -rf public/build
|
||||
|
||||
help: ## Display this help.
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
# Plugin development
|
||||
# Plugin Development
|
||||
|
||||
This document is not meant as a complete guide for developing plugins but more as a changelog for changes in
|
||||
Grafana that can impact plugin development. Whenever you as a plugin author encounter an issue with your plugin after
|
||||
upgrading Grafana please check here before creating an issue.
|
||||
|
||||
## Plugin development resources
|
||||
## Links
|
||||
|
||||
- [Grafana plugin developer guide](http://docs.grafana.org/plugins/developing/development/)
|
||||
- [Webpack Grafana plugin template project](https://github.com/CorpGlory/grafana-plugin-template-webpack)
|
||||
- [Datasource plugin written in TypeScript](https://github.com/grafana/typescript-template-datasource)
|
||||
- [Simple JSON datasource plugin](https://github.com/grafana/simple-json-datasource)
|
||||
- [Plugin development guide](http://docs.grafana.org/plugins/developing/development/)
|
||||
- [Webpack Grafana plugin template project](https://github.com/CorpGlory/grafana-plugin-template-webpack)
|
||||
|
||||
## Changes in Grafana v4.6
|
||||
## Changes in v4.6
|
||||
|
||||
This version of Grafana has big changes that will impact a limited set of plugins. We moved from systemjs to webpack
|
||||
for built-in plugins and everything internal. External plugins still use systemjs but now with a limited
|
||||
for built-in plugins & everything internal. External plugins still use systemjs but now with a limited
|
||||
set of Grafana components they can import. Plugins can depend on libs like lodash & moment and internal components
|
||||
like before using the same import paths. However since everything in Grafana is no longer accessible, a few plugins could encounter issues when importing a Grafana dependency.
|
||||
|
||||
@@ -24,10 +25,10 @@ If you think we missed exposing a crucial lib or Grafana component let us know b
|
||||
### Deprecated components
|
||||
|
||||
The angular directive `<spectrum-picker>` is now deprecated (will still work for a version more) but we recommend plugin authors
|
||||
upgrade to new `<color-picker color="ctrl.color" onChange="ctrl.onSparklineColorChange"></color-picker>`
|
||||
to upgrade to new `<color-picker color="ctrl.color" onChange="ctrl.onSparklineColorChange"></color-picker>`
|
||||
|
||||
## Changes in Grafana v6.0
|
||||
## Changes in v6.0
|
||||
|
||||
### DashboardSrv.ts
|
||||
|
||||
If you utilize [DashboardSrv](https://github.com/grafana/grafana/commit/8574dca081002f36e482b572517d8f05fd44453f#diff-1ab99561f9f6a10e1fafcddc39bc1d65) in your plugin code, `dash` was renamed to `dashboard`.
|
||||
If you utilize [DashboardSrv](https://github.com/grafana/grafana/commit/8574dca081002f36e482b572517d8f05fd44453f#diff-1ab99561f9f6a10e1fafcddc39bc1d65) in your plugin code, `dash` was renamed to `dashboard`
|
||||
|
||||
235
README.md
235
README.md
@@ -1,46 +1,223 @@
|
||||

|
||||
# [Grafana](https://grafana.com) [](https://circleci.com/gh/grafana/grafana) [](https://goreportcard.com/report/github.com/grafana/grafana)
|
||||
|
||||
The open-source platform for monitoring and observability.
|
||||
[Website](https://grafana.com) |
|
||||
[Twitter](https://twitter.com/grafana) |
|
||||
[Community & Forum](https://community.grafana.com)
|
||||
|
||||
[](LICENSE)
|
||||
[](https://circleci.com/gh/grafana/grafana)
|
||||
[](https://goreportcard.com/report/github.com/grafana/grafana)
|
||||
Grafana is an open source, feature rich metrics dashboard and graph editor for
|
||||
Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB.
|
||||
|
||||
Grafana allows you to query, visualize, alert on and understand your metrics no matter where they are stored. Create, explore, and share dashboards with your team and foster a data driven culture:
|
||||
<!---
|
||||

|
||||
-->
|
||||
|
||||
- **Visualize:** Fast and flexible client side graphs with a multitude of options. Panel plugins for many different way to visualize metrics and logs.
|
||||
- **Dynamic Dashboards:** Create dynamic & reusable dashboards with template variables that appear as dropdowns at the top of the dashboard.
|
||||
- **Explore Metrics:** Explore your data through ad-hoc queries and dynamic drilldown. Split view and compare different time ranges, queries and data sources side by side.
|
||||
- **Explore Logs:** Experience the magic of switching from metrics to logs with preserved label filters. Quickly search through all your logs or streaming them live.
|
||||
- **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.
|
||||
## Installation
|
||||
|
||||
## Get started
|
||||
Head to [docs.grafana.org](http://docs.grafana.org/installation/) for documentation or [download](https://grafana.com/get) to get the latest release.
|
||||
|
||||
- [Get Grafana](https://grafana.com/get)
|
||||
- [Installation guides](http://docs.grafana.org/installation/)
|
||||
## Documentation & Support
|
||||
|
||||
Unsure if Grafana is for you? Watch Grafana in action on [play.grafana.org](https://play.grafana.org/)!
|
||||
Be sure to read the [getting started guide](http://docs.grafana.org/guides/gettingstarted/) and the other feature guides.
|
||||
|
||||
## Documentation
|
||||
## Run from master
|
||||
|
||||
The Grafana documentation is available at [grafana.com/docs](https://grafana.com/docs/).
|
||||
If you want to build a package yourself, or contribute - here is a guide for how to do that. You can always find
|
||||
the latest master builds [here](https://grafana.com/grafana/download).
|
||||
|
||||
## Contributing
|
||||
### Dependencies
|
||||
|
||||
If you're interested in contributing to the Grafana project:
|
||||
- Go (Latest Stable)
|
||||
- Node.js LTS
|
||||
- yarn [`npm install -g yarn`]
|
||||
|
||||
- Start by reading the [Contributing guide](/CONTRIBUTING.md).
|
||||
- Learn how to set up your local environment, in our [Developer guide](/contribute/developer-guide.md).
|
||||
- Explore our [beginner-friendly issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22).
|
||||
### Get the project
|
||||
|
||||
## Get involved
|
||||
**The project located in the go-path will be your working directory.**
|
||||
|
||||
- Follow [@grafana on Twitter](https://twitter.com/grafana/)
|
||||
- Read and subscribe to the [Grafana blog](https://grafana.com/blog/)
|
||||
- If you have a specific question, check out our [discussion forums](https://community.grafana.com/).
|
||||
- For general discussions, join us on the [official Slack](http://slack.raintank.io/) team.
|
||||
```bash
|
||||
go get github.com/grafana/grafana
|
||||
cd $GOPATH/src/github.com/grafana/grafana
|
||||
```
|
||||
|
||||
### Run and rebuild on source change
|
||||
|
||||
#### Backend
|
||||
|
||||
To run the backend and rebuild on source change:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
#### Frontend
|
||||
Install front-end dependencies first:
|
||||
|
||||
```bash
|
||||
yarn install --pure-lockfile
|
||||
```
|
||||
|
||||
Rebuild on file change, and serve them by Grafana's webserver (http://localhost:3000):
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
Build the assets, rebuild on file change with Hot Module Replacement (HMR), and serve them by webpack-dev-server (http://localhost:3333):
|
||||
|
||||
```bash
|
||||
yarn start:hot
|
||||
# OR set a theme
|
||||
env GRAFANA_THEME=light yarn start:hot
|
||||
```
|
||||
|
||||
_Note: HMR for Angular is not supported. If you edit files in the Angular part of the app, the whole page will reload._
|
||||
|
||||
Run tests and rebuild on source change:
|
||||
|
||||
```bash
|
||||
yarn jest
|
||||
```
|
||||
|
||||
**Open grafana in your browser (default: e.g. `http://localhost:3000`) and login with admin user (default: `user/pass = admin/admin`).**
|
||||
|
||||
### Building
|
||||
|
||||
#### The backend
|
||||
|
||||
```bash
|
||||
go run build.go setup
|
||||
go run build.go build
|
||||
```
|
||||
|
||||
#### Frontend assets
|
||||
|
||||
_For this you need Node.js (LTS version)._
|
||||
|
||||
```bash
|
||||
yarn install --pure-lockfile
|
||||
```
|
||||
|
||||
### Building a Docker image
|
||||
|
||||
There are two different ways to build a Grafana docker image. If your machine is setup for Grafana development and you run linux/amd64 you can build just the image. Otherwise, there is the option to build Grafana completely within Docker.
|
||||
|
||||
Run the image you have built using: `docker run --rm -p 3000:3000 grafana/grafana:dev`
|
||||
|
||||
#### Building on linux/amd64 (fast)
|
||||
|
||||
1. Build the frontend `go run build.go build-frontend`.
|
||||
2. Build the docker image `make build-docker-dev`.
|
||||
|
||||
The resulting image will be tagged as `grafana/grafana:dev`.
|
||||
|
||||
#### Building anywhere (slower)
|
||||
|
||||
Choose this option to build on platforms other than linux/amd64 and/or not have to setup the Grafana development environment.
|
||||
|
||||
1. `make build-docker-full` or `docker build -t grafana/grafana:dev`.
|
||||
|
||||
The resulting image will be tagged as `grafana/grafana:dev`.
|
||||
|
||||
Notice: If you are using Docker for MacOS, be sure to set the memory limit to be larger than 2 GiB (at docker -> Preferences -> Advanced), otherwise `grunt build` may fail.
|
||||
|
||||
## Development
|
||||
|
||||
### Dev config
|
||||
|
||||
Create a custom.ini in the conf directory to override default configuration options.
|
||||
You only need to add the options you want to override. Config files are applied in the order of:
|
||||
|
||||
1. grafana.ini
|
||||
1. custom.ini
|
||||
|
||||
In your custom.ini uncomment (remove the leading `;`) sign. And set `app_mode = development`.
|
||||
|
||||
### Running tests
|
||||
|
||||
#### Frontend
|
||||
|
||||
Execute all frontend tests:
|
||||
|
||||
```bash
|
||||
yarn test
|
||||
```
|
||||
|
||||
Write and watch frontend tests:
|
||||
|
||||
- Start watcher: `yarn jest`.
|
||||
- Jest runs all test files that end with the name ".test.ts".
|
||||
|
||||
#### Backend
|
||||
|
||||
```bash
|
||||
# Run Golang tests using sqlite3 as database (default)
|
||||
go test ./pkg/...
|
||||
```
|
||||
|
||||
##### Running the MySQL or Postgres backend tests:
|
||||
|
||||
Run these by setting `GRAFANA_TEST_DB` in your environment.
|
||||
|
||||
- `GRAFANA_TEST_DB=mysql` to test MySQL
|
||||
- `GRAFANA_TEST_DB=postgres` to test Postgres
|
||||
|
||||
Follow the instructions in `./devenv` to spin up test containers running the appropriate databases with `docker-compose`
|
||||
- Use `docker/blocks/mysql_tests` or `docker/blocks/postgres_tests` as appropriate.
|
||||
|
||||
```bash
|
||||
# MySQL
|
||||
# Tests can only be ran in one Go package at a time due to clashing db queries. To run MySQL tests for the "pkg/services/sqlstore" package, run:
|
||||
GRAFANA_TEST_DB=mysql go test ./pkg/services/sqlstore/...
|
||||
|
||||
# Or run all the packages using the circle CI scripts. This method will be slower as the scripts will run all the tests, including the integration tests.
|
||||
./scripts/circle-test-mysql.sh
|
||||
```
|
||||
|
||||
```bash
|
||||
# Postgres
|
||||
# Tests can only be ran in one Go package at a time due to clashing db queries. To run Postgres tests for the "pkg/services/sqlstore" package, run:
|
||||
GRAFANA_TEST_DB=postgres go test ./pkg/services/sqlstore/...
|
||||
|
||||
# Or run all the packages using the circle CI scripts. This method will be slower as the scripts will run all the tests, including the integration tests.
|
||||
./scripts/circle-test-postgres.sh
|
||||
```
|
||||
|
||||
#### End-to-end
|
||||
|
||||
Execute all end-to-end tests:
|
||||
|
||||
```bash
|
||||
yarn e2e-tests
|
||||
```
|
||||
|
||||
Execute all end-to-end tests using using a specific url:
|
||||
|
||||
```bash
|
||||
ENV BASE_URL=http://localhost:3333 yarn e2e-tests
|
||||
```
|
||||
|
||||
Debugging all end-to-end tests (BROWSER=1 starts the browser and SLOWMO=1 delays each puppeteer operation by 100ms):
|
||||
|
||||
```bash
|
||||
ENV BROWSER=1 SLOWMO=1 yarn e2e-tests
|
||||
```
|
||||
|
||||
### Datasource and dashboard provisioning
|
||||
|
||||
[Here](https://github.com/grafana/grafana/tree/master/devenv) you can find helpful scripts and docker-compose setup
|
||||
that will populate your dev environment for quicker testing and experimenting.
|
||||
|
||||
## Contribute
|
||||
|
||||
If you have any ideas for improvement or have found a bug, do not hesitate to open an issue.
|
||||
And if you have time, clone this repo and submit a pull request to help me make Grafana the kickass metrics and devops dashboard we all dream about!
|
||||
|
||||
Read the [contributing](https://github.com/grafana/grafana/blob/master/CONTRIBUTING.md) guide then check the [`beginner friendly`](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3A%22beginner+friendly%22) label to find issues that are easy and that we would like help with.
|
||||
|
||||
## Plugin development
|
||||
|
||||
Checkout the [Plugin Development Guide](http://docs.grafana.org/plugins/developing/development/) and checkout the [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) file for changes in Grafana that relate to plugin development.
|
||||
|
||||
## License
|
||||
|
||||
Grafana is distributed under the [Apache 2.0 License](https://github.com/grafana/grafana/blob/master/LICENSE).
|
||||
Grafana is distributed under [Apache 2.0 License](https://github.com/grafana/grafana/blob/master/LICENSE).
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Roadmap
|
||||
|
||||
The roadmap is a tentative plan for the core development team. Things change constantly as pull requests come in and priorities change, but it will give you an idea of our current vision and plan.
|
||||
This roadmap is a tentative plan for the core development team. Things change constantly as PRs come in and priorities change.
|
||||
But it will give you an idea of our current vision and plan.
|
||||
|
||||
To view the Roadmap, go to the Issues tab on GitHub. There you will find three roadmap issues pinned at the top.
|
||||
Go to the Issues tab on GitHub. There you will find, at the top, 3 pinned roadmap issues.
|
||||
|
||||
15
SECURITY.md
15
SECURITY.md
@@ -1,8 +1,7 @@
|
||||
# Reporting security issues
|
||||
Reporting Security Issues
|
||||
------------------
|
||||
|
||||
If you think you have found a security vulnerability, please send a report to [security@grafana.com](mailto:security@grafana.com). This address can be used for all of Grafana Labs's open source and commercial products (including but not limited to Grafana, Grafana Cloud, Grafana Enterprise, and grafana.com). We can accept only vulnerability reports at this address.
|
||||
|
||||
Please encrypt your message to us; please use our PGP key. The key fingerprint is:
|
||||
If you think you have found a security vulnerability, please send a report to [security@grafana.com](mailto:security@grafana.com). This address can be used for all of Grafana Labs's open source and commercial products (including but not limited to Grafana, Grafana Cloud, Grafana Enterprise, and grafana.com). We can accept only vulnerability reports at this address. We would prefer that you encrypt your message to us; please use our PGP key. The key fingerprint is:
|
||||
|
||||
F988 7BEA 027A 049F AE8E 5CAA D125 8932 BE24 C5CA
|
||||
|
||||
@@ -10,11 +9,9 @@ The key is available from [pgp.mit.edu](https://pgp.mit.edu/pks/lookup?op=get&se
|
||||
|
||||
Grafana Labs will send you a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
|
||||
**Important:** We ask you to not disclose the vulnerability before it have been fixed and announced, unless you received a response from the Grafana Labs security team that you can do so.
|
||||
**Important:** We ask you to not disclose the vulnerability before it have been fixed and announced, unless you have got a response from the Grafana Labs security team that you can do that.
|
||||
|
||||
## Security announcements
|
||||
### Security Announcements
|
||||
|
||||
We maintain a category on the community site called [Security Announcements](https://community.grafana.com/c/security-announcements),
|
||||
where we will post a summary, remediation, and mitigation details for any patch containing security fixes.
|
||||
|
||||
You can also subscribe to email updates to this category if you have a grafana.com account and sign on to the community site or track updates via an [RSS feed](https://community.grafana.com/c/security-announcements.rss).
|
||||
where we will post a summary, remediation, and mitigation details for any patch containing security fixes. You can also subscribe to email updates to this category if you have a grafana.com account and sign on to the community site or track updates via an [RSS feed](https://community.grafana.com/c/security-announcements.rss).
|
||||
|
||||
13
SUPPORT.md
13
SUPPORT.md
@@ -1,10 +1,9 @@
|
||||
# Get Grafana help
|
||||
Need help or support?
|
||||
------------------
|
||||
First, check the official [Grafana documentation](https://grafana.com/docs/).
|
||||
|
||||
If you require further help or support then ask a question in the [Grafana community site](https://community.grafana.com/) or [Grafana Slack](http://slack.raintank.io/). You can also search the community site for previously answered questions, in case someone already had your problem and got help.
|
||||
|
||||
**Please note:**
|
||||
- The Grafana project uses GitHub mainly for tracking bugs and feature requests.
|
||||
- Do not open an issue just to ask a question. The issue will be closed immediately.
|
||||
- Only submit issues for bug reports, feature requests, or enhancements.
|
||||
- Only submit issues for bug reports, feature requests or enhancements.
|
||||
- Grafana project uses GitHub mainly for tracking bugs and feature requests.
|
||||
- Asking a question by opening an issue will directly result in issue being closed.
|
||||
|
||||
If you require help or support then ask a question and/or find existing questions/answers in the [Grafana community site](https://community.grafana.com/).
|
||||
@@ -1,4 +1,4 @@
|
||||
# Guide to upgrading dependencies
|
||||
# Guide to Upgrading Dependencies
|
||||
|
||||
Upgrading Go or Node.js requires making changes in many different files. See below for a list and explanation for each.
|
||||
|
||||
@@ -16,7 +16,7 @@ Upgrading Go or Node.js requires making changes in many different files. See bel
|
||||
- Appveyor
|
||||
- Dockerfile
|
||||
|
||||
## Go dependencies
|
||||
## Go Dependencies
|
||||
|
||||
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.
|
||||
|
||||
@@ -46,7 +46,7 @@ GO111MODULE=on go mod vendor
|
||||
|
||||
You have to commit the changes to `go.mod`, `go.sum` and the `vendor/` directory before submitting the pull request.
|
||||
|
||||
## Node.js dependencies
|
||||
## Node.js Dependencies
|
||||
|
||||
Updated using `yarn`.
|
||||
|
||||
|
||||
@@ -1,34 +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"
|
||||
}
|
||||
},
|
||||
"tsdocMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
build.go
48
build.go
@@ -33,7 +33,6 @@ var (
|
||||
goos string
|
||||
gocc string
|
||||
cgo bool
|
||||
libc string
|
||||
pkgArch string
|
||||
version string = "v1"
|
||||
// deb & rpm does not support semver so have to handle their version a little differently
|
||||
@@ -52,7 +51,6 @@ var (
|
||||
skipRpmGen bool = false
|
||||
skipDebGen bool = false
|
||||
printGenVersion bool = false
|
||||
modVendor bool = true
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -66,12 +64,10 @@ func main() {
|
||||
flag.StringVar(&goarch, "goarch", runtime.GOARCH, "GOARCH")
|
||||
flag.StringVar(&goos, "goos", runtime.GOOS, "GOOS")
|
||||
flag.StringVar(&gocc, "cc", "", "CC")
|
||||
flag.StringVar(&libc, "libc", "", "LIBC")
|
||||
flag.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")
|
||||
@@ -108,7 +104,7 @@ func main() {
|
||||
case "setup":
|
||||
setup()
|
||||
|
||||
case "build-srv", "build-server":
|
||||
case "build-srv":
|
||||
clean()
|
||||
build("grafana-server", "./pkg/cmd/grafana-server", []string{})
|
||||
|
||||
@@ -116,6 +112,10 @@ func main() {
|
||||
clean()
|
||||
build("grafana-cli", "./pkg/cmd/grafana-cli", []string{})
|
||||
|
||||
case "build-server":
|
||||
clean()
|
||||
build("grafana-server", "./pkg/cmd/grafana-server", []string{})
|
||||
|
||||
case "build":
|
||||
//clean()
|
||||
for _, binary := range binaries {
|
||||
@@ -174,15 +174,12 @@ func makeLatestDistCopies() {
|
||||
}
|
||||
|
||||
latestMapping := map[string]string{
|
||||
"_amd64.deb": "dist/grafana_latest_amd64.deb",
|
||||
".x86_64.rpm": "dist/grafana-latest-1.x86_64.rpm",
|
||||
".linux-amd64.tar.gz": "dist/grafana-latest.linux-x64.tar.gz",
|
||||
".linux-amd64-musl.tar.gz": "dist/grafana-latest.linux-x64-musl.tar.gz",
|
||||
".linux-armv7.tar.gz": "dist/grafana-latest.linux-armv7.tar.gz",
|
||||
".linux-armv7-musl.tar.gz": "dist/grafana-latest.linux-armv7-musl.tar.gz",
|
||||
".linux-armv6.tar.gz": "dist/grafana-latest.linux-armv6.tar.gz",
|
||||
".linux-arm64.tar.gz": "dist/grafana-latest.linux-arm64.tar.gz",
|
||||
".linux-arm64-musl.tar.gz": "dist/grafana-latest.linux-arm64-musl.tar.gz",
|
||||
"_amd64.deb": "dist/grafana_latest_amd64.deb",
|
||||
".x86_64.rpm": "dist/grafana-latest-1.x86_64.rpm",
|
||||
".linux-amd64.tar.gz": "dist/grafana-latest.linux-x64.tar.gz",
|
||||
".linux-armv7.tar.gz": "dist/grafana-latest.linux-armv7.tar.gz",
|
||||
".linux-armv6.tar.gz": "dist/grafana-latest.linux-armv6.tar.gz",
|
||||
".linux-arm64.tar.gz": "dist/grafana-latest.linux-arm64.tar.gz",
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
@@ -456,9 +453,6 @@ func gruntBuildArg(task string) []string {
|
||||
if pkgArch != "" {
|
||||
args = append(args, fmt.Sprintf("--arch=%v", pkgArch))
|
||||
}
|
||||
if libc != "" {
|
||||
args = append(args, fmt.Sprintf("--libc=%s", libc))
|
||||
}
|
||||
if phjsToRelease != "" {
|
||||
args = append(args, fmt.Sprintf("--phjsToRelease=%v", phjsToRelease))
|
||||
}
|
||||
@@ -485,13 +479,9 @@ func test(pkg string) {
|
||||
}
|
||||
|
||||
func build(binaryName, pkg string, tags []string) {
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("-%s", libc)
|
||||
}
|
||||
binary := fmt.Sprintf("./bin/%s-%s%s/%s", goos, goarch, libcPart, binaryName)
|
||||
binary := fmt.Sprintf("./bin/%s-%s/%s", goos, goarch, binaryName)
|
||||
if isDev {
|
||||
//don't include os/arch/libc in output path in dev environment
|
||||
//don't include os and arch in output path in dev environment
|
||||
binary = fmt.Sprintf("./bin/%s", binaryName)
|
||||
}
|
||||
|
||||
@@ -509,9 +499,6 @@ 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)
|
||||
@@ -519,11 +506,7 @@ func build(binaryName, pkg string, tags []string) {
|
||||
if !isDev {
|
||||
setBuildEnv()
|
||||
runPrint("go", "version")
|
||||
libcPart := ""
|
||||
if libc != "" {
|
||||
libcPart = fmt.Sprintf("/%s", libc)
|
||||
}
|
||||
fmt.Printf("Targeting %s/%s%s\n", goos, goarch, libcPart)
|
||||
fmt.Printf("Targeting %s/%s\n", goos, goarch)
|
||||
}
|
||||
|
||||
runPrint("go", args...)
|
||||
@@ -546,7 +529,7 @@ func ldflags() string {
|
||||
b.WriteString(fmt.Sprintf(" -X main.buildstamp=%d", buildStamp()))
|
||||
b.WriteString(fmt.Sprintf(" -X main.buildBranch=%s", getGitBranch()))
|
||||
if v := os.Getenv("LDFLAGS"); v != "" {
|
||||
b.WriteString(fmt.Sprintf(" -extldflags \"%s\"", v))
|
||||
b.WriteString(fmt.Sprintf(" -extldflags=%s", v))
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
@@ -638,7 +621,6 @@ func runError(cmd string, args ...string) ([]byte, error) {
|
||||
func runPrint(cmd string, args ...string) {
|
||||
log.Println(cmd, strings.Join(args, " "))
|
||||
ecmd := exec.Command(cmd, args...)
|
||||
ecmd.Env = append(os.Environ(), "GO111MODULE=on")
|
||||
ecmd.Stdout = os.Stdout
|
||||
ecmd.Stderr = os.Stderr
|
||||
err := ecmd.Run()
|
||||
|
||||
@@ -155,9 +155,6 @@ google_tag_manager_id =
|
||||
|
||||
#################################### Security ############################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
disable_initial_admin_creation = false
|
||||
|
||||
# default admin user, created on startup
|
||||
admin_user = admin
|
||||
|
||||
@@ -179,7 +176,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 +227,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 not set/unrestricted.
|
||||
# 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 =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
# disable user signup / registration
|
||||
@@ -322,7 +315,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 =
|
||||
|
||||
@@ -336,7 +328,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 #########################
|
||||
@@ -370,19 +361,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 =
|
||||
|
||||
#################################### Generic OAuth #######################
|
||||
[auth.generic_oauth]
|
||||
name = OAuth
|
||||
@@ -393,17 +371,16 @@ client_secret = some_secret
|
||||
scopes = user:email
|
||||
email_attribute_name = email:primary
|
||||
email_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
|
||||
@@ -456,12 +433,9 @@ 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 =
|
||||
headers =
|
||||
enable_login_token = false
|
||||
|
||||
#################################### Auth LDAP ###########################
|
||||
[auth.ldap]
|
||||
@@ -610,8 +584,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]
|
||||
@@ -636,7 +608,6 @@ basic_auth_password =
|
||||
address =
|
||||
prefix = prod.grafana.%(instance_name)s.
|
||||
|
||||
#################################### Grafana.com integration ##########################
|
||||
[grafana_net]
|
||||
url = https://grafana.com
|
||||
|
||||
@@ -667,13 +638,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 =
|
||||
@@ -701,10 +669,8 @@ container_name =
|
||||
# does not require any configuration
|
||||
|
||||
[rendering]
|
||||
# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
|
||||
# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
|
||||
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
|
||||
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 =
|
||||
|
||||
[panels]
|
||||
|
||||
163
conf/sample.ini
163
conf/sample.ini
@@ -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
|
||||
|
||||
@@ -156,9 +151,6 @@
|
||||
|
||||
#################################### Security ####################################
|
||||
[security]
|
||||
# disable creation of admin user on first start of grafana
|
||||
;disable_initial_admin_creation = false
|
||||
|
||||
# default admin user, created on startup
|
||||
;admin_user = admin
|
||||
|
||||
@@ -180,7 +172,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 +221,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 not set/unrestricted.
|
||||
# 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 =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
# disable user signup / registration
|
||||
@@ -244,15 +232,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,9 +279,6 @@
|
||||
# This setting is ignored if multiple OAuth providers are configured.
|
||||
;oauth_auto_login = false
|
||||
|
||||
# limit of api_key seconds to live before expiration
|
||||
;api_key_max_seconds_to_live = -1
|
||||
|
||||
#################################### Anonymous Auth ######################
|
||||
[auth.anonymous]
|
||||
# enable anonymous access
|
||||
@@ -321,23 +300,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
|
||||
@@ -349,29 +314,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 =
|
||||
|
||||
#################################### Generic OAuth ##########################
|
||||
[auth.generic_oauth]
|
||||
@@ -386,15 +328,17 @@
|
||||
;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 =
|
||||
;tls_skip_verify_insecure = false
|
||||
;tls_client_cert =
|
||||
;tls_client_key =
|
||||
;tls_client_ca =
|
||||
|
||||
; 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.
|
||||
@@ -436,9 +380,14 @@
|
||||
# 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]
|
||||
;enabled = true
|
||||
#################################### 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]
|
||||
@@ -446,11 +395,13 @@
|
||||
;header_name = X-WEBAUTH-USER
|
||||
;header_property = username
|
||||
;auto_sign_up = true
|
||||
;sync_ttl = 60
|
||||
;ldap_sync_ttl = 60
|
||||
;whitelist = 192.168.1.1, 192.168.2.1
|
||||
;headers = Email:X-User-Email, Name:X-User-Name
|
||||
# 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]
|
||||
@@ -468,7 +419,7 @@
|
||||
;enabled = false
|
||||
;host = localhost:25
|
||||
;user =
|
||||
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
|
||||
# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
|
||||
;password =
|
||||
;cert_file =
|
||||
;key_file =
|
||||
@@ -480,7 +431,6 @@
|
||||
|
||||
[emails]
|
||||
;welcome_email_on_sign_up = false
|
||||
;templates_pattern = emails/*.html
|
||||
|
||||
#################################### Logging ##########################
|
||||
[log]
|
||||
@@ -539,41 +489,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
|
||||
@@ -601,9 +516,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
|
||||
@@ -614,14 +526,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]
|
||||
@@ -629,11 +538,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)
|
||||
@@ -656,6 +560,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.
|
||||
@@ -663,8 +572,6 @@
|
||||
;provider =
|
||||
|
||||
[external_image_storage.s3]
|
||||
;endpoint =
|
||||
;path_style_access =
|
||||
;bucket =
|
||||
;region =
|
||||
;path =
|
||||
@@ -691,12 +598,14 @@
|
||||
# does not require any configuration
|
||||
|
||||
[rendering]
|
||||
# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
|
||||
# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
|
||||
# Options to configure external image rendering server like https://github.com/grafana/grafana-image-renderer
|
||||
;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 =
|
||||
|
||||
[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.
|
||||
;disable_sanitize_html = false
|
||||
@@ -704,11 +613,3 @@
|
||||
[plugins]
|
||||
;enable_alpha = false
|
||||
;app_tls_skip_verify_insecure = false
|
||||
|
||||
[enterprise]
|
||||
# Path to a valid Grafana Enterprise license.jwt file
|
||||
;license_path =
|
||||
|
||||
[feature_toggles]
|
||||
# enable features, separated by spaces
|
||||
;enable =
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Contribute
|
||||
|
||||
This directory contains guides for contributors to the Grafana project.
|
||||
|
||||
- [Create a pull request](create-pull-request.md)
|
||||
- [Contributing documentation](documentation.md)
|
||||
- [Developer guide](developer-guide.md)
|
||||
- [Triage issues](triage-issues.md)
|
||||
|
||||
The `style-guides` directory contains style guides for the Grafana software project and documentation.
|
||||
|
||||
- [Backend style guide](style-guides/backend.md) for how to style and format backend functionality and code.
|
||||
- [Documentation style guide](style-guides/documentation-style-guide.md) for how to style and format documentation.
|
||||
- [Frontend style guide](style-guides/frontend.md) for how to style and format the user-facing functionality and code.
|
||||
- [Redux framework](style-guides/redux.md) for designing the Grafana redux framework.
|
||||
- [Themes style guide](style-guides/themes.md) for designing and updating Grafana themes.
|
||||
@@ -1,10 +0,0 @@
|
||||
# Architecture
|
||||
|
||||
Are you looking to take on contributions with bigger impact? These guides help you get a better understanding of the structure and design of the Grafana codebase.
|
||||
|
||||
Learn more about the backend architecture:
|
||||
|
||||
- Part 1: [Services](services.md)
|
||||
- Part 2: [Communication](communication.md)
|
||||
- Part 3: [Database](database.md)
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
# Communication
|
||||
|
||||
Grafana uses a _bus_ to pass messages between different parts of the application. All communication over the bus happens synchronously.
|
||||
|
||||
There are three types of messages: _events_, _commands_, and _queries_.
|
||||
|
||||
## Events
|
||||
|
||||
An event is something that happened in the past. Since an event has already happened, you can't change it. Instead, you can react to events by triggering additional application logic to be run, whenever they occur.
|
||||
|
||||
> Because they happened in the past, event names are written in past tense, such as `UserCreated`, and `OrgUpdated`.
|
||||
|
||||
### Subscribe to an event
|
||||
|
||||
In order to react to an event, you first need to _subscribe_ to it.
|
||||
|
||||
To subscribe to an event, register an _event listener_ in the service's `Init` method:
|
||||
|
||||
```go
|
||||
func (s *MyService) Init() error {
|
||||
s.bus.AddEventListener(s.UserCreated)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MyService) UserCreated(event *events.UserCreated) error {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Tip:** Browse the available events in the `events` package.
|
||||
|
||||
### Publish an event
|
||||
|
||||
If you want to let other parts of the application react to changes in a service, you can publish your own events:
|
||||
|
||||
```go
|
||||
event := &events.StickersSentEvent {
|
||||
UserID: "taylor",
|
||||
Count: 1,
|
||||
}
|
||||
if err := s.bus.Publish(event); err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
A command is a request for an action to be taken. Unlike an event's fire-and-forget approach, a command can fail as it is handled. The handler will then return an error.
|
||||
|
||||
> Because we request an operation to be performed, command are written in imperative mood, such as `CreateFolderCommand`, and `DeletePlaylistCommand`.
|
||||
|
||||
### Dispatch a command
|
||||
|
||||
To dispatch a command, pass the object to the `Dispatch` method:
|
||||
|
||||
```go
|
||||
cmd := &models.SendStickersCommand {
|
||||
UserID: "taylor",
|
||||
Count: 1,
|
||||
}
|
||||
if err := s.bus.Dispatch(cmd); err != nil {
|
||||
if err == bus.ErrHandlerNotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** `Dispatch` will return an error if no handler is registered for that command.
|
||||
|
||||
**Tip:** Browse the available commands in the `models` package.
|
||||
|
||||
### Handle commands
|
||||
|
||||
Let other 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.
|
||||
|
||||
```go
|
||||
func (s *MyService) Init() error {
|
||||
s.bus.AddHandler(s.SendStickers)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MyService) SendStickers(cmd *models.SendStickersCommand) error {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The handler method may return an error if unable to complete the command.
|
||||
|
||||
## Queries
|
||||
|
||||
A command handler can optionally populate the command sent to it. This pattern is commonly used to implement _queries_.
|
||||
|
||||
### Making a query
|
||||
|
||||
To make a query, dispatch the query instance just like you would a command. When the `Dispatch` method returns, the `Results` field contains the result of the query.
|
||||
|
||||
```go
|
||||
query := &models.FindDashboardQuery{
|
||||
ID: "foo",
|
||||
}
|
||||
if err := bus.Dispatch(query); err != nil {
|
||||
return err
|
||||
}
|
||||
// The query now contains a result.
|
||||
for _, item := range query.Results {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Return query results
|
||||
|
||||
To return results for a query, set any of the fields on the query argument before returning:
|
||||
|
||||
```go
|
||||
func (s *MyService) FindDashboard(query *models.FindDashboardQuery) error {
|
||||
// ...
|
||||
query.Result = dashboard
|
||||
return nil
|
||||
}
|
||||
```
|
||||
@@ -1,123 +0,0 @@
|
||||
# Database
|
||||
|
||||
Grafana uses a database to persist settings between restarts. In fact, if you don't specify one, Grafana creates a [SQLite3](https://www.sqlite.org/) database file on your local disk. This guide explains how to store and retrieve data from the database.
|
||||
|
||||
Grafana supports the [following databases](https://grafana.com/docs/installation/requirements/#database):
|
||||
|
||||
- [MySQL](https://www.mysql.com/)
|
||||
- [PostgreSQL](https://www.postgresql.org/)
|
||||
- [SQLite3](https://www.sqlite.org/)
|
||||
|
||||
Grafana uses the [XORM](https://xorm.io) framework for persisting objects to the database. For more information on how to use XORM, refer to the [documentation](http://gobook.io/read/github.com/go-xorm/manual-en-US/).
|
||||
|
||||
[Services](services.md) don't use XORM directly. Instead, services use the _SQL store_, a special type of service that provides an abstraction for the database layer. There are two ways of using the `sqlstore`: using `sqlstore` handlers, and using the `SqlStore` instance.
|
||||
|
||||
## `sqlstore` handlers
|
||||
|
||||
> **Deprecated:** We are deprecating `sqlstore` handlers in favor of using the `SqlStore` object directly in each service. Since most services still use the `sqlstore` handlers, we still want to explain how they work.
|
||||
|
||||
The `sqlstore` package allows you to register [command handlers](communication.md#handle-commands) that either store, or retrieve objects from the database. `sqlstore` handlers are similar to services:
|
||||
|
||||
- [Services](services.md) are command handlers that _contain business logic_.
|
||||
- `sqlstore` handlers are command handlers that _access the database_.
|
||||
|
||||
### Register a `sqlstore` handler
|
||||
|
||||
> **Deprecated:** Refer to the [deprecation note for `sqlstore` handlers](#sqlstore-handlers).
|
||||
|
||||
To register a handler:
|
||||
|
||||
- Create a new file `myrepo.go` in the `sqlstore` package.
|
||||
- Create a [command handler](communication.md#handle-commands).
|
||||
- Register the handler in the `init` function:
|
||||
|
||||
```go
|
||||
func init() {
|
||||
bus.AddHandler("sql", DeleteDashboard)
|
||||
}
|
||||
|
||||
func DeleteDashboard(cmd *models.DeleteDashboardCommand) error {
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
_, err := sess.Exec("DELETE FROM dashboards WHERE dashboard_id=?", cmd.DashboardID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Here, `inTransaction` is a helper function in the `sqlstore` package that provides a session, that lets you execute SQL statements.
|
||||
|
||||
## `SqlStore`
|
||||
|
||||
As opposed to a `sqlstore` handler, the `SqlStore` is a service itself. The `SqlStore` has the same responsibility however: to store and retrieve objects, to and from the database.
|
||||
|
||||
To use the `SqlStore`, inject the `SQLStore` in your service struct:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
SQLStore *sqlstore.SqlStore `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
You can now make SQL queries in any of your [command handlers](communication.md#handle-commands) or [event listeners](communication.md#subscribe-to-an-event):
|
||||
|
||||
```go
|
||||
func (s *MyService) DeleteDashboard(cmd *models.DeleteDashboardCommand) error {
|
||||
if err := s.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
_, err := sess.Exec("DELETE FROM dashboards WHERE dashboard_id=?", cmd.DashboardID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
For transactions, use the `WithTransactionalDbSession` method instead.
|
||||
|
||||
## Migrations
|
||||
|
||||
As Grafana evolves, it becomes necessary to create _schema migrations_ for one or more database tables.
|
||||
|
||||
To see all the types of migrations you can add, refer to [migrations.go](/pkg/services/sqlstore/migrator/migrations.go).
|
||||
|
||||
Before you add a migration, make sure that you:
|
||||
|
||||
- Never change a migration that has been committed and pushed to master.
|
||||
- Always add new migrations, to change or undo previous migrations.
|
||||
|
||||
Add a migration using one of the following methods:
|
||||
|
||||
- Add migrations in the `migrations` package.
|
||||
- Implement the `DatabaseMigrator` for the service.
|
||||
|
||||
**Important:** If there are previous migrations for a service, use that method. By adding migrations using both methods, you risk running migrations in the wrong order.
|
||||
|
||||
### Add migrations in `migrations` package
|
||||
|
||||
Most services have their migrations located in the [migrations](/pkg/services/sqlstore/migrations/migrations.go) package.
|
||||
|
||||
To add a migration:
|
||||
|
||||
- Open the [migrations.go](/pkg/services/sqlstore/migrations/migrations.go) file.
|
||||
- In the `AddMigrations` function, find the `addXxxMigration` function for the service you want to create a migration for.
|
||||
- At the end of the `addXxxMigration` function, register your migration:
|
||||
|
||||
[Example](https://github.com/grafana/grafana/blob/00d0640b6e778ddaca021670fe851fe00982acf2/pkg/services/sqlstore/migrations/migrations.go#L55-L70)
|
||||
|
||||
### Implement `DatabaseMigrator`
|
||||
|
||||
During initialization, SQL store queries the service registry, and runs migrations for every service that implements the [DatabaseMigrator](https://github.com/grafana/grafana/blob/44c2007498c76c2dbb48e8366b4af410f1ee1b98/pkg/registry/registry.go#L101-L106) interface.
|
||||
|
||||
To add a migration:
|
||||
|
||||
- If needed, add the `AddMigration(mg *migrator.Migrator)` method to the service.
|
||||
- At the end of the `AddMigration` method, register your migration:
|
||||
|
||||
```go
|
||||
func (s *MyService) AddMigration(mg *migrator.Migrator) {
|
||||
// ...
|
||||
|
||||
mg.AddMigration("Add column age", NewAddColumnMigration(table, &Column{
|
||||
Name: "age",
|
||||
Type: migrator.DB_BigInt,
|
||||
Nullable: true,
|
||||
}))
|
||||
}
|
||||
```
|
||||
@@ -1,69 +0,0 @@
|
||||
# Services
|
||||
|
||||
A Grafana _service_ encapsulates and exposes application logic to the rest of the application, through a set of related operations.
|
||||
|
||||
Before a service can start communicating with the rest of Grafana, it needs to be registered in the _service registry_.
|
||||
|
||||
The service registry keeps track of all available services during runtime. On start-up, Grafana uses the registry to build a dependency graph of services, a _service graph_.
|
||||
|
||||
Even though the services in Grafana do different things, they share a number of patterns. To better understand how a service works, let's build one from scratch!
|
||||
|
||||
## Create a service
|
||||
|
||||
To start building a service:
|
||||
|
||||
- Create a new Go package `mysvc` in the [pkg/services](/pkg/services) directory.
|
||||
- Create a `service.go` file inside your new directory.
|
||||
|
||||
All services need to implement the [Service](https://godoc.org/github.com/grafana/grafana/pkg/registry#Service) interface:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
}
|
||||
|
||||
func (s *MyService) Init() error {
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
The `Init` method is used to initialize and configure the service to make it ready to use. Services that return an error halt Grafana's startup process and cause the error to be logged as it exits.
|
||||
|
||||
## Register a service
|
||||
|
||||
Every service needs to be registered with the application for it to be included in the service graph.
|
||||
|
||||
To register a service, call the `registry.RegisterService` function in an `init` function within your package.
|
||||
|
||||
```go
|
||||
func init() {
|
||||
registry.RegisterService(&MyService{})
|
||||
}
|
||||
```
|
||||
|
||||
`init` functions are only run whenever a package is imported, so we also need to import the package in the application. In the `server.go` file under `pkg/cmd/grafana-server`, import the package we just created:
|
||||
|
||||
```go
|
||||
import _ "github.com/grafana/grafana/pkg/services/mysvc"
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
Grafana uses the [inject](https://github.com/facebookgo/inject) package to inject dependencies during runtime.
|
||||
|
||||
For example, to access the [bus](communication.md), add it to the `MyService` struct:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
Bus bus.Bus `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
You can also inject other services in the same way:
|
||||
|
||||
```go
|
||||
type MyService struct {
|
||||
Service other.Service `inject:""`
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** Any injected dependency needs to be an exported field. Any unexported fields result in a runtime error.
|
||||
@@ -1,95 +0,0 @@
|
||||
# Create a pull request
|
||||
|
||||
We're excited that you're considering making a contribution to the Grafana project! This document guides you through the process of creating a [pull request](https://help.github.com/en/articles/about-pull-requests/).
|
||||
|
||||
## Before you begin
|
||||
|
||||
We know you're excited to create your first pull request. Before we get started, read these resources first:
|
||||
|
||||
- Learn how to start [Contributing to Grafana](/CONTRIBUTING.md).
|
||||
- Make sure your code follows the relevant [style guides](/contribute/style-guides).
|
||||
|
||||
## Your first pull request
|
||||
|
||||
If this is your first time contributing to an open-source project on GitHub, make sure you read about [Creating a pull request](https://help.github.com/en/articles/creating-a-pull-request).
|
||||
|
||||
To increase the chance of having your pull request accepted, make sure your pull request follows these guidelines:
|
||||
|
||||
- Title and description matches the implementation.
|
||||
- Commits within the pull request follow the [Formatting guidelines](#Formatting-guidelines).
|
||||
- The pull request closes one related issue.
|
||||
- The pull request contains necessary tests that verify the intended behavior.
|
||||
- If your pull request has conflicts, rebase your branch onto the master branch.
|
||||
|
||||
If the pull request fixes a bug:
|
||||
|
||||
- The pull request description must include `Closes #<issue number>` or `Fixes #<issue number>`.
|
||||
- To avoid regressions, the pull request should include tests that replicate the fixed bug.
|
||||
|
||||
### Frontend-specific guidelines
|
||||
|
||||
Pull requests for frontend contributions must:
|
||||
|
||||
- Use [Emotion](/contribute/style-guides/styling.md) for styling.
|
||||
- Not increase the Angular code base.
|
||||
- Not use `any` or `{}` without reason.
|
||||
- Not contain large React components that could easily be split into several smaller components.
|
||||
- Not contain backend calls directly from components—use actions and Redux instead.
|
||||
|
||||
Pull requests for Redux contributions must:
|
||||
|
||||
- Use the `actionCreatorFactory` and `reducerFactory` helpers instead of traditional switch statement reducers in Redux. Refer to [Redux framework](/contribute/style-guides/redux.md) for more details.
|
||||
- Use `reducerTester` to test reducers. Refer to [Redux framework](/contribute/style-guides/redux.md) for more details.
|
||||
- Not contain code that mutates state in reducers or thunks.
|
||||
- Not contain code that accesses the reducers state slice directly. Instead, the code should use state selectors to access state.
|
||||
|
||||
## Code review
|
||||
|
||||
Once you've created a pull request, the next step is to have someone review your change. A review is a learning opportunity for both the reviewer and the author of the pull request.
|
||||
|
||||
If you think a specific person needs to review your pull request, then you can tag them in the description or in a comment. Tag a user by typing the `@` symbol followed by their GitHub username.
|
||||
|
||||
We recommend that you read [How to do a code review](https://google.github.io/eng-practices/review/reviewer/) to learn more about code reviews.
|
||||
|
||||
## Formatting guidelines
|
||||
|
||||
A well-written pull request minimizes the time to get your change accepted. These guidelines help you write good commit messages and descriptions for your pull requests.
|
||||
|
||||
### Commit message format
|
||||
|
||||
Grafana uses the guidelines for commit messages outlined in [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/), with the following additions:
|
||||
|
||||
- Subject line must begin with the _area_ of the commit.
|
||||
- A footer in the form of an optional [keyword and issue reference](https://help.github.com/en/articles/closing-issues-using-keywords).
|
||||
|
||||
#### Area
|
||||
|
||||
The area should use upper camel case, e.g. UpperCamelCase.
|
||||
|
||||
Prefer using one of the following areas:
|
||||
|
||||
- **Build:** Changes to the build system, or external dependencies.
|
||||
- **Chore:** Changes that don't affect functionality.
|
||||
- **Dashboard:** Changes to the Dashboard feature.
|
||||
- **Docs:** Changes to documentation.
|
||||
- **Explore:** Changes to the Explore feature.
|
||||
- **Plugins:** Changes to any of the plugins.
|
||||
|
||||
For changes to data sources, the area should be the name of the data source, e.g., AzureMonitor, Graphite, and Prometheus.
|
||||
|
||||
For changes to panels, the area should be the name of the panel, suffixed with Panel, e.g., GraphPanel, SinglestatPanel, and TablePanel.
|
||||
|
||||
**Examples**
|
||||
|
||||
- `Build: Support publishing MSI to grafana.com`
|
||||
- `Explore: Add Live option for supported data sources`
|
||||
- `GraphPanel: Fix legend sorting issues`
|
||||
- `Docs: Changed url to URL in all documentation files`
|
||||
|
||||
### Pull request titles
|
||||
|
||||
The Grafana team _squashes_ all commits into one when we accept a pull request. The title of the pull request becomes the subject line of the squashed commit message. We still encourage contributors to write informative commit messages, as they becomes a part of the Git commit body.
|
||||
|
||||
We use the pull request title when we generate change logs for releases. As such, we strive to make the title as informative as possible.
|
||||
|
||||
Make sure that the title for your pull request uses the same format as the subject line in the commit message.
|
||||
@@ -1,210 +0,0 @@
|
||||
# Developer guide
|
||||
|
||||
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)
|
||||
- [Node.js (Long Term Support)](https://nodejs.org)
|
||||
- [Yarn](https://yarnpkg.com)
|
||||
|
||||
### macOS
|
||||
|
||||
We recommend using [Homebrew](https://brew.sh/) for installing any missing dependencies:
|
||||
|
||||
```
|
||||
brew install git
|
||||
brew install go
|
||||
brew install node
|
||||
|
||||
npm install -g yarn
|
||||
```
|
||||
|
||||
## Download Grafana
|
||||
|
||||
We recommend using Go to download the source code for the Grafana project:
|
||||
|
||||
1. Add `export GOPATH=$HOME/go/` to the bottom of your `$HOME/.bash_profile`.
|
||||
1. Open a terminal and run `go get github.com/grafana/grafana` in your terminal. This command downloads, and installs Grafana to your `$GOPATH`.
|
||||
1. Open `$GOPATH/src/github.com/grafana/grafana` in your favorite code editor.
|
||||
|
||||
## Build Grafana
|
||||
|
||||
Grafana consists of two components; the _frontend_, and the _backend_.
|
||||
|
||||
### Frontend
|
||||
|
||||
Before we can build the frontend assets, we need to install the dependencies:
|
||||
|
||||
```
|
||||
yarn install --pure-lockfile
|
||||
```
|
||||
|
||||
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 whenever every time you change the code.
|
||||
|
||||
Next, we'll build the web server that will serve the frontend assets we just built.
|
||||
|
||||
### Backend
|
||||
|
||||
Build and run the backend by running `make run` in the root directory of the repository. This command compiles the Go source code and starts a web server.
|
||||
|
||||
> Are you having problems with [too many open files](#troubleshooting)?
|
||||
|
||||
By default, you can access the web server at `http://localhost:3000/`.
|
||||
|
||||
Log in using the default credentials:
|
||||
|
||||
| username | password |
|
||||
| -------- | -------- |
|
||||
| `admin` | `admin` |
|
||||
|
||||
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_.
|
||||
|
||||
### Run frontend tests
|
||||
|
||||
We use [jest](https://jestjs.io/) for our frontend tests. Run them using Yarn:
|
||||
|
||||
```
|
||||
yarn jest
|
||||
```
|
||||
|
||||
### Run backend tests
|
||||
|
||||
If you're developing for the backend, run the tests with the standard Go tool:
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
```
|
||||
yarn e2e-tests
|
||||
```
|
||||
|
||||
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-tests
|
||||
```
|
||||
|
||||
To follow the tests in the browser while they're running, use the `yarn e2e-tests:debug` instead.
|
||||
|
||||
```
|
||||
yarn e2e-tests:debug
|
||||
```
|
||||
|
||||
## Configure Grafana for development
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
To set up data sources for your development environment, go to the [devenv](/devenv) directory in the Grafana repository:
|
||||
|
||||
```
|
||||
cd devenv
|
||||
```
|
||||
|
||||
Run the `setup.sh` script to set up a set of data sources and dashboards in your local Grafana instance. The script creates a set of data sources called **gdev-\<type\>**, and a set of dashboards located in a folder called **gdev dashboards**.
|
||||
|
||||
Some of the data sources require databases to run in the background.
|
||||
|
||||
Installing and configuring databases can be a tricky business. Grafana uses [Docker](https://docker.com) to make the task of setting up databases a little easier. Make sure you [install Docker](https://docs.docker.com/docker-for-mac/install/) before proceeding to the next step.
|
||||
|
||||
In the root directory of your Grafana repository, run the following command:
|
||||
|
||||
```
|
||||
make devenv sources=influxdb,loki
|
||||
```
|
||||
|
||||
The script generates a Docker Compose file with the databases you specify as `sources`, and runs them in the background.
|
||||
|
||||
See the repository for all the [available data sources](/devenv/docker/blocks). Note that some data sources have specific Docker images for macOS, e.g. `prometheus_mac`.
|
||||
|
||||
## Build a Docker image
|
||||
|
||||
To build a Docker image, run:
|
||||
|
||||
```
|
||||
make build-docker-full
|
||||
```
|
||||
|
||||
The resulting image will be tagged as grafana/grafana:dev.
|
||||
|
||||
**Note:** If you've already set up a local development environment, and you're running a `linux/amd64` machine, you can speed up building the Docker image:
|
||||
|
||||
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**.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Are you having issues with setting up your environment? Here are some tips that might help.
|
||||
|
||||
### Too many open files when running `make run`
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
ulimit -a
|
||||
```
|
||||
|
||||
To change the number of open files allowed, run:
|
||||
|
||||
```
|
||||
ulimit -S -n 2048
|
||||
```
|
||||
|
||||
The number of files needed may be different on your environment. To determine the number of open files needed by `make run`, run:
|
||||
|
||||
```
|
||||
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.
|
||||
|
||||
## Next steps
|
||||
|
||||
- Read our [style guides](/contribute/style-guides).
|
||||
- Learn how to [Create a pull request](/contribute/create-pull-request.md).
|
||||
- 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).
|
||||
- Read about the [architecture](architecture).
|
||||
@@ -1,42 +0,0 @@
|
||||
# Contributing to documentation
|
||||
|
||||
This documents guides you through the process of contributing to the Grafana documentation. Make sure you've read the guide for [Contributing to Grafana](/CONTRIBUTING.md).
|
||||
|
||||
## Your first contribution
|
||||
|
||||
If you’re unsure about where to start, check out some of our [open docs issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3Atype%2Fdocs).
|
||||
|
||||
Sometimes it can be difficult to understand an issue when you're just getting started. Refer to this list of [beginner-friendly issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+label%3Atype%2Fdocs+label%3A"beginner+friendly") for tasks suitable for first-time contributors.
|
||||
|
||||
When you’ve found an issue you want to work on, please comment on the issue to let other people know you intend to work on it.
|
||||
|
||||
If you encounter any misspellings or violations to the style guide, please let us know by submitting an issue (or just fix them if they are minor changes).
|
||||
|
||||
On every page in the [documentation](https://grafana.com/docs/) are two links in the upper right corner:
|
||||
|
||||
- **Edit this page** takes you directly to the file on GitHub where you can contribute a fix.
|
||||
- **Request doc changes** prepares an issue on GitHub with relevant information already filled in.
|
||||
|
||||
## Join our community
|
||||
|
||||
For general discussions on documentation, you’re welcome to join the `#docs` channel on our [public Grafana Slack](http://slack.raintank.io) team.
|
||||
|
||||
## Style and formatting
|
||||
|
||||
All Grafana documentation is written using [Markdown](https://en.wikipedia.org/wiki/Markdown), and can be found in the [docs](/docs) directory in the [Grafana GitHub repository](https://github.com/grafana/grafana). The [documentation website](https://grafana.com/docs) is generated with [Hugo](https://gohugo.io) which uses [Blackfriday](https://github.com/russross/blackfriday) as its Markdown rendering engine.
|
||||
|
||||
### Documentation structure
|
||||
|
||||
The Grafana documentation is organized into topics, called _sections_. You can take a look at the current build at [grafana.com/docs/](https://grafana.com/docs/).
|
||||
|
||||
Each top-level section is located under the [docs/sources](/docs/sources) directory. Subsections are added by creating a subdirectory in the directory of the parent section.
|
||||
|
||||
For each section, an `_index.md` file provides an overview of the topic.
|
||||
|
||||
### Style guide
|
||||
|
||||
Refer to the [Documentation style guide](style-guides/documentation-style-guide.md) for information about Grafana style, word choice, and grammar conventions.
|
||||
|
||||
### Spelling
|
||||
|
||||
The [codespell](https://github.com/codespell-project/codespell) tool is run for every change to catch common misspellings.
|
||||
@@ -1,41 +0,0 @@
|
||||
# Backend style guide
|
||||
|
||||
Grafanas backend has been developed for a long time with a mix of code styles. This guide explains how we want to write Go code in the future.
|
||||
|
||||
Unless stated otherwise, use the guidelines listed in the following articles:
|
||||
|
||||
- [Effective Go](https://golang.org/doc/effective_go.html)
|
||||
- [Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
|
||||
- [Go: Best Practices for Production Environments](http://peter.bourgon.org/go-in-production/#formatting-and-style)
|
||||
|
||||
## Linting and formatting
|
||||
|
||||
To ensure consistency across the Go codebase, we require all code to pass a number of linter checks.
|
||||
|
||||
We use the standard following linters:
|
||||
|
||||
- [gofmt](https://golang.org/cmd/gofmt/)
|
||||
- [golint](https://github.com/golang/lint)
|
||||
- [go vet](https://golang.org/cmd/vet/)
|
||||
|
||||
In addition to the standard linters, we also use:
|
||||
|
||||
- [revive](https://revive.run/) with a [custom config](https://github.com/grafana/grafana/blob/master/conf/revive.toml)
|
||||
- [GolangCI-Lint](https://github.com/golangci/golangci-lint)
|
||||
- [gosec](https://github.com/securego/gosec)
|
||||
|
||||
To run all linters, use the `lint-go` Makefile target:
|
||||
|
||||
```bash
|
||||
make lint-go
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
We value clean and readable code, that is loosely coupled and covered by unit tests. This makes it easier to collaborate and maintain the code.
|
||||
|
||||
Tests must use the standard library, `testing`. For assertions, prefer using [testify](https://github.com/stretchr/testify).
|
||||
|
||||
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.
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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 "()".
|
||||
@@ -1,159 +0,0 @@
|
||||
# Documentation style guide
|
||||
|
||||
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).
|
||||
|
||||
## 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.
|
||||
|
||||
## Published guides
|
||||
|
||||
For all items not covered in this guide, refer to the [Microsoft Style Guide](https://docs.microsoft.com/en-us/style-guide/welcome/) and the [Chicago Manual of Style](https://www.chicagomanualofstyle.org/home.html).
|
||||
|
||||
## Spelling
|
||||
|
||||
The [codespell](https://github.com/codespell-project/codespell) tool is run for every change to catch common misspellings.
|
||||
|
||||
## Grafana-specific style
|
||||
|
||||
The following sections provide general guidelines on topics specific to Grafana documentation. Note that for the most part, these are *guidelines*, not rigid rules. If you have questions, ask in the #docs channel of Grafana Slack.
|
||||
|
||||
### General
|
||||
|
||||
* Use active voice. Avoid passive voice.
|
||||
- Passive: The heatmap visualization is displayed.
|
||||
- Active: Grafana displays the heatmap visualization.
|
||||
* Write in the imperative second person. Examples: You can write a query. Click the panel. Close the window.
|
||||
* Write in present tense.
|
||||
- Not: The panel will open.
|
||||
- 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.
|
||||
|
||||
### File naming conventions
|
||||
|
||||
- Files that are displayed in the help system should have names that are all lowercase, no spaces. Use hyphens instead of spaces. Example: glossary.md
|
||||
- Documentation file names should match the title. **Note:** This only applies to new files at this time. Do not change the names of older files unless directed to do so.
|
||||
- Internal reference file names should be all uppercase except the file extension. Example: CONTRIBUTING.md
|
||||
|
||||
### Headings
|
||||
|
||||
* Write headings in sentence case, not title case.
|
||||
- This is sentence case
|
||||
- This Is Title Case
|
||||
* Task topic headings start with a verb.
|
||||
- Write a query. Create a dashboard.
|
||||
* Concept and reference topic headings should be nouns or gerunds. Examples: Contributing to docs, Visualizations, Style guide
|
||||
* Avoid following one heading with another heading.
|
||||
* Avoid skipping heading levels. For example, an h1 should be followed by an h2 rather than an h3.
|
||||
* Avoid having just one lower-level heading. For example, h1, h2, h2, h3, h3, h2 is a good order. Do no go h1, h2, h3, h2, h3, h2.
|
||||
* Don't include parenthetical words like (Important!) in headings.
|
||||
|
||||
### Images
|
||||
|
||||
* Preferred format is .png
|
||||
* File extension should be all lowercase.
|
||||
* Preferred DPI is 72.
|
||||
* Assume all graphics will be exclusively viewed on the web.
|
||||
* Maximum image size is 3840px X 2160px.
|
||||
* Screenshots should be readable, but not too large.
|
||||
|
||||
### Capitalization
|
||||
|
||||
* Grafana, Loki, and Prometheus are always capitalized unless part of a code block.
|
||||
* API names are always Title Case, followed by "API"—for example, "Dashboard Permissions API"
|
||||
* Git is always capitalized, unless part of a code block.
|
||||
* Abbreviations are always capitalized (such as API, HTTP, ID, JSON, SQL, or URL) unless they are part of a code block.
|
||||
* Menu and submenu titles always use sentence case: capitalize the first word, and lowercase the rest.
|
||||
- "Dashboards" when referring to the submenu title.
|
||||
- "Keyboard shortcuts" when referring to the submenu topic.
|
||||
* Generic and plural versions are always lowercase.
|
||||
- Lowercase "dashboard" when referring to a dashboard generally.
|
||||
- Lowercase "dashboards" when referring to multiple dashboards.
|
||||
* **Exceptions:** If a term is lowercased in the Grafana UI, then match the UI.
|
||||
|
||||
### Links and references
|
||||
|
||||
When referencing another document, use "Refer to" rather than alternatives such as "See" or "Check out."
|
||||
|
||||
Always give the reader some idea of what to expect in the reference. Avoid blind references, such as, "Refer to [this file](link)."
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Word usage
|
||||
|
||||
Grafana products has some words, abbreviations, and slang particular to this 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.
|
||||
|
||||
#### data source
|
||||
|
||||
Two words, not one
|
||||
|
||||
**Exceptions:**
|
||||
* "datasource" used as an identifier
|
||||
* "datasource" in a URL
|
||||
* Use "data source" instead of "datasource" unless used as an identifier, in code, or as part of a URL.
|
||||
* 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.
|
||||
|
||||
#### display (verb)
|
||||
|
||||
*Display* is a transitive verb, which means it always needs a direct object.
|
||||
* Correct, active voice: Grafana displays your list of active alarms.
|
||||
* Correct, but passive voice: Your list of active alarms is displayed.
|
||||
* Incorrect: The list of active alarms displays.
|
||||
|
||||
#### 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._
|
||||
|
||||
Do not hyphenate when it is used as a noun. For example: _Open source is the best way to develop software._
|
||||
|
||||
#### setup, set up
|
||||
|
||||
Two words if used as a verb, one word if used as a noun.
|
||||
|
||||
**Examples**
|
||||
|
||||
* Set up the workspace.
|
||||
* Initial setup might take five minutes.
|
||||
@@ -1,168 +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.
|
||||
|
||||
## 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`
|
||||
- `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 = pageFactory({
|
||||
url: '/login', // used when called from Login.visit()
|
||||
selectors: {
|
||||
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/src/pages/index.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={e2e.pages.Login.selectors.username}/>
|
||||
</div>
|
||||
```
|
||||
|
||||
The last step in our example is to use our `Login` page as part of a test. The `pageFactory` function we used before gives us two things:
|
||||
- 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 in the `selectors` property 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 = pageFactory({
|
||||
url: '/datasources',
|
||||
selectors: {
|
||||
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/src/pages/index.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={e2e.pages.DataSources.selectors.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.
|
||||
@@ -1,291 +0,0 @@
|
||||
# Frontend Style Guide
|
||||
|
||||
Generally we follow the Airbnb [React Style Guide](https://github.com/airbnb/javascript/tree/master/react).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Frontend Style Guide](#frontend-style-guide)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Basic rules](#basic-rules)
|
||||
- [Naming conventions](#naming-conventions)
|
||||
- [Files and directories naming conventions](#files-and-directories-naming-conventions)
|
||||
- [Code organization](#code-organization)
|
||||
- [Exports](#exports)
|
||||
- [Comments](#comments)
|
||||
- [React](#react)
|
||||
- [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
|
||||
|
||||
#### Use `PascalCase` for:
|
||||
|
||||
##### Typescript class names
|
||||
|
||||
```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._
|
||||
|
||||
### 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.
|
||||
|
||||
```tsx
|
||||
// bad
|
||||
handleChange = () => {
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MyComponent changed={this.handleChange} />
|
||||
);
|
||||
}
|
||||
|
||||
// good
|
||||
onChange = () => {
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<MyComponent onChange={this.onChange} />
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
##### React Component definitions
|
||||
|
||||
```jsx
|
||||
// bad
|
||||
export class YourClass extends PureComponent { ... }
|
||||
|
||||
// good
|
||||
export class YourClass extends PureComponent<{},{}> { ... }
|
||||
```
|
||||
|
||||
##### React Component constructor
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
constructor(props) {...}
|
||||
|
||||
// good
|
||||
constructor(props: Props) {...}
|
||||
```
|
||||
|
||||
##### React Component defaultProps
|
||||
|
||||
```typescript
|
||||
// bad
|
||||
static defaultProps = { ... }
|
||||
|
||||
// good
|
||||
static defaultProps: Partial<Props> = { ... }
|
||||
```
|
||||
|
||||
## State management
|
||||
|
||||
- Don't mutate state in reducers or thunks.
|
||||
- Use helpers `actionCreatorFactory` and `reducerFactory` instead of traditional `switch statement` reducers in Redux. See [Redux framework](redux.md) for more details.
|
||||
- Use `reducerTester` to test reducers. See [Redux framework](redux.md) for more details.
|
||||
- Use state selectors to access state instead of accessing state directly.
|
||||
@@ -1,48 +0,0 @@
|
||||
# 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.
|
||||
|
||||
## Test functionality
|
||||
|
||||
### reducerTester
|
||||
|
||||
Fluent API that simplifies the testing of reducers
|
||||
|
||||
#### Usage
|
||||
|
||||
```typescript
|
||||
reducerTester()
|
||||
.givenReducer(someReducer, initialState)
|
||||
.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')]);
|
||||
```
|
||||
@@ -1,179 +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`.
|
||||
|
||||
### 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 [Storybook’s 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 don’t 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 component’s stories
|
||||
|
||||
To link a component’s 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 don’ts 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. Something that is required when the MDX file has no relation to a component is a `Meta` tag that says where in the hierarchy the component will live. 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.
|
||||
@@ -1,91 +0,0 @@
|
||||
# Styling Grafana
|
||||
|
||||
[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
|
||||
|
||||
### Basic styling
|
||||
|
||||
For styling components, use [Emotion's `css` function](https://emotion.sh/docs/emotion#css).
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { css } from 'emotion';
|
||||
|
||||
const ComponentA = () => (
|
||||
<div
|
||||
className={css`
|
||||
background: red;
|
||||
`}
|
||||
>
|
||||
As red as you can get
|
||||
</div>
|
||||
);
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
Let's say you need to style a component that has a 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';
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
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};
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
const ComponentA = () => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme);
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
As red as you can get
|
||||
<i className={styles.icon} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
For more information about themes at Grafana please see the [themes guide](./themes.md).
|
||||
|
||||
### Composing class names
|
||||
|
||||
For class composition, use [Emotion's `cx` function](https://emotion.sh/docs/emotion#cx).
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ComponentA: React.FC<Props> = ({ className }) => {
|
||||
const finalClassName = cx(
|
||||
className,
|
||||
css`
|
||||
background: red;
|
||||
`
|
||||
);
|
||||
|
||||
return <div className={finalClassName}>As red as you can ge</div>;
|
||||
};
|
||||
```
|
||||
@@ -1,162 +0,0 @@
|
||||
# Theming Grafana
|
||||
|
||||
## 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.
|
||||
|
||||
## 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
|
||||
import { ThemeContext } from '@grafana/ui';
|
||||
|
||||
<ThemeContext.Consumer>{theme => <Foo theme={theme} />}</ThemeContext.Consumer>;
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```tsx
|
||||
import React, { useContext } from 'react';
|
||||
import { ThemeContext } from '@grafana/ui';
|
||||
|
||||
const Foo: React.FunctionComponent<FooProps> = () => {
|
||||
const theme = useContext(ThemeContext);
|
||||
|
||||
// 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.
|
||||
|
||||
```ts
|
||||
import { ThemeContext, Themeable } from '@grafana/ui';
|
||||
|
||||
interface FooProps extends Themeable {}
|
||||
|
||||
const Foo: React.FunctionComponent<FooProps> = () => ...
|
||||
|
||||
export default withTheme(Foo);
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
To make your snapshot theme independent, use the `mockThemeContext` helper function:
|
||||
|
||||
```tsx
|
||||
import { mockThemeContext } from '@grafana/ui';
|
||||
import { MyComponent } from './MyComponent';
|
||||
|
||||
describe('MyComponent', () => {
|
||||
let restoreThemeContext;
|
||||
|
||||
beforeAll(() => {
|
||||
// Create ThemeContext mock before any snapshot test is executed
|
||||
restoreThemeContext = mockThemeContext({ type: GrafanaThemeType.Dark });
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// Make sure the theme is restored after snapshot tests are performed
|
||||
restoreThemeContext();
|
||||
});
|
||||
|
||||
it('renders correctyl', () => {
|
||||
const wrapper = mount(<MyComponent />)
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Using themes in [Storybook](https://storybook.js.org/)
|
||||
|
||||
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:
|
||||
|
||||
```tsx
|
||||
// Foo.story.tsx
|
||||
const FooWithTheme = withTheme(Foo);
|
||||
|
||||
FooStories.add('Story' () => {
|
||||
return <FooWithTheme />
|
||||
});
|
||||
```
|
||||
|
||||
#### Use `renderComponentWithTheme` helper:
|
||||
|
||||
```tsx
|
||||
// Bar.story.tsx
|
||||
|
||||
BarStories.add('Story' () => {
|
||||
return renderComponentWithTheme(Bar, /* pass props here */)
|
||||
});
|
||||
```
|
||||
|
||||
### 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:
|
||||
|
||||
```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?
|
||||
|
||||
> 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!**
|
||||
|
||||
#### If you need to modify a *Sass variable value* you need to modify the corresponding Typescript file that is the 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:
|
||||
- `_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:
|
||||
|
||||
```ts
|
||||
// graph.ts
|
||||
import { provideTheme } from 'app/core/utils/ConfigProvider';
|
||||
|
||||
// Create component with ThemeContext.Provider first.
|
||||
// Otherwise React will create new components every time it renders!
|
||||
const LegendWithThemeProvider = provideTheme(Legend);
|
||||
|
||||
const legendReactElem = React.createElement(LegendWithThemeProvider, legendProps);
|
||||
ReactDOM.render(legendReactElem, this.legendElem, () => this.renderPanel());
|
||||
```
|
||||
|
||||
`provideTheme` makes current theme available via ThemeContext by checking if user has `lightTheme` set in her boot data.
|
||||
@@ -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 a topic 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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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 quite 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.
|
||||
@@ -1,32 +0,0 @@
|
||||
# Triage issues
|
||||
|
||||
Triage helps ensure that issues resolve quickly by:
|
||||
|
||||
- Ensuring the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took.
|
||||
- Giving a contributor the information they need before they commit to resolving an issue.
|
||||
- Lowering the issue count by preventing duplicate issues.
|
||||
- Streamlining the development process by preventing duplicate discussions.
|
||||
|
||||
This document gives you some ideas on what you can do to help. For more information, read more about [how the core Grafana team triage issues](/ISSUE_TRIAGE.md).
|
||||
|
||||
## Improve issues
|
||||
|
||||
Improve issues by suggesting improvements to the title and description. If you think an issue has formatting issues, bad language, or grammatical errors, post a comment to let the author and maintainers know.
|
||||
|
||||
## Report resolved issues
|
||||
|
||||
If you think an issue has been resolved, or is no longer relevant, suggest us to close it. Add a comment on the issue, where you explain the reason it should be closed. Make sure to include any related issues and pull requests.
|
||||
|
||||
## Investigate issues
|
||||
|
||||
Investigate issues that we haven't been able to reproduce yet. In some cases, there are many combinations of panels, dashboards, and data sources that make it difficult for us to reproduce certain issues. Help us by adding more information.
|
||||
|
||||
## Vote on issues
|
||||
|
||||
Use [GitHub reactions](https://help.github.com/en/articles/about-conversations-on-github#reacting-to-ideas-in-comments) to let us know what's important to you. Vote on bugs if you've experienced the same problem. **Don't vote, or react, by commenting on the issue.**
|
||||
|
||||
Read more about [how we prioritize issues](/ISSUE_TRIAGE.md#4-prioritization-of-issues).
|
||||
|
||||
## Report duplicates
|
||||
|
||||
If you find two issues that describe the same thing, add a comment in one of the issues, with a reference (`#<issue number>`) to the other. Explain why you think the issue is duplicated.
|
||||
@@ -1,40 +1,37 @@
|
||||
# Set up your development environment
|
||||
This folder contains useful scripts and configuration for...
|
||||
|
||||
This folder contains useful scripts and configuration so you can:
|
||||
* Configuring dev datasources in Grafana
|
||||
* Configuring dev & test scenarios dashboards.
|
||||
* Creating docker-compose file with DBs and fake data.
|
||||
|
||||
* Configure data sources in Grafana for development.
|
||||
* Configure dashboards for development and test scenarios.
|
||||
* Create docker-compose file with databases and fake data.
|
||||
|
||||
## Install Docker
|
||||
|
||||
Grafana uses [Docker](https://docker.com) to make the task of setting up databases a little easier. If you do not have it already, make sure you [install Docker](https://docs.docker.com/docker-for-mac/install/) before proceeding to the next step.
|
||||
|
||||
## Developer dashboards and data sources
|
||||
# Dev dashboards and data sources
|
||||
|
||||
```bash
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
After restarting the Grafana server, there should be a number of data sources named `gdev-<type>` provisioned as well as
|
||||
a dashboard folder named `gdev dashboards`. This folder contains dashboard and panel features tests dashboards.
|
||||
After restarting grafana server there should now be a number of datasources named `gdev-<type>` provisioned as well as
|
||||
a dashboard folder named `gdev dashboards`. This folder contains dashboard & panel features tests dashboards.
|
||||
|
||||
Please update these dashboards or make new ones as new panels and dashboards features are developed or new bugs are
|
||||
#### Dev dashboards
|
||||
|
||||
Please update these dashboards or make new ones as new panels & dashboards features are developed or new bugs are
|
||||
found. The dashboards are located in the `devenv/dev-dashboards` folder.
|
||||
|
||||
## docker-compose with databases
|
||||
|
||||
This command creates a docker-compose file with specified databases configured and ready to run. Each database has
|
||||
a prepared image with some fake data ready to use. For available databases, see `docker/blocks` directory. Notice that
|
||||
for some databases there are multiple images, for example there is prometheus_mac specifically for Macs or different
|
||||
version.
|
||||
# docker-compose with databases
|
||||
|
||||
```bash
|
||||
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:
|
||||
This command will create a docker compose file with specified databases configured and ready to run. Each database has
|
||||
a prepared image with some fake data ready to use. For available databases see `docker/blocks` directory. Mind that
|
||||
for some databases there are multiple images, for example there is prometheus_mac specifically for Macs or different
|
||||
version.
|
||||
|
||||
Some of the blocks support dynamic change of the image version used in docker file. The signature looks like this - `make devenv sources=postgres,openldap name-of-block_version=9.2` -
|
||||
|
||||
```bash
|
||||
make devenv sources=postgres,openldap postgres_version=9.2
|
||||
```
|
||||
```
|
||||
@@ -5,7 +5,6 @@ providers:
|
||||
folder: 'gdev dashboards'
|
||||
folderUid: ''
|
||||
type: file
|
||||
allowUiUpdates: false
|
||||
updateIntervalSeconds: 60
|
||||
options:
|
||||
path: devenv/dev-dashboards
|
||||
|
||||
@@ -20,8 +20,8 @@ datasources:
|
||||
url: http://localhost:3011
|
||||
|
||||
- name: gdev-testdata
|
||||
isDefault: true
|
||||
type: testdata
|
||||
isDefault: true
|
||||
|
||||
- name: gdev-influxdb
|
||||
type: influxdb
|
||||
@@ -227,20 +227,6 @@ 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
|
||||
|
||||
@@ -28,7 +28,11 @@
|
||||
"value": "triggered"
|
||||
}
|
||||
],
|
||||
"colors": ["#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a"],
|
||||
"colors": [
|
||||
"#299c46",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"#d44a3a"
|
||||
],
|
||||
"d3DivId": "d3_svg_4",
|
||||
"datasource": "gdev-testdata",
|
||||
"decimals": 2,
|
||||
@@ -111,7 +115,11 @@
|
||||
},
|
||||
"id": 4,
|
||||
"links": [],
|
||||
"notcolors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
|
||||
"notcolors": [
|
||||
"rgba(245, 54, 54, 0.9)",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(50, 172, 45, 0.97)"
|
||||
],
|
||||
"operatorName": "avg",
|
||||
"operatorOptions": [
|
||||
{
|
||||
@@ -876,8 +884,8 @@
|
||||
"value": "celsius"
|
||||
},
|
||||
{
|
||||
"text": "Fahrenheit (°F)",
|
||||
"value": "fahrenheit"
|
||||
"text": "Farenheit (°F)",
|
||||
"value": "farenheit"
|
||||
},
|
||||
{
|
||||
"text": "Kelvin (K)",
|
||||
@@ -1106,7 +1114,11 @@
|
||||
"value": "triggered"
|
||||
}
|
||||
],
|
||||
"colors": ["#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a"],
|
||||
"colors": [
|
||||
"#299c46",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"#d44a3a"
|
||||
],
|
||||
"d3DivId": "d3_svg_5",
|
||||
"datasource": "gdev-testdata",
|
||||
"decimals": 2,
|
||||
@@ -1189,7 +1201,11 @@
|
||||
},
|
||||
"id": 5,
|
||||
"links": [],
|
||||
"notcolors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
|
||||
"notcolors": [
|
||||
"rgba(245, 54, 54, 0.9)",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(50, 172, 45, 0.97)"
|
||||
],
|
||||
"operatorName": "avg",
|
||||
"operatorOptions": [
|
||||
{
|
||||
@@ -1975,8 +1991,8 @@
|
||||
"value": "celsius"
|
||||
},
|
||||
{
|
||||
"text": "Fahrenheit (°F)",
|
||||
"value": "fahrenheit"
|
||||
"text": "Farenheit (°F)",
|
||||
"value": "farenheit"
|
||||
},
|
||||
{
|
||||
"text": "Kelvin (K)",
|
||||
@@ -2205,7 +2221,11 @@
|
||||
"value": "triggered"
|
||||
}
|
||||
],
|
||||
"colors": ["#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a"],
|
||||
"colors": [
|
||||
"#299c46",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"#d44a3a"
|
||||
],
|
||||
"d3DivId": "d3_svg_2",
|
||||
"datasource": "gdev-testdata",
|
||||
"decimals": 2,
|
||||
@@ -2288,7 +2308,11 @@
|
||||
},
|
||||
"id": 2,
|
||||
"links": [],
|
||||
"notcolors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
|
||||
"notcolors": [
|
||||
"rgba(245, 54, 54, 0.9)",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(50, 172, 45, 0.97)"
|
||||
],
|
||||
"operatorName": "avg",
|
||||
"operatorOptions": [
|
||||
{
|
||||
@@ -3054,8 +3078,8 @@
|
||||
"value": "celsius"
|
||||
},
|
||||
{
|
||||
"text": "Fahrenheit (°F)",
|
||||
"value": "fahrenheit"
|
||||
"text": "Farenheit (°F)",
|
||||
"value": "farenheit"
|
||||
},
|
||||
{
|
||||
"text": "Kelvin (K)",
|
||||
@@ -3276,7 +3300,10 @@
|
||||
],
|
||||
"schemaVersion": 16,
|
||||
"style": "dark",
|
||||
"tags": ["panel-test", "gdev"],
|
||||
"tags": [
|
||||
"panel-test",
|
||||
"gdev"
|
||||
],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
@@ -3285,8 +3312,29 @@
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
|
||||
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
|
||||
"refresh_intervals": [
|
||||
"5s",
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
],
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - Polystat",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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": [],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -876,8 +876,8 @@
|
||||
"value": "celsius"
|
||||
},
|
||||
{
|
||||
"text": "Fahrenheit (°F)",
|
||||
"value": "fahrenheit"
|
||||
"text": "Farenheit (°F)",
|
||||
"value": "farenheit"
|
||||
},
|
||||
{
|
||||
"text": "Kelvin (K)",
|
||||
@@ -1975,8 +1975,8 @@
|
||||
"value": "celsius"
|
||||
},
|
||||
{
|
||||
"text": "Fahrenheit (°F)",
|
||||
"value": "fahrenheit"
|
||||
"text": "Farenheit (°F)",
|
||||
"value": "farenheit"
|
||||
},
|
||||
{
|
||||
"text": "Kelvin (K)",
|
||||
@@ -3054,8 +3054,8 @@
|
||||
"value": "celsius"
|
||||
},
|
||||
{
|
||||
"text": "Fahrenheit (°F)",
|
||||
"value": "fahrenheit"
|
||||
"text": "Farenheit (°F)",
|
||||
"value": "farenheit"
|
||||
},
|
||||
{
|
||||
"text": "Kelvin (K)",
|
||||
|
||||
@@ -1,512 +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": 3,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 6,
|
||||
"interval": "6m",
|
||||
"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": "auto",
|
||||
"sparkline": {
|
||||
"show": true
|
||||
}
|
||||
},
|
||||
"pluginVersion": "6.6.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
|
||||
},
|
||||
"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": 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,
|
||||
"w": 4,
|
||||
"x": 6,
|
||||
"y": 15
|
||||
},
|
||||
"id": 8,
|
||||
"interval": "10m",
|
||||
"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": "line",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"sparkline": {
|
||||
"show": true
|
||||
}
|
||||
},
|
||||
"pluginVersion": "6.6.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": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": null,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 8,
|
||||
"x": 10,
|
||||
"y": 15
|
||||
},
|
||||
"id": 12,
|
||||
"interval": "10m",
|
||||
"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": "line",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "horizontal",
|
||||
"sparkline": {
|
||||
"show": true
|
||||
}
|
||||
},
|
||||
"pluginVersion": "6.6.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": "stat"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 22,
|
||||
"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"]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - Stat"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
FROM jmferrer/apache2-reverse-proxy:latest
|
||||
|
||||
COPY ports.conf /etc/apache2/sites-enabled
|
||||
COPY proxy.conf /etc/apache2/sites-enabled
|
||||
@@ -1,10 +0,0 @@
|
||||
# This will proxy all requests for http://localhost:10081/grafana/ to
|
||||
# http://localhost:3000 (Grafana running locally)
|
||||
#
|
||||
# Please note that you'll need to change the root_url in the Grafana configuration:
|
||||
# root_url = %(protocol)s://%(domain)s:10081/grafana/
|
||||
|
||||
apacheproxy:
|
||||
build: docker/blocks/apache_proxy_mac
|
||||
ports:
|
||||
- "10081:10081"
|
||||
@@ -1 +0,0 @@
|
||||
Listen 10081
|
||||
@@ -1,4 +0,0 @@
|
||||
<VirtualHost *:10081>
|
||||
ProxyPass /grafana/ http://host.docker.internal:3000/
|
||||
ProxyPassReverse /grafana/ http://host.docker.internal:3000/
|
||||
</VirtualHost>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,27 +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
|
||||
# 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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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://localhost:3000/login;
|
||||
}
|
||||
|
||||
proxy_set_header Authorization "";
|
||||
proxy_pass http://localhost:3000/;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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/;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# This Dockerfile builds an image for a client_golang example.
|
||||
|
||||
# Builder image, where we build the example.
|
||||
FROM golang:1.13.4 AS builder
|
||||
FROM golang:1.9.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
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
FROM golang:latest
|
||||
ADD main.go /
|
||||
WORKDIR /
|
||||
RUN go build -o main .
|
||||
EXPOSE 3011
|
||||
ENTRYPOINT ["/main"]
|
||||
@@ -1,6 +0,0 @@
|
||||
slow_proxy_mac:
|
||||
build: docker/blocks/slow_proxy_mac
|
||||
ports:
|
||||
- '3011:3011'
|
||||
environment:
|
||||
ORIGIN_SERVER: 'http://host.docker.internal:9090/'
|
||||
@@ -1,31 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
origin := os.Getenv("ORIGIN_SERVER")
|
||||
if origin == "" {
|
||||
origin = "http://host.docker.internal:9090/"
|
||||
}
|
||||
|
||||
sleep := time.Minute
|
||||
|
||||
originURL, _ := url.Parse(origin)
|
||||
proxy := httputil.NewSingleHostReverseProxy(originURL)
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Printf("sleeping for %s then proxying request: %s", sleep.String(), r.RequestURI)
|
||||
<-time.After(sleep)
|
||||
proxy.ServeHTTP(w, r)
|
||||
})
|
||||
|
||||
log.Fatal(http.ListenAndServe(":3011", nil))
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,2 +1,2 @@
|
||||
version: "2.1"
|
||||
version: "2"
|
||||
services:
|
||||
|
||||
@@ -7,7 +7,7 @@ Included services
|
||||
|
||||
* Grafana
|
||||
* Mysql - Grafana configuration database and session storage
|
||||
* Prometheus - Monitoring of Grafana and used as data source of provisioned alert rules
|
||||
* Prometheus - Monitoring of Grafana and used as datasource of provisioned alert rules
|
||||
* Nginx - Reverse proxy for Grafana and Prometheus. Enables browsing Grafana/Prometheus UI using a hostname
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -35,12 +35,6 @@ Run load test for 10 virtual users:
|
||||
$ ./run.sh -v 10
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
@@ -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) => {}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user