diff --git a/.betterer.results b/.betterer.results index 99f95f77907..d7bcd469270 100644 --- a/.betterer.results +++ b/.betterer.results @@ -107,7 +107,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:381298544": [ + "packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:689615064": [ [14, 19, 13, "RegExp match", "2409514259"] ], "packages/jaeger-ui-components/src/common/NewWindowIcon.test.js:1750458349": [ diff --git a/packages/jaeger-ui-components/package.json b/packages/jaeger-ui-components/package.json index 71416421909..fd0aa8b3302 100644 --- a/packages/jaeger-ui-components/package.json +++ b/packages/jaeger-ui-components/package.json @@ -30,6 +30,7 @@ "@emotion/css": "11.9.0", "@grafana/data": "9.0.2", "@grafana/e2e-selectors": "9.0.2", + "@grafana/runtime": "9.0.2", "@grafana/ui": "9.0.2", "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 77f47586d93..ef409b7698f 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 fe612d483f5..d2e0db09ea3 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 } 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; updateNextViewRangeTime: (update: ViewRangeTimeUpdate) => void; updateViewRangeTime: TUpdateViewRangeTimeFunction; viewRange: ViewRange; @@ -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 df058b92202..98f55048a92 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -297,12 +297,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 65d17d11555..18b5b644301 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 } 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, + }); + }; const countWarning = withTraceView && nodes[0]?.length > 1000 ? ( @@ -70,7 +79,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} >
diff --git a/public/app/features/explore/TraceView/TraceView.tsx b/public/app/features/explore/TraceView/TraceView.tsx index c0e09e3356f..e6fb7b9911f 100644 --- a/public/app/features/explore/TraceView/TraceView.tsx +++ b/public/app/features/explore/TraceView/TraceView.tsx @@ -135,6 +135,7 @@ export function TraceView(props: Props) { ); const onSlimViewClicked = useCallback(() => setSlim(!slim), [slim]); const timeZone = useSelector((state: StoreState) => getTimeZone(state.user)); + const datasourceType = datasource ? datasource?.type : 'unknown'; return ( <> @@ -158,6 +159,7 @@ export function TraceView(props: Props) { scrollToFirstVisibleSpan={noop} findMatchesIDs={spanFindMatches} trace={traceProp} + datasourceType={datasourceType} traceTimeline={traceTimeline} updateNextViewRangeTime={updateNextViewRangeTime} updateViewRangeTime={updateViewRangeTime} diff --git a/public/app/features/explore/TraceView/TraceViewContainer.test.tsx b/public/app/features/explore/TraceView/TraceViewContainer.test.tsx index 19ea70aee5d..4952978d605 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 2ee50f259bf..159582d049f 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -126,6 +126,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( @@ -165,7 +171,7 @@ export class TempoDatasource extends DataSourceWithBackend 0) { + reportInteraction('grafana_traces_service_graph_queried', { + datasourceType: 'tempo', + app: options.app ?? '', + serviceMapQuery: targets.serviceMap[0].serviceMapQuery ?? '', + }); subQueries.push(serviceMapQuery(options, this.serviceMap.datasourceUid)); } diff --git a/yarn.lock b/yarn.lock index 376f12bc034..2af34b9032f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3998,7 +3998,7 @@ __metadata: languageName: node linkType: hard -"@grafana/runtime@workspace:*, @grafana/runtime@workspace:packages/grafana-runtime": +"@grafana/runtime@9.0.2, @grafana/runtime@workspace:*, @grafana/runtime@workspace:packages/grafana-runtime": version: 0.0.0-use.local resolution: "@grafana/runtime@workspace:packages/grafana-runtime" dependencies: @@ -4433,6 +4433,7 @@ __metadata: "@emotion/css": 11.9.0 "@grafana/data": 9.0.2 "@grafana/e2e-selectors": 9.0.2 + "@grafana/runtime": 9.0.2 "@grafana/tsconfig": ^1.2.0-rc1 "@grafana/ui": 9.0.2 "@testing-library/react": 12.1.4