Skip to content

Commit

Permalink
[Obs UX] Include with_filters and with_query to hosts count event (el…
Browse files Browse the repository at this point in the history
…astic#173279)

closes elastic#173077

## Summary

Adds `with_query` and `with_filters` attributes to the "Host View Total
Host Count Retrieved" event.

**note**: date picker isn't considered for the flags above.

### How to test

1. Start  ES, Kibana, and  metricbeat
2. Navigate to Infrastructure > Hosts
3. Inspect the `kibana-browser` request payload and check if the new
attributes are there
4. Add/remove filters and query and repeat step 3.

Co-authored-by: Kibana Machine <[email protected]>
(cherry picked from commit c622478)
  • Loading branch information
crespocarlos committed Dec 18, 2023
1 parent dab8881 commit 88ca21d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

import * as rt from 'io-ts';
import { ES_SEARCH_STRATEGY, IKibanaSearchResponse } from '@kbn/data-plugin/common';
import { useCallback, useEffect } from 'react';
import { catchError, map, Observable, of, startWith } from 'rxjs';
import { useCallback, useEffect, useMemo } from 'react';
import { catchError, map, Observable, of, startWith, tap } from 'rxjs';
import createContainer from 'constate';
import type { QueryDslQueryContainer, SearchResponse } from '@elastic/elasticsearch/lib/api/types';
import type { ITelemetryClient } from '../../../../services/telemetry';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { decodeOrThrow } from '../../../../../common/runtime_types';
import { useDataSearch, useLatestPartialDataSearchResponse } from '../../../../utils/data_search';
Expand Down Expand Up @@ -79,7 +80,23 @@ export const useHostCount = () => {
searchCriteria.dateRange.from,
searchCriteria.dateRange.to,
]),
parseResponses: normalizeDataSearchResponse,
parseResponses: useMemo(
() =>
normalizeDataSearchResponse({
telemetry,
telemetryData: {
withQuery: !!searchCriteria.query.query,
withFilters:
searchCriteria.filters.length > 0 || searchCriteria.panelFilters.length > 0,
},
}),
[
searchCriteria.filters.length,
searchCriteria.panelFilters.length,
searchCriteria.query.query,
telemetry,
]
),
});

const { isRequestRunning, isResponsePartial, latestResponseData, latestResponseErrors } =
Expand All @@ -89,14 +106,6 @@ export const useHostCount = () => {
fetchHostCount();
}, [fetchHostCount]);

useEffect(() => {
if (latestResponseData) {
telemetry.reportHostsViewTotalHostCountRetrieved({
total: latestResponseData.count.value,
});
}
}, [latestResponseData, telemetry]);

return {
errors: latestResponseErrors,
isRequestRunning,
Expand All @@ -116,27 +125,42 @@ const INITIAL_STATE = {
loaded: 0,
total: undefined,
};
const normalizeDataSearchResponse = (
response$: Observable<IKibanaSearchResponse<SearchResponse<Record<string, unknown>>>>
) =>
response$.pipe(
map((response) => ({
data: decodeOrThrow(HostCountResponseRT)(response.rawResponse.aggregations),
errors: [],
isPartial: response.isPartial ?? false,
isRunning: response.isRunning ?? false,
loaded: response.loaded,
total: response.total,
})),
startWith(INITIAL_STATE),
catchError((error) =>
of({
...INITIAL_STATE,
errors: [error.message ?? error],
isRunning: false,
})
)
);

const normalizeDataSearchResponse =
({
telemetry,
telemetryData,
}: {
telemetry: ITelemetryClient;
telemetryData: { withQuery: boolean; withFilters: boolean };
}) =>
(response$: Observable<IKibanaSearchResponse<SearchResponse<Record<string, unknown>>>>) => {
return response$.pipe(
map((response) => ({
data: decodeOrThrow(HostCountResponseRT)(response.rawResponse.aggregations),
errors: [],
isPartial: response.isPartial ?? false,
isRunning: response.isRunning ?? false,
loaded: response.loaded,
total: response.total,
})),
tap(({ data }) => {
telemetry.reportHostsViewTotalHostCountRetrieved({
total: data.count.value,
with_query: telemetryData.withQuery,
with_filters: telemetryData.withFilters,
});
}),
startWith(INITIAL_STATE),
catchError((error) =>
of({
...INITIAL_STATE,
errors: [error.message ?? error],
isRunning: false,
})
)
);
};

const HostCountResponseRT = rt.type({
count: rt.type({
Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/infra/public/services/telemetry/telemetry_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,20 @@ const hostViewTotalHostCountRetrieved: InfraTelemetryEvent = {
optional: false,
},
},
with_query: {
type: 'boolean',
_meta: {
description: 'Has KQL query',
optional: false,
},
},
with_filters: {
type: 'boolean',
_meta: {
description: 'Has filters',
optional: false,
},
},
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,17 @@ describe('TelemetryService', () => {

telemetry.reportHostsViewTotalHostCountRetrieved({
total: 300,
with_filters: true,
with_query: false,
});

expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
InfraTelemetryEventTypes.HOST_VIEW_TOTAL_HOST_COUNT_RETRIEVED,
{
total: 300,
with_filters: true,
with_query: false,
}
);
});
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/infra/public/services/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export interface HostFlyoutFilterActionParams {

export interface HostsViewQueryHostsCountRetrievedParams {
total: number;
with_query: boolean;
with_filters: boolean;
}

export interface AssetDetailsFlyoutViewedParams {
Expand Down

0 comments on commit 88ca21d

Please sign in to comment.