diff --git a/public/app/features/dashboard/components/Inspector/InspectContent.tsx b/public/app/features/dashboard/components/Inspector/InspectContent.tsx index daa3608548d..5d3e5b9fc36 100644 --- a/public/app/features/dashboard/components/Inspector/InspectContent.tsx +++ b/public/app/features/dashboard/components/Inspector/InspectContent.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; -import { DataSourceApi, formattedValueToString, getValueFormat, PanelData, PanelPlugin } from '@grafana/data'; +import { CoreApp, DataSourceApi, formattedValueToString, getValueFormat, PanelData, PanelPlugin } from '@grafana/data'; import { getTemplateSrv } from '@grafana/runtime'; import { Drawer, Tab, TabsBar } from '@grafana/ui'; import { InspectDataTab } from 'app/features/inspector/InspectDataTab'; @@ -90,6 +90,7 @@ export const InspectContent: React.FC = ({ options={dataOptions} onOptionsChange={onDataOptionsChange} timeZone={dashboard.timezone} + app={CoreApp.Dashboard} /> )} {data && activeTab === InspectTab.Meta && ( diff --git a/public/app/features/explore/ExploreQueryInspector.tsx b/public/app/features/explore/ExploreQueryInspector.tsx index f231bd9a33d..bc39f5ea0eb 100644 --- a/public/app/features/explore/ExploreQueryInspector.tsx +++ b/public/app/features/explore/ExploreQueryInspector.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { connect, ConnectedProps } from 'react-redux'; -import { TimeZone } from '@grafana/data'; +import { CoreApp, TimeZone } from '@grafana/data'; import { TabbedContainer, TabConfig } from '@grafana/ui'; import { ExploreDrawer } from 'app/features/explore/ExploreDrawer'; import { InspectDataTab } from 'app/features/inspector/InspectDataTab'; @@ -51,6 +51,7 @@ export function ExploreQueryInspector(props: Props) { isLoading={loading} options={{ withTransforms: false, withFieldConfig: false }} timeZone={timeZone} + app={CoreApp.Explore} /> ), }; diff --git a/public/app/features/explore/ExploreToolbar.tsx b/public/app/features/explore/ExploreToolbar.tsx index 52fb54f81b6..520c98833f7 100644 --- a/public/app/features/explore/ExploreToolbar.tsx +++ b/public/app/features/explore/ExploreToolbar.tsx @@ -2,7 +2,7 @@ import React, { lazy, PureComponent, RefObject, Suspense } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { DataSourceInstanceSettings, RawTimeRange } from '@grafana/data'; -import { config, DataSourcePicker } from '@grafana/runtime'; +import { config, DataSourcePicker, reportInteraction } from '@grafana/runtime'; import { defaultIntervals, PageToolbar, @@ -192,17 +192,28 @@ class UnConnectedExploreToolbar extends PureComponent { {hasLiveOption && ( - {(controls) => ( - - )} + {(c) => { + const controls = { + ...c, + start: () => { + reportInteraction('grafana_explore_logs_result_displayed', { + datasourceType: this.props.datasourceType, + }); + c.start(); + }, + }; + return ( + + ); + }} )} @@ -223,6 +234,7 @@ const mapStateToProps = (state: StoreState, { exploreId }: OwnProps) => { return { datasourceMissing, datasourceName: datasourceInstance?.name, + datasourceType: datasourceInstance?.type, loading, range, timeZone: getTimeZone(state.user), diff --git a/public/app/features/explore/Logs.tsx b/public/app/features/explore/Logs.tsx index 516f53c4bd9..0e0628be007 100644 --- a/public/app/features/explore/Logs.tsx +++ b/public/app/features/explore/Logs.tsx @@ -23,6 +23,7 @@ import { SplitOpen, DataQueryResponse, } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { TooltipDisplayMode } from '@grafana/schema'; import { RadioButtonGroup, @@ -68,6 +69,7 @@ interface Props extends Themeable2 { scanning?: boolean; scanRange?: RawTimeRange; exploreId: ExploreId; + datasourceType?: string; logsVolumeData: DataQueryResponse | undefined; loadLogsVolumeData: (exploreId: ExploreId) => void; showContextToggle?: (row?: LogRowModel) => boolean; @@ -144,6 +146,10 @@ class UnthemedLogs extends PureComponent { }; onChangeDedup = (dedupStrategy: LogsDedupStrategy) => { + reportInteraction('grafana_explore_logs_deduplication_clicked', { + deduplicationType: dedupStrategy, + datasourceType: this.props.datasourceType, + }); this.setState({ dedupStrategy }); }; diff --git a/public/app/features/explore/LogsContainer.tsx b/public/app/features/explore/LogsContainer.tsx index 750de6ba9e4..be59ff37e36 100644 --- a/public/app/features/explore/LogsContainer.tsx +++ b/public/app/features/explore/LogsContainer.tsx @@ -131,6 +131,7 @@ class LogsContainer extends PureComponent { ({ + ...jest.requireActual('@grafana/runtime'), + reportInteraction: () => null, +})); + type LogsNavigationProps = ComponentProps; const defaultProps: LogsNavigationProps = { absoluteRange: { from: 1637319381811, to: 1637322981811 }, diff --git a/public/app/features/explore/LogsNavigation.tsx b/public/app/features/explore/LogsNavigation.tsx index 5c2cd5a0904..5d495660161 100644 --- a/public/app/features/explore/LogsNavigation.tsx +++ b/public/app/features/explore/LogsNavigation.tsx @@ -3,6 +3,7 @@ import { isEqual } from 'lodash'; import React, { memo, useState, useEffect, useRef } from 'react'; import { LogsSortOrder, AbsoluteTimeRange, TimeZone, DataQuery, GrafanaTheme2 } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { Button, Icon, Spinner, useTheme2 } from '@grafana/ui'; import { LogsNavigationPages } from './LogsNavigationPages'; @@ -107,6 +108,9 @@ function LogsNavigation({ variant="secondary" onClick={() => { //If we are not on the last page, use next page's range + reportInteraction('grafana_explore_logs_pagination_clicked', { + pageType: 'olderLogsButton', + }); if (!onLastPage) { const indexChange = oldestLogsFirst ? -1 : 1; changeTime({ @@ -133,6 +137,9 @@ function LogsNavigation({ className={styles.navButton} variant="secondary" onClick={() => { + reportInteraction('grafana_explore_logs_pagination_clicked', { + pageType: 'newerLogsButton', + }); //If we are not on the first page, use previous page's range if (!onFirstPage) { const indexChange = oldestLogsFirst ? 1 : -1; diff --git a/public/app/features/explore/LogsNavigationPages.tsx b/public/app/features/explore/LogsNavigationPages.tsx index a5c978b0d8c..b4ab4153d92 100644 --- a/public/app/features/explore/LogsNavigationPages.tsx +++ b/public/app/features/explore/LogsNavigationPages.tsx @@ -2,6 +2,7 @@ import { css, cx } from '@emotion/css'; import React from 'react'; import { dateTimeFormat, systemDateFormats, TimeZone, AbsoluteTimeRange, GrafanaTheme2 } from '@grafana/data'; +import { reportInteraction } from '@grafana/runtime'; import { CustomScrollbar, Spinner, useTheme2 } from '@grafana/ui'; import { LogsPage } from './LogsNavigation'; @@ -51,7 +52,13 @@ export function LogsNavigationPages({ data-testid={`page${index + 1}`} className={styles.page} key={page.queryRange.to} - onClick={() => !loading && changeTime({ from: page.queryRange.from, to: page.queryRange.to })} + onClick={() => { + reportInteraction('grafana_explore_logs_pagination_clicked', { + pageType: 'page', + pageNumber: index + 1, + }); + !loading && changeTime({ from: page.queryRange.from, to: page.queryRange.to }); + }} >
diff --git a/public/app/features/explore/spec/queryHistory.test.tsx b/public/app/features/explore/spec/queryHistory.test.tsx index f8d99773ac8..86dae67df45 100644 --- a/public/app/features/explore/spec/queryHistory.test.tsx +++ b/public/app/features/explore/spec/queryHistory.test.tsx @@ -118,7 +118,6 @@ describe('Explore: Query History', () => { await openQueryHistory(); await assertQueryHistoryExists(RAW_QUERY); - expect(reportInteractionMock).toBeCalledTimes(2); expect(reportInteractionMock).toBeCalledWith('grafana_explore_query_history_opened', { queryHistoryEnabled: false, }); diff --git a/public/app/features/explore/state/query.ts b/public/app/features/explore/state/query.ts index 6a192bfcda5..137e7e6acc3 100644 --- a/public/app/features/explore/state/query.ts +++ b/public/app/features/explore/state/query.ts @@ -19,7 +19,7 @@ import { QueryFixAction, toLegacyResponseData, } from '@grafana/data'; -import { config } from '@grafana/runtime'; +import { config, reportInteraction } from '@grafana/runtime'; import { buildQueryTransaction, ensureQueries, @@ -442,6 +442,11 @@ export const runQueries = ( ) .subscribe({ next(data) { + if (data.logsResult !== null) { + reportInteraction('grafana_explore_logs_result_displayed', { + datasourceType: datasourceInstance.type, + }); + } dispatch(queryStreamUpdatedAction({ exploreId, response: data })); // Keep scanning for results if this was the last scanning transaction diff --git a/public/app/features/inspector/InspectDataTab.tsx b/public/app/features/inspector/InspectDataTab.tsx index 8e30ce87e50..046d4677888 100644 --- a/public/app/features/inspector/InspectDataTab.tsx +++ b/public/app/features/inspector/InspectDataTab.tsx @@ -16,8 +16,10 @@ import { toCSV, transformDataFrame, TimeZone, + CoreApp, } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { reportInteraction } from '@grafana/runtime'; import { Button, Spinner, Table } from '@grafana/ui'; import { config } from 'app/core/config'; import { dataFrameToLogsModel } from 'app/core/logs_model'; @@ -34,6 +36,7 @@ interface Props { isLoading: boolean; options: GetDataOptions; timeZone: TimeZone; + app?: CoreApp; data?: DataFrame[]; panel?: PanelModel; onOptionsChange?: (options: GetDataOptions) => void; @@ -107,7 +110,11 @@ export class InspectDataTab extends PureComponent { }; exportLogsAsTxt = () => { - const { data, panel } = this.props; + const { data, panel, app } = this.props; + reportInteraction('grafana_logs_download_logs_clicked', { + app, + format: 'logs', + }); const logsModel = dataFrameToLogsModel(data || [], undefined); let textToDownload = ''; @@ -223,7 +230,7 @@ export class InspectDataTab extends PureComponent { } render() { - const { isLoading, options, data, panel, onOptionsChange } = this.props; + const { isLoading, options, data, panel, onOptionsChange, app } = this.props; const { dataFrameIndex, transformId, transformationOptions, selectedDataFrame, downloadForExcel } = this.state; const styles = getPanelInspectorStyles(); @@ -266,7 +273,15 @@ export class InspectDataTab extends PureComponent { />
); diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx index 1c84d804923..b0f045f1f4c 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx @@ -126,7 +126,7 @@ export const LokiQueryEditorSelector = React.memo((props) )} {editorMode === QueryEditorMode.Explain && } {editorMode !== QueryEditorMode.Explain && ( - + )}