Merge remote-tracking branch 'origin/main' into zoltan/mssql-migration
This commit is contained in:
+75
-27
@@ -44,7 +44,7 @@ exports[`no enzyme tests`] = {
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/ListView/index.test.js:1734982398": [
|
||||
[14, 26, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js:700147304": [
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/SpanDetail/index.test.js:1241675783": [
|
||||
[16, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/SpanTreeOffset.test.js:174536706": [
|
||||
@@ -65,9 +65,6 @@ exports[`no enzyme tests`] = {
|
||||
"packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:276996587": [
|
||||
[14, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx:3743889097": [
|
||||
[0, 26, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"public/app/core/components/Select/MetricSelect.test.tsx:1074737147": [
|
||||
[0, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
@@ -3114,6 +3111,12 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/core/components/PageNew/PageTabs.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/core/components/PageNew/SectionNav.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
@@ -3125,10 +3128,6 @@ exports[`better eslint`] = {
|
||||
"public/app/core/components/PermissionList/PermissionList.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/core/components/RolePicker/RolePickerMenu.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
@@ -3212,17 +3211,8 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "9"]
|
||||
],
|
||||
"public/app/core/logsModel.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "6"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "7"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "10"]
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/core/mod_defs.d.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@@ -4532,8 +4522,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
|
||||
],
|
||||
"public/app/features/dashboard/state/DashboardMigrator.test.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@@ -5728,6 +5717,56 @@ exports[`better eslint`] = {
|
||||
"public/app/features/sandbox/TestStuffPage.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/scenes/components/SceneFlexLayout.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/scenes/core/SceneComponentEditWrapper.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
|
||||
],
|
||||
"public/app/features/scenes/core/SceneObjectBase.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "5"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "7"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "9"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "10"]
|
||||
],
|
||||
"public/app/features/scenes/core/SceneTimeRange.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/features/scenes/core/events.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"public/app/features/scenes/core/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/features/scenes/editor/SceneObjectTree.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"]
|
||||
],
|
||||
"public/app/features/scenes/querying/SceneQueryRunner.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "4"]
|
||||
],
|
||||
"public/app/features/scenes/variables/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/features/search/components/SearchCard.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
@@ -5808,6 +5847,20 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"]
|
||||
],
|
||||
"public/app/features/storage/StoragePage.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/features/storage/helper.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
|
||||
],
|
||||
"public/app/features/teams/CreateTeam.test.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/features/teams/TeamGroupSync.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
@@ -8929,9 +8982,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "14"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "18"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "19"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "17"]
|
||||
],
|
||||
"public/app/plugins/panel/geomap/components/DataHoverRows.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
@@ -10300,9 +10351,6 @@ exports[`no undocumented stories`] = {
|
||||
"packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx:5381": [
|
||||
[0, 0, 0, "No undocumented stories are allowed, please add an .mdx file with some documentation", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/PluginSignatureBadge/PluginSignatureBadge.story.tsx:5381": [
|
||||
[0, 0, 0, "No undocumented stories are allowed, please add an .mdx file with some documentation", "5381"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/QueryField/QueryField.story.tsx:5381": [
|
||||
[0, 0, 0, "No undocumented stories are allowed, please add an .mdx file with some documentation", "5381"]
|
||||
],
|
||||
|
||||
@@ -108,6 +108,7 @@ pkg/tsdb/testdatasource/sims/ @grafana/grafana-edge-squad
|
||||
/public/app/features/comments/ @grafana/grafana-edge-squad
|
||||
/public/app/features/dimensions/ @grafana/grafana-edge-squad
|
||||
/public/app/features/geo/ @grafana/grafana-edge-squad
|
||||
/public/app/features/storage/ @grafana/grafana-edge-squad
|
||||
/public/app/features/live/ @grafana/grafana-edge-squad
|
||||
/public/app/features/explore/ @grafana/observability-experience-squad
|
||||
/public/app/features/plugins @grafana/plugins-platform-frontend
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
name: "doc-validator"
|
||||
on:
|
||||
pull_request:
|
||||
paths: ["docs/sources/**"]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
doc-validator:
|
||||
runs-on: "ubuntu-latest"
|
||||
container:
|
||||
image: "grafana/doc-validator:latest"
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: "actions/checkout@v3"
|
||||
- name: "Run doc-validator tool"
|
||||
# Ensure that the CI always passes until all errors are resolved.
|
||||
run: "doc-validator ./docs/sources || true"
|
||||
@@ -1 +0,0 @@
|
||||
http-bind-address: :8086
|
||||
@@ -5,6 +5,7 @@
|
||||
- '8086:8086'
|
||||
environment:
|
||||
INFLUXD_REPORTING_DISABLED: 'true'
|
||||
INFLUXD_HTTP_BIND_ADDRESS: ':8086'
|
||||
DOCKER_INFLUXDB_INIT_MODE: 'setup'
|
||||
DOCKER_INFLUXDB_INIT_USERNAME: 'grafana'
|
||||
DOCKER_INFLUXDB_INIT_PASSWORD: 'grafana12345'
|
||||
@@ -12,7 +13,6 @@
|
||||
DOCKER_INFLUXDB_INIT_BUCKET: 'mybucket'
|
||||
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: 'mytoken'
|
||||
volumes:
|
||||
- ./docker/blocks/influxdb/config.yaml:/etc/influxdb2/config.yaml
|
||||
- ./docker/blocks/influxdb/setup_influxql.sh:/docker-entrypoint-initdb.d/setup_influxql.sh
|
||||
|
||||
telegraf:
|
||||
|
||||
@@ -233,7 +233,10 @@ datasources:
|
||||
|
||||
> This feature is available from v7.1
|
||||
|
||||
You can manage plugins in Grafana by adding one or more YAML config files in the [`provisioning/plugins`]({{< relref "../../setup-grafana/configure-grafana/#provisioning" >}}) directory. Each config file can contain a list of `apps` that will be updated during start up. Grafana updates each app to match the configuration file.
|
||||
You can manage plugin applications in Grafana by adding one or more YAML config files in the [`provisioning/plugins`]({{< relref "../../setup-grafana/configure-grafana/#provisioning" >}}) directory. Each config file can contain a list of `apps` that will be updated during start up. Grafana updates each app to match the configuration file.
|
||||
|
||||
> **Note:** This feature enables you to provision plugin configurations, not the plugins themselves.
|
||||
> The plugins must already be installed on the grafana instance
|
||||
|
||||
### Example plugin configuration file
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ The following tables list permissions associated with basic and fixed roles.
|
||||
| `fixed:settings:reader` | `settings:read` | Read Grafana instance settings. |
|
||||
| `fixed:settings:writer` | All permissions from `fixed:settings:reader` and<br>`settings:write` | Read and update Grafana instance settings. |
|
||||
| `fixed:stats:reader` | `server.stats:read` | Read Grafana instance statistics. |
|
||||
| `fixed:teams:creator` | `teams:create`<br>`org.users:read` | Create a team and list organization users (required to manage the created team). |
|
||||
| `fixed:teams:creator` | `teams:create`<br>`org.users:read`<br>`serviceaccounts:read` | Create a team and list organization users and service accounts (required to manage the created team). |
|
||||
| `fixed:teams:writer` | `teams:create`<br>`teams:delete`<br>`teams:read`<br>`teams:write`<br>`teams.permissions:read`<br>`teams.permissions:write` | Create, read, update and delete teams and manage team memberships. |
|
||||
| `fixed:users:reader` | `users:read`<br>`users.quotas:read`<br>`users.authtoken:read`<br>` | Read all users and their information, such as team memberships, authentication tokens, and quotas. |
|
||||
| `fixed:users:writer` | All permissions from `fixed:users:reader` and <br>`users:write`<br>`users:create`<br>`users:delete`<br>`users:enable`<br>`users:disable`<br>`users.password:write`<br>`users.permissions:write`<br>`users:logout`<br>`users.authtoken:write`<br>`users.quotas:write` | Read and update all attributes and settings for all users in Grafana: update user information, read user information, create or enable or disable a user, make a user a Grafana administrator, sign out a user, update a user’s authentication token, or update quotas for all users. |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/alerting/contact-points/message-templating/example-template-functions/
|
||||
- /docs/grafana/latest/alerting/fundamentals/annotation-label/example-template-functions/
|
||||
- /docs/grafana/latest/alerting/unified-alerting/fundamentals/annotation-label/template-functions/
|
||||
keywords:
|
||||
- grafana
|
||||
- alerting
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/alerting/contact-points/message-templating/template-functions/
|
||||
- /docs/grafana/latest/alerting/message-templating/template-functions/
|
||||
- /docs/grafana/latest/alerting/unified-alerting/message-templating/template-functions/
|
||||
- /docs/grafana/latest/alerting/fundamentals/annotation-label/template-functions/
|
||||
- /docs/grafana/latest/alerting/unified-alerting/fundamentals/annotation-label/template-functions/
|
||||
keywords:
|
||||
|
||||
@@ -51,6 +51,6 @@ Once you have a strategy or design guidelines, write them down to help maintain
|
||||
- Use the left and right Y-axes when displaying time series with different units or ranges.
|
||||
- Add documentation to dashboards and panels.
|
||||
- To add documentation to a dashboard, add a [Text panel visualization]({{< relref "../visualizations/text-panel/" >}}) to the dashboard. Record things like the purpose of the dashboard, useful resource links, and any instructions users might need to interact with the dashboard. Check out this [Wikimedia example](https://grafana.wikimedia.org/d/000000066/resourceloader?orgId=1).
|
||||
- To add documentation to a panel, [edit the panel settings]({{< relref "../panels/working-with-panels/add-panel/" >}}) and add a description. Any text you add will appear if you hover your cursor over the small `i` in the top left corner of the panel.
|
||||
- To add documentation to a panel, edit the panel settings and add a description. Any text you add will appear if you hover your cursor over the small `i` in the top left corner of the panel.
|
||||
- Reuse your dashboards and enforce consistency by using [templates and variables]({{< relref "../variables/" >}}).
|
||||
- Be careful with stacking graph data. The visualizations can be misleading, and hide important data. We recommend turning it off in most cases.
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/working-with-panels/navigate-panel-editor/
|
||||
- /docs/grafana/latest/panels/working-with-panels/navigate-inspector-panel/
|
||||
- /docs/grafana/latest/dashboards/dashboard-create/
|
||||
- /docs/grafana/latest/features/dashboard/dashboards/
|
||||
- /docs/grafana/latest/panels/working-with-panels/add-panel/
|
||||
- /docs/grafana/latest/dashboards/add-organize-panels/
|
||||
title: Add and organize panels
|
||||
menuTitle: Add and organize panels
|
||||
weight: 2
|
||||
---
|
||||
|
||||
# Add and organize panels
|
||||
|
||||
This section describes the areas of the Grafana panel editor.
|
||||
|
||||
1. Panel header: The header section lists the dashboard in which the panel appears and the following controls:
|
||||
|
||||
- **Dashboard settings (gear) icon -** Click to access the dashboard settings.
|
||||
- **Discard -** Discards changes you have made to the panel since you last saved the dashboard.
|
||||
- **Save -** Saves changes you made to the panel.
|
||||
- **Apply -** Applies changes you made and closes the panel editor, returning you to the dashboard. You will have to save the dashboard to persist the applied changes.
|
||||
|
||||
1. Visualization preview: The visualization preview section contains the following options:
|
||||
|
||||
- **Table view -** Convert any visualization to a table so that you can see the data. Table views are useful for troubleshooting.
|
||||
- **Fill -** The visualization preview fills the available space. If you change the width of the side pane or height of the bottom pane the visualization changes to fill the available space.
|
||||
- **Actual -** The visualization preview will have the exact size as the size on the dashboard. If not enough space is available, the visualization will scale down preserving the aspect ratio.
|
||||
- **Time range controls -** For more information, refer to [Time range controls]({{< relref "time-range-controls/" >}}).
|
||||
|
||||
1. Data section: The data section contains tabs where you enter queries, transform your data, and create alert rules (if applicable).
|
||||
|
||||
- **Query tab -** Select your data source and enter queries here. For more information, refer to [Add a query]({{< relref "../panels/query-a-data-source/add-a-query/" >}}).
|
||||
- **Transform tab -** Apply data transformations. For more information, refer to [Transform data]({{< relref "../panels/transform-data/" >}}).
|
||||
- **Alert tab -** Write alert rules. For more information, refer to [Overview of Grafana 8 alerting]({{< relref "../alerting/" >}}).
|
||||
|
||||
1. Panel display options: The display options section contains tabs where you configure almost every aspect of your data visualization, including:
|
||||
|
||||
- [Apply color to series and fields]({{< relref "../panels/working-with-panels/apply-color-to-series/" >}})
|
||||
- [Format a standard field]({{< relref "../panels/working-with-panels/format-standard-fields/" >}})
|
||||
- [Add a title and description to a panel]({{< relref "../panels/working-with-panels/add-title-and-description/" >}})
|
||||
|
||||
> Not all options are available for each visualization.
|
||||
|
||||
{{< figure src="/static/img/docs/panel-editor/panel-editor-8-0.png" class="docs-image--no-shadow" max-width="1500px" >}}
|
||||
|
||||
## Open the panel inspect drawer
|
||||
|
||||
The inspect drawer helps you understand and troubleshoot your panels. You can view the raw data for any panel, export that data to a comma-separated values (CSV) file, view query requests, and export panel and data JSON.
|
||||
|
||||
> **Note:** Not all panel types include all tabs. For example, dashboard list panels do not have raw data to inspect, so they do not display the Stats, Data, or Query tabs.
|
||||
|
||||
The panel inspector consists of the following options:
|
||||
|
||||
1. The panel inspect drawer displays opens a drawer on the right side. Click the arrow in the upper right corner to expand or reduce the drawer pane.
|
||||
|
||||
1. **Data tab -** Shows the raw data returned by the query with transformations applied. Field options such as overrides and value mappings are not applied by default.
|
||||
|
||||
1. **Stats tab -** Shows how long your query takes and how much it returns.
|
||||
|
||||
1. **JSON tab -** Allows you to view and copy the panel JSON, panel data JSON, and data frame structure JSON. This is useful if you are provisioning or administering Grafana.
|
||||
|
||||
1. **Query tab -** Shows you the requests to the server sent when Grafana queries the data source.
|
||||
|
||||
1. **Error tab -** Shows the error. Only visible when query returns error.
|
||||
|
||||
## Create a dashboard and add a panel
|
||||
|
||||
Dashboards and panels allow you to show your data in visual form. Each panel needs at least one query to display a visualization.
|
||||
|
||||
**Before you begin:**
|
||||
|
||||
- Ensure that you have the proper permissions. For more information about permissions, refer to [About users and permissions]({{< relref "../administration/roles-and-permissions/" >}}).
|
||||
- Identify the dashboard to which you want to add the panel.
|
||||
- Understand the query language of the target data source.
|
||||
- Ensure that data source for which you are writing a query has been added. For more information about adding a data source, refer to [Add a data source]({{< relref "../datasources/add-a-data-source/" >}}) if you need instructions.
|
||||
|
||||
**To create a dashboard and add a panel**:
|
||||
|
||||
1. Sign in to Grafana, hover your cursor over **Dashboard**, and click **+ New Dashboard**.
|
||||
1. Click **Add a new panel**.
|
||||
1. In the first line of the **Query** tab, click the drop-down list and select a data source.
|
||||
1. Write or construct a query in the query language of your data source.
|
||||
|
||||
For more information about data sources, refer to [Data sources]({{< relref "../datasources/" >}}) for specific guidelines.
|
||||
|
||||
1. In the Visualization list, select a visualization type.
|
||||
|
||||
Grafana displays a preview of your query results with the visualization applied.
|
||||
|
||||

|
||||
|
||||
For more information about individual visualizations, refer to [Visualizations options]({{< relref "../visualizations/" >}}).
|
||||
|
||||
1. Refer to the following documentation for ways you can adjust panel settings.
|
||||
|
||||
While not required, most visualizations need some adjustment before they properly display the information that you need.
|
||||
|
||||
- [Format data using value mapping]({{< relref "../panels/format-data/about-value-mapping/" >}})
|
||||
- [Visualization-specific options]({{< relref "../visualizations/" >}})
|
||||
- [Override field values]({{< relref "../panels/override-field-values/about-field-overrides/" >}})
|
||||
- [Configure thresholds]({{< relref "../panels/configure-thresholds/" >}})
|
||||
- [Apply color to series and fields]({{< relref "../panels/working-with-panels/apply-color-to-series/" >}})
|
||||
|
||||
1. Add a note to describe the visualization (or describe your changes) and then click **Save** in the upper-right corner of the page.
|
||||
|
||||
Notes can be helpful if you need to revert the dashboard to a previous version.
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/panel-library/
|
||||
- /docs/grafana/latest/panels/library-panels/
|
||||
- /docs/grafana/latest/panels/library-panels/create-library-panel/
|
||||
- /docs/grafana/latest/panels/library-panels/add-library-panel/
|
||||
- /docs/grafana/latest/panels/library-panels/unlink-library-panel/
|
||||
- /docs/grafana/latest/panels/library-panels/manage-library-panel/
|
||||
- /docs/grafana/latest/panels/library-panels/delete-library-panel/
|
||||
- /docs/grafana/latest/dashboards/manage-library-panels/
|
||||
title: Manage Grafana library panels
|
||||
menuTitle: Manage library panels
|
||||
weight: 3
|
||||
---
|
||||
|
||||
# Manage Grafana library panels
|
||||
|
||||
A library panel is a reusable panel that you can use in any dashboard. When you make a change to a library panel, that change propagates to all instances of where the panel is used. Library panels streamline reuse of panels across multiple dashboards.
|
||||
|
||||
You can save a library panel in a folder alongside saved dashboards.
|
||||
|
||||
## Create a library panel
|
||||
|
||||
When you create a library panel, the panel on the source dashboard is converted to a library panel as well. You need to save the original dashboard once a panel is converted.
|
||||
|
||||
1. Open a panel in edit mode.
|
||||
1. In the panel display options, click the down arrow option to bring changes to the visualization.
|
||||
{{< figure src="/static/img/docs/library-panels/create-lib-panel-from-edit-8-0.png" class="docs-image--no-shadow" max-width= "800px" caption="Screenshot of the edit panel" >}}
|
||||
1. Click the **Library panels** option, and then click **Create library panel** to open the create dialog.
|
||||
{{< figure src="/static/img/docs/library-panels/create-lib-panel-8-0.png" class="docs-image--no-shadow" max-width= "500px" caption="Screenshot of the create library panel dialog" >}}
|
||||
1. In **Library panel name**, enter the name.
|
||||
1. In **Save in folder**, select the folder to save the library panel.
|
||||
1. Click **Create library panel** to save your changes.
|
||||
1. Save the dashboard.
|
||||
|
||||
Once created, you can modify the library panel using any dashboard on which it appears. After you save the changes, all instances of the library panel reflect these modifications.
|
||||
|
||||
{{< figure src="/static/img/docs/library-panels/create-from-more-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the edit panel" >}}
|
||||
|
||||
## Add a library panel to a dashboard
|
||||
|
||||
Add a Grafana library panel to a dashboard when you want to provide visualizations to other dashboard users.
|
||||
|
||||
1. Hover over the **Dashboards** option on the left menu, then select **New dashboard** from the drop-down options.
|
||||
|
||||
The **Add** panel dialog opens.
|
||||
{{< figure src="/static/img/docs/library-panels/add-library-panel-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the edit panel" >}}
|
||||
|
||||
1. Click the **Add a panel from the panel library** option.
|
||||
|
||||
You will see a list of your library panels.
|
||||
|
||||
1. Filter the list or search to find the panel you want to add.
|
||||
1. Click a panel to add it to the dashboard.
|
||||
|
||||
## Unlink a library panel
|
||||
|
||||
Unlink a library panel when you want to make a change to the panel and not affect other instances of the library panel.
|
||||
|
||||
1. Hover over **Dashboard** on the left menu, and then click **Library panels**.
|
||||
1. Select a library panel that is being used in different dashboards.
|
||||
1. Select the panel you want to unlink.
|
||||
1. Click the title of the panel and then click **Edit**. The panel opens in edit mode.
|
||||
1. Click the **Unlink** option on the top right corner of the page.
|
||||
|
||||
## View a list of library panels
|
||||
|
||||
You can view a list of available library panels and search for a library panel.
|
||||
|
||||
1. Hover over the **Dashboard** option on the left menu, then click **Library panels**.
|
||||
|
||||
You can see a list of previously defined library panels.
|
||||
{{< figure src="/static/img/docs/library-panels/library-panel-list-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the edit panel" >}}
|
||||
|
||||
1. Search for a specific library panel if you know its name.
|
||||
|
||||
You can also filter the panels by folder or type.
|
||||
|
||||
## Delete a library panel
|
||||
|
||||
Delete a library panel when you no longer need it.
|
||||
|
||||
1. Hover over **Dashboard** on the left menu, and select **Library panels**.
|
||||
|
||||
1. Select the panel you want to delete.
|
||||
|
||||
1. Click the delete icon next to the library panel name.
|
||||
@@ -10,7 +10,7 @@ aliases:
|
||||
- /docs/grafana/latest/reference/search/
|
||||
title: 'Use dashboards'
|
||||
menuTitle: Use dashboards
|
||||
weight: 2
|
||||
weight: 1
|
||||
keywords:
|
||||
- dashboard
|
||||
- search
|
||||
|
||||
@@ -103,7 +103,7 @@ Further documentation on multi-dimensional metrics is available [here](https://d
|
||||
|
||||
#### Supported Azure Monitor metrics
|
||||
|
||||
Not all metrics returned by the Azure Monitor Metrics API have values. To make it easier for you when building a query, the Grafana data source has a list of supported metrics and ignores metrics which will never have values. This list is updated regularly as new services and metrics are added to the Azure cloud. For more information about the list of metrics, refer to [current supported namespaces](https://github.com/grafana/grafana/blob/main/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/supported_namespaces.ts).
|
||||
Not all metrics returned by the Azure Monitor Metrics API have values. To make it easier for you when building a query, the Grafana data source has a list of supported metrics and ignores metrics which will never have values. This list is updated regularly as new services and metrics are added to the Azure cloud. For more information about the list of metrics, refer to [current supported namespaces](https://github.com/grafana/grafana/blob/main/public/app/plugins/datasource/grafana-azure-monitor-datasource/azureMetadata/metricNamespaces.ts).
|
||||
|
||||
### Querying Azure Monitor Logs
|
||||
|
||||
|
||||
@@ -66,6 +66,16 @@ This is a configuration for the beta Node Graph visualization. The Node Graph is
|
||||
|
||||
-- **Enable Node Graph -** Enables the Node Graph visualization.
|
||||
|
||||
### Span bar label
|
||||
|
||||
You can configure the span bar label. The span bar label allows you add additional information to the span bar row.
|
||||
|
||||
Select one of the following four options. The default selection is Duration.
|
||||
|
||||
- **None -** Do not show any additional information on the span bar row.
|
||||
- **Duration -** Show the span duration on the span bar row.
|
||||
- **Tag -** Show the span tag on the span bar row. Note: You will also need to specify the tag key to use to get the tag value. For example, `span.kind`.
|
||||
|
||||
## Query traces
|
||||
|
||||
You can query and display traces from Jaeger via [Explore]({{< relref "../explore/" >}}).
|
||||
|
||||
@@ -84,6 +84,16 @@ This is a configuration for the Loki search query type.
|
||||
|
||||
-- **Data source -** The Loki instance in which you want to search traces. You must configure derived fields in the Loki instance.
|
||||
|
||||
### Span bar label
|
||||
|
||||
You can configure the span bar label. The span bar label allows you add additional information to the span bar row.
|
||||
|
||||
Select one of the following four options. The default selection is Duration.
|
||||
|
||||
- **None -** Do not show any additional information on the span bar row.
|
||||
- **Duration -** Show the span duration on the span bar row.
|
||||
- **Tag -** Show the span tag on the span bar row. Note: You will also need to specify the tag key to use to get the tag value. For example, `span.kind`.
|
||||
|
||||
## Query traces
|
||||
|
||||
You can query and display traces from Tempo via [Explore]({{< relref "../explore/" >}}).
|
||||
|
||||
@@ -65,6 +65,16 @@ This is a configuration for the beta Node Graph visualization. The Node Graph is
|
||||
|
||||
-- **Enable Node Graph -** Enables the Node Graph visualization.
|
||||
|
||||
### Span bar label
|
||||
|
||||
You can configure the span bar label. The span bar label allows you add additional information to the span bar row.
|
||||
|
||||
Select one of the following four options. The default selection is Duration.
|
||||
|
||||
- **None -** Do not show any additional information on the span bar row.
|
||||
- **Duration -** Show the span duration on the span bar row.
|
||||
- **Tag -** Show the span tag on the span bar row. Note: You will also need to specify the tag key to use to get the tag value. For example, `span.kind`.
|
||||
|
||||
## Query traces
|
||||
|
||||
Querying and displaying traces from Zipkin is available via [Explore]({{< relref "../explore/" >}}).
|
||||
|
||||
@@ -12,7 +12,6 @@ You can change a value mapping at any time.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- Ensure you have an existing value mapping to edit.
|
||||
|
||||
**To edit a value mapping**:
|
||||
|
||||
@@ -10,12 +10,6 @@ weight: 30
|
||||
|
||||
Map a range of values when you want to format multiple, continuous values.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To map a range**:
|
||||
|
||||
1. Edit the panel for which you want to map a range of values.
|
||||
1. In panel display options, in the **Value mappings** section, click **Add value mappings**.
|
||||
1. Click **Add a new mapping** and then select **Range**.
|
||||
|
||||
@@ -10,14 +10,8 @@ weight: 40
|
||||
|
||||
Map a regular expression when you want to format the text and color of a regular expression value.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To map a regular expression**:
|
||||
|
||||
1. Edit the panel for which you want to map a regular expression.
|
||||
1. In the panel display options, in the **Value mappings** section, click **Add value mappings**.
|
||||
1. In the **Value mappings** section of the panel display options, click **Add value mappings**.
|
||||
1. Click **Add a new mapping** and then select **Regex**.
|
||||
1. Enter the regular expression pattern for Grafana to match.
|
||||
1. (Optional) Enter display text.
|
||||
|
||||
@@ -10,12 +10,6 @@ weight: 50
|
||||
|
||||
Map a special value when you want to format uncommon, boolean, or empty values.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To map a special value**:
|
||||
|
||||
1. Edit the panel for which you want to map a special value.
|
||||
1. In panel display options, locate the **Value mappings** section and click **Add value mappings**.
|
||||
1. Click **Add a new mapping** and then select **Special**.
|
||||
|
||||
@@ -10,12 +10,6 @@ weight: 20
|
||||
|
||||
Map a value when you want to format a single value.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To map a value**:
|
||||
|
||||
1. Open a panel for which you want to map a value.
|
||||
1. In panel display options, locate the **Value mappings** section and click **Add value mappings**.
|
||||
1. Click **Add a new mapping** and then select **Value**.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/
|
||||
- /docs/grafana/latest/panels/panel-library/
|
||||
- /docs/sources/panels/library-panels/
|
||||
title: Create reusable Grafana panels
|
||||
weight: 700
|
||||
---
|
||||
|
||||
# Create reusable Grafana panels
|
||||
|
||||
Library panels enable you to create reusable panels that you can add to any dashboard in your organization.
|
||||
|
||||
{{< section >}}
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/about-library-panels/
|
||||
- /docs/sources/panels/library-panels/about-library-panels/
|
||||
title: About Grafana library panels
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# About Grafana panel libraries
|
||||
|
||||
A library panel is a reusable panel that you can use in any dashboard. When you make a change to a library panel, that change propagates to all instances of where the panel is used. Library panels streamline reuse of panels across multiple dashboards.
|
||||
|
||||
You can save a library panel in a folder alongside saved dashboards.
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/add-library-panel/
|
||||
- /docs/sources/panels/library-panels/add-library-panel/
|
||||
title: Add a Grafana library panel to a dashboard
|
||||
weight: 30
|
||||
---
|
||||
|
||||
# Add a Grafana library panel to a dashboard
|
||||
|
||||
Add a Grafana library panel to a dashboard when you want to provide visualizations to other dashboard users.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Create a library panel]({{< relref "create-library-panel/" >}}).
|
||||
|
||||
**To add a library panel to a dashboard**:
|
||||
|
||||
1. Hover over the **Dashboards** option on the left menu, then select **New dashboard** from the drop-down options.
|
||||
|
||||
The **Add** panel dialog opens.
|
||||
{{< figure src="/static/img/docs/library-panels/add-library-panel-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the edit panel" >}}
|
||||
|
||||
1. Click the **Add a panel from the panel library** option.
|
||||
|
||||
You will see a list of your library panels.
|
||||
|
||||
1. Filter the list or search to find the panel you want to add.
|
||||
1. Click a panel to add it to the dashboard.
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/create-library-panel/
|
||||
- /docs/sources/panels/library-panels/create-library-panel/
|
||||
title: Create a Grafana library panel
|
||||
weight: 20
|
||||
---
|
||||
|
||||
# Create a Grafana library panel
|
||||
|
||||
When you create a library panel, the panel on the source dashboard is converted to a library panel as well. You need to save the original dashboard once a panel is converted.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To create a library panel**:
|
||||
|
||||
1. Open a panel in edit mode.
|
||||
1. In the panel display options, click the down arrow option to bring changes to the visualization.
|
||||
{{< figure src="/static/img/docs/library-panels/create-lib-panel-from-edit-8-0.png" class="docs-image--no-shadow" max-width= "800px" caption="Screenshot of the edit panel" >}}
|
||||
1. Click the **Library panels** option, and then click **Create new library panel** to open the create dialog.
|
||||
{{< figure src="/static/img/docs/library-panels/create-lib-panel-8-0.png" class="docs-image--no-shadow" max-width= "500px" caption="Screenshot of the create library panel dialog" >}}
|
||||
1. In **Library panel name**, enter the name.
|
||||
1. In **Save in folder**, select the folder to save the library panel.
|
||||
1. Click **Create library panel** to save your changes.
|
||||
1. Save the dashboard.
|
||||
|
||||
Once created, you can modify the library panel using any dashboard on which it appears. After you save the changes, all instances of the library panel reflect these modifications.
|
||||
|
||||
{{< figure src="/static/img/docs/library-panels/create-from-more-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the edit panel" >}}
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/delete-library-panel/
|
||||
- /docs/sources/panels/library-panels/delete-library-panel/
|
||||
title: Delete a Grafana library panel
|
||||
weight: 60
|
||||
---
|
||||
|
||||
# Delete a Grafana library panel
|
||||
|
||||
Delete a library panel when you no longer need it.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- Verify that the panel does not appear on a dashboard.
|
||||
|
||||
**To delete a library panel**:
|
||||
|
||||
1. Hover over **Dashboard** on the left menu, and select Library panels from the drop-down options.
|
||||
1. Select a library panel that is being used in different dashboards.
|
||||
|
||||
You will see a list of all the dashboards.
|
||||
|
||||
1. Select the panel you want to delete.
|
||||
1. Click the delete icon next to the library panel name.
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/manage-library-panel/
|
||||
- /docs/sources/panels/library-panels/manage-library-panel/
|
||||
title: Manage Grafana library panels
|
||||
weight: 40
|
||||
---
|
||||
|
||||
# Manage Grafana library panels
|
||||
|
||||
You can adjust library panel configuration at any time.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To view and manage a library panel**:
|
||||
|
||||
1. Hover over the **Dashboard** option on the left menu, then click **Library panels**.
|
||||
|
||||
You can see a list of previously defined library panels.
|
||||
{{< figure src="/static/img/docs/library-panels/library-panel-list-8-0.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the edit panel" >}}
|
||||
|
||||
1. Search for a specific library panel if you know its name.
|
||||
|
||||
You can also filter the panels by folder or type.
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/library-panels/unlink-library-panel/
|
||||
- /docs/sources/panels/library-panels/unlink-library-panel/
|
||||
title: Unlink a Grafana library panel
|
||||
weight: 50
|
||||
---
|
||||
|
||||
# Unlink a Grafana library panel
|
||||
|
||||
Unlink a library panel when you want to make a change to the panel and not affect other instances of the library panel.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- Identify the panel you want to unlink.
|
||||
|
||||
**To unlink a library panel from a dashboard**:
|
||||
|
||||
1. Hover over **Dashboard** on the left menu, and then click **Library panels**.
|
||||
1. Select a library panel that is being used in different dashboards.
|
||||
1. Select the panel you want to unlink.
|
||||
1. Click the title of the panel and then click **Edit**. The panel opens in edit mode.
|
||||
1. Click the **Unlink** option on the top right corner of the page.
|
||||
@@ -10,12 +10,6 @@ weight: 30
|
||||
|
||||
You can override a field when you want to change the display of the value in the visualization.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To add a field override**:
|
||||
|
||||
1. Edit the panel to which you want to add an override.
|
||||
1. In the panel display options, in the **Overrides** section, click **Add field override**.
|
||||
|
||||
|
||||
@@ -12,13 +12,6 @@ Delete a field override when you no longer need it.
|
||||
|
||||
When you delete an override, the appearance of value defaults to its original format. This change impacts dashboards and dashboard users that rely on an affected panel.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- [Add a field override]({{< relref "add-a-field-override/" >}}).
|
||||
|
||||
**To delete a field override**:
|
||||
|
||||
1. Edit the panel that contains the override you want to delete.
|
||||
1. In panel display options, click the **Overrides** tab.
|
||||
1. Click the override you want to delete and then click the associated trash icon.
|
||||
|
||||
@@ -10,11 +10,6 @@ weight: 40
|
||||
|
||||
Edit a field override when you want to make changes to an override setting.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- [Add a field override]({{< relref "add-a-field-override/" >}}).
|
||||
|
||||
**To edit a field override**:
|
||||
|
||||
1. Edit the panel that contains the overrides you want to edit.
|
||||
|
||||
@@ -10,11 +10,6 @@ weight: 20
|
||||
|
||||
You can view field overrides in the panel display options.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- [Add a field override]({{< relref "add-a-field-override/" >}}).
|
||||
|
||||
**To view field overrides**:
|
||||
|
||||
1. Open for edit the panel that contains the overrides you want to view.
|
||||
|
||||
@@ -14,7 +14,6 @@ A query returns data that Grafana visualizes in dashboards. When you create a pa
|
||||
|
||||
- [Add a data source](../../../datasources/add-a-data-source).
|
||||
- Ensure that you know the query language of the data source.
|
||||
- [Add a panel]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To add a query**:
|
||||
|
||||
|
||||
@@ -10,13 +10,6 @@ weight: 70
|
||||
|
||||
Grafana generates a CSV file that contains your data, including any transformations to that data. You can choose to view the data before or after the panel applies field options or field option overrides.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- [Add a query]({{< relref "add-a-query/" >}}).
|
||||
|
||||
**To download raw query results**:
|
||||
|
||||
1. Edit the panel that contains the query data you want to download.
|
||||
1. In the query editor, click **Query Inspector**.
|
||||
1. Click **Data**.
|
||||
|
||||
@@ -10,13 +10,6 @@ weight: 80
|
||||
|
||||
The **Stats** tab displays statistics that tell you how long your query takes, how many queries you send, and the number of rows returned. This information can help you troubleshoot your queries, especially if any of the numbers are unexpectedly high or low.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- [Add a query]({{< relref "add-a-query/" >}}).
|
||||
|
||||
**To inspect query performance**:
|
||||
|
||||
1. Edit the panel that contains the query with performance you want to inspect.
|
||||
1. In the query editor, click **Query Inspector**.
|
||||
1. Click **Stats**.
|
||||
|
||||
@@ -10,13 +10,6 @@ weight: 90
|
||||
|
||||
Inspect query request and response data when you want to troubleshoot a query that returns unexpected results, or fails to return expected results.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
- [Add a query]({{< relref "add-a-query/" >}}).
|
||||
|
||||
**To inspect query request and response data**:
|
||||
|
||||
1. Edit the panel that contains the query you want to export.
|
||||
1. In the query editor, click **Query Inspector**.
|
||||
1. Click **Refresh**.
|
||||
|
||||
@@ -14,9 +14,7 @@ The Dashboard data source lets you select a panel in your dashboard that contain
|
||||
|
||||
This strategy can drastically reduce the number of queries being made when you for example have several panels visualizing the same data.
|
||||
|
||||
**To share data source queries with another panel**:
|
||||
|
||||
1. [Add a panel to a dashboard]({{< relref "../working-with-panels/add-panel/" >}}).
|
||||
1. [Create a dashboard and add a panel]({{< relref "../../dashboards/add-organize-panels/#create-a-dashboard-and-add-a-panel" >}}).
|
||||
1. Change the title to "Source panel". You'll use this panel as a source for the other panels.
|
||||
1. Define the [query]({{< relref "add-a-query/" >}}) or queries that you want share.
|
||||
|
||||
|
||||
-6
@@ -12,12 +12,6 @@ If your data source supports them, then Grafana displays the **Expression** butt
|
||||
|
||||
For more information about expressions, refer to [About expressions]({{< relref "about-expressions/" >}}).
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel]({{< relref "../../working-with-panels/add-panel/" >}}).
|
||||
|
||||
**To write an expression**:
|
||||
|
||||
1. Open the panel.
|
||||
1. Below the query, click **Expression**.
|
||||
1. In the **Operation** field, select the type of expression you want to write.
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/working-with-panels/add-panel/
|
||||
- /docs/sources/panels/working-with-panels/add-panel/
|
||||
title: Add a panel to a dashboard
|
||||
weight: 20
|
||||
---
|
||||
|
||||
# Add a panel to a dashboard
|
||||
|
||||
Panels allow you to show your data in visual form. Each panel needs at least one query to display a visualization.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- Ensure that you have the proper permissions. For more information about permissions, refer to [About users and permissions]({{< relref "../../administration/manage-users-and-permissions/about-users-and-permissions/" >}}).
|
||||
- Identify the dashboard to which you want to add the panel.
|
||||
- Understand the query language of the target data source.
|
||||
- Ensure that data source for which you are writing a query has been added. For more information about adding a data source, refer to [Add a data source]({{< relref "../../datasources/add-a-data-source/" >}}) if you need instructions.
|
||||
|
||||
**To add a panel to a dashboard**:
|
||||
|
||||
1. Navigate to the dashboard to which you want to add a panel.
|
||||
1. Click the **Add panel** icon.
|
||||
|
||||

|
||||
|
||||
1. Click **Add an empty panel**.
|
||||
|
||||
Grafana creates an empty time-series panel and selects the default data source.
|
||||
|
||||
1. In the first line of the **Query** tab, click the drop-down list and select a data source.
|
||||
|
||||
1. Write or construct a query in the query language of your data source.
|
||||
|
||||
For more information about data sources, refer to [Data sources]({{< relref "../../datasources/" >}}) for specific guidelines.
|
||||
|
||||
1. In the Visualization list, select a visualization type.
|
||||
|
||||
Grafana displays a preview of your query results with the visualization applied.
|
||||
|
||||

|
||||
|
||||
For more information about individual visualizations, refer to [Visualizations options]({{< relref "../../visualizations/" >}}).
|
||||
|
||||
1. Refer to the following documentation for ways you adjust panel settings.
|
||||
|
||||
While not required, most visualizations need some adjustment before they properly display the information that you need.
|
||||
|
||||
- [Format data using value mapping]({{< relref "../format-data/about-value-mapping/" >}})
|
||||
- [Visualization-specific options]({{< relref "../../visualizations/" >}})
|
||||
- [Override field values]({{< relref "../override-field-values/about-field-overrides/" >}})
|
||||
- [Configure thresholds]({{< relref "../configure-thresholds/" >}})
|
||||
- [Apply color to series and fields]({{< relref "apply-color-to-series/" >}})
|
||||
|
||||
1. Add a note to describe the visualization (or describe your changes) and then click **Save** in the upper-right corner of the page.
|
||||
|
||||
Notes can be helpful if you need to revert the dashboard to a previous version.
|
||||
@@ -10,12 +10,6 @@ weight: 30
|
||||
|
||||
Add a title and description to a panel to share with users any important information about the visualization. For example, use the description to document the purpose of the visualization.
|
||||
|
||||
## Before you begin:
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "add-panel/" >}}).
|
||||
|
||||
**To add a title and description to a panel**:
|
||||
|
||||
1. Open a panel.
|
||||
|
||||
1. In the panel display options pane, locate the **Panel options** section.
|
||||
|
||||
@@ -13,12 +13,6 @@ In addition to specifying color based on thresholds, you can configure the color
|
||||
You can specify a single color, or select a continuous (gradient) color schemes, based on a value.
|
||||
Continuous color interpolates a color using the percentage of a value relative to min and max.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "add-panel/" >}}).
|
||||
|
||||
**To apply color to series and fields**:
|
||||
|
||||
1. In panel display options, scroll to the **Standard options** or **override** section.
|
||||
|
||||
1. Click the **Standard options Color scheme** drop-down, and select one of the following palettes:
|
||||
|
||||
@@ -16,12 +16,6 @@ Visualizations can often be visually complex, and include many data series. You
|
||||
|
||||
When you apply your changes, the visualization changes appear to all users of the panel.
|
||||
|
||||
### Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "add-panel/" >}}).
|
||||
|
||||
**To isolate series data in a visualization**:
|
||||
|
||||
1. Open the panel.
|
||||
|
||||
1. In the legend, click the label of the series you want to isolate.
|
||||
|
||||
@@ -16,12 +16,6 @@ For a complete list of field formatting options, refer to [Standard field defini
|
||||
|
||||
> You can apply standard options to most built-in Grafana panels. Some older panels and community panels that have not updated to the new panel and data model will be missing either all or some of these field options.
|
||||
|
||||
## Before you begin
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "add-panel/" >}}).
|
||||
|
||||
**To format a standard field**:
|
||||
|
||||
1. Open a dashboard, click the panel title, and click **Edit**.
|
||||
|
||||
1. In the panel display options pane, locate the **Standard options** section.
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
aliases:
|
||||
- /docs/grafana/latest/panels/working-with-panels/navigate-panel-editor/
|
||||
- /docs/sources/panels/working-with-panels/navigate-panel-editor/
|
||||
title: Navigate the Grafana panel editor
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# Navigate the Grafana panel editor
|
||||
|
||||
This page describes the parts of the Grafana panel editor.
|
||||
|
||||
1. Panel header: The header section lists the dashboard in which the panel appears and the following controls:
|
||||
|
||||
- **Dashboard settings (gear) icon -** Click to access the dashboard settings.
|
||||
- **Discard -** Discards changes you have made to the panel since you last saved the dashboard.
|
||||
- **Save -** Saves changes you made to the panel.
|
||||
- **Apply -** Applies changes you made and closes the panel editor, returning you to the dashboard. You will have to save the dashboard to persist the applied changes.
|
||||
|
||||
2. Visualization preview: The visualization preview section contains the following options:
|
||||
|
||||
- **Table view -** Convert any visualization to a table so that you can see the data. Table views are useful for troubleshooting.
|
||||
- **Fill -** The visualization preview fills the available space. If you change the width of the side pane or height of the bottom pane the visualization changes to fill the available space.
|
||||
- **Actual -** The visualization preview will have the exact size as the size on the dashboard. If not enough space is available, the visualization will scale down preserving the aspect ratio.
|
||||
- **Time range controls -** For more information, refer to [Time range controls]({{< relref "../../dashboards/time-range-controls/" >}}).
|
||||
|
||||
3. Data section: The data section contains tabs where you enter queries, transform your data, and create alert rules (if applicable).
|
||||
|
||||
- **Query tab -** Select your data source and enter queries here. For more information, refer to [Add a query]({{< relref "../query-a-data-source/add-a-query/" >}}).
|
||||
|
||||
- **Transform tab -** Apply data transformations. For more information, refer to [Transform data]({{< relref "../transform-data/" >}}).
|
||||
- **Alert tab -** Write alert rules. For more information, refer to [Overview of Grafana 8 alerting]({{< relref "../../alerting/" >}}).
|
||||
|
||||
4. Panel display options: The display options section contains tabs where you configure almost every aspect of your data visualization, including:
|
||||
|
||||
- [Apply color to series and fields]({{< relref "apply-color-to-series/" >}})
|
||||
- [Format a standard field]({{< relref "format-standard-fields/" >}})
|
||||
- [Add a title and description to a panel]({{< relref "add-title-and-description/" >}})
|
||||
|
||||
> Not all options are available for each visualization.
|
||||
|
||||
{{< figure src="/static/img/docs/panel-editor/panel-editor-8-0.png" class="docs-image--no-shadow" max-width="1500px" >}}
|
||||
@@ -10,12 +10,6 @@ weight: 100
|
||||
|
||||
Explore and export panel, panel data, and data frame JSON models.
|
||||
|
||||
## Before you begin:
|
||||
|
||||
- [Add a panel to a dashboard]({{< relref "add-panel/" >}}).
|
||||
|
||||
**To view a panel JSON model**:
|
||||
|
||||
1. Open the panel inspector and then click the **JSON** tab or in the panel menu click **Inspect > Panel JSON**.
|
||||
|
||||
1. In Select source, choose one of the following options:
|
||||
|
||||
@@ -10,7 +10,7 @@ weight: 75
|
||||
|
||||
Grafana offers a variety of visualizations to support different use cases. This section of the documentation highlights the built-in panels, their options and typical usage.
|
||||
|
||||
> **Note:** If you are unsure which visualization to pick, Grafana can provide visualization suggestions based on the panel query. When you select a visualization, Grafana will show a preview with that visualization applied. For more information, see the [add a panel]({{< relref "../panels/working-with-panels/add-panel/" >}}) documentation.
|
||||
> **Note:** If you are unsure which visualization to pick, Grafana can provide visualization suggestions based on the panel query. When you select a visualization, Grafana will show a preview with that visualization applied.
|
||||
|
||||
- Graphs & charts
|
||||
- [Time series]({{< relref "time-series/" >}}) is the default and main Graph visualization.
|
||||
|
||||
@@ -18,9 +18,7 @@ This section explains how to use Time series field options to visualize time ser
|
||||
|
||||
For more information about the time series visualization, refer to [Time series]({{< relref "_index.md" >}}).
|
||||
|
||||
## Create the panel
|
||||
|
||||
1. [Add a panel]({{< relref "../../panels/working-with-panels/add-panel/" >}}).
|
||||
1. [Create a dashboard and add a panel]({{< relref "../../dashboards/add-organize-panels/#create-a-dashboard-and-add-a-panel" >}}).
|
||||
1. Select the **Time series** visualization.
|
||||
1. In the Panel editor side pane, click **Graph styles** to expand it.
|
||||
1. In Style, click **Bars**.
|
||||
|
||||
@@ -16,9 +16,8 @@ weight: 200
|
||||
|
||||
This section explains how to use Time series field options to visualize time series data as lines and illustrates what the options do.
|
||||
|
||||
## Create the panel
|
||||
|
||||
1. [Add a panel]({{< relref "../../panels/working-with-panels/add-panel/" >}}). Select the [Time series]({{< relref "_index.md" >}}) visualization.
|
||||
1. [Create a dashboard and add a panel]({{< relref "../../dashboards/add-organize-panels/#create-a-dashboard-and-add-a-panel" >}}).
|
||||
1. Select the [Time series]({{< relref "_index.md" >}}) visualization.
|
||||
1. In the Panel editor side pane, click **Graph styles** to expand it.
|
||||
1. In Style, click **Lines**.
|
||||
|
||||
|
||||
@@ -16,9 +16,8 @@ weight: 300
|
||||
|
||||
This section explains how to use Time series field options to visualize time series data as points and illustrates what the options do.
|
||||
|
||||
## Create the panel
|
||||
|
||||
1. [Add a panel]({{< relref "../../panels/working-with-panels/add-panel/" >}}). Select the [Time series]({{< relref "_index.md" >}}) visualization.
|
||||
1. [Create a dashboard and add a panel]({{< relref "../../dashboards/add-organize-panels/#create-a-dashboard-and-add-a-panel" >}}).
|
||||
1. Select the [Time series]({{< relref "_index.md" >}}) visualization.
|
||||
1. In the Panel editor side pane, click **Graph styles** to expand it.
|
||||
1. In Style, click **Points**.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v7.5
|
||||
weight: -32
|
||||
---
|
||||
|
||||
# What’s new in Grafana v7.5
|
||||
# What's new in Grafana v7.5
|
||||
|
||||
This topic includes the release notes for Grafana v7.5. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md).
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v8.0
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v8.0
|
||||
# What's new in Grafana v8.0
|
||||
|
||||
This topic includes the release notes for Grafana v8.0. For all details, read the full [CHANGELOG.md](https://github.com/grafana/grafana/blob/master/CHANGELOG.md).
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v8.1
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v8.1
|
||||
# What's new in Grafana v8.1
|
||||
|
||||
> **Note:** This topic will be updated frequently between now and the final release.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v8.2
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v8.2
|
||||
# What's new in Grafana v8.2
|
||||
|
||||
Grafana 8.2 continues to build on the foundation of Grafana 8.0 & 8.1. Grafana 8.2 also marks the start of our work to bring Grafana closer to all users with a focus on increasing Grafana’s accessibility, part of its continuing mission to democratize metrics _for everyone_.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v8.3
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v8.3
|
||||
# What's new in Grafana v8.3
|
||||
|
||||
Grafana 8.3 is an exciting release for Grafana Labs. This release includes the new Candlestick Panel, a new visualization suggestions engine and, for enterprise users, Recorded Queries.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v8.4
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v8.4
|
||||
# What's new in Grafana v8.4
|
||||
|
||||
We’re excited to announce Grafana v8.4, with a variety of improvements that focus on Grafana’s usability, performance, and security. Read on to learn about Alerting enhancements like a WeCom contact point, improved Alert panel and custom mute timings, as well as visualization improvements and details to help you share playlists more easily. In Grafana Enterprise, we’ve made caching more powerful to save you time and money while loading dashboards, boosted database encryption to keep secrets safe in your Grafana database, and made usability improvements to Recorded Queries, which allow you to track any data point over time.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v8.5
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v8.5
|
||||
# What's new in Grafana v8.5
|
||||
|
||||
We’re excited to announce Grafana v8.5, with a variety of improvements that focus on Grafana’s usability, performance, and security.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ title: What's new in Grafana v9.0
|
||||
weight: -33
|
||||
---
|
||||
|
||||
# What’s new in Grafana v9.0
|
||||
# What's new in Grafana v9.0
|
||||
|
||||
As tradition goes, GrafanaCon — our yearly community event for Grafana open source users — is also where we launch the latest software release of Grafana. Keeping up with tradition, we are excited to be announcing Grafana v9.0: a release that elevates Grafana’s ease of use, discovery of data through new and improved visualizations and a default Grafana Alerting experience.
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ require (
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/gchaincl/sqlhooks v1.3.0
|
||||
github.com/getsentry/sentry-go v0.13.0
|
||||
github.com/go-git/go-git/v5 v5.4.2
|
||||
github.com/go-kit/kit v0.11.0
|
||||
github.com/go-openapi/strfmt v0.20.2
|
||||
github.com/go-redis/redis/v8 v8.11.4
|
||||
@@ -213,7 +214,7 @@ require (
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
|
||||
github.com/segmentio/encoding v0.3.2
|
||||
github.com/sercand/kuberesolver v2.4.0+incompatible // indirect
|
||||
github.com/sergi/go-diff v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
@@ -273,7 +274,9 @@ require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.2.1 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
||||
github.com/RoaringBitmap/roaring v0.9.4 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.0 // indirect
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||
@@ -288,17 +291,23 @@ require (
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.3.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/klauspost/compress v1.15.2 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/labstack/echo/v4 v4.7.2 // indirect
|
||||
github.com/labstack/gommon v0.3.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
|
||||
@@ -307,11 +316,13 @@ require (
|
||||
github.com/smartystreets/goconvey v1.7.2 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
github.com/wk8/go-ordered-map v1.0.0
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/xlab/treeprint v1.1.0 // indirect
|
||||
github.com/yudai/pp v2.0.1+incompatible // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.3 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.15.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
k8s.io/api v0.22.5 // indirect
|
||||
k8s.io/apimachinery v0.22.5 // indirect
|
||||
k8s.io/klog/v2 v2.30.0 // indirect
|
||||
|
||||
@@ -254,6 +254,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
@@ -275,6 +277,8 @@ github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrU
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgXrwqZOwZ2DAc/aCi3Bu3xENpspW935vxu0=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3HiCrHjHBdcm6E83vGaXh1KomZMA2P6aeo3hKx/wg0=
|
||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||
@@ -294,6 +298,8 @@ github.com/aliyun/aliyun-oss-go-sdk v2.0.4+incompatible/go.mod h1:T/Aws4fEfogEE9
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.0.3 h1:fpcw+r1N1h0Poc1F/pHbW40cUm/lMEQslZtCkBQ0UnM=
|
||||
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/antonmedv/expr v1.8.9/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8=
|
||||
@@ -316,6 +322,7 @@ github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
@@ -783,6 +790,8 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT
|
||||
github.com/emicklei/proto v1.6.15/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
|
||||
github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw=
|
||||
github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@@ -816,6 +825,7 @@ github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphs
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
|
||||
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
@@ -851,6 +861,8 @@ github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ER
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
@@ -863,6 +875,15 @@ github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0
|
||||
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
|
||||
github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
|
||||
github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
||||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -1557,6 +1578,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jaegertracing/jaeger v1.24.0/go.mod h1:mqdtFDA447va5j0UewDaAWyNlGreGQyhGxXVhbF58gQ=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
@@ -1618,6 +1641,8 @@ github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
@@ -1729,6 +1754,7 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
@@ -2226,8 +2252,9 @@ github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfP
|
||||
github.com/sercand/kuberesolver v2.1.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ=
|
||||
github.com/sercand/kuberesolver v2.4.0+incompatible h1:WE2OlRf6wjLxHwNkkFLQGaZcVLEXjMjBPjjEU5vksH8=
|
||||
github.com/sercand/kuberesolver v2.4.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shirou/gopsutil v3.21.6+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
@@ -2426,6 +2453,8 @@ github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr
|
||||
github.com/wk8/go-ordered-map v1.0.0 h1:BV7z+2PaK8LTSd/mWgY12HyMAo5CEgkHqbkVq2thqr8=
|
||||
github.com/wk8/go-ordered-map v1.0.0/go.mod h1:9ZIbRunKbuvfPKyBP1SIKLcXNlv74YCOZ3t3VTS6gRk=
|
||||
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
@@ -2609,6 +2638,7 @@ golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -2644,6 +2674,7 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
@@ -2785,6 +2816,7 @@ golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
@@ -2984,6 +3016,7 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -3459,6 +3492,7 @@ gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w
|
||||
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
||||
@@ -218,7 +218,6 @@
|
||||
"mutationobserver-shim": "0.3.7",
|
||||
"ngtemplate-loader": "2.1.0",
|
||||
"node-notifier": "10.0.1",
|
||||
"nodemon": "2.0.16",
|
||||
"postcss": "8.4.14",
|
||||
"postcss-loader": "7.0.0",
|
||||
"postcss-reporter": "7.0.5",
|
||||
|
||||
@@ -160,13 +160,13 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
for (const frame of frames) {
|
||||
for (const field of frame.fields) {
|
||||
if (field.type === FieldType.number) {
|
||||
allValues = allValues.concat(
|
||||
field.values.toArray().map((val: number) => Number(val.toFixed(field.config.decimals ?? 0)))
|
||||
);
|
||||
allValues = allValues.concat(field.values.toArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allValues = allValues.filter((v) => v != null);
|
||||
|
||||
allValues.sort((a, b) => a - b);
|
||||
|
||||
let smallestDelta = Infinity;
|
||||
@@ -204,6 +204,9 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
|
||||
const getBucket = (v: number) => incrRoundDn(v - bucketOffset, bucketSize!) + bucketOffset;
|
||||
|
||||
// guess number of decimals
|
||||
let bucketDecimals = (('' + bucketSize).match(/\.\d+$/) ?? ['.'])[0].length - 1;
|
||||
|
||||
let histograms: AlignedData[] = [];
|
||||
let counts: Field[] = [];
|
||||
let config: FieldConfig | undefined = undefined;
|
||||
@@ -220,7 +223,7 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
unit: undefined,
|
||||
},
|
||||
});
|
||||
if (!config && Object.keys(field.config).length) {
|
||||
if (!config && field.config.unit) {
|
||||
config = field.config;
|
||||
}
|
||||
}
|
||||
@@ -251,7 +254,13 @@ export function buildHistogram(frames: DataFrame[], options?: HistogramTransform
|
||||
values: new ArrayVector(joinedHists[0]),
|
||||
type: FieldType.number,
|
||||
state: undefined,
|
||||
config: config ?? {},
|
||||
config:
|
||||
bucketDecimals === 0
|
||||
? config ?? {}
|
||||
: {
|
||||
...config,
|
||||
decimals: bucketDecimals,
|
||||
},
|
||||
};
|
||||
const bucketMax = {
|
||||
...bucketMin,
|
||||
|
||||
@@ -483,7 +483,6 @@ export interface DataQueryRequest<TQuery extends DataQuery = DataQuery> {
|
||||
timeInfo?: string; // The query time description (blue text in the upper right)
|
||||
panelId?: number;
|
||||
dashboardId?: number;
|
||||
// Temporary prop for public dashboards, to be replaced by publicAccessKey
|
||||
publicDashboardAccessToken?: string;
|
||||
|
||||
// Request Timing
|
||||
|
||||
@@ -56,6 +56,7 @@ export interface FeatureToggles {
|
||||
autoMigrateGraphPanels?: boolean;
|
||||
prometheusWideSeries?: boolean;
|
||||
canvasPanelNesting?: boolean;
|
||||
scenes?: boolean;
|
||||
useLegacyHeatmapPanel?: boolean;
|
||||
cloudMonitoringExperimentalUI?: boolean;
|
||||
logRequestsInstrumentedAsUnknown?: boolean;
|
||||
|
||||
@@ -56,10 +56,6 @@ export interface NavModel {
|
||||
* This is the current active tab/navigation.
|
||||
*/
|
||||
node: NavModelItem;
|
||||
/**
|
||||
* Describes breadcrumbs that are used in places such as data source settings., folder page and plugins page.
|
||||
*/
|
||||
breadcrumbs?: NavModelItem[];
|
||||
}
|
||||
|
||||
export interface NavModelBreadcrumb {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { AbsoluteTimeRange, FieldConfigSource, PanelData } from '@grafana/data';
|
||||
* @internal
|
||||
*/
|
||||
export interface PanelRendererProps<P extends object = any, F extends object = any> {
|
||||
data: PanelData;
|
||||
data?: PanelData;
|
||||
pluginId: string;
|
||||
title: string;
|
||||
options?: Partial<P>;
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { of } from 'rxjs';
|
||||
import { BackendSrv, BackendSrvRequest } from 'src/services';
|
||||
|
||||
import { DataQueryRequest, DataSourceRef } from '@grafana/data';
|
||||
import { DataQueryRequest, DataSourceInstanceSettings, DataSourceRef } from '@grafana/data';
|
||||
|
||||
import { PublicDashboardDataSource } from '../../../../public/app/features/dashboard/services/PublicDashboardDataSource';
|
||||
import {
|
||||
PUBLIC_DATASOURCE,
|
||||
PublicDashboardDataSource,
|
||||
} from '../../../../public/app/features/dashboard/services/PublicDashboardDataSource';
|
||||
|
||||
import { DataSourceWithBackend } from './DataSourceWithBackend';
|
||||
|
||||
const mockDatasourceRequest = jest.fn();
|
||||
|
||||
@@ -28,7 +33,7 @@ describe('PublicDashboardDatasource', () => {
|
||||
mockDatasourceRequest.mockReset();
|
||||
mockDatasourceRequest.mockReturnValue(Promise.resolve({}));
|
||||
|
||||
const ds = new PublicDashboardDataSource();
|
||||
const ds = new PublicDashboardDataSource('public');
|
||||
const panelId = 1;
|
||||
const publicDashboardAccessToken = 'abc123';
|
||||
|
||||
@@ -47,4 +52,27 @@ describe('PublicDashboardDatasource', () => {
|
||||
`/api/public/dashboards/${publicDashboardAccessToken}/panels/${panelId}/query`
|
||||
);
|
||||
});
|
||||
|
||||
test('returns public datasource uid when datasource passed in is null', () => {
|
||||
let ds = new PublicDashboardDataSource(null);
|
||||
expect(ds.uid).toBe(PUBLIC_DATASOURCE);
|
||||
});
|
||||
|
||||
test('returns datasource when datasource passed in is a string', () => {
|
||||
let ds = new PublicDashboardDataSource('theDatasourceUid');
|
||||
expect(ds.uid).toBe('theDatasourceUid');
|
||||
});
|
||||
|
||||
test('returns datasource uid when datasource passed in is a DataSourceRef implementation', () => {
|
||||
const datasource = { type: 'datasource', uid: 'abc123' };
|
||||
let ds = new PublicDashboardDataSource(datasource);
|
||||
expect(ds.uid).toBe('abc123');
|
||||
});
|
||||
|
||||
test('returns datasource uid when datasource passed in is a DatasourceApi instance', () => {
|
||||
const settings: DataSourceInstanceSettings = { id: 1, uid: 'abc123' } as DataSourceInstanceSettings;
|
||||
const datasource = new DataSourceWithBackend(settings);
|
||||
let ds = new PublicDashboardDataSource(datasource);
|
||||
expect(ds.uid).toBe('abc123');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,7 +41,7 @@ chmod 755 /usr/local/bin/golangci-lint
|
||||
# Install code climate
|
||||
get_file "https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64" \
|
||||
"/usr/local/bin/cc-test-reporter" \
|
||||
"9fbe34cd207924d8f51ac0f3ffa690df4169e055cd7134a2370f6650f5b356e1"
|
||||
"9e6c3e628b1258aefbc6e3550438a691abb0d1924d63c038881031d3d343c7d0"
|
||||
chmod 755 /usr/local/bin/cc-test-reporter
|
||||
|
||||
wget -O /usr/local/bin/grabpl "https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v2.9.27/grabpl"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { IconName } from '../../types/icon';
|
||||
import { ComponentSize } from '../../types/size';
|
||||
import { getPropertiesForButtonSize } from '../Forms/commonStyles';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { PopoverContent, Tooltip, TooltipPlacement } from '../Tooltip';
|
||||
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'destructive';
|
||||
export const allButtonVariants: ButtonVariant[] = ['primary', 'secondary', 'destructive'];
|
||||
@@ -24,6 +25,10 @@ type CommonProps = {
|
||||
children?: React.ReactNode;
|
||||
fullWidth?: boolean;
|
||||
type?: string;
|
||||
/** Tooltip content to display on hover */
|
||||
tooltip?: PopoverContent;
|
||||
/** Position of the tooltip */
|
||||
tooltipPlacement?: TooltipPlacement;
|
||||
};
|
||||
|
||||
export type ButtonProps = CommonProps & ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
@@ -79,6 +84,8 @@ export const LinkButton = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
|
||||
onBlur,
|
||||
onFocus,
|
||||
disabled,
|
||||
tooltip,
|
||||
tooltipPlacement,
|
||||
...otherProps
|
||||
},
|
||||
ref
|
||||
@@ -103,12 +110,22 @@ export const LinkButton = React.forwardRef<HTMLAnchorElement, ButtonLinkProps>(
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
const button = (
|
||||
<a className={linkButtonStyles} {...otherProps} tabIndex={disabled ? -1 : 0} ref={ref}>
|
||||
{icon && <Icon name={icon} size={size} className={styles.icon} />}
|
||||
{children && <span className={styles.content}>{children}</span>}
|
||||
</a>
|
||||
);
|
||||
|
||||
if (tooltip) {
|
||||
return (
|
||||
<Tooltip content={tooltip} placement={tooltipPlacement}>
|
||||
{button}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import React, { CSSProperties } from 'react';
|
||||
|
||||
import { LinkModel } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
@@ -12,6 +12,7 @@ import { MenuItem } from '../Menu/MenuItem';
|
||||
interface DataLinksContextMenuProps {
|
||||
children: (props: DataLinksContextMenuApi) => JSX.Element;
|
||||
links: () => LinkModel[];
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
export interface DataLinksContextMenuApi {
|
||||
@@ -19,7 +20,7 @@ export interface DataLinksContextMenuApi {
|
||||
targetClassName?: string;
|
||||
}
|
||||
|
||||
export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ children, links }) => {
|
||||
export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ children, links, style }) => {
|
||||
const itemsGroup: MenuItemsGroup[] = [{ items: linkModelToContextMenuItems(links), label: 'Data links' }];
|
||||
const linksCounter = itemsGroup[0].items.length;
|
||||
const renderMenuGroupItems = () => {
|
||||
@@ -61,7 +62,7 @@ export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ chil
|
||||
onClick={linkModel.onClick}
|
||||
target={linkModel.target}
|
||||
title={linkModel.title}
|
||||
style={{ display: 'flex', width: '100%' }}
|
||||
style={style}
|
||||
aria-label={selectors.components.DataLinksContextMenu.singleLink}
|
||||
>
|
||||
{children({})}
|
||||
|
||||
@@ -118,7 +118,7 @@ export function UnthemedTimeRangePicker(props: TimeRangePickerProps): ReactEleme
|
||||
</ToolbarButton>
|
||||
</Tooltip>
|
||||
{isOpen && (
|
||||
<FocusScope contain autoFocus restoreFocus>
|
||||
<FocusScope contain autoFocus>
|
||||
<section ref={ref} {...overlayProps} {...dialogProps}>
|
||||
<TimePickerContent
|
||||
timeZone={timeZone}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Meta, Preview, Props } from '@storybook/addon-docs/blocks';
|
||||
import { PluginSignatureBadge } from './PluginSignatureBadge';
|
||||
|
||||
<Meta title="MDX|PluginSignatureBadge" component={PluginSignatureBadge} />
|
||||
|
||||
# Plugin Signature Badge
|
||||
|
||||
The Plugin Signature Badge can be found in each information plugin card of the configuration plugins panel (Grafana menu > Configuration > Plugins).
|
||||
This is a security measure to make sure plugins haven't been tampered with. Upon loading, Grafana checks to see the plugin signature status.
|
||||
|
||||
## Badges:
|
||||
|
||||
1.- Core: this badge indicates that the plugin has been built into Grafana.
|
||||
|
||||
<Preview>
|
||||
<PluginSignatureBadge status="internal" />
|
||||
</Preview>
|
||||
|
||||
2.- Signed: the plugin's signature was successfully verified.
|
||||
|
||||
<Preview>
|
||||
<PluginSignatureBadge status="valid" />
|
||||
</Preview>
|
||||
|
||||
3.- Invalid signature: this plugin has a invalid signature.
|
||||
|
||||
<Preview>
|
||||
<PluginSignatureBadge status="invalid" />
|
||||
</Preview>
|
||||
|
||||
4.- Modified signature: this plugin has changed since it was signed. This may indicate malicious intent.
|
||||
|
||||
<Preview>
|
||||
<PluginSignatureBadge status="modified" />
|
||||
</Preview>
|
||||
|
||||
5.- Unsigned: the plugin is not signed. In this case, as upon loading Grafana checks the plugins signature, Grafana will not load or start it. Furthermore, it will write an error message to the server log.
|
||||
|
||||
<Preview>
|
||||
<PluginSignatureBadge status="unsigned" />
|
||||
</Preview>
|
||||
|
||||
<Props of={PluginSignatureBadge} />
|
||||
@@ -6,6 +6,8 @@ import { PluginSignatureBadge } from '@grafana/ui';
|
||||
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
|
||||
import mdx from './PluginSignatureBadge.mdx';
|
||||
|
||||
export default {
|
||||
title: 'Data Display/PluginSignatureBadge',
|
||||
decorators: [withCenteredStory],
|
||||
@@ -24,6 +26,11 @@ export default {
|
||||
],
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
page: mdx,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const Basic: Story = (args) => {
|
||||
|
||||
@@ -50,7 +50,7 @@ export const BarGaugeCell: FC<TableCellProps> = (props) => {
|
||||
return field.getLinks({ valueRowIndex: row.index });
|
||||
};
|
||||
|
||||
const hasLinks = !!getLinks().length;
|
||||
const hasLinks = Boolean(getLinks().length);
|
||||
|
||||
const renderComponent = (menuProps: DataLinksContextMenuApi) => {
|
||||
const { openMenu, targetClassName } = menuProps;
|
||||
@@ -76,7 +76,11 @@ export const BarGaugeCell: FC<TableCellProps> = (props) => {
|
||||
|
||||
return (
|
||||
<div {...cellProps} className={tableStyles.cellContainer}>
|
||||
{hasLinks && <DataLinksContextMenu links={getLinks}>{(api) => renderComponent(api)}</DataLinksContextMenu>}
|
||||
{hasLinks && (
|
||||
<DataLinksContextMenu links={getLinks} style={{ display: 'flex', width: '100%' }}>
|
||||
{(api) => renderComponent(api)}
|
||||
</DataLinksContextMenu>
|
||||
)}
|
||||
{!hasLinks && (
|
||||
<BarGauge
|
||||
width={innerWidth}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const ImageCell: FC<TableCellProps> = (props) => {
|
||||
|
||||
const displayValue = field.display!(cell.value);
|
||||
|
||||
const hasLinks = getCellLinks(field, row)?.length;
|
||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||
|
||||
return (
|
||||
<div {...cellProps} className={tableStyles.cellContainer}>
|
||||
|
||||
@@ -27,7 +27,7 @@ export function JSONViewCell(props: TableCellProps): JSX.Element {
|
||||
displayValue = JSON.stringify(value, null, ' ');
|
||||
}
|
||||
|
||||
const hasLinks = getCellLinks(field, row)?.length;
|
||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||
|
||||
return (
|
||||
<div {...cellProps} className={inspectEnabled ? tableStyles.cellContainerNoOverflow : tableStyles.cellContainer}>
|
||||
|
||||
@@ -165,7 +165,6 @@ export const getTableStyles = (theme: GrafanaTheme2) => {
|
||||
imageCellLink: css`
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`,
|
||||
headerFilter: css`
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useStyles2 } from '../../themes/ThemeContext';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
import { Counter } from './Counter';
|
||||
import { TabProps } from './Tab';
|
||||
|
||||
export const VerticalTab = React.forwardRef<HTMLAnchorElement, TabProps>(
|
||||
({ label, active, icon, counter, className, suffix: Suffix, onChangeTab, href, ...otherProps }, ref) => {
|
||||
const tabsStyles = useStyles2(getTabStyles);
|
||||
const content = () => (
|
||||
<>
|
||||
{icon && <Icon name={icon} />}
|
||||
{label}
|
||||
{typeof counter === 'number' && <Counter value={counter} />}
|
||||
{Suffix && <Suffix className={tabsStyles.suffix} />}
|
||||
</>
|
||||
);
|
||||
|
||||
const linkClass = cx(tabsStyles.link, active && tabsStyles.activeStyle);
|
||||
|
||||
return (
|
||||
<li className={tabsStyles.item}>
|
||||
<a
|
||||
href={href}
|
||||
className={linkClass}
|
||||
{...otherProps}
|
||||
onClick={onChangeTab}
|
||||
aria-label={otherProps['aria-label'] || selectors.components.Tab.title(label)}
|
||||
role="tab"
|
||||
aria-selected={active}
|
||||
ref={ref}
|
||||
>
|
||||
{content()}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
VerticalTab.displayName = 'Tab';
|
||||
|
||||
const getTabStyles = (theme: GrafanaTheme2) => {
|
||||
return {
|
||||
item: css`
|
||||
list-style: none;
|
||||
margin-right: ${theme.spacing(2)};
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
`,
|
||||
link: css`
|
||||
padding: 6px 12px;
|
||||
display: block;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
|
||||
color: ${theme.colors.text.primary};
|
||||
|
||||
svg {
|
||||
margin-right: ${theme.spacing(1)};
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`,
|
||||
activeStyle: css`
|
||||
label: activeTabStyle;
|
||||
color: ${theme.colors.text.maxContrast};
|
||||
font-weight: 500;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
display: block;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 4px;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
border-radius: 2px;
|
||||
background-image: linear-gradient(0deg, #f05a28 30%, #fbca0a 99%);
|
||||
}
|
||||
`,
|
||||
suffix: css`
|
||||
margin-left: ${theme.spacing(1)};
|
||||
`,
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Story, Preview, Props } from '@storybook/addon-docs/blocks';
|
||||
import { Tag } from './Tag';
|
||||
|
||||
<Meta title="MDX|Tag" component={Tag} />
|
||||
|
||||
# Tag
|
||||
|
||||
Used for displaying metadata, for example to add more details to search results. Background and border colors are generated from the tag name.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { Story } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Tag } from '@grafana/ui';
|
||||
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
|
||||
import { Props as TagProps, Tag } from './Tag';
|
||||
import mdx from './Tag.mdx';
|
||||
|
||||
export default {
|
||||
@@ -15,9 +15,28 @@ export default {
|
||||
docs: {
|
||||
page: mdx,
|
||||
},
|
||||
controls: {
|
||||
exclude: ['onClick'],
|
||||
},
|
||||
},
|
||||
args: {
|
||||
name: 'Tag',
|
||||
colorIndex: 0,
|
||||
showIcon: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const single = () => {
|
||||
return <Tag name="Tag" onClick={action('Tag clicked')} />;
|
||||
interface StoryProps extends TagProps {
|
||||
showIcon?: boolean;
|
||||
}
|
||||
|
||||
export const Single: Story<StoryProps> = (args) => {
|
||||
return (
|
||||
<Tag
|
||||
name={args.name}
|
||||
colorIndex={args.colorIndex}
|
||||
onClick={action('Tag clicked')}
|
||||
icon={args.showIcon ? args.icon : undefined}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -64,13 +64,15 @@ const getTagStyles = (theme: GrafanaTheme, name: string, colorIndex?: number) =>
|
||||
font-weight: ${theme.typography.weight.semibold};
|
||||
font-size: ${theme.typography.size.sm};
|
||||
line-height: ${theme.typography.lineHeight.xs};
|
||||
vertical-align: baseline;
|
||||
background-color: ${colors.color};
|
||||
color: ${theme.palette.gray98};
|
||||
white-space: nowrap;
|
||||
text-shadow: none;
|
||||
padding: 3px 6px;
|
||||
border-radius: ${theme.border.radius.md};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
`,
|
||||
hover: css`
|
||||
&:hover {
|
||||
|
||||
@@ -79,6 +79,7 @@ export { TableCellDisplayMode, TableSortByFieldState } from './Table/types';
|
||||
export { TableInputCSV } from './TableInputCSV/TableInputCSV';
|
||||
export { TabsBar } from './Tabs/TabsBar';
|
||||
export { Tab } from './Tabs/Tab';
|
||||
export { VerticalTab } from './Tabs/VerticalTab';
|
||||
export { TabContent } from './Tabs/TabContent';
|
||||
export { Counter } from './Tabs/Counter';
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { NONE, DURATION, TAG } from '../settings/SpanBarSettings';
|
||||
|
||||
import SpanBarRow from './SpanBarRow';
|
||||
|
||||
describe('<SpanBarRow>', () => {
|
||||
@@ -43,11 +45,10 @@ describe('<SpanBarRow>', () => {
|
||||
showErrorIcon: false,
|
||||
getViewedBounds: () => ({ start: 0, end: 1 }),
|
||||
span: {
|
||||
duration: 'test-duration',
|
||||
duration: 9000,
|
||||
hasChildren: true,
|
||||
process: {
|
||||
serviceName: 'service-name',
|
||||
tags: [],
|
||||
},
|
||||
spanID,
|
||||
logs: [],
|
||||
@@ -181,4 +182,89 @@ describe('<SpanBarRow>', () => {
|
||||
);
|
||||
expect(screen.getAllByTestId('SpanLinksMenu')).toHaveLength(1);
|
||||
});
|
||||
|
||||
describe('render span bar label', () => {
|
||||
it('with default value', () => {
|
||||
render(<SpanBarRow {...props} />);
|
||||
expect(screen.getByText('(9ms)')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('with none value', () => {
|
||||
const testProps = Object.assign(
|
||||
{
|
||||
spanBarOptions: {
|
||||
type: NONE,
|
||||
},
|
||||
},
|
||||
props
|
||||
);
|
||||
render(<SpanBarRow {...testProps} />);
|
||||
expect(screen.queryByText('(9ms)')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('with duration value', () => {
|
||||
const testProps = Object.assign(
|
||||
{
|
||||
spanBarOptions: {
|
||||
type: DURATION,
|
||||
},
|
||||
},
|
||||
props
|
||||
);
|
||||
render(<SpanBarRow {...testProps} />);
|
||||
expect(screen.getByText('(9ms)')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('with tag value', () => {
|
||||
const testProps = Object.assign(
|
||||
{
|
||||
spanBarOptions: {
|
||||
type: TAG,
|
||||
tag: 'tag',
|
||||
},
|
||||
},
|
||||
{
|
||||
...props,
|
||||
span: {
|
||||
process: {},
|
||||
tags: [
|
||||
{
|
||||
key: 'tag',
|
||||
value: 'tag-value',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
render(<SpanBarRow {...testProps} />);
|
||||
expect(screen.getByText('(tag-value)')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('with process value', () => {
|
||||
let testProps = Object.assign(
|
||||
{
|
||||
spanBarOptions: {
|
||||
type: TAG,
|
||||
tag: 'tag',
|
||||
},
|
||||
},
|
||||
{
|
||||
...props,
|
||||
span: {
|
||||
process: {
|
||||
tags: [
|
||||
{
|
||||
key: 'tag',
|
||||
value: 'process-value',
|
||||
},
|
||||
],
|
||||
},
|
||||
tags: [],
|
||||
},
|
||||
}
|
||||
);
|
||||
render(<SpanBarRow {...testProps} />);
|
||||
expect(screen.getByText('(process-value)')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,11 +18,12 @@ import * as React from 'react';
|
||||
import IoAlert from 'react-icons/lib/io/alert';
|
||||
import IoArrowRightA from 'react-icons/lib/io/arrow-right-a';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaTheme2, TraceKeyValuePair } from '@grafana/data';
|
||||
import { stylesFactory, withTheme2 } from '@grafana/ui';
|
||||
|
||||
import { autoColor } from '../Theme';
|
||||
import { SpanLinkFunc, TNil } from '../types';
|
||||
import { DURATION, NONE, TAG } from '../settings/SpanBarSettings';
|
||||
import { SpanBarOptions, SpanLinkFunc, TNil } from '../types';
|
||||
import { SpanLinks } from '../types/links';
|
||||
import { TraceSpan } from '../types/trace';
|
||||
|
||||
@@ -290,6 +291,7 @@ type SpanBarRowProps = {
|
||||
className?: string;
|
||||
theme: GrafanaTheme2;
|
||||
color: string;
|
||||
spanBarOptions: SpanBarOptions | undefined;
|
||||
columnDivision: number;
|
||||
isChildrenExpanded: boolean;
|
||||
isDetailExpanded: boolean;
|
||||
@@ -352,6 +354,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
||||
const {
|
||||
className,
|
||||
color,
|
||||
spanBarOptions,
|
||||
columnDivision,
|
||||
isChildrenExpanded,
|
||||
isDetailExpanded,
|
||||
@@ -379,6 +382,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
||||
process: { serviceName },
|
||||
} = span;
|
||||
const label = formatDuration(duration);
|
||||
|
||||
const viewBounds = getViewedBounds(span.startTime, span.startTime + span.duration);
|
||||
const viewStart = viewBounds.start;
|
||||
const viewEnd = viewBounds.end;
|
||||
@@ -473,7 +477,7 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
||||
)}
|
||||
</span>
|
||||
<small className={styles.endpointName}>{rpc ? rpc.operationName : operationName}</small>
|
||||
<small className={styles.endpointName}> | {label}</small>
|
||||
<small className={styles.endpointName}> {this.getSpanBarLabel(span, spanBarOptions, label)}</small>
|
||||
</a>
|
||||
{createSpanLink &&
|
||||
(() => {
|
||||
@@ -542,6 +546,35 @@ export class UnthemedSpanBarRow extends React.PureComponent<SpanBarRowProps> {
|
||||
</TimelineRow>
|
||||
);
|
||||
}
|
||||
|
||||
getSpanBarLabel = (span: TraceSpan, spanBarOptions: SpanBarOptions | undefined, duration: string) => {
|
||||
const type = spanBarOptions?.type ?? '';
|
||||
|
||||
if (type === NONE) {
|
||||
return '';
|
||||
} else if (type === '' || type === DURATION) {
|
||||
return `(${duration})`;
|
||||
} else if (type === TAG) {
|
||||
const tagKey = spanBarOptions?.tag?.trim() ?? '';
|
||||
if (tagKey !== '' && span.tags) {
|
||||
const tag = span.tags?.find((tag: TraceKeyValuePair) => {
|
||||
return tag.key === tagKey;
|
||||
});
|
||||
const process = span.process?.tags?.find((process: TraceKeyValuePair) => {
|
||||
return process.key === tagKey;
|
||||
});
|
||||
|
||||
if (tag) {
|
||||
return `(${tag.value})`;
|
||||
}
|
||||
if (process) {
|
||||
return `(${process.value})`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
}
|
||||
|
||||
export default withTheme2(UnthemedSpanBarRow);
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ describe('AccordianLogs tests', () => {
|
||||
it('shows the number of log entries', () => {
|
||||
setup();
|
||||
|
||||
expect(screen.getByRole('switch', { name: 'Logs (2)' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('switch', { name: 'Events (2)' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('hides log entries when not expanded', () => {
|
||||
|
||||
@@ -90,7 +90,7 @@ export default function AccordianLogs(props: AccordianLogsProps) {
|
||||
return (
|
||||
<div className={styles.AccordianLogs}>
|
||||
<HeaderComponent className={styles.AccordianLogsHeader} {...headerProps}>
|
||||
{arrow} <strong>Logs</strong> ({logs.length})
|
||||
{arrow} <strong>Events</strong> ({logs.length})
|
||||
</HeaderComponent>
|
||||
{isOpen && (
|
||||
<div className={styles.AccordianLogsContent}>
|
||||
|
||||
@@ -146,14 +146,14 @@ describe('<SpanDetail>', () => {
|
||||
});
|
||||
|
||||
it('renders the span tags', () => {
|
||||
const target = <AccordianKeyValues data={span.tags} label="Tags" isOpen={detailState.isTagsOpen} />;
|
||||
const target = <AccordianKeyValues data={span.tags} label="Attributes" isOpen={detailState.isTagsOpen} />;
|
||||
expect(wrapper.containsMatchingElement(target)).toBe(true);
|
||||
wrapper.find({ data: span.tags }).simulate('toggle');
|
||||
expect(props.tagsToggle).toHaveBeenLastCalledWith(span.spanID);
|
||||
});
|
||||
|
||||
it('renders the process tags', () => {
|
||||
const target = <AccordianKeyValues data={span.process.tags} label="Process" isOpen={detailState.isProcessOpen} />;
|
||||
const target = <AccordianKeyValues data={span.process.tags} label="Resource" isOpen={detailState.isProcessOpen} />;
|
||||
expect(wrapper.containsMatchingElement(target)).toBe(true);
|
||||
wrapper.find({ data: span.process.tags }).simulate('toggle');
|
||||
expect(props.processToggle).toHaveBeenLastCalledWith(span.spanID);
|
||||
|
||||
@@ -213,7 +213,7 @@ export default function SpanDetail(props: SpanDetailProps) {
|
||||
<div>
|
||||
<AccordianKeyValues
|
||||
data={tags}
|
||||
label="Tags"
|
||||
label="Attributes"
|
||||
linksGetter={linksGetter}
|
||||
isOpen={isTagsOpen}
|
||||
onToggle={() => tagsToggle(spanID)}
|
||||
@@ -222,7 +222,7 @@ export default function SpanDetail(props: SpanDetailProps) {
|
||||
<AccordianKeyValues
|
||||
className={ubMb1}
|
||||
data={process.tags}
|
||||
label="Process"
|
||||
label="Resource"
|
||||
linksGetter={linksGetter}
|
||||
isOpen={isProcessOpen}
|
||||
onToggle={() => processToggle(spanID)}
|
||||
|
||||
@@ -23,7 +23,7 @@ import { stylesFactory, withTheme2, ToolbarButton } from '@grafana/ui';
|
||||
|
||||
import { Accessors } from '../ScrollManager';
|
||||
import { PEER_SERVICE } from '../constants/tag-keys';
|
||||
import { SpanLinkFunc, TNil } from '../types';
|
||||
import { SpanBarOptions, SpanLinkFunc, TNil } from '../types';
|
||||
import TTraceTimeline from '../types/TTraceTimeline';
|
||||
import { TraceLog, TraceSpan, Trace, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||
import { getColorByKey } from '../utils/color-generator';
|
||||
@@ -89,6 +89,7 @@ type TVirtualizedTraceViewOwnProps = {
|
||||
scrollToFirstVisibleSpan: () => void;
|
||||
registerAccessors: (accesors: Accessors) => void;
|
||||
trace: Trace;
|
||||
spanBarOptions: SpanBarOptions | undefined;
|
||||
linksGetter: (span: TraceSpan, items: TraceKeyValuePair[], itemIndex: number) => TraceLink[];
|
||||
childrenToggle: (spanID: string) => void;
|
||||
clearShouldScrollToFirstUiFindMatch: () => void;
|
||||
@@ -387,6 +388,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
|
||||
findMatchesIDs,
|
||||
spanNameColumnWidth,
|
||||
trace,
|
||||
spanBarOptions,
|
||||
hoverIndentGuideIds,
|
||||
addHoverIndentGuideId,
|
||||
removeHoverIndentGuideId,
|
||||
@@ -440,6 +442,7 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
|
||||
clippingLeft={this.getClipping().left}
|
||||
clippingRight={this.getClipping().right}
|
||||
color={color}
|
||||
spanBarOptions={spanBarOptions}
|
||||
columnDivision={spanNameColumnWidth}
|
||||
isChildrenExpanded={!isCollapsed}
|
||||
isDetailExpanded={isDetailExpanded}
|
||||
|
||||
@@ -21,6 +21,7 @@ import { stylesFactory, withTheme2 } from '@grafana/ui';
|
||||
import { Accessors } from '../ScrollManager';
|
||||
import { autoColor } from '../Theme';
|
||||
import { merge as mergeShortcuts } from '../keyboard-shortcuts';
|
||||
import { SpanBarOptions } from '../settings/SpanBarSettings';
|
||||
import { SpanLinkFunc, TNil } from '../types';
|
||||
import TTraceTimeline from '../types/TTraceTimeline';
|
||||
import { TraceSpan, Trace, TraceLog, TraceKeyValuePair, TraceLink, TraceSpanReference } from '../types/trace';
|
||||
@@ -75,6 +76,7 @@ type TProps = TExtractUiFindFromStateReturn & {
|
||||
scrollToFirstVisibleSpan: () => void;
|
||||
traceTimeline: TTraceTimeline;
|
||||
trace: Trace;
|
||||
spanBarOptions: SpanBarOptions | undefined;
|
||||
updateNextViewRangeTime: (update: ViewRangeTimeUpdate) => void;
|
||||
updateViewRangeTime: TUpdateViewRangeTimeFunction;
|
||||
viewRange: ViewRange;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export { default as TraceTimelineViewer } from './TraceTimelineViewer';
|
||||
export { default as TracePageHeader } from './TracePageHeader';
|
||||
export { default as SpanBarSettings } from './settings/SpanBarSettings';
|
||||
export * from './types';
|
||||
export * from './TraceTimelineViewer/types';
|
||||
export { default as DetailState } from './TraceTimelineViewer/SpanDetail/DetailState';
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
DataSourceJsonData,
|
||||
DataSourcePluginOptionsEditorProps,
|
||||
GrafanaTheme,
|
||||
toOption,
|
||||
updateDatasourcePluginJsonDataOption,
|
||||
} from '@grafana/data';
|
||||
import { InlineField, InlineFieldRow, Input, Select, useStyles } from '@grafana/ui';
|
||||
|
||||
export interface SpanBarOptions {
|
||||
type?: string;
|
||||
tag?: string;
|
||||
}
|
||||
|
||||
export interface SpanBarOptionsData extends DataSourceJsonData {
|
||||
spanBar?: SpanBarOptions;
|
||||
}
|
||||
|
||||
export const NONE = 'None';
|
||||
export const DURATION = 'Duration';
|
||||
export const TAG = 'Tag';
|
||||
|
||||
interface Props extends DataSourcePluginOptionsEditorProps<SpanBarOptionsData> {}
|
||||
|
||||
export default function SpanBarSettings({ options, onOptionsChange }: Props) {
|
||||
const styles = useStyles(getStyles);
|
||||
const selectOptions = [NONE, DURATION, TAG].map(toOption);
|
||||
|
||||
return (
|
||||
<div className={css({ width: '100%' })}>
|
||||
<h3 className="page-heading">Span bar label</h3>
|
||||
|
||||
<div className={styles.infoText}>Span bar label lets you add additional info to the span bar row.</div>
|
||||
|
||||
<InlineFieldRow className={styles.row}>
|
||||
<InlineField label="Label" labelWidth={26} grow>
|
||||
<Select
|
||||
inputId="label"
|
||||
options={selectOptions}
|
||||
value={options.jsonData.spanBar?.type || ''}
|
||||
onChange={(v) => {
|
||||
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'spanBar', {
|
||||
...options.jsonData.spanBar,
|
||||
type: v?.value ?? '',
|
||||
});
|
||||
}}
|
||||
placeholder="Duration"
|
||||
isClearable
|
||||
aria-label={'select-label-name'}
|
||||
width={25}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
{options.jsonData.spanBar?.type === TAG && (
|
||||
<InlineFieldRow className={styles.row}>
|
||||
<InlineField label="Tag key" labelWidth={26} tooltip="Tag key which will be used to get the tag value">
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Enter tag key"
|
||||
onChange={(v) =>
|
||||
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'spanBar', {
|
||||
...options.jsonData.spanBar,
|
||||
tag: v.currentTarget.value,
|
||||
})
|
||||
}
|
||||
value={options.jsonData.spanBar?.tag || ''}
|
||||
width={25}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme) => ({
|
||||
infoText: css`
|
||||
label: infoText;
|
||||
padding-bottom: ${theme.spacing.md};
|
||||
color: ${theme.colors.textSemiWeak};
|
||||
`,
|
||||
|
||||
row: css`
|
||||
label: row;
|
||||
align-items: baseline;
|
||||
`,
|
||||
});
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
export { TraceSpan, TraceResponse, Trace, TraceProcess, TraceKeyValuePair, TraceLink } from './trace';
|
||||
export { SpanLinkFunc, SpanLinkDef } from './links';
|
||||
export { SpanBarOptions, SpanBarOptionsData } from '../settings/SpanBarSettings';
|
||||
export { default as TTraceTimeline } from './TTraceTimeline';
|
||||
export { default as TNil } from './TNil';
|
||||
export { SpanLinkFunc, SpanLinkDef } from './links';
|
||||
|
||||
@@ -35,13 +35,13 @@ RUN apk add --no-cache openssl --repository=http://dl-cdn.alpinelinux.org/alpine
|
||||
RUN if [ `arch` = "x86_64" ]; then \
|
||||
apk add --no-cache libaio libnsl && \
|
||||
ln -s /usr/lib/libnsl.so.2 /usr/lib/libnsl.so.1 && \
|
||||
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-2.30-r0.apk \
|
||||
-O /tmp/glibc-2.30-r0.apk && \
|
||||
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.30-r0/glibc-bin-2.30-r0.apk \
|
||||
-O /tmp/glibc-bin-2.30-r0.apk && \
|
||||
apk add --no-cache --allow-untrusted /tmp/glibc-2.30-r0.apk /tmp/glibc-bin-2.30-r0.apk && \
|
||||
rm -f /tmp/glibc-2.30-r0.apk && \
|
||||
rm -f /tmp/glibc-bin-2.30-r0.apk && \
|
||||
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk \
|
||||
-O /tmp/glibc-2.35-r0.apk && \
|
||||
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-bin-2.35-r0.apk \
|
||||
-O /tmp/glibc-bin-2.35-r0.apk && \
|
||||
apk add --no-cache --allow-untrusted /tmp/glibc-2.35-r0.apk /tmp/glibc-bin-2.35-r0.apk && \
|
||||
rm -f /tmp/glibc-2.35-r0.apk && \
|
||||
rm -f /tmp/glibc-bin-2.35-r0.apk && \
|
||||
rm -f /lib/ld-linux-x86-64.so.2 && \
|
||||
rm -f /etc/ld.so.cache; \
|
||||
fi
|
||||
|
||||
@@ -16,6 +16,10 @@ Further documentation can be found at http://docs.grafana.org/installation/docke
|
||||
|
||||
## Changelog
|
||||
|
||||
### v9.0.3
|
||||
|
||||
- Upgraded glibc version to glibc [2.35](https://sourceware.org/pipermail/libc-alpha/2022-February/136040.html) [#51107](https://github.com/grafana/grafana/pull/51107/files)
|
||||
|
||||
### v8.3.0-beta2
|
||||
|
||||
- Our Alpine based images have been upgraded to Alpine [3.14.3](https://alpinelinux.org/posts/Alpine-3.14.3-released.html) [#41922](https://github.com/grafana/grafana/pull/41922) [@hairyhenderson](https://github.com/hairyhenderson)
|
||||
|
||||
@@ -223,11 +223,12 @@ func (hs *HTTPServer) declareFixedRoles() error {
|
||||
Role: ac.RoleDTO{
|
||||
Name: "fixed:teams:creator",
|
||||
DisplayName: "Team creator",
|
||||
Description: "Create teams and read organisation users (required to manage the created teams).",
|
||||
Description: "Create teams and read organisation users and service accounts (required to manage the created teams).",
|
||||
Group: "Teams",
|
||||
Permissions: []ac.Permission{
|
||||
{Action: ac.ActionTeamsCreate},
|
||||
{Action: ac.ActionOrgUsersRead, Scope: ac.ScopeUsersAll},
|
||||
{Action: serviceaccounts.ActionRead, Scope: serviceaccounts.ScopeAll},
|
||||
},
|
||||
},
|
||||
Grants: teamCreatorGrants,
|
||||
|
||||
@@ -53,7 +53,7 @@ func (hs *HTTPServer) GetAnnotations(c *models.ReqContext) response.Response {
|
||||
item.DashboardUID = val
|
||||
} else {
|
||||
query := models.GetDashboardQuery{Id: item.DashboardId, OrgId: c.OrgId}
|
||||
err := hs.dashboardService.GetDashboard(c.Req.Context(), &query)
|
||||
err := hs.DashboardService.GetDashboard(c.Req.Context(), &query)
|
||||
if err == nil && query.Result != nil {
|
||||
item.DashboardUID = &query.Result.Uid
|
||||
dashboardCache[item.DashboardId] = &query.Result.Uid
|
||||
@@ -82,7 +82,7 @@ func (hs *HTTPServer) PostAnnotation(c *models.ReqContext) response.Response {
|
||||
// overwrite dashboardId when dashboardUID is not empty
|
||||
if cmd.DashboardUID != "" {
|
||||
query := models.GetDashboardQuery{OrgId: c.OrgId, Uid: cmd.DashboardUID}
|
||||
err := hs.dashboardService.GetDashboard(c.Req.Context(), &query)
|
||||
err := hs.DashboardService.GetDashboard(c.Req.Context(), &query)
|
||||
if err == nil {
|
||||
cmd.DashboardId = query.Result.Id
|
||||
}
|
||||
@@ -291,7 +291,7 @@ func (hs *HTTPServer) MassDeleteAnnotations(c *models.ReqContext) response.Respo
|
||||
|
||||
if cmd.DashboardUID != "" {
|
||||
query := models.GetDashboardQuery{OrgId: c.OrgId, Uid: cmd.DashboardUID}
|
||||
err := hs.dashboardService.GetDashboard(c.Req.Context(), &query)
|
||||
err := hs.DashboardService.GetDashboard(c.Req.Context(), &query)
|
||||
if err == nil {
|
||||
cmd.DashboardId = query.Result.Id
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ func postAnnotationScenario(t *testing.T, desc string, url string, routePattern
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
hs := setupSimpleHTTPServer(nil)
|
||||
hs.SQLStore = store
|
||||
hs.dashboardService = dashSvc
|
||||
hs.DashboardService = dashSvc
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
@@ -428,7 +428,7 @@ func deleteAnnotationsScenario(t *testing.T, desc string, url string, routePatte
|
||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||
hs := setupSimpleHTTPServer(nil)
|
||||
hs.SQLStore = store
|
||||
hs.dashboardService = dashSvc
|
||||
hs.DashboardService = dashSvc
|
||||
|
||||
sc := setupScenarioContext(t, url)
|
||||
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
||||
|
||||
+14
-18
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
publicdashboardsapi "github.com/grafana/grafana/pkg/services/publicdashboards/api"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
@@ -28,7 +29,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
reqGrafanaAdmin := middleware.ReqGrafanaAdmin
|
||||
reqEditorRole := middleware.ReqEditorRole
|
||||
reqOrgAdmin := middleware.ReqOrgAdmin
|
||||
reqOrgAdminDashOrFolderAdminOrTeamAdmin := middleware.OrgAdminDashOrFolderAdminOrTeamAdmin(hs.SQLStore, hs.dashboardService)
|
||||
reqOrgAdminDashOrFolderAdminOrTeamAdmin := middleware.OrgAdminDashOrFolderAdminOrTeamAdmin(hs.SQLStore, hs.DashboardService)
|
||||
reqCanAccessTeams := middleware.AdminOrEditorAndFeatureEnabled(hs.Cfg.EditorsCanAdmin)
|
||||
reqSnapshotPublicModeOrSignedIn := middleware.SnapshotPublicModeOrSignedIn(hs.Cfg)
|
||||
redirectFromLegacyPanelEditURL := middleware.RedirectFromLegacyPanelEditURL(hs.Cfg)
|
||||
@@ -75,6 +76,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
r.Get("/admin/orgs", authorizeInOrg(reqGrafanaAdmin, ac.UseGlobalOrg, orgsAccessEvaluator), hs.Index)
|
||||
r.Get("/admin/orgs/edit/:id", authorizeInOrg(reqGrafanaAdmin, ac.UseGlobalOrg, orgsAccessEvaluator), hs.Index)
|
||||
r.Get("/admin/stats", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionServerStatsRead)), hs.Index)
|
||||
r.Get("/admin/storage/*", reqGrafanaAdmin, hs.Index)
|
||||
r.Get("/admin/ldap", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionLDAPStatusRead)), hs.Index)
|
||||
r.Get("/styleguide", reqSignedIn, hs.Index)
|
||||
|
||||
@@ -102,6 +104,10 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
r.Get("/dashboards/*", reqSignedIn, hs.Index)
|
||||
r.Get("/goto/:uid", reqSignedIn, hs.redirectFromShortURL, hs.Index)
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
|
||||
r.Get("/public-dashboards/:accessToken", publicdashboardsapi.SetPublicDashboardFlag(), hs.Index)
|
||||
}
|
||||
|
||||
r.Get("/explore", authorize(func(c *models.ReqContext) {
|
||||
if f, ok := reqSignedIn.(func(c *models.ReqContext)); ok {
|
||||
f(c)
|
||||
@@ -327,10 +333,12 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
apiRoute.Any("/plugins/:pluginId/resources/*", hs.CallResource)
|
||||
apiRoute.Get("/plugins/errors", routing.Wrap(hs.GetPluginErrorsList))
|
||||
|
||||
apiRoute.Group("/plugins", func(pluginRoute routing.RouteRegister) {
|
||||
pluginRoute.Post("/:pluginId/install", routing.Wrap(hs.InstallPlugin))
|
||||
pluginRoute.Post("/:pluginId/uninstall", routing.Wrap(hs.UninstallPlugin))
|
||||
}, reqGrafanaAdmin)
|
||||
if hs.Cfg.PluginAdminEnabled && !hs.Cfg.PluginAdminExternalManageEnabled {
|
||||
apiRoute.Group("/plugins", func(pluginRoute routing.RouteRegister) {
|
||||
pluginRoute.Post("/:pluginId/install", routing.Wrap(hs.InstallPlugin))
|
||||
pluginRoute.Post("/:pluginId/uninstall", routing.Wrap(hs.UninstallPlugin))
|
||||
}, reqGrafanaAdmin)
|
||||
}
|
||||
|
||||
apiRoute.Group("/plugins", func(pluginRoute routing.RouteRegister) {
|
||||
pluginRoute.Get("/:pluginId/dashboards/", routing.Wrap(hs.GetPluginDashboards))
|
||||
@@ -388,11 +396,6 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
})
|
||||
|
||||
dashboardRoute.Group("/uid/:uid", func(dashUidRoute routing.RouteRegister) {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
|
||||
dashUidRoute.Get("/public-config", authorize(reqSignedIn, ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.GetPublicDashboardConfig))
|
||||
dashUidRoute.Post("/public-config", authorize(reqSignedIn, ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.SavePublicDashboardConfig))
|
||||
}
|
||||
|
||||
if hs.ThumbService != nil {
|
||||
dashUidRoute.Get("/img/:kind/:theme", hs.ThumbService.GetImage)
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagDashboardPreviewsAdmin) {
|
||||
@@ -595,7 +598,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
// grafana.net proxy
|
||||
r.Any("/api/gnet/*", reqSignedIn, hs.ProxyGnetRequest)
|
||||
|
||||
// Gravatar service.
|
||||
// Gravatar service
|
||||
r.Get("/avatar/:hash", hs.AvatarCacheServer.Handler)
|
||||
|
||||
// Snapshots
|
||||
@@ -605,13 +608,6 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
r.Get("/api/snapshots-delete/:deleteKey", reqSnapshotPublicModeOrSignedIn, routing.Wrap(hs.DeleteDashboardSnapshotByDeleteKey))
|
||||
r.Delete("/api/snapshots/:key", reqEditorRole, routing.Wrap(hs.DeleteDashboardSnapshot))
|
||||
|
||||
// Public API
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
|
||||
r.Get("/public-dashboards/:accessToken", middleware.SetPublicDashboardFlag(), hs.Index)
|
||||
r.Get("/api/public/dashboards/:accessToken", routing.Wrap(hs.GetPublicDashboard))
|
||||
r.Post("/api/public/dashboards/:accessToken/panels/:panelId/query", routing.Wrap(hs.QueryPublicDashboard))
|
||||
}
|
||||
|
||||
// Frontend logs
|
||||
sourceMapStore := frontendlogging.NewSourceMapStore(hs.Cfg, hs.pluginStaticRouteResolver, frontendlogging.ReadSourceMapFromFS)
|
||||
r.Post("/log", middleware.RateLimit(hs.Cfg.Sentry.EndpointRPS, hs.Cfg.Sentry.EndpointBurst, time.Now),
|
||||
|
||||
+1
-11
@@ -43,7 +43,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/searchusers"
|
||||
"github.com/grafana/grafana/pkg/services/searchusers/filters"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
"github.com/grafana/grafana/pkg/web/webtest"
|
||||
@@ -341,15 +340,6 @@ func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessCont
|
||||
return setupHTTPServerWithCfgDb(t, useFakeAccessControl, enableAccessControl, cfg, db, db, featuremgmt.WithFeatures())
|
||||
}
|
||||
|
||||
func setupHTTPServerWithMockDb(t *testing.T, useFakeAccessControl, enableAccessControl bool, features *featuremgmt.FeatureManager) accessControlScenarioContext {
|
||||
// Use a new conf
|
||||
cfg := setting.NewCfg()
|
||||
db := sqlstore.InitTestDB(t)
|
||||
db.Cfg = setting.NewCfg()
|
||||
|
||||
return setupHTTPServerWithCfgDb(t, useFakeAccessControl, enableAccessControl, cfg, db, mockstore.NewSQLStoreMock(), features)
|
||||
}
|
||||
|
||||
func setupHTTPServerWithCfgDb(t *testing.T, useFakeAccessControl, enableAccessControl bool, cfg *setting.Cfg, db *sqlstore.SQLStore, store sqlstore.Store, features *featuremgmt.FeatureManager) accessControlScenarioContext {
|
||||
t.Helper()
|
||||
|
||||
@@ -396,7 +386,7 @@ func setupHTTPServerWithCfgDb(t *testing.T, useFakeAccessControl, enableAccessCo
|
||||
AccessControl: ac,
|
||||
teamPermissionsService: teamPermissionService,
|
||||
searchUsersService: searchusers.ProvideUsersService(db, filters.ProvideOSSSearchUserFilter()),
|
||||
dashboardService: dashboardservice.ProvideDashboardService(
|
||||
DashboardService: dashboardservice.ProvideDashboardService(
|
||||
cfg, dashboardsStore, nil, features,
|
||||
accesscontrolmock.NewMockedPermissionsService(), accesscontrolmock.NewMockedPermissionsService(), ac,
|
||||
),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user