From 5aacc7cc2a4383f3db1f82d712c1c691cb20b8e8 Mon Sep 17 00:00:00 2001 From: Joey Tawadrous <90795735+joey-grafana@users.noreply.github.com> Date: Mon, 11 Jul 2022 10:21:24 +0100 Subject: [PATCH 01/71] Traces: More feature tracking (#51686) * Added tracing for json upload, service graph, loki queries * Tracking for node graph expand/collapse * Tracking for traceID expand/collapse * Updated betterer.results * Update tests * Updated betterer.results * Fixed? * Fix for test * Update report interaction key for loki expr * Change grafana_traces_search_queried limit to resultLimit as limit is reserved keyword --- .betterer.results | 2 +- packages/jaeger-ui-components/package.json | 1 + .../src/TraceTimelineViewer/index.test.js | 7 +++++++ .../src/TraceTimelineViewer/index.tsx | 18 ++++++++++++++++++ public/app/features/explore/Explore.tsx | 5 ++++- .../explore/NodeGraphContainer.test.tsx | 2 ++ .../features/explore/NodeGraphContainer.tsx | 13 +++++++++++-- .../features/explore/TraceView/TraceView.tsx | 2 ++ .../TraceView/TraceViewContainer.test.tsx | 7 +++++++ .../plugins/datasource/tempo/datasource.ts | 19 ++++++++++++++++++- yarn.lock | 3 ++- 11 files changed, 73 insertions(+), 6 deletions(-) diff --git a/.betterer.results b/.betterer.results index e50a7678a16..c93e559c2a7 100644 --- a/.betterer.results +++ b/.betterer.results @@ -62,7 +62,7 @@ exports[`no enzyme tests`] = { "packages/jaeger-ui-components/src/TraceTimelineViewer/VirtualizedTraceView.test.js:551014442": [ [13, 26, 13, "RegExp match", "2409514259"] ], - "packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:276996587": [ + "packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:1541367299": [ [14, 19, 13, "RegExp match", "2409514259"] ], "public/app/core/components/Select/MetricSelect.test.tsx:1074737147": [ diff --git a/packages/jaeger-ui-components/package.json b/packages/jaeger-ui-components/package.json index b54ab4c63a4..8972a296add 100644 --- a/packages/jaeger-ui-components/package.json +++ b/packages/jaeger-ui-components/package.json @@ -33,6 +33,7 @@ "@emotion/css": "11.9.0", "@grafana/data": "9.1.0-pre", "@grafana/e2e-selectors": "9.1.0-pre", + "@grafana/runtime": "9.1.0-pre", "@grafana/ui": "9.1.0-pre", "chance": "^1.0.10", "classnames": "^2.2.5", diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js index b116b3c2e7d..17d0e9f30a4 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js @@ -24,6 +24,13 @@ import TimelineHeaderRow from './TimelineHeaderRow'; import TraceTimelineViewer from './index'; +jest.mock('@grafana/runtime', () => { + return { + ...jest.requireActual('@grafana/runtime'), + reportInteraction: jest.fn(), + }; +}); + describe('', () => { const trace = transformTraceData(traceGenerator.trace({})); const props = { diff --git a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx index 8b966c86155..abbd98fabff 100644 --- a/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx +++ b/packages/jaeger-ui-components/src/TraceTimelineViewer/index.tsx @@ -16,6 +16,7 @@ import { css } from '@emotion/css'; import React, { RefObject } from 'react'; import { GrafanaTheme2, LinkModel, TimeZone } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { stylesFactory, withTheme2 } from '@grafana/ui'; import { Accessors } from '../ScrollManager'; @@ -76,6 +77,7 @@ type TProps = TExtractUiFindFromStateReturn & { scrollToFirstVisibleSpan: () => void; traceTimeline: TTraceTimeline; trace: Trace; + datasourceType: string; spanBarOptions: SpanBarOptions | undefined; updateNextViewRangeTime: (update: ViewRangeTimeUpdate) => void; updateViewRangeTime: TUpdateViewRangeTimeFunction; @@ -143,18 +145,34 @@ export class UnthemedTraceTimelineViewer extends React.PureComponent { this.props.collapseAll(this.props.trace.spans); + reportInteraction('grafana_traces_traceID_expand_collapse_clicked', { + datasourceType: this.props.datasourceType, + type: 'collapseAll', + }); }; collapseOne = () => { this.props.collapseOne(this.props.trace.spans); + reportInteraction('grafana_traces_traceID_expand_collapse_clicked', { + datasourceType: this.props.datasourceType, + type: 'collapseOne', + }); }; expandAll = () => { this.props.expandAll(); + reportInteraction('grafana_traces_traceID_expand_collapse_clicked', { + datasourceType: this.props.datasourceType, + type: 'expandAll', + }); }; expandOne = () => { this.props.expandOne(this.props.trace.spans); + reportInteraction('grafana_traces_traceID_expand_collapse_clicked', { + datasourceType: this.props.datasourceType, + type: 'expandOne', + }); }; render() { diff --git a/public/app/features/explore/Explore.tsx b/public/app/features/explore/Explore.tsx index 2987f65b1cf..4d0a513972b 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -280,12 +280,15 @@ export class Explore extends React.PureComponent { } renderNodeGraphPanel() { - const { exploreId, showTrace, queryResponse } = this.props; + const { exploreId, showTrace, queryResponse, datasourceInstance } = this.props; + const datasourceType = datasourceInstance ? datasourceInstance?.type : 'unknown'; + return ( ); } diff --git a/public/app/features/explore/NodeGraphContainer.test.tsx b/public/app/features/explore/NodeGraphContainer.test.tsx index f05619fe848..e9bd95d2393 100644 --- a/public/app/features/explore/NodeGraphContainer.test.tsx +++ b/public/app/features/explore/NodeGraphContainer.test.tsx @@ -16,6 +16,7 @@ describe('NodeGraphContainer', () => { range={getDefaultTimeRange()} splitOpen={(() => {}) as any} withTraceView={true} + datasourceType={''} /> ); @@ -30,6 +31,7 @@ describe('NodeGraphContainer', () => { exploreId={ExploreId.left} range={getDefaultTimeRange()} splitOpen={(() => {}) as any} + datasourceType={''} /> ); diff --git a/public/app/features/explore/NodeGraphContainer.tsx b/public/app/features/explore/NodeGraphContainer.tsx index b815aa522fd..40e3f588942 100644 --- a/public/app/features/explore/NodeGraphContainer.tsx +++ b/public/app/features/explore/NodeGraphContainer.tsx @@ -4,6 +4,7 @@ import { connect, ConnectedProps } from 'react-redux'; import { useToggle, useWindowSize } from 'react-use'; import { applyFieldOverrides, DataFrame, GrafanaTheme2 } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { Badge, Collapse, useStyles2, useTheme2 } from '@grafana/ui'; import { NodeGraph } from '../../plugins/panel/nodeGraph'; @@ -27,12 +28,13 @@ interface OwnProps { exploreId: ExploreId; // When showing the node graph together with trace view we do some changes so it works better. withTraceView?: boolean; + datasourceType: string; } type Props = OwnProps & ConnectedProps; export function UnconnectedNodeGraphContainer(props: Props) { - const { dataFrames, range, splitOpen, withTraceView } = props; + const { dataFrames, range, splitOpen, withTraceView, datasourceType } = props; const getLinks = useLinks(range, splitOpen); const theme = useTheme2(); const styles = useStyles2(getStyles); @@ -53,6 +55,13 @@ export function UnconnectedNodeGraphContainer(props: Props) { const { nodes } = useCategorizeFrames(frames); const [open, toggleOpen] = useToggle(false); + const toggled = () => { + toggleOpen(); + reportInteraction('grafana_traces_node_graph_panel_clicked', { + datasourceType: datasourceType, + expanded: !open, + }); + }; // Calculate node graph height based on window and top position, with some padding const { height: windowHeight } = useWindowSize(); @@ -82,7 +91,7 @@ export function UnconnectedNodeGraphContainer(props: Props) { collapsible={withTraceView} // We allow collapsing this only when it is shown together with trace view. isOpen={withTraceView ? open : true} - onToggle={withTraceView ? () => toggleOpen() : undefined} + onToggle={withTraceView ? () => toggled() : undefined} >
setSlim(!slim), [slim]); const timeZone = useSelector((state: StoreState) => getTimeZone(state.user)); + const datasourceType = datasource ? datasource?.type : 'unknown'; return ( <> @@ -162,6 +163,7 @@ export function TraceView(props: Props) { scrollToFirstVisibleSpan={noop} findMatchesIDs={spanFindMatches} trace={traceProp} + datasourceType={datasourceType} spanBarOptions={spanBarOptions?.spanBar} traceTimeline={traceTimeline} updateNextViewRangeTime={updateNextViewRangeTime} diff --git a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx index be29de1c3f5..8766896cb1c 100644 --- a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx +++ b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx @@ -11,6 +11,13 @@ import { configureStore } from '../../../store/configureStore'; import { frameOld } from './TraceView.test'; import { TraceViewContainer } from './TraceViewContainer'; +jest.mock('@grafana/runtime', () => { + return { + ...jest.requireActual('@grafana/runtime'), + reportInteraction: jest.fn(), + }; +}); + function renderTraceViewContainer(frames = [frameOld]) { const store = configureStore(); const mockPanelData = { diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index dec0213a80d..93308043580 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -136,6 +136,12 @@ export class TempoDatasource extends DataSourceWithBackend 0) { + reportInteraction('grafana_traces_loki_search_queried', { + datasourceType: 'tempo', + app: options.app ?? '', + linkedQueryExpr: targets.search[0].linkedQuery?.expr ?? '', + }); + const dsSrv = getDatasourceSrv(); subQueries.push( from(dsSrv.get(logsDatasourceUid)).pipe( @@ -175,7 +181,7 @@ export class TempoDatasource extends DataSourceWithBackend 0) { + reportInteraction('grafana_traces_service_graph_queried', { + datasourceType: 'tempo', + app: options.app ?? '', + serviceMapQuery: targets.serviceMap[0].serviceMapQuery ?? '', + }); + const dsId = this.serviceMap.datasourceUid; if (config.featureToggles.tempoApmTable) { subQueries.push( diff --git a/yarn.lock b/yarn.lock index 1e591172308..71913426369 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4812,7 +4812,7 @@ __metadata: languageName: node linkType: hard -"@grafana/runtime@workspace:*, @grafana/runtime@workspace:packages/grafana-runtime": +"@grafana/runtime@9.1.0-pre, @grafana/runtime@workspace:*, @grafana/runtime@workspace:packages/grafana-runtime": version: 0.0.0-use.local resolution: "@grafana/runtime@workspace:packages/grafana-runtime" dependencies: @@ -5256,6 +5256,7 @@ __metadata: "@emotion/css": 11.9.0 "@grafana/data": 9.1.0-pre "@grafana/e2e-selectors": 9.1.0-pre + "@grafana/runtime": 9.1.0-pre "@grafana/tsconfig": ^1.2.0-rc1 "@grafana/ui": 9.1.0-pre "@testing-library/jest-dom": 5.16.4 From fcfde8abd8c55620b5121f7e43ef5b11fb2bafc4 Mon Sep 17 00:00:00 2001 From: Jeff Levin Date: Mon, 11 Jul 2022 03:50:34 -0800 Subject: [PATCH 02/71] public dashboards:fix time regression (#51998) This PR fixes a regression bug for public dashboards and adds a test to ensure the regression does not resurface. --- .../ShareModal/SharePublicDashboard.test.tsx | 28 +++++++++++++++---- .../ShareModal/SharePublicDashboard.tsx | 4 +-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.test.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.test.tsx index 2fc2e330276..3288b4fa7ee 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.test.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.test.tsx @@ -96,10 +96,28 @@ describe('SharePublic', () => { await screen.findByText('Welcome to Grafana public dashboards alpha!'); }); - // test when checkboxes show up - // test checkboxes hidden - // test url hidden - // test url shows up - // + it('renders default time in inputs', async () => { + config.featureToggles.publicDashboards = true; + const mockDashboard = new DashboardModel({ + uid: 'mockDashboardUid', + }); + const mockPanel = new PanelModel({ + id: 'mockPanelId', + }); + + expect(mockDashboard.time).toEqual({ from: 'now-6h', to: 'now' }); + //@ts-ignore + mockDashboard.originalTime = { from: 'test-from', to: 'test-to' }; + + render( {}} />); + + await waitFor(() => screen.getByText('Link')); + fireEvent.click(screen.getByText('Public Dashboard')); + + await screen.findByText('Welcome to Grafana public dashboards alpha!'); + expect(screen.getByDisplayValue('test-from')).toBeInTheDocument(); + expect(screen.getByDisplayValue('test-to')).toBeInTheDocument(); + }); + // test checking if current version of dashboard in state is persisted to db }); diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.tsx index 6c42a952944..cd6146deede 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard.tsx @@ -164,14 +164,14 @@ export const SharePublicDashboard = (props: Props) => {
From: } /> To: From 2f41ee7333b3ad9625dab3a80374917e1b2aa8be Mon Sep 17 00:00:00 2001 From: brendamuir <100768211+brendamuir@users.noreply.github.com> Date: Mon, 11 Jul 2022 13:04:15 +0100 Subject: [PATCH 03/71] Docs: fixes couple of typos (#52031) --- docs/sources/alerting/alerting-limitations.md | 2 +- docs/sources/alerting/fundamentals/data-source-alerting.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/alerting/alerting-limitations.md b/docs/sources/alerting/alerting-limitations.md index 58b9a955f95..b0f36ea5548 100644 --- a/docs/sources/alerting/alerting-limitations.md +++ b/docs/sources/alerting/alerting-limitations.md @@ -21,7 +21,7 @@ As an example, if the current Prometheus version is `2.31.1`, we support >= `2.2 ## Grafana is not an alert receiver -Grafana is not an alert receiver; is it an alert generator. This means that Grafana cannot receive alerts from anything other than its internal alert generator. +Grafana is not an alert receiver; it is an alert generator. This means that Grafana cannot receive alerts from anything other than its internal alert generator. Receiving alerts from Prometheus (or anything else) is not supported at the time. diff --git a/docs/sources/alerting/fundamentals/data-source-alerting.md b/docs/sources/alerting/fundamentals/data-source-alerting.md index 08ad66165e7..3f7674ad593 100644 --- a/docs/sources/alerting/fundamentals/data-source-alerting.md +++ b/docs/sources/alerting/fundamentals/data-source-alerting.md @@ -23,7 +23,7 @@ These are the data sources that are compatible with and supported by Grafana Ale - [Graphite]({{< relref "../../datasources/graphite/" >}}) - [InfluxDB]({{< relref "influxdb/" >}}) - [Loki]({{< relref "../../datasources/loki/" >}}) -- ]Microsoft SQL Server (MSSQL)]({{< relref "../../datasources/mssql/" >}}) +- [Microsoft SQL Server (MSSQL)]({{< relref "../../datasources/mssql/" >}}) - [MySQL]({{< relref "../../datasources/mysql/" >}}) - [Open TSDB]({{< relref "../../datasources/opentsdb/" >}}) - [PostgreSQL]({{< relref "../../datasources/postgres/" >}}) From 0a2a370b77a42dce41b1af1d7b6f158d7a9c6f56 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Mon, 11 Jul 2022 14:24:49 +0200 Subject: [PATCH 04/71] Loki: Fix suggesting operations from different category (#52034) --- .../datasource/loki/querybuilder/operations.ts | 3 +++ .../shared/LokiAndPromQueryModellerBase.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/public/app/plugins/datasource/loki/querybuilder/operations.ts b/public/app/plugins/datasource/loki/querybuilder/operations.ts index 63e347b4751..e2483642b61 100644 --- a/public/app/plugins/datasource/loki/querybuilder/operations.ts +++ b/public/app/plugins/datasource/loki/querybuilder/operations.ts @@ -288,6 +288,7 @@ export function getOperationDefinitions(): QueryBuilderOperationDef[] { { name: 'Value', type: 'string' }, ], defaultParams: ['', '=', ''], + alternativesKey: 'label filter', category: LokiVisualQueryOperationCategory.LabelFilters, orderRank: LokiOperationOrder.LabelFilters, renderer: labelFilterRenderer, @@ -299,6 +300,7 @@ export function getOperationDefinitions(): QueryBuilderOperationDef[] { name: 'No pipeline errors', params: [], defaultParams: [], + alternativesKey: 'label filter', category: LokiVisualQueryOperationCategory.LabelFilters, orderRank: LokiOperationOrder.NoErrors, renderer: (model, def, innerExpr) => `${innerExpr} | __error__=\`\``, @@ -310,6 +312,7 @@ export function getOperationDefinitions(): QueryBuilderOperationDef[] { name: 'Unwrap', params: [{ name: 'Identifier', type: 'string', hideName: true, minWidth: 16, placeholder: 'Label key' }], defaultParams: [''], + alternativesKey: 'format', category: LokiVisualQueryOperationCategory.Formats, orderRank: LokiOperationOrder.Unwrap, renderer: (op, def, innerExpr) => `${innerExpr} | unwrap ${op.params[0]}`, diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts b/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts index 98e929e831e..81afc5a2762 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/LokiAndPromQueryModellerBase.ts @@ -19,11 +19,11 @@ export interface PromLokiVisualQuery { } export abstract class LokiAndPromQueryModellerBase implements VisualQueryModeller { - protected operationsRegisty: Registry; + protected operationsRegistry: Registry; private categories: string[] = []; constructor(getOperations: () => QueryBuilderOperationDef[]) { - this.operationsRegisty = new Registry(getOperations); + this.operationsRegistry = new Registry(getOperations); } protected setOperationCategories(categories: string[]) { @@ -31,11 +31,11 @@ export abstract class LokiAndPromQueryModellerBase implements VisualQueryModelle } getOperationsForCategory(category: string) { - return this.operationsRegisty.list().filter((op) => op.category === category && !op.hideFromList); + return this.operationsRegistry.list().filter((op) => op.category === category && !op.hideFromList); } getAlternativeOperations(key: string) { - return this.operationsRegisty.list().filter((op) => op.alternativesKey === key); + return this.operationsRegistry.list().filter((op) => op.alternativesKey && op.alternativesKey === key); } getCategories() { @@ -43,12 +43,12 @@ export abstract class LokiAndPromQueryModellerBase implements VisualQueryModelle } getOperationDef(id: string): QueryBuilderOperationDef | undefined { - return this.operationsRegisty.getIfExists(id); + return this.operationsRegistry.getIfExists(id); } renderOperations(queryString: string, operations: QueryBuilderOperation[]) { for (const operation of operations) { - const def = this.operationsRegisty.getIfExists(operation.id); + const def = this.operationsRegistry.getIfExists(operation.id); if (!def) { throw new Error(`Could not find operation ${operation.id} in the registry`); } From 94175a801a27023d57af2faf496399feda378eda Mon Sep 17 00:00:00 2001 From: Christopher Moyer <35463610+chri2547@users.noreply.github.com> Date: Mon, 11 Jul 2022 07:35:19 -0500 Subject: [PATCH 05/71] refactors all dashboard and linking content (#52005) --- .../best-practices-for-managing-dashboards.md | 4 +- .../dashboard-management-maturity-levels.md | 2 +- .../manage-dashboard-links/index.md} | 88 ++++++++++++-- docs/sources/linking/_index.md | 31 ----- docs/sources/linking/data-link-variables.md | 62 ---------- docs/sources/linking/data-links.md | 54 --------- docs/sources/linking/linking-overview.md | 39 ------ docs/sources/linking/panel-links.md | 52 -------- .../panels/configure-data-links/index.md | 114 ++++++++++++++++++ .../panels/standard-field-definitions.md | 2 +- .../working-with-panels/add-link-to-panel.md | 13 -- docs/sources/whatsnew/whats-new-in-v8-0.md | 2 +- docs/sources/whatsnew/whats-new-in-v8-1.md | 2 +- 13 files changed, 199 insertions(+), 266 deletions(-) rename docs/sources/{linking/dashboard-links.md => dashboards/manage-dashboard-links/index.md} (52%) delete mode 100644 docs/sources/linking/_index.md delete mode 100644 docs/sources/linking/data-link-variables.md delete mode 100644 docs/sources/linking/data-links.md delete mode 100644 docs/sources/linking/linking-overview.md delete mode 100644 docs/sources/linking/panel-links.md create mode 100644 docs/sources/panels/configure-data-links/index.md delete mode 100644 docs/sources/panels/working-with-panels/add-link-to-panel.md diff --git a/docs/sources/best-practices/best-practices-for-managing-dashboards.md b/docs/sources/best-practices/best-practices-for-managing-dashboards.md index cc7c3e29881..bf9ffe8a48b 100644 --- a/docs/sources/best-practices/best-practices-for-managing-dashboards.md +++ b/docs/sources/best-practices/best-practices-for-managing-dashboards.md @@ -31,9 +31,9 @@ What is your dashboard maturity level? Analyze your current dashboard setup and - If you create a temporary dashboard, perhaps to test something, prefix the name with `TEST: `. Delete the dashboard when you are finished. - Copying dashboards with no significant changes is not a good idea. - You miss out on updates to the original dashboard, such as documentation changes, bug fixes, or additions to metrics. - - In many cases copies are being made to simply customize the view by setting template parameters. This should instead be done by maintaining a link to the master dashboard and customizing the view with [URL parameters]({{< relref "../linking/data-link-variables/" >}}). + - In many cases copies are being made to simply customize the view by setting template parameters. This should instead be done by maintaining a link to the master dashboard and customizing the view with [URL parameters]({{< relref "../panels/configure-data-links/#data-link-variables" >}}). - When you must copy a dashboard, clearly rename it and _do not_ copy the dashboard tags. Tags are important metadata for dashboards that are used during search. Copying tags can result in false matches. - Maintain a dashboard of dashboards or cross-reference dashboards. This can be done in several ways: - - Create dashboard links, panel, or data links. Links can go to other dashboards or to external systems. For more information, refer to [Linking]({{< relref "../linking/" >}}). + - Create dashboard links, panel, or data links. Links can go to other dashboards or to external systems. For more information, refer to [Manage dashboard links]({{< relref "../dashboards/manage-dashboard-links/" >}}). - Add a [Dashboard list panel]({{< relref "../visualizations/dashboard-list-panel/" >}}). You can then customize what you see by doing tag or folder searches. - Add a [Text panel]({{< relref "../visualizations/text-panel/" >}}) and use markdown to customize the display. diff --git a/docs/sources/best-practices/dashboard-management-maturity-levels.md b/docs/sources/best-practices/dashboard-management-maturity-levels.md index 4f9c59b4288..ec7d735a1f8 100644 --- a/docs/sources/best-practices/dashboard-management-maturity-levels.md +++ b/docs/sources/best-practices/dashboard-management-maturity-levels.md @@ -53,7 +53,7 @@ How can you tell you are here? - Directed browsing cuts down on "guessing." - Template variables make it harder to “just browse” randomly or aimlessly. - Most dashboards should be linked to by alerts. - - Browsing is directed with links. For more information, refer to [Linking]({{< relref "../linking/" >}}). + - Browsing is directed with links. For more information, refer to [Manage dashboard links]({{< relref "../dashboards/manage-dashboard-links/" >}}). - Version-controlled dashboard JSON. ## High - optimized use diff --git a/docs/sources/linking/dashboard-links.md b/docs/sources/dashboards/manage-dashboard-links/index.md similarity index 52% rename from docs/sources/linking/dashboard-links.md rename to docs/sources/dashboards/manage-dashboard-links/index.md index 6024b854d11..e641d9179c6 100644 --- a/docs/sources/linking/dashboard-links.md +++ b/docs/sources/dashboards/manage-dashboard-links/index.md @@ -1,20 +1,53 @@ --- aliases: + - /docs/grafana/latest/linking/ + - /docs/grafana/latest/features/navigation-links/ + - /docs/grafana/latest/linking/linking-overview/ - /docs/grafana/latest/linking/dashboard-links/ -description: '' + - /docs/grafana/latest/dashboards/manage-dashboard-links/ + - /docs/grafana/latest/panels/working-with-panels/add-link-to-panel/ +description: How to link Grafana dashboards. keywords: + - link + - dashboard - grafana - linking - create links - link dashboards - navigate -title: Dashboard links -weight: 200 +title: Manage dashboard links +menuTitle: Manage dashboard links +weight: 400 --- -# Dashboard links +# Manage dasboard links -When you create a dashboard link, you can include the time range and current template variables to directly jump to the same context in another dashboard. This way, you don’t have to worry whether the person you send the link to is looking at the right data. For other types of links, refer to [Data link variables]({{< relref "data-link-variables/" >}}). +You can use links to navigate between commonly-used dashboards or to connect others to your visualizations. Links let you create shortcuts to other dashboards, panels, and even external websites. + +Grafana supports dashboard links, panel links, and data links. Dashboard links are displayed at the top of the dashboard. Panel links are accessible by clicking an icon on the top left corner of the panel. + +## Which link should you use? + +Start by figuring out how you're currently navigating between dashboards. If you're often jumping between a set of dashboards and struggling to find the same context in each, links can help optimize your workflow. + +The next step is to figure out which link type is right for your workflow. Even though all the link types in Grafana are used to create shortcuts to other dashboards or external websites, they work in different contexts. + +- If the link relates to most if not all of the panels in the dashboard, use [dashboard links]({{< relref "#dashboard-links" >}}). +- If you want to drill down into specific panels, use [panel links]({{< relref "#panel-links" >}}). +- If you want to link to an external site, you can use either a dashboard link or a panel link. +- If you want to drill down into a specific series, or even a single measurement, use [data links]({{< relref "../../panels/configure-data-links/#data-links" >}}). + +## Controlling time range using the URL + +You can control the time range of a panel or dashboard by providing following query parameters in dashboard URL: + +- `from` - defines lower limit of the time range, specified in ms epoch +- `to` - defines upper limit of the time range, specified in ms epoch +- `time` and `time.window` - defines a time range from `time-time.window/2` to `time+time.window/2`. Both params should be specified in ms. For example `?time=1500000000000&time.window=10000` will result in 10s time range from 1499999995000 to 1500000005000 + +## Dashboard links + +When you create a dashboard link, you can include the time range and current template variables to directly jump to the same context in another dashboard. This way, you don’t have to worry whether the person you send the link to is looking at the right data. For other types of links, refer to [Data link variables]({{< relref "../../panels/configure-data-links/#data-link-variables/" >}}). Dashboard links can also be used as shortcuts to external systems, such as submitting [a GitHub issue with the current dashboard name](https://github.com/grafana/grafana/issues/new?title=Dashboard%3A%20HTTP%20Requests). @@ -25,7 +58,7 @@ To see an example of dashboard links in action, check out: Once you've added a dashboard link, it appears in the upper right corner of your dashboard. -## Add links to dashboards +### Add links to dashboards Add links to other dashboards at the top of your current dashboard. @@ -40,7 +73,7 @@ Add links to other dashboards at the top of your current dashboard. - **Open in new tab** – Select this option if you want the dashboard link to open in a new tab or window. 1. Click **Add**. -## Add a URL link to a dashboard +### Add a URL link to a dashboard Add a link to a URL at the top of your current dashboard. You can link to any available URL, including dashboards, panels, or external sites. You can even control the time range to ensure the user is zoomed in on the right data in Grafana. @@ -60,7 +93,7 @@ Add a link to a URL at the top of your current dashboard. You can link to any av - **Open in new tab** – Select this option if you want the dashboard link to open in a new tab or window. 1. Click **Add**. -## Update a dashboard link +### Update a dashboard link To change or update an existing dashboard link, follow this procedure. @@ -71,6 +104,43 @@ To change or update an existing dashboard link, follow this procedure. To duplicate an existing dashboard link, click the duplicate icon next to the existing link that you want to duplicate. -## Delete a dashboard link +### Delete a dashboard link To delete an existing dashboard link, click the trash icon next to the duplicate icon that you want to delete. + +## Panel links + +Each panel can have its own set of links that are shown in the upper left corner of the panel. You can link to any available URL, including dashboards, panels, or external sites. You can even control the time range to ensure the user is zoomed in on the right data in Grafana. + +Click the icon on the top left corner of a panel to see available panel links. + +{{< figure src="/static/img/docs/linking/panel-links.png" width="200px" >}} + +### Add a panel link + +1. Hover your cursor over the panel that you want to add a link to and then press `e`. Or click the dropdown arrow next to the panel title and then click **Edit**. +1. On the Panel tab, scroll down to the Links section. +1. Expand Links and then click **Add link**. +1. Enter a **Title**. **Title** is a human-readable label for the link that will be displayed in the UI. +1. Enter the **URL** you want to link to. + You can even add one of the template variables defined in the dashboard. Press Ctrl+Space or Cmd+Space and click in the **URL** field to see the available variables. By adding template variables to your panel link, the link sends the user to the right context, with the relevant variables already set. You can also use time variables: + - `from` - Defines the lower limit of the time range, specified in ms epoch. + - `to` - Defines the upper limit of the time range, specified in ms epoch. + - `time` and `time.window` - Define a time range from `time-time.window/2` to `time+time.window/2`. Both params should be specified in ms. For example `?time=1500000000000&time.window=10000` will result in 10s time range from 1499999995000 to 1500000005000. +1. If you want the link to open in a new tab, then select **Open in a new tab**. +1. Click **Save** to save changes and close the window. +1. Click **Save** in the upper right to save your changes to the dashboard. + +### Update a panel link + +1. On the Panel tab, find the link that you want to make changes to. +1. Click the Edit (pencil) icon to open the Edit link window. +1. Make any necessary changes. +1. Click **Save** to save changes and close the window. +1. Click **Save** in the upper right to save your changes to the dashboard. + +### Delete a panel link + +1. On the Panel tab, find the link that you want to delete. +1. Click the **X** icon next to the link you want to delete. +1. Click **Save** in the upper right to save your changes to the dashboard. diff --git a/docs/sources/linking/_index.md b/docs/sources/linking/_index.md deleted file mode 100644 index 7dee41357b3..00000000000 --- a/docs/sources/linking/_index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -aliases: - - /docs/grafana/latest/linking/ -title: Linking -weight: 120 ---- - -# Linking overview - -You can use links to navigate between commonly-used dashboards or to connect others to your visualizations. Links let you create shortcuts to other dashboards, panels, and even external websites. - -Grafana supports dashboard links, panel links, and data links. Dashboard links are displayed at the top of the dashboard. Panel links are accessible by clicking an icon on the top left corner of the panel. - -## Which link should you use? - -Start by figuring out how you're currently navigating between dashboards. If you're often jumping between a set of dashboards and struggling to find the same context in each, links can help optimize your workflow. - -The next step is to figure out which link type is right for your workflow. Even though all the link types in Grafana are used to create shortcuts to other dashboards or external websites, they work in different contexts. - -- If the link relates to most if not all of the panels in the dashboard, use [dashboard links]({{< relref "dashboard-links/" >}}). -- If you want to drill down into specific panels, use [panel links]({{< relref "panel-links/" >}}). -- If you want to link to an external site, you can use either a dashboard link or a panel link. -- If you want to drill down into a specific series, or even a single measurement, use [data links]({{< relref "data-links/" >}}). - -## Controlling time range using the URL - -You can control the time range of a panel or dashboard by providing following query parameters in dashboard URL: - -- `from` - defines lower limit of the time range, specified in ms epoch -- `to` - defines upper limit of the time range, specified in ms epoch -- `time` and `time.window` - defines a time range from `time-time.window/2` to `time+time.window/2`. Both params should be specified in ms. For example `?time=1500000000000&time.window=10000` will result in 10s time range from 1499999995000 to 1500000005000 diff --git a/docs/sources/linking/data-link-variables.md b/docs/sources/linking/data-link-variables.md deleted file mode 100644 index 76faf455886..00000000000 --- a/docs/sources/linking/data-link-variables.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -aliases: - - /docs/grafana/latest/linking/data-link-variables/ - - /docs/grafana/latest/variables/url-variables/ - - /docs/grafana/latest/variables/variable-types/url-variables/ -keywords: - - grafana - - url variables - - documentation - - variables - - data link -title: URL variables -weight: 400 ---- - -# Data link variables - -You can use variables in data links to refer to series fields, labels, and values. For more information about data links, refer to [Data links]({{< relref "data-links/" >}}). - -To see a list of available variables, type `$` in the data link **URL** field to see a list of variables that you can use. - -> **Note:** These variables changed in 6.4 so if you have an older version of Grafana, then use the version picker to select docs for an older version of Grafana. - -You can also use template variables in your data links URLs, refer to [Templates and variables]({{< relref "../variables/" >}}) for more information on template variables. - -## Time range panel variables - -These variables allow you to include the current time range in the data link URL. - -- `__url_time_range` - current dashboard's time range (i.e. `?from=now-6h&to=now`) -- `$__from and $__to` - For more information, refer to [Global variables]({{< relref "../variables/variable-types/global-variables/#__from-and-__to" >}}). - -## Series variables - -Series specific variables are available under `__series` namespace: - -- `__series.name` - series name to the URL - -## Field variables - -Field-specific variables are available under `__field` namespace: - -- `__field.name` - the name of the field -- `__field.labels.