Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] [APM[Services] Add custom events to new ServiceTabEmptyState (#192385) #193005

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ export function ServiceOverview() {
const hasSignal =
serviceEntitySummary?.dataStreamTypes && serviceEntitySummary?.dataStreamTypes?.length > 0;

const hasLogsSignal = hasSignal && isLogsSignal(serviceEntitySummary.dataStreamTypes);

const hasLogsOnlySignal = hasSignal && isLogsOnlySignal(serviceEntitySummary.dataStreamTypes);

const hasLogsSignal = hasSignal && isLogsSignal(serviceEntitySummary.dataStreamTypes);

// Shows APM overview when entity has APM signal or when Entity centric is not enabled
const hasApmSignal = hasSignal && isApmSignal(serviceEntitySummary.dataStreamTypes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const emptyStateDefinitions: Record<EmptyStateKey, EmptyStateContent> = {
}),
content: i18n.translate('xpack.apm.serviceTabEmptyState.dependenciesContent', {
defaultMessage:
'See your services dependencies on both internal and third-party services by instrumenting with APM.',
"See your service's dependencies on both internal and third-party services by instrumenting with APM.",
}),
imgName: 'service_tab_empty_state_dependencies.png',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

/* eslint-disable @elastic/eui/href-or-on-click */

import {
EuiButton,
EuiButtonIcon,
Expand All @@ -19,6 +22,9 @@ import {
} from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { EmptyStateClickParams, EntityInventoryAddDataParams } from '../../../services/telemetry';
import { ApmPluginStartDeps, ApmServices } from '../../../plugin';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useKibanaUrl } from '../../../hooks/use_kibana_url';
import { AddApmData } from '../../shared/add_data_buttons/buttons';
Expand All @@ -44,9 +50,17 @@ const learnMoreLink = {
};

const baseImgFolder = '/plugins/apm/assets/service_tab_empty_state';
const defaultAddDataTelemetryParams: EntityInventoryAddDataParams = {
view: 'add_apm_cta',
};

const defaultClickTelemetryParams: EmptyStateClickParams = {
view: 'add_apm_cta',
};

export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStateProps) {
const { euiTheme } = useEuiTheme();
const { services } = useKibana<ApmPluginStartDeps & ApmServices>();
const { core } = useApmPluginContext();

const imgFolder = `${baseImgFolder}/${
Expand All @@ -57,6 +71,18 @@ export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStatePro
`${imgFolder}/${imgName ? imgName : 'service_tab_empty_state_overview.png'}`
);

function handleAddAPMClick() {
services.telemetry.reportEntityInventoryAddData(defaultAddDataTelemetryParams);
}

function handleTryItClick() {
services.telemetry.reportTryItClick(defaultClickTelemetryParams);
}

function handleLearnMoreClick() {
services.telemetry.reportLearnMoreClick(defaultClickTelemetryParams);
}

return (
<>
<EuiPanel color="subdued" paddingSize="xl" style={{ position: 'relative' }}>
Expand All @@ -70,14 +96,20 @@ export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStatePro
<EuiSpacer size="m" />
<EuiFlexGroup alignItems="center" gutterSize="m">
<EuiFlexItem grow={false}>
<AddApmData data-test-subj="ServiceTabEmptyStateAddApmButton" size="m" fill />
<AddApmData
data-test-subj="ServiceTabEmptyStateAddApmButton"
size="m"
fill
onClick={handleAddAPMClick}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
data-test-subj="ServiceTabEmptyStateTryItNowButton"
iconType="launch"
iconSide="right"
href={tryItNowButton.href}
onClick={handleTryItClick}
target="_blank"
>
{tryItNowButton.label}
Expand All @@ -86,6 +118,7 @@ export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStatePro
<EuiFlexItem grow={false}>
<EuiLink
href={learnMoreLink.href}
onClick={handleLearnMoreClick}
target="_blank"
data-test-subj="ServiceTabEmptyStateLearnMoreButton"
external
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
TelemetryEventTypes,
EntityInventoryPageStateParams,
EntityInventoryAddDataParams,
EmptyStateClickParams,
} from './types';

export class TelemetryClient implements ITelemetryClient {
Expand Down Expand Up @@ -41,4 +42,12 @@ export class TelemetryClient implements ITelemetryClient {
public reportEntityInventoryAddData = (params: EntityInventoryAddDataParams) => {
this.analytics.reportEvent(TelemetryEventTypes.ENTITY_INVENTORY_ADD_DATA, params);
};

public reportTryItClick = (params: EmptyStateClickParams) => {
this.analytics.reportEvent(TelemetryEventTypes.TRY_IT_CLICK, params);
};

public reportLearnMoreClick = (params: EmptyStateClickParams) => {
this.analytics.reportEvent(TelemetryEventTypes.LEARN_MORE_CLICK, params);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,37 @@ const entityInventoryAddDataEventType: TelemetryEvent = {
},
};

const tryItClickEventType: TelemetryEvent = {
eventType: TelemetryEventTypes.TRY_IT_CLICK,
schema: {
view: {
type: 'keyword',
_meta: {
description:
'Where the action was initiated (empty_state or add_data_button or add_apm_cta)',
},
},
},
};

const learnMoreClickEventType: TelemetryEvent = {
eventType: TelemetryEventTypes.LEARN_MORE_CLICK,
schema: {
view: {
type: 'keyword',
_meta: {
description:
'Where the action was initiated (empty_state or add_data_button or add_apm_cta)',
},
},
},
};

export const apmTelemetryEventBasedTypes = [
searchQuerySubmittedEventType,
entityExperienceStatusEventType,
entityInventoryPageStateEventType,
entityInventoryAddDataEventType,
tryItClickEventType,
learnMoreClickEventType,
];
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,33 @@ export interface EntityInventoryAddDataParams {
journey?: 'add_apm_agent' | 'associate_existing_service_logs' | 'collect_new_service_logs';
}

export interface EmptyStateClickParams {
view: Extract<EntityInventoryAddDataParams['view'], 'add_apm_cta'>;
}

export type TelemetryEventParams =
| SearchQuerySubmittedParams
| EntityExperienceStatusParams
| EntityInventoryPageStateParams
| EntityInventoryAddDataParams;
| EntityInventoryAddDataParams
| EmptyStateClickParams;

export interface ITelemetryClient {
reportSearchQuerySubmitted(params: SearchQuerySubmittedParams): void;
reportEntityExperienceStatusChange(params: EntityExperienceStatusParams): void;
reportEntityInventoryPageState(params: EntityInventoryPageStateParams): void;
reportEntityInventoryAddData(params: EntityInventoryAddDataParams): void;
reportTryItClick(params: EmptyStateClickParams): void;
reportLearnMoreClick(params: EmptyStateClickParams): void;
}

export enum TelemetryEventTypes {
SEARCH_QUERY_SUBMITTED = 'Search Query Submitted',
ENTITY_EXPERIENCE_STATUS = 'entity_experience_status',
ENTITY_INVENTORY_PAGE_STATE = 'entity_inventory_page_state',
ENTITY_INVENTORY_ADD_DATA = 'entity_inventory_add_data',
TRY_IT_CLICK = 'try_it_click',
LEARN_MORE_CLICK = 'learn_more_click',
}

export interface TelemetryEvent {
Expand Down