[8.8] [Infrastructure UI] Host limit telemetry (#155726) (#157409)

# Backport

This will backport the following commits from `main` to `8.8`:
- [[Infrastructure UI] Host limit telemetry
(#155726)](https://github.com/elastic/kibana/pull/155726)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Carlos
Crespo","email":"crespocarlos@users.noreply.github.com"},"sourceCommit":{"committedDate":"2023-05-11T15:44:38Z","message":"[Infrastructure
UI] Host limit telemetry (#155726)\n\ncloses:
https://github.com/elastic/kibana/issues/155567\r\n\r\n##
Summary\r\n\r\nThis PR adds a new custom event to track the total number
of hosts, as\r\nwell as adjusts a few `data-test-subj` attribute values
to meet the\r\nnaming convention defined in the
observability-dev\r\n[docs](https://github.com/elastic/observability-dev/blob/main/docs/how-we-work/telemetry/telemetry-convention.md#naming-convention)\r\n\r\n\r\n###
For Reviewers\r\n\r\nAn option for not allowing yet a new custom event
in FS could be\r\ntriggering the new custom events only for self-managed
customers, and in\r\nFS watch the element that holds the total number of
hosts. But for now,\r\nI decided to allow the new custom event in FS for
consistency\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine
<42973632+kibanamachine@users.noreply.github.com>","sha":"937912b056f5876247f27a7baad5314401e65939","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Metrics
UI","Team:Infra Monitoring
UI","release_note:skip","backport:prev-minor","Feature:ObsHosts","v8.9.0"],"number":155726,"url":"https://github.com/elastic/kibana/pull/155726","mergeCommit":{"message":"[Infrastructure
UI] Host limit telemetry (#155726)\n\ncloses:
https://github.com/elastic/kibana/issues/155567\r\n\r\n##
Summary\r\n\r\nThis PR adds a new custom event to track the total number
of hosts, as\r\nwell as adjusts a few `data-test-subj` attribute values
to meet the\r\nnaming convention defined in the
observability-dev\r\n[docs](https://github.com/elastic/observability-dev/blob/main/docs/how-we-work/telemetry/telemetry-convention.md#naming-convention)\r\n\r\n\r\n###
For Reviewers\r\n\r\nAn option for not allowing yet a new custom event
in FS could be\r\ntriggering the new custom events only for self-managed
customers, and in\r\nFS watch the element that holds the total number of
hosts. But for now,\r\nI decided to allow the new custom event in FS for
consistency\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine
<42973632+kibanamachine@users.noreply.github.com>","sha":"937912b056f5876247f27a7baad5314401e65939"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/155726","number":155726,"mergeCommit":{"message":"[Infrastructure
UI] Host limit telemetry (#155726)\n\ncloses:
https://github.com/elastic/kibana/issues/155567\r\n\r\n##
Summary\r\n\r\nThis PR adds a new custom event to track the total number
of hosts, as\r\nwell as adjusts a few `data-test-subj` attribute values
to meet the\r\nnaming convention defined in the
observability-dev\r\n[docs](https://github.com/elastic/observability-dev/blob/main/docs/how-we-work/telemetry/telemetry-convention.md#naming-convention)\r\n\r\n\r\n###
For Reviewers\r\n\r\nAn option for not allowing yet a new custom event
in FS could be\r\ntriggering the new custom events only for self-managed
customers, and in\r\nFS watch the element that holds the total number of
hosts. But for now,\r\nI decided to allow the new custom event in FS for
consistency\r\n\r\n---------\r\n\r\nCo-authored-by: Kibana Machine
<42973632+kibanamachine@users.noreply.github.com>","sha":"937912b056f5876247f27a7baad5314401e65939"}}]}]
BACKPORT-->

Co-authored-by: Carlos Crespo <crespocarlos@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2023-05-11 13:01:52 -04:00 committed by GitHub
parent 31ff66e0d5
commit d927533c49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 100 additions and 19 deletions

View file

@ -20,7 +20,7 @@ const HOSTS_CHART: Omit<Props, 'loading' | 'value'> = {
toolTip: i18n.translate('xpack.infra.hostsViewPage.metricTrend.hostCount.tooltip', {
defaultMessage: 'The number of hosts returned by your current search criteria.',
}),
['data-test-subj']: 'hostsView-metricsTrend-hosts',
['data-test-subj']: 'hostsViewKPI-hostsCount',
};
export const HostsTile = () => {

View file

@ -70,7 +70,7 @@ export const KPIGrid = () => {
direction="row"
gutterSize="s"
style={{ flexGrow: 0 }}
data-test-subj="hostsView-metricsTrend"
data-test-subj="hostsViewKPIGrid"
>
<EuiFlexItem>
<HostsTile />

View file

@ -115,7 +115,7 @@ export const Tile = ({
hasShadow={false}
paddingSize={error ? 'm' : 'none'}
style={{ minHeight: MIN_HEIGHT }}
data-test-subj={`hostsView-metricsTrend-${type}`}
data-test-subj={`hostsViewKPI-${type}`}
>
{error ? (
<EuiFlexGroup
@ -145,7 +145,7 @@ export const Tile = ({
anchorClassName="eui-fullWidth"
>
<LensWrapper
id={`hostViewKPIChart-${type}`}
id={`hostsViewKPIGrid${type}Tile`}
attributes={afterLoadedState.attributes}
style={{ height: MIN_HEIGHT }}
extraActions={[extraActionOptions.openInLens]}

View file

@ -77,5 +77,5 @@ const options: EuiButtonGroupOptionProps[] = HOST_LIMIT_OPTIONS.map((option) =>
id: buildId(option),
label: `${option}`,
value: option,
'data-test-subj': `hostsViewLimitSelection${option}button`,
'data-test-subj': `hostsViewLimitSelection${option}Button`,
}));

View file

@ -11,6 +11,7 @@ import { useCallback, useEffect } from 'react';
import { catchError, map, Observable, of, startWith } from 'rxjs';
import createContainer from 'constate';
import type { QueryDslQueryContainer, SearchResponse } from '@elastic/elasticsearch/lib/api/types';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { decodeOrThrow } from '../../../../../common/runtime_types';
import { useDataSearch, useLatestPartialDataSearchResponse } from '../../../../utils/data_search';
import { useMetricsDataViewContext } from './use_data_view';
@ -18,6 +19,9 @@ import { useUnifiedSearchContext } from './use_unified_search';
export const useHostCount = () => {
const { dataView, metricAlias } = useMetricsDataViewContext();
const {
services: { telemetry },
} = useKibanaContextForPlugin();
const { buildQuery, getParsedDateRange } = useUnifiedSearchContext();
const { search: fetchHostCount, requests$ } = useDataSearch({
@ -81,6 +85,14 @@ export const useHostCount = () => {
fetchHostCount();
}, [fetchHostCount]);
useEffect(() => {
if (latestResponseData) {
telemetry.reportHostsViewTotalHostCountRetrieved({
total: latestResponseData.count.value,
});
}
}, [latestResponseData, telemetry]);
return {
errors: latestResponseErrors,
isRequestRunning,

View file

@ -21,7 +21,7 @@ import {
InfraAssetMetricType,
} from '../../../../../common/http_api';
import { useHostFlyoutOpen } from './use_host_flyout_open_url_state';
import { Sorting, useHostsTableProperties } from './use_hosts_table_url_state';
import { Sorting, useHostsTableUrlState } from './use_hosts_table_url_state';
import { useHostsViewContext } from './use_hosts_view';
import { useUnifiedSearchContext } from './use_unified_search';
@ -166,7 +166,7 @@ const toggleDialogActionLabel = i18n.translate(
export const useHostsTable = () => {
const { hostNodes } = useHostsViewContext();
const { searchCriteria } = useUnifiedSearchContext();
const [{ pagination, sorting }, setProperties] = useHostsTableProperties();
const [{ pagination, sorting }, setProperties] = useHostsTableUrlState();
const {
services: { telemetry },
} = useKibanaContextForPlugin();

View file

@ -37,7 +37,7 @@ const reducer = (prevState: TableProperties, params: Payload) => {
};
};
export const useHostsTableProperties = (): [TableProperties, TablePropertiesUpdater] => {
export const useHostsTableUrlState = (): [TableProperties, TablePropertiesUpdater] => {
const [localStoragePageSize, setLocalStoragePageSize] = useLocalStorage<number>(
LOCAL_STORAGE_PAGE_SIZE_KEY,
DEFAULT_PAGE_SIZE

View file

@ -25,13 +25,14 @@ import {
const buildQuerySubmittedPayload = (
hostState: HostsState & { parsedDateRange: StringDateRangeTimestamp }
) => {
const { panelFilters, filters, parsedDateRange, query: queryObj } = hostState;
const { panelFilters, filters, parsedDateRange, query: queryObj, limit } = hostState;
return {
control_filters: panelFilters.map((filter) => JSON.stringify(filter)),
filters: filters.map((filter) => JSON.stringify(filter)),
interval: telemetryTimeRangeFormatter(parsedDateRange.to - parsedDateRange.from),
query: queryObj.query,
limit,
};
};

View file

@ -12,4 +12,5 @@ export const createTelemetryClientMock = (): jest.Mocked<ITelemetryClient> => ({
reportHostsViewQuerySubmitted: jest.fn(),
reportHostFlyoutFilterRemoved: jest.fn(),
reportHostFlyoutFilterAdded: jest.fn(),
reportHostsViewTotalHostCountRetrieved: jest.fn(),
});

View file

@ -9,6 +9,7 @@ import { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
import {
HostEntryClickedParams,
HostFlyoutFilterActionParams,
HostsViewQueryHostsCountRetrievedParams,
HostsViewQuerySubmittedParams,
InfraTelemetryEventTypes,
ITelemetryClient,
@ -50,4 +51,13 @@ export class TelemetryClient implements ITelemetryClient {
public reportHostsViewQuerySubmitted = (params: HostsViewQuerySubmittedParams) => {
this.analytics.reportEvent(InfraTelemetryEventTypes.HOSTS_VIEW_QUERY_SUBMITTED, params);
};
public reportHostsViewTotalHostCountRetrieved(
params: HostsViewQueryHostsCountRetrievedParams
): void {
this.analytics.reportEvent(
InfraTelemetryEventTypes.HOST_VIEW_TOTAL_HOST_COUNT_RETRIEVED,
params
);
}
}

View file

@ -43,6 +43,13 @@ const hostsViewQuerySubmittedEvent: InfraTelemetryEvent = {
optional: false,
},
},
limit: {
type: 'integer',
_meta: {
description: 'Selected host limit',
optional: false,
},
},
},
};
@ -78,6 +85,7 @@ const hostFlyoutRemoveFilter: InfraTelemetryEvent = {
},
},
};
const hostFlyoutAddFilter: InfraTelemetryEvent = {
eventType: InfraTelemetryEventTypes.HOST_FLYOUT_FILTER_ADDED,
schema: {
@ -91,9 +99,23 @@ const hostFlyoutAddFilter: InfraTelemetryEvent = {
},
};
const hostViewTotalHostCountRetrieved: InfraTelemetryEvent = {
eventType: InfraTelemetryEventTypes.HOST_VIEW_TOTAL_HOST_COUNT_RETRIEVED,
schema: {
total: {
type: 'integer',
_meta: {
description: 'Total number of hosts retrieved.',
optional: false,
},
},
},
};
export const infraTelemetryEvents = [
hostsViewQuerySubmittedEvent,
hostsEntryClickedEvent,
hostFlyoutRemoveFilter,
hostFlyoutAddFilter,
hostViewTotalHostCountRetrieved,
];

View file

@ -107,6 +107,7 @@ describe('TelemetryService', () => {
filters: [],
interval: 'interval(now-1h)',
query: '',
limit: 100,
});
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
@ -117,6 +118,7 @@ describe('TelemetryService', () => {
filters: [],
interval: 'interval(now-1h)',
query: '',
limit: 100,
}
);
});
@ -161,4 +163,24 @@ describe('TelemetryService', () => {
);
});
});
describe('#reportHostsViewTotalHostCountRetrieved', () => {
it('should report Host Flyout Filter Added click with field name', async () => {
const setupParams = getSetupParams();
service.setup(setupParams);
const telemetry = service.start();
telemetry.reportHostsViewTotalHostCountRetrieved({
total: 300,
});
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
InfraTelemetryEventTypes.HOST_VIEW_TOTAL_HOST_COUNT_RETRIEVED,
{
total: 300,
}
);
});
});
});

View file

@ -17,6 +17,7 @@ export enum InfraTelemetryEventTypes {
HOSTS_ENTRY_CLICKED = 'Host Entry Clicked',
HOST_FLYOUT_FILTER_REMOVED = 'Host Flyout Filter Removed',
HOST_FLYOUT_FILTER_ADDED = 'Host Flyout Filter Added',
HOST_VIEW_TOTAL_HOST_COUNT_RETRIEVED = 'Host View Total Host Count Retrieved',
}
export interface HostsViewQuerySubmittedParams {
@ -24,6 +25,7 @@ export interface HostsViewQuerySubmittedParams {
filters: string[];
interval: string;
query: string | { [key: string]: any };
limit: number;
}
export interface HostEntryClickedParams {
@ -35,15 +37,21 @@ export interface HostFlyoutFilterActionParams {
field_name: string;
}
export interface HostsViewQueryHostsCountRetrievedParams {
total: number;
}
export type InfraTelemetryEventParams =
| HostsViewQuerySubmittedParams
| HostEntryClickedParams
| HostFlyoutFilterActionParams;
| HostFlyoutFilterActionParams
| HostsViewQueryHostsCountRetrievedParams;
export interface ITelemetryClient {
reportHostEntryClicked(params: HostEntryClickedParams): void;
reportHostFlyoutFilterRemoved(params: HostFlyoutFilterActionParams): void;
reportHostFlyoutFilterAdded(params: HostFlyoutFilterActionParams): void;
reportHostsViewTotalHostCountRetrieved(params: HostsViewQueryHostsCountRetrievedParams): void;
reportHostsViewQuerySubmitted(params: HostsViewQuerySubmittedParams): void;
}
@ -63,4 +71,8 @@ export type InfraTelemetryEvent =
| {
eventType: InfraTelemetryEventTypes.HOSTS_ENTRY_CLICKED;
schema: RootSchema<HostEntryClickedParams>;
}
| {
eventType: InfraTelemetryEventTypes.HOST_VIEW_TOTAL_HOST_COUNT_RETRIEVED;
schema: RootSchema<HostsViewQueryHostsCountRetrievedParams>;
};

View file

@ -371,7 +371,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
[
{ metric: 'hosts', value: '6' },
{ metric: 'hostsCount', value: '6' },
{ metric: 'cpu', value: '0.8%' },
{ metric: 'memory', value: '16.81%' },
{ metric: 'tx', value: 'N/A' },
@ -510,7 +510,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
it('should update the KPIs content on a search submit', async () => {
await Promise.all(
[
{ metric: 'hosts', value: '3' },
{ metric: 'hostsCount', value: '3' },
{ metric: 'cpu', value: '0.8%' },
{ metric: 'memory', value: '16.25%' },
{ metric: 'tx', value: 'N/A' },

View file

@ -103,8 +103,8 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
return cellContent.getVisibleText();
},
async getKPIContainer() {
return testSubjects.find('hostsView-metricsTrend');
async getMetricsTrendContainer() {
return testSubjects.find('hostsViewKPIGrid');
},
async getChartsContainer() {
@ -118,7 +118,7 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
async visitMetricsTab() {
const metricsTab = await this.getMetricsTab();
await metricsTab.click();
return metricsTab.click();
},
async getAllMetricsCharts() {
@ -144,14 +144,15 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
},
async getAllKPITiles() {
const container = await this.getKPIContainer();
return container.findAllByCssSelector('[data-test-subj*="hostsView-metricsTrend-"]');
const container = await this.getMetricsTrendContainer();
return container.findAllByCssSelector('[data-test-subj*="hostsViewKPI-"]');
},
async getKPITileValue(type: string) {
const element = await testSubjects.find(`hostsView-metricsTrend-${type}`);
const container = await this.getMetricsTrendContainer();
const element = await container.findByTestSubject(`hostsViewKPI-${type}`);
const div = await element.findByClassName('echMetricText__value');
return await div.getAttribute('title');
return div.getAttribute('title');
},
// Flyout Tabs