Traces: extra feature tracking (#61348)

* grafana_traces_service_graph_size

* grafana_traces_trace_view_find_next_prev_clicked

* grafana_traces_trace_view_scroll_to_top_clicked

* grafana_traces_cheatsheet_clicked
This commit is contained in:
Joey Tawadrous
2023-01-17 14:43:28 +00:00
committed by GitHub
parent 6dcc94ecb2
commit 4076933e66
8 changed files with 42 additions and 2 deletions

View File

@@ -17,6 +17,7 @@ import cx from 'classnames';
import React, { memo, Dispatch, SetStateAction } from 'react'; import React, { memo, Dispatch, SetStateAction } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { Button, useStyles2 } from '@grafana/ui'; import { Button, useStyles2 } from '@grafana/ui';
import UiFindInput from '../common/UiFindInput'; import UiFindInput from '../common/UiFindInput';
@@ -77,6 +78,7 @@ export type TracePageSearchBarProps = {
focusedSpanIdForSearch: string; focusedSpanIdForSearch: string;
setSearchBarSuffix: Dispatch<SetStateAction<string>>; setSearchBarSuffix: Dispatch<SetStateAction<string>>;
setFocusedSpanIdForSearch: Dispatch<SetStateAction<string>>; setFocusedSpanIdForSearch: Dispatch<SetStateAction<string>>;
datasourceType: string;
}; };
export default memo(function TracePageSearchBar(props: TracePageSearchBarProps) { export default memo(function TracePageSearchBar(props: TracePageSearchBarProps) {
@@ -89,6 +91,7 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps)
focusedSpanIdForSearch, focusedSpanIdForSearch,
setSearchBarSuffix, setSearchBarSuffix,
setFocusedSpanIdForSearch, setFocusedSpanIdForSearch,
datasourceType,
} = props; } = props;
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
@@ -112,6 +115,11 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps)
}; };
const nextResult = () => { const nextResult = () => {
reportInteraction('grafana_traces_trace_view_find_next_prev_clicked', {
datasourceType: datasourceType,
direction: 'next',
});
const spanMatches = Array.from(spanFindMatches!); const spanMatches = Array.from(spanFindMatches!);
const prevMatchedIndex = spanMatches.indexOf(focusedSpanIdForSearch) const prevMatchedIndex = spanMatches.indexOf(focusedSpanIdForSearch)
? spanMatches.indexOf(focusedSpanIdForSearch) ? spanMatches.indexOf(focusedSpanIdForSearch)
@@ -130,6 +138,11 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps)
}; };
const prevResult = () => { const prevResult = () => {
reportInteraction('grafana_traces_trace_view_find_next_prev_clicked', {
datasourceType: datasourceType,
direction: 'prev',
});
const spanMatches = Array.from(spanFindMatches!); const spanMatches = Array.from(spanFindMatches!);
const prevMatchedIndex = spanMatches.indexOf(focusedSpanIdForSearch) const prevMatchedIndex = spanMatches.indexOf(focusedSpanIdForSearch)
? spanMatches.indexOf(focusedSpanIdForSearch) ? spanMatches.indexOf(focusedSpanIdForSearch)

View File

@@ -19,6 +19,7 @@ import * as React from 'react';
import { createRef, RefObject } from 'react'; import { createRef, RefObject } from 'react';
import { GrafanaTheme2, LinkModel, TimeZone } from '@grafana/data'; import { GrafanaTheme2, LinkModel, TimeZone } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { stylesFactory, withTheme2, ToolbarButton } from '@grafana/ui'; import { stylesFactory, withTheme2, ToolbarButton } from '@grafana/ui';
import { Accessors } from '../ScrollManager'; import { Accessors } from '../ScrollManager';
@@ -536,8 +537,13 @@ export class UnthemedVirtualizedTraceView extends React.Component<VirtualizedTra
} }
scrollToTop = () => { scrollToTop = () => {
const { topOfViewRef } = this.props; const { topOfViewRef, datasourceType, trace } = this.props;
topOfViewRef?.current?.scrollIntoView({ behavior: 'smooth' }); topOfViewRef?.current?.scrollIntoView({ behavior: 'smooth' });
reportInteraction('grafana_traces_trace_view_scroll_to_top_clicked', {
datasourceType: datasourceType,
numServices: trace.services.length,
numSpans: trace.spans.length,
});
}; };
render() { render() {

View File

@@ -216,6 +216,7 @@ export class UnthemedTraceTimelineViewer extends React.PureComponent<TProps, Sta
currentViewRangeTime={viewRange.time.current} currentViewRangeTime={viewRange.time.current}
topOfViewRef={topOfViewRef} topOfViewRef={topOfViewRef}
focusedSpanIdForSearch={focusedSpanIdForSearch} focusedSpanIdForSearch={focusedSpanIdForSearch}
datasourceType={this.props.datasourceType}
/> />
</div> </div>
); );

View File

@@ -59,7 +59,7 @@ export function UnconnectedNodeGraphContainer(props: Props) {
toggleOpen(); toggleOpen();
reportInteraction('grafana_traces_node_graph_panel_clicked', { reportInteraction('grafana_traces_node_graph_panel_clicked', {
datasourceType: datasourceType, datasourceType: datasourceType,
expanded: !open, isExpanded: !open,
}); });
}; };

View File

@@ -29,6 +29,7 @@ export function TraceViewContainer(props: Props) {
const datasource = useSelector( const datasource = useSelector(
(state: StoreState) => state.explore[props.exploreId!]?.datasourceInstance ?? undefined (state: StoreState) => state.explore[props.exploreId!]?.datasourceInstance ?? undefined
); );
const datasourceType = datasource ? datasource?.type : 'unknown';
if (!traceProp) { if (!traceProp) {
return null; return null;
@@ -45,6 +46,7 @@ export function TraceViewContainer(props: Props) {
setSearchBarSuffix={setSearchBarSuffix} setSearchBarSuffix={setSearchBarSuffix}
focusedSpanIdForSearch={focusedSpanIdForSearch} focusedSpanIdForSearch={focusedSpanIdForSearch}
setFocusedSpanIdForSearch={setFocusedSpanIdForSearch} setFocusedSpanIdForSearch={setFocusedSpanIdForSearch}
datasourceType={datasourceType}
/> />
<TraceView <TraceView
exploreId={exploreId} exploreId={exploreId}

View File

@@ -1,6 +1,12 @@
import React from 'react'; import React from 'react';
import { reportInteraction } from '@grafana/runtime';
export default function CheatSheet() { export default function CheatSheet() {
reportInteraction('grafana_traces_cheatsheet_clicked', {
datasourceType: 'tempo',
});
return ( return (
<div> <div>
<h2 id="tempo-cheat-sheet">Tempo Cheat Sheet</h2> <h2 id="tempo-cheat-sheet">Tempo Cheat Sheet</h2>

View File

@@ -471,6 +471,16 @@ function serviceMapQuery(request: DataQueryRequest<TempoQuery>, datasourceUid: s
} }
const { nodes, edges } = mapPromMetricsToServiceMap(responses, request.range); const { nodes, edges } = mapPromMetricsToServiceMap(responses, request.range);
if (nodes.fields.length > 0 && edges.fields.length > 0) {
const nodeLength = nodes.fields[0].values.length;
const edgeLength = edges.fields[0].values.length;
reportInteraction('grafana_traces_service_graph_size', {
datasourceType: 'tempo',
nodeLength,
edgeLength,
});
}
// No handling of multiple targets assume just one. NodeGraph does not support it anyway, but still should be // No handling of multiple targets assume just one. NodeGraph does not support it anyway, but still should be
// fixed at some point. // fixed at some point.

View File

@@ -27,6 +27,7 @@ export const TracesPanel: React.FunctionComponent<PanelProps> = ({ data }) => {
return await getDataSourceSrv().get(data.request?.targets[0].datasource?.uid); return await getDataSourceSrv().get(data.request?.targets[0].datasource?.uid);
}); });
const scrollElement = document.getElementsByClassName(styles.wrapper)[0]; const scrollElement = document.getElementsByClassName(styles.wrapper)[0];
const datasourceType = dataSource && dataSource.value ? dataSource.value.type : 'unknown';
if (!data || !data.series.length || !traceProp) { if (!data || !data.series.length || !traceProp) {
return ( return (
@@ -49,6 +50,7 @@ export const TracesPanel: React.FunctionComponent<PanelProps> = ({ data }) => {
setSearchBarSuffix={setSearchBarSuffix} setSearchBarSuffix={setSearchBarSuffix}
focusedSpanIdForSearch={focusedSpanIdForSearch} focusedSpanIdForSearch={focusedSpanIdForSearch}
setFocusedSpanIdForSearch={setFocusedSpanIdForSearch} setFocusedSpanIdForSearch={setFocusedSpanIdForSearch}
datasourceType={datasourceType}
/> />
) : null} ) : null}