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
This commit is contained in:
Joey Tawadrous
2022-07-11 10:21:24 +01:00
committed by GitHub
parent b808cd4432
commit 5aacc7cc2a
11 changed files with 73 additions and 6 deletions

View File

@@ -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": [

View File

@@ -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",

View File

@@ -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('<TraceTimelineViewer>', () => {
const trace = transformTraceData(traceGenerator.trace({}));
const props = {

View File

@@ -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<TProps, Sta
collapseAll = () => {
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() {

View File

@@ -280,12 +280,15 @@ export class Explore extends React.PureComponent<Props, ExploreState> {
}
renderNodeGraphPanel() {
const { exploreId, showTrace, queryResponse } = this.props;
const { exploreId, showTrace, queryResponse, datasourceInstance } = this.props;
const datasourceType = datasourceInstance ? datasourceInstance?.type : 'unknown';
return (
<NodeGraphContainer
dataFrames={this.memoizedGetNodeGraphDataFrames(queryResponse.series)}
exploreId={exploreId}
withTraceView={showTrace}
datasourceType={datasourceType}
/>
);
}

View File

@@ -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={''}
/>
);

View File

@@ -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<typeof connector>;
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}
>
<div
ref={containerRef}

View File

@@ -139,6 +139,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 (
<>
@@ -162,6 +163,7 @@ export function TraceView(props: Props) {
scrollToFirstVisibleSpan={noop}
findMatchesIDs={spanFindMatches}
trace={traceProp}
datasourceType={datasourceType}
spanBarOptions={spanBarOptions?.spanBar}
traceTimeline={traceTimeline}
updateNextViewRangeTime={updateNextViewRangeTime}

View File

@@ -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 = {

View File

@@ -136,6 +136,12 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
// Run search queries on linked datasource
if (logsDatasourceUid && targets.search?.length > 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<TempoQuery, TempoJson
app: options.app ?? '',
serviceName: targets.nativeSearch[0].serviceName ?? '',
spanName: targets.nativeSearch[0].spanName ?? '',
limit: targets.nativeSearch[0].limit ?? '',
resultLimit: targets.nativeSearch[0].limit ?? '',
search: targets.nativeSearch[0].search ?? '',
});
@@ -201,6 +207,11 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
if (targets.upload?.length) {
if (this.uploadedJson) {
reportInteraction('grafana_traces_json_file_uploaded', {
datasourceType: 'tempo',
app: options.app ?? '',
});
const jsonData = JSON.parse(this.uploadedJson as string);
const isTraceData = jsonData.batches;
const isServiceGraphData =
@@ -219,6 +230,12 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
}
if (this.serviceMap?.datasourceUid && targets.serviceMap?.length > 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(

View File

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