Skip to content

Commit

Permalink
[APM] Add telemetry to track usage of the agent config to fleet synch…
Browse files Browse the repository at this point in the history
…ronisation feature (#105297)

* removing telemetry hook from pages

* adding telemetry to schema and agent config
  • Loading branch information
cauemarcondes authored Jul 13, 2021
1 parent 4ae6dd3 commit ee8c9be
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
import React from 'react';
import { useLocation } from 'react-router-dom';
import { useTrackPageview } from '../../../../../../observability/public';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { createAgentConfigurationHref } from '../../../shared/Links/apm/agentConfigurationLinks';
Expand All @@ -34,9 +33,6 @@ export function AgentConfigurations() {
{ preservePreviousData: false, showToastOnError: false }
);

useTrackPageview({ app: 'apm', path: 'agent_configuration' });
useTrackPageview({ app: 'apm', path: 'agent_configuration', delay: 15000 });

const hasConfigurations = !isEmpty(data.configurations);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
htmlIdGenerator,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useUiTracker } from '../../../../../../observability/public';
import { ElasticDocsLink } from '../../../shared/Links/ElasticDocsLink';

interface Props {
Expand All @@ -27,6 +28,7 @@ export function ConfirmSwitchModal({
onCancel,
unsupportedConfigs,
}: Props) {
const trackApmEvent = useUiTracker({ app: 'apm' });
const [isConfirmChecked, setIsConfirmChecked] = useState(false);
const hasUnsupportedConfigs = !!unsupportedConfigs.length;
return (
Expand All @@ -48,7 +50,12 @@ export function ConfirmSwitchModal({
}
)}
defaultFocusedButton="confirm"
onConfirm={onConfirm}
onConfirm={() => {
trackApmEvent({
metric: 'confirm_data_stream_switch',
});
onConfirm();
}}
confirmButtonDisabled={!isConfirmChecked}
>
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common';
import { useTrackPageview } from '../../../../../observability/public';
import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { useErrorGroupDistributionFetcher } from '../../../hooks/use_error_group_distribution_fetcher';
Expand Down Expand Up @@ -128,9 +127,6 @@ export function ErrorGroupDetails({
groupId,
});

useTrackPageview({ app: 'apm', path: 'error_group_details' });
useTrackPageview({ app: 'apm', path: 'error_group_details', delay: 15000 });

if (!errorGroupData || !errorDistributionData) {
return <ErrorGroupHeader groupId={groupId} />;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useTrackPageview } from '../../../../../observability/public';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { useErrorGroupDistributionFetcher } from '../../../hooks/use_error_group_distribution_fetcher';
import { useFetcher } from '../../../hooks/use_fetcher';
Expand Down Expand Up @@ -60,12 +59,6 @@ export function ErrorGroupOverview({ serviceName }: ErrorGroupOverviewProps) {
[environment, kuery, serviceName, start, end, sortField, sortDirection]
);

useTrackPageview({
app: 'apm',
path: 'error_group_overview',
});
useTrackPageview({ app: 'apm', path: 'error_group_overview', delay: 15000 });

if (!errorDistributionData || !errorGroupListData) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useEffect } from 'react';
import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public';
import { useTrackPageview } from '../../../../../observability/public';
import { useAnomalyDetectionJobsContext } from '../../../context/anomaly_detection_jobs/use_anomaly_detection_jobs_context';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
Expand Down Expand Up @@ -92,13 +91,6 @@ export function ServiceInventory() {
const { core } = useApmPluginContext();
const { servicesData, servicesStatus } = useServicesFetcher();

// The page is called "service inventory" to avoid confusion with the
// "service overview", but this is tracked in some dashboards because it's the
// initial landing page for APM, so it stays as "services_overview" (plural.)
// for backward compatibility.
useTrackPageview({ app: 'apm', path: 'services_overview' });
useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 });

const {
anomalyDetectionJobsData,
anomalyDetectionJobsStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
} from '@elastic/eui';
import React, { PropsWithChildren, ReactNode } from 'react';
import { isActivePlatinumLicense } from '../../../../common/license_check';
import { useTrackPageview } from '../../../../../observability/public';
import {
invalidLicenseMessage,
SERVICE_MAP_TIMEOUT_ERROR,
Expand Down Expand Up @@ -106,9 +105,6 @@ export function ServiceMap({
const PADDING_BOTTOM = 24;
const heightWithPadding = height - PADDING_BOTTOM;

useTrackPageview({ app: 'apm', path: 'service_map' });
useTrackPageview({ app: 'apm', path: 'service_map', delay: 15000 });

if (!license) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
import React from 'react';
import { useTrackPageview } from '../../../../../observability/public';
import { isRumAgentName, isIosAgentName } from '../../../../common/agent_name';
import { AnnotationsContextProvider } from '../../../context/annotations/annotations_context';
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
Expand Down Expand Up @@ -35,9 +34,6 @@ interface ServiceOverviewProps {
export function ServiceOverview({ serviceName }: ServiceOverviewProps) {
const { agentName } = useApmServiceContext();

useTrackPageview({ app: 'apm', path: 'service_overview' });
useTrackPageview({ app: 'apm', path: 'service_overview', delay: 15000 });

// The default EuiFlexGroup breaks at 768, but we want to break at 992, so we
// observe the window width and set the flex directions of rows accordingly
const { isMedium } = useBreakPoints();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

import React from 'react';
import { useTrackPageview } from '../../../../../observability/public';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { APIReturnType } from '../../../services/rest/createCallApmApi';
Expand Down Expand Up @@ -43,9 +42,6 @@ export function TraceOverview() {
[environment, kuery, start, end]
);

useTrackPageview({ app: 'apm', path: 'traces_overview' });
useTrackPageview({ app: 'apm', path: 'traces_overview', delay: 15000 });

return (
<>
<SearchBar />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { EuiHorizontalRule, EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import { flatten, isEmpty } from 'lodash';
import React from 'react';
import { useHistory } from 'react-router-dom';
import { useTrackPageview } from '../../../../../observability/public';
import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
Expand Down Expand Up @@ -41,9 +40,6 @@ export function TransactionDetails() {
} = useWaterfallFetcher();
const { transactionName } = urlParams;

useTrackPageview({ app: 'apm', path: 'transaction_details' });
useTrackPageview({ app: 'apm', path: 'transaction_details', delay: 15000 });

const selectedSample = flatten(
distributionData.buckets.map((bucket) => bucket.samples)
).find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { Location } from 'history';
import React from 'react';
import { useLocation } from 'react-router-dom';
import { useTrackPageview } from '../../../../../observability/public';
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
import { IUrlParams } from '../../../context/url_params_context/types';
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
Expand Down Expand Up @@ -62,8 +61,6 @@ export function TransactionOverview({ serviceName }: TransactionOverviewProps) {
// redirect to first transaction type
useRedirect(getRedirectLocation({ location, transactionType, urlParams }));

useTrackPageview({ app: 'apm', path: 'transaction_overview' });
useTrackPageview({ app: 'apm', path: 'transaction_overview', delay: 15000 });
const {
transactionListData,
transactionListStatus,
Expand Down
24 changes: 17 additions & 7 deletions x-pack/plugins/apm/public/components/routing/app_root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,29 @@ import { ApmRoute } from '@elastic/apm-rum-react';
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
import React from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import { Route, RouteComponentProps, Router, Switch } from 'react-router-dom';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { APP_WRAPPER_CLASS } from '../../../../../../src/core/public';
import {
KibanaContextProvider,
RedirectAppLinks,
useUiSetting$,
} from '../../../../../../src/plugins/kibana_react/public';
import { HeaderMenuPortal } from '../../../../observability/public';
import { ScrollToTopOnPathChange } from '../../components/app/Main/ScrollToTopOnPathChange';
import { AnomalyDetectionJobsContextProvider } from '../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import {
ApmPluginContext,
ApmPluginContextValue,
} from '../../context/apm_plugin/apm_plugin_context';
import { useApmPluginContext } from '../../context/apm_plugin/use_apm_plugin_context';
import { LicenseProvider } from '../../context/license/license_context';
import { UrlParamsProvider } from '../../context/url_params_context/url_params_context';
import { useApmBreadcrumbs } from '../../hooks/use_apm_breadcrumbs';
import { ApmPluginStartDeps } from '../../plugin';
import { HeaderMenuPortal } from '../../../../observability/public';
import { ApmHeaderActionMenu } from '../shared/apm_header_action_menu';
import { useApmPluginContext } from '../../context/apm_plugin/use_apm_plugin_context';
import { AnomalyDetectionJobsContextProvider } from '../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import { apmRouteConfig } from './apm_route_config';
import { TelemetryWrapper } from './telemetry_wrapper';

export function ApmAppRoot({
apmPluginContextValue,
Expand Down Expand Up @@ -62,9 +63,18 @@ export function ApmAppRoot({

<Route component={ScrollToTopOnPathChange} />
<Switch>
{apmRouteConfig.map((route, i) => (
<ApmRoute key={i} {...route} />
))}
{apmRouteConfig.map((route, i) => {
const { component, render, ...rest } = route;
return (
<ApmRoute
key={i}
{...rest}
component={(props: RouteComponentProps) => {
return TelemetryWrapper({ route, props });
}}
/>
);
})}
</Switch>
</ApmThemeProvider>
</AnomalyDetectionJobsContextProvider>
Expand Down
33 changes: 33 additions & 0 deletions x-pack/plugins/apm/public/components/routing/telemetry_wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { useTrackPageview } from '../../../../observability/public';
import { APMRouteDefinition } from '../../application/routes';
import { redirectTo } from './redirect_to';

export function TelemetryWrapper({
route,
props,
}: {
route: APMRouteDefinition;
props: RouteComponentProps;
}) {
const { component, render, path } = route;
const pathAsString = path as string;

useTrackPageview({ app: 'apm', path: pathAsString });
useTrackPageview({ app: 'apm', path: pathAsString, delay: 15000 });

if (component) {
return React.createElement(component, props);
}
if (render) {
return <>{render(props)}</>;
}
return <>{redirectTo('/')}</>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
CoreStart,
SavedObjectsClientContract,
} from 'kibana/server';
import { TelemetryUsageCounter } from '../../routes/typings';
import { APMPluginStartDependencies } from '../../types';
import { getInternalSavedObjectsClient } from '../helpers/get_internal_saved_objects_client';
import { Setup } from '../helpers/setup_request';
Expand All @@ -21,11 +22,19 @@ export async function syncAgentConfigsToApmPackagePolicies({
core,
fleetPluginStart,
setup,
telemetryUsageCounter,
}: {
core: { setup: CoreSetup; start: () => Promise<CoreStart> };
fleetPluginStart: NonNullable<APMPluginStartDependencies['fleet']>;
setup: Setup;
telemetryUsageCounter?: TelemetryUsageCounter;
}) {
if (telemetryUsageCounter) {
telemetryUsageCounter.incrementCounter({
counterName: 'sync_agent_config_to_apm_package_policies',
counterType: 'success',
});
}
const coreStart = await core.start();
const esClient = coreStart.elasticsearch.client.asInternalUser;
const [
Expand Down
12 changes: 7 additions & 5 deletions x-pack/plugins/apm/server/routes/register_routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import {
routeValidationObject,
} from '@kbn/server-route-repository';
import { mergeRt, jsonRt } from '@kbn/io-ts-utils';
import { UsageCollectionSetup } from '../../../../../../src/plugins/usage_collection/server';
import { pickKeys } from '../../../common/utils/pick_keys';
import { APMRouteHandlerResources, InspectResponse } from '../typings';
import {
APMRouteHandlerResources,
InspectResponse,
TelemetryUsageCounter,
} from '../typings';
import type { ApmPluginRequestHandlerContext } from '../typings';

const inspectRt = t.exact(
Expand Down Expand Up @@ -56,9 +59,7 @@ export function registerRoutes({
repository: ServerRouteRepository<APMRouteHandlerResources>;
config: APMRouteHandlerResources['config'];
ruleDataClient: APMRouteHandlerResources['ruleDataClient'];
telemetryUsageCounter?: ReturnType<
UsageCollectionSetup['createUsageCounter']
>;
telemetryUsageCounter?: TelemetryUsageCounter;
}) {
const routes = repository.getRoutes();

Expand Down Expand Up @@ -104,6 +105,7 @@ export function registerRoutes({
logger,
core,
plugins,
telemetryUsageCounter,
params: merge(
{
query: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const deleteAgentConfigurationRoute = createApmServerRoute({
}),
handler: async (resources) => {
const setup = await setupRequest(resources);
const { params, logger, core } = resources;
const { params, logger, core, telemetryUsageCounter } = resources;

const { service } = params.body;

Expand All @@ -106,6 +106,7 @@ const deleteAgentConfigurationRoute = createApmServerRoute({
core,
fleetPluginStart: await resources.plugins.fleet.start(),
setup,
telemetryUsageCounter,
});
logger.info(
`Updated Fleet integration policy for APM to remove the deleted agent configuration.`
Expand All @@ -128,7 +129,7 @@ const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
]),
handler: async (resources) => {
const setup = await setupRequest(resources);
const { params, logger, core } = resources;
const { params, logger, core, telemetryUsageCounter } = resources;
const { body, query } = params;

// if the config already exists, it is fetched and updated
Expand Down Expand Up @@ -162,6 +163,7 @@ const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
core,
fleetPluginStart: await resources.plugins.fleet.start(),
setup,
telemetryUsageCounter,
});
logger.info(
`Saved latest agent settings to Fleet integration policy for APM.`
Expand Down
Loading

0 comments on commit ee8c9be

Please sign in to comment.