From 1d98534b63bf701bd340faf150cc0e3b45e63c7b Mon Sep 17 00:00:00 2001 From: WangQianliang Date: Wed, 25 Sep 2019 23:15:18 +0800 Subject: [PATCH] chore(code/frontend): frontend telemetry (#46154) --- .../plugins/code/model/usage_telemetry_metrics.ts | 11 +++++++++++ .../code/public/components/admin_page/admin.tsx | 7 +++++++ .../code/public/components/editor/editor.tsx | 4 ++++ .../code/public/components/file_tree/file_tree.tsx | 4 ++++ .../main/__snapshots__/breadcrumb.test.tsx.snap | 6 ++++++ .../code/public/components/main/breadcrumb.tsx | 7 +++++++ .../plugins/code/public/components/main/main.tsx | 4 ++++ .../code/public/components/search_page/search.tsx | 4 ++++ .../components/symbol_tree/code_symbol_tree.tsx | 11 +++++++++++ .../plugins/code/public/services/ui_metric.ts | 13 +++++++++++++ 10 files changed, 71 insertions(+) create mode 100644 x-pack/legacy/plugins/code/public/services/ui_metric.ts diff --git a/x-pack/legacy/plugins/code/model/usage_telemetry_metrics.ts b/x-pack/legacy/plugins/code/model/usage_telemetry_metrics.ts index c9e77c4ec0631..7e0242d751214 100644 --- a/x-pack/legacy/plugins/code/model/usage_telemetry_metrics.ts +++ b/x-pack/legacy/plugins/code/model/usage_telemetry_metrics.ts @@ -9,3 +9,14 @@ export enum CodeUsageMetrics { REPOSITORIES = 'repositories', LANGUAGE_SERVERS = 'langserver', } + +export enum CodeUIUsageMetrics { + ADMIN_PAGE_LOAD_COUNT = 'adminPageLoadCount', + SOURCE_VIEW_PAGE_LOAD_COUNT = 'sourceViewPageLoadCount', + SEARCH_PAGE_LOAD_COUNT = 'searchPageLoadCount', + FILE_TREE_CLICK_COUNT = 'fileTreeClickCount', + BREADCRUMB_CLICK_COUNT = 'breadcrumbClickCount', + LINE_NUMBER_CLICK_COUNT = 'lineNumberClickCount', + STRUCTURE_TREE_CLICK_COUNT = 'structureTreeClickCount', + LSP_DATA_AVAILABLE_PAGE_VIEW_COUNT = 'lspDataAvailablePageViewCount', +} diff --git a/x-pack/legacy/plugins/code/public/components/admin_page/admin.tsx b/x-pack/legacy/plugins/code/public/components/admin_page/admin.tsx index bbdf92b9d54f2..68c96b904e98a 100644 --- a/x-pack/legacy/plugins/code/public/components/admin_page/admin.tsx +++ b/x-pack/legacy/plugins/code/public/components/admin_page/admin.tsx @@ -18,6 +18,8 @@ import { SearchBar } from '../search_bar'; import { EmptyProject } from './empty_project'; import { LanguageSeverTab } from './language_server_tab'; import { ProjectTab } from './project_tab'; +import { METRIC_TYPE, trackCodeUiMetric } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; enum AdminTabs { projects = '0', @@ -82,6 +84,11 @@ class AdminPage extends React.PureComponent { }; } + componentDidMount() { + // track admin page load count + trackCodeUiMetric(METRIC_TYPE.LOADED, CodeUIUsageMetrics.ADMIN_PAGE_LOAD_COUNT); + } + public getAdminTabClickHandler = (tab: AdminTabs) => () => { this.setState({ tab }); this.props.history.push(url.format({ pathname: '/admin', query: { tab } })); diff --git a/x-pack/legacy/plugins/code/public/components/editor/editor.tsx b/x-pack/legacy/plugins/code/public/components/editor/editor.tsx index f26d4cc6ec3e7..36821897571de 100644 --- a/x-pack/legacy/plugins/code/public/components/editor/editor.tsx +++ b/x-pack/legacy/plugins/code/public/components/editor/editor.tsx @@ -22,6 +22,8 @@ import { history } from '../../utils/url'; import { Modifier, Shortcut } from '../shortcuts'; import { ReferencesPanel } from './references_panel'; import { encodeRevisionString } from '../../../common/uri_util'; +import { trackCodeUiMetric, METRIC_TYPE } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; export interface EditorActions { closePanel(changeUrl: boolean): void; @@ -64,6 +66,8 @@ export class EditorComponent extends React.Component { if (!this.gutterClickHandler) { this.gutterClickHandler = this.editor!.onMouseDown( (e: editorInterfaces.IEditorMouseEvent) => { + // track line number click count + trackCodeUiMetric(METRIC_TYPE.COUNT, CodeUIUsageMetrics.LINE_NUMBER_CLICK_COUNT); const { resource, org, repo, revision, path, pathType } = this.props.match.params; const queryString = this.props.location.search; const repoUri = `${resource}/${org}/${repo}`; diff --git a/x-pack/legacy/plugins/code/public/components/file_tree/file_tree.tsx b/x-pack/legacy/plugins/code/public/components/file_tree/file_tree.tsx index d9bb5d9511525..0c9df3e563c35 100644 --- a/x-pack/legacy/plugins/code/public/components/file_tree/file_tree.tsx +++ b/x-pack/legacy/plugins/code/public/components/file_tree/file_tree.tsx @@ -14,6 +14,8 @@ import { FileTree as Tree, FileTreeItemType } from '../../../model'; import { EuiSideNavItem, MainRouteParams, PathTypes } from '../../common/types'; import { RootState } from '../../reducers'; import { encodeRevisionString } from '../../../common/uri_util'; +import { trackCodeUiMetric, METRIC_TYPE } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; interface Props extends RouteComponentProps { node?: Tree; @@ -129,6 +131,8 @@ export class CodeFileTree extends React.Component { const path = flattenFrom ? flattenFrom.path! : node.path!; this.toggleTree(path); this.onClick(node); + // track file tree click count + trackCodeUiMetric(METRIC_TYPE.COUNT, CodeUIUsageMetrics.FILE_TREE_CLICK_COUNT); }; const nodeTypeMap = { [FileTreeItemType.Directory]: 'Directory', diff --git a/x-pack/legacy/plugins/code/public/components/main/__snapshots__/breadcrumb.test.tsx.snap b/x-pack/legacy/plugins/code/public/components/main/__snapshots__/breadcrumb.test.tsx.snap index 699f677427a35..c65f88bb22e4d 100644 --- a/x-pack/legacy/plugins/code/public/components/main/__snapshots__/breadcrumb.test.tsx.snap +++ b/x-pack/legacy/plugins/code/public/components/main/__snapshots__/breadcrumb.test.tsx.snap @@ -9,6 +9,7 @@ exports[`render correctly 1`] = ` className="euiLink euiLink--subdued euiBreadcrumb codeNoMinWidth" data-test-subj="codeFileBreadcrumb-src" href="#github.com/elastic/TypeScript-Node-Starter/tree/master/src" + onClick={[Function]} rel="noreferrer" title="src" > @@ -21,6 +22,7 @@ exports[`render correctly 1`] = ` className="euiLink euiLink--subdued euiBreadcrumb codeNoMinWidth" data-test-subj="codeFileBreadcrumb-public" href="#github.com/elastic/TypeScript-Node-Starter/tree/master/src/public" + onClick={[Function]} rel="noreferrer" title="public" > @@ -33,6 +35,7 @@ exports[`render correctly 1`] = ` className="euiLink euiLink--subdued euiBreadcrumb codeNoMinWidth" data-test-subj="codeFileBreadcrumb-css" href="#github.com/elastic/TypeScript-Node-Starter/tree/master/src/public/css" + onClick={[Function]} rel="noreferrer" title="css" > @@ -45,6 +48,7 @@ exports[`render correctly 1`] = ` className="euiLink euiLink--subdued euiBreadcrumb codeNoMinWidth" data-test-subj="codeFileBreadcrumb-lib" href="#github.com/elastic/TypeScript-Node-Starter/tree/master/src/public/css/lib" + onClick={[Function]} rel="noreferrer" title="lib" > @@ -57,6 +61,7 @@ exports[`render correctly 1`] = ` className="euiLink euiLink--subdued euiBreadcrumb codeNoMinWidth" data-test-subj="codeFileBreadcrumb-bootstrap" href="#github.com/elastic/TypeScript-Node-Starter/tree/master/src/public/css/lib/bootstrap" + onClick={[Function]} rel="noreferrer" title="bootstrap" > @@ -69,6 +74,7 @@ exports[`render correctly 1`] = ` className="euiLink euiLink--subdued euiBreadcrumb codeNoMinWidth" data-test-subj="codeFileBreadcrumb-mixins" href="#github.com/elastic/TypeScript-Node-Starter/tree/master/src/public/css/lib/bootstrap/mixins" + onClick={[Function]} rel="noreferrer" title="mixins" > diff --git a/x-pack/legacy/plugins/code/public/components/main/breadcrumb.tsx b/x-pack/legacy/plugins/code/public/components/main/breadcrumb.tsx index 5907d7ad3d351..642e74ba7fc94 100644 --- a/x-pack/legacy/plugins/code/public/components/main/breadcrumb.tsx +++ b/x-pack/legacy/plugins/code/public/components/main/breadcrumb.tsx @@ -9,6 +9,8 @@ import { EuiBreadcrumbs } from '@elastic/eui'; import React from 'react'; import { MainRouteParams } from '../../common/types'; import { encodeRevisionString } from '../../../common/uri_util'; +import { trackCodeUiMetric, METRIC_TYPE } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; interface Props { routeParams: MainRouteParams; @@ -23,6 +25,7 @@ export class Breadcrumb extends React.PureComponent { href: string; className?: string; ['data-test-subj']: string; + onClick?: Function; }> = []; const pathSegments = path ? path.split('/') : []; @@ -34,6 +37,10 @@ export class Breadcrumb extends React.PureComponent { href, className: 'codeNoMinWidth', ['data-test-subj']: `codeFileBreadcrumb-${p}`, + onClick: () => { + // track breadcrumb click count + trackCodeUiMetric(METRIC_TYPE.COUNT, CodeUIUsageMetrics.BREADCRUMB_CLICK_COUNT); + }, }; if (index === array.length - 1) { delete breadcrumb.href; diff --git a/x-pack/legacy/plugins/code/public/components/main/main.tsx b/x-pack/legacy/plugins/code/public/components/main/main.tsx index d852e0edceb4f..c3ae03760e397 100644 --- a/x-pack/legacy/plugins/code/public/components/main/main.tsx +++ b/x-pack/legacy/plugins/code/public/components/main/main.tsx @@ -17,6 +17,8 @@ import { SideTabs } from './side_tabs'; import { structureSelector, currentTreeSelector } from '../../selectors'; import { RootState } from '../../reducers'; import { FileTree } from '../../../model'; +import { trackCodeUiMetric, METRIC_TYPE } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; interface Props extends RouteComponentProps { loadingFileTree: boolean; @@ -29,6 +31,8 @@ interface Props extends RouteComponentProps { class CodeMain extends React.Component { public componentDidMount() { this.setBreadcrumbs(); + // track source page load count + trackCodeUiMetric(METRIC_TYPE.LOADED, CodeUIUsageMetrics.SOURCE_VIEW_PAGE_LOAD_COUNT); } public componentDidUpdate() { diff --git a/x-pack/legacy/plugins/code/public/components/search_page/search.tsx b/x-pack/legacy/plugins/code/public/components/search_page/search.tsx index 457a28ac0adba..2813fbd389a8a 100644 --- a/x-pack/legacy/plugins/code/public/components/search_page/search.tsx +++ b/x-pack/legacy/plugins/code/public/components/search_page/search.tsx @@ -22,6 +22,8 @@ import { CodeResult } from './code_result'; import { EmptyPlaceholder } from './empty_placeholder'; import { Pagination } from './pagination'; import { SideBar } from './side_bar'; +import { trackCodeUiMetric, METRIC_TYPE } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; interface Props { searchOptions: SearchOptions; @@ -49,6 +51,8 @@ class SearchPage extends React.PureComponent { public searchBar: any = null; public componentDidMount() { + // track search page load count + trackCodeUiMetric(METRIC_TYPE.LOADED, CodeUIUsageMetrics.SEARCH_PAGE_LOAD_COUNT); chrome.breadcrumbs.push({ text: `Search` }); } diff --git a/x-pack/legacy/plugins/code/public/components/symbol_tree/code_symbol_tree.tsx b/x-pack/legacy/plugins/code/public/components/symbol_tree/code_symbol_tree.tsx index 86b58ab83e58d..58038c2d59008 100644 --- a/x-pack/legacy/plugins/code/public/components/symbol_tree/code_symbol_tree.tsx +++ b/x-pack/legacy/plugins/code/public/components/symbol_tree/code_symbol_tree.tsx @@ -15,6 +15,8 @@ import { isEqual } from 'lodash'; import { RepositoryUtils } from '../../../common/repository_utils'; import { EuiSideNavItem, MainRouteParams } from '../../common/types'; import { SymbolWithMembers } from '../../actions/structure'; +import { trackCodeUiMetric, METRIC_TYPE } from '../../services/ui_metric'; +import { CodeUIUsageMetrics } from '../../../model/usage_telemetry_metrics'; interface Props extends RouteComponentProps { structureTree: SymbolWithMembers[]; @@ -32,8 +34,17 @@ interface ActiveSymbol { export class CodeSymbolTree extends React.PureComponent { public state: { activeSymbol?: ActiveSymbol } = {}; + public componentDidUpdate(prevProps: Props) { + if (this.props.uri && prevProps.uri !== this.props.uri && this.props.structureTree.length > 0) { + // track lsp data available page view count + trackCodeUiMetric(METRIC_TYPE.COUNT, CodeUIUsageMetrics.LSP_DATA_AVAILABLE_PAGE_VIEW_COUNT); + } + } + public getClickHandler = (symbol: ActiveSymbol) => () => { this.setState({ activeSymbol: symbol }); + // track structure tree click count + trackCodeUiMetric(METRIC_TYPE.COUNT, CodeUIUsageMetrics.STRUCTURE_TREE_CLICK_COUNT); }; public getStructureTreeItemRenderer = ( diff --git a/x-pack/legacy/plugins/code/public/services/ui_metric.ts b/x-pack/legacy/plugins/code/public/services/ui_metric.ts new file mode 100644 index 0000000000000..245ca14e77aa7 --- /dev/null +++ b/x-pack/legacy/plugins/code/public/services/ui_metric.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { + createUiStatsReporter, + METRIC_TYPE, +} from '../../../../../../src/legacy/core_plugins/ui_metric/public'; +import { APP_USAGE_TYPE } from '../../common/constants'; + +export const trackCodeUiMetric = createUiStatsReporter(APP_USAGE_TYPE); +export { METRIC_TYPE };