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] 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