[Profiling] Telemetry (#161702)

- Adding telemetry when the `show more information` is clicked in the
Flamegraph page
   key: `flamegraph_node_details_click`

- Adding telemetry when the `show more information` is clicked in the
TopN functions page
   key: `topN_function_details_click`

- Adding telemetry success/error on the initialization API
   Counter name: `POST /internal/profiling/setup/es_resources`
   Counter type: `success` or `error`

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Cauê Marcondes 2023-07-19 16:16:17 -03:00 committed by GitHub
parent 4b38775515
commit 8ba4477933
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 40 additions and 5 deletions

View file

@ -75,7 +75,7 @@ export type HasData<T extends ObservabilityFetchDataPlugins> = (
export type ObservabilityFetchDataPlugins = Exclude<
ObservabilityApp,
'observability-overview' | 'stack_monitoring' | 'fleet' | 'synthetics'
'observability-overview' | 'stack_monitoring' | 'fleet' | 'synthetics' | 'profiling'
>;
export interface DataHandler<

View file

@ -15,4 +15,5 @@ export type ObservabilityApp =
| 'observability-overview'
| 'stack_monitoring'
| 'ux'
| 'fleet';
| 'fleet'
| 'profiling';

View file

@ -7,7 +7,10 @@
"server": true,
"browser": true,
"configPath": ["xpack", "profiling"],
"optionalPlugins": ["spaces"],
"optionalPlugins": [
"spaces",
"usageCollection"
],
"requiredPlugins": [
"charts",
"cloud",

View file

@ -18,6 +18,7 @@ import {
import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui';
import { Maybe } from '@kbn/observability-plugin/common/typings';
import React, { useEffect, useMemo, useState } from 'react';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
import { ElasticFlameGraph } from '../../../common/flamegraph';
import { getFlamegraphModel } from '../../utils/get_flamegraph_model';
import { FlameGraphLegend } from './flame_graph_legend';
@ -52,6 +53,7 @@ export function FlameGraph({
onChangeSearchText,
}: Props) {
const theme = useEuiTheme();
const trackProfilingEvent = useUiTracker({ app: 'profiling' });
const columnarData = useMemo(() => {
return getFlamegraphModel({
@ -154,6 +156,7 @@ export function FlameGraph({
baselineScaleFactor={baseline}
comparisonScaleFactor={comparison}
onShowMoreClick={() => {
trackProfilingEvent({ metric: 'flamegraph_node_details_click' });
if (!showInformationWindow) {
toggleShowInformationWindow();
}

View file

@ -20,6 +20,7 @@ import { i18n } from '@kbn/i18n';
import { last } from 'lodash';
import React, { forwardRef, Ref, useMemo, useState } from 'react';
import { GridOnScrollProps } from 'react-window';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
import { TopNFunctions, TopNFunctionSortField } from '../../../common/functions';
import { CPULabelWithHint } from '../cpu_label_with_hint';
import { FrameInformationTooltip } from '../frame_information_window/frame_information_tooltip';
@ -66,6 +67,7 @@ export const TopNFunctionsGrid = forwardRef(
ref: Ref<EuiDataGridRefProps> | undefined
) => {
const [selectedRow, setSelectedRow] = useState<IFunctionRow | undefined>();
const trackProfilingEvent = useUiTracker({ app: 'profiling' });
function onSort(newSortingColumns: EuiDataGridSorting['columns']) {
const lastItem = last(newSortingColumns);
@ -220,6 +222,7 @@ export const TopNFunctionsGrid = forwardRef(
},
rowCellRender: function RowCellRender({ rowIndex }) {
function handleOnClick() {
trackProfilingEvent({ metric: 'topN_function_details_click' });
setSelectedRow(rows[rowIndex]);
}
return (
@ -234,7 +237,7 @@ export const TopNFunctionsGrid = forwardRef(
});
}
return { columns: gridColumns, leadingControlColumns: gridLeadingControlColumns };
}, [isDifferentialView, rows, showDiffColumn]);
}, [isDifferentialView, rows, showDiffColumn, trackProfilingEvent]);
const [visibleColumns, setVisibleColumns] = useState(columns.map(({ id }) => id));

View file

@ -7,7 +7,7 @@
import { CoreSetup, CoreStart, Logger, Plugin, PluginInitializerContext } from '@kbn/core/server';
import { ProfilingConfig } from '.';
import { PROFILING_FEATURE } from './feature';
import { PROFILING_FEATURE, PROFILING_SERVER_FEATURE_ID } from './feature';
import { registerRoutes } from './routes';
import {
ProfilingPluginSetup,
@ -41,6 +41,10 @@ export class ProfilingPlugin
const config = this.initializerContext.config.get();
const telemetryUsageCounter = deps.usageCollection?.createUsageCounter(
PROFILING_SERVER_FEATURE_ID
);
core.getStartServices().then(([coreStart, depsStart]) => {
const profilingSpecificEsClient = config.elasticsearch
? coreStart.elasticsearch.createClient('profiling', {
@ -57,6 +61,7 @@ export class ProfilingPlugin
start: depsStart,
setup: deps,
config,
telemetryUsageCounter,
},
services: {
createProfilingEsClient: ({

View file

@ -13,6 +13,7 @@ import {
ProfilingPluginSetupDeps,
ProfilingPluginStartDeps,
ProfilingRequestHandlerContext,
TelemetryUsageCounter,
} from '../types';
import { ProfilingESClient } from '../utils/create_profiling_es_client';
import { registerFlameChartSearchRoute } from './flamechart';
@ -33,6 +34,7 @@ export interface RouteRegisterParameters {
start: ProfilingPluginStartDeps;
setup: ProfilingPluginSetupDeps;
config: ProfilingConfig;
telemetryUsageCounter?: TelemetryUsageCounter;
};
services: {
createProfilingEsClient: (params: {

View file

@ -200,11 +200,24 @@ export function registerSetupRoute({
await Promise.all(executeFunctions.map((fn) => fn(setupOptions)));
if (dependencies.telemetryUsageCounter) {
dependencies.telemetryUsageCounter.incrementCounter({
counterName: `POST ${paths.HasSetupESResources}`,
counterType: 'success',
});
}
// We return a status code of 202 instead of 200 because enabling
// resource management in Elasticsearch is an asynchronous action
// and is not guaranteed to complete before Kibana sends a response.
return response.accepted();
} catch (error) {
if (dependencies.telemetryUsageCounter) {
dependencies.telemetryUsageCounter.incrementCounter({
counterName: `POST ${paths.HasSetupESResources}`,
counterType: 'error',
});
}
return handleRouteHandlerError({
error,
logger,

View file

@ -11,6 +11,7 @@ import type { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'
import { SpacesPluginStart, SpacesPluginSetup } from '@kbn/spaces-plugin/server';
import { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server';
import { FleetSetupContract, FleetStartContract } from '@kbn/fleet-plugin/server';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
export interface ProfilingPluginSetupDeps {
observability: ObservabilityPluginSetup;
@ -18,6 +19,7 @@ export interface ProfilingPluginSetupDeps {
cloud: CloudSetup;
fleet: FleetSetupContract;
spaces?: SpacesPluginSetup;
usageCollection?: UsageCollectionSetup;
}
export interface ProfilingPluginStartDeps {
@ -34,3 +36,5 @@ export interface ProfilingPluginSetup {}
export interface ProfilingPluginStart {}
export type ProfilingRequestHandlerContext = CustomRequestHandlerContext<{}>;
export type TelemetryUsageCounter = ReturnType<UsageCollectionSetup['createUsageCounter']>;

View file

@ -46,6 +46,7 @@
"@kbn/observability-shared-plugin",
"@kbn/licensing-plugin",
"@kbn/utility-types",
"@kbn/usage-collection-plugin",
// add references to other TypeScript projects the plugin depends on
// requiredPlugins from ./kibana.json