mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 05:55:59 +08:00
chore: aws integration UI events (#7172)
* chore: add constants for AWS Integration UI event names * chore: log event for account viewed and account connection attempt started * chore: log telemetry event on successful account connection * chore: log telemetry event when an account connection attempt times out * chore: log telemetry event on redirecting to AWS for account connection * chore: log telemetry event on opening account settings * chore: log telemetry event on saving account settings * chore: log telemetry event on removing account * chore: log telemetry event on viewing details of a service * chore: log telemetry event on opening service settings * chore: log telemetry event on saving service settings * chore: some cleanup * chore: address PR comment * chore: minor cleanup
This commit is contained in:
parent
ae73033826
commit
a3bc290500
@ -3,6 +3,7 @@ import './AccountActions.style.scss';
|
|||||||
import { Color } from '@signozhq/design-tokens';
|
import { Color } from '@signozhq/design-tokens';
|
||||||
import { Button, Select, Skeleton } from 'antd';
|
import { Button, Select, Skeleton } from 'antd';
|
||||||
import { SelectProps } from 'antd/lib';
|
import { SelectProps } from 'antd/lib';
|
||||||
|
import logEvent from 'api/common/logEvent';
|
||||||
import { useAwsAccounts } from 'hooks/integration/aws/useAwsAccounts';
|
import { useAwsAccounts } from 'hooks/integration/aws/useAwsAccounts';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { Check, ChevronDown } from 'lucide-react';
|
import { Check, ChevronDown } from 'lucide-react';
|
||||||
@ -167,9 +168,31 @@ function AccountActions(): JSX.Element {
|
|||||||
}, [initialAccount]);
|
}, [initialAccount]);
|
||||||
|
|
||||||
const [isIntegrationModalOpen, setIsIntegrationModalOpen] = useState(false);
|
const [isIntegrationModalOpen, setIsIntegrationModalOpen] = useState(false);
|
||||||
|
const startAccountConnectionAttempt = (): void => {
|
||||||
|
setIsIntegrationModalOpen(true);
|
||||||
|
logEvent('AWS Integration: Account connection attempt started', {});
|
||||||
|
};
|
||||||
|
|
||||||
const [isAccountSettingsModalOpen, setIsAccountSettingsModalOpen] = useState(
|
const [isAccountSettingsModalOpen, setIsAccountSettingsModalOpen] = useState(
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
const openAccountSettings = (): void => {
|
||||||
|
setIsAccountSettingsModalOpen(true);
|
||||||
|
logEvent('AWS Integration: Account settings viewed', {
|
||||||
|
cloudAccountId: activeAccount?.cloud_account_id,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// log telemetry event when an account is viewed.
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeAccount) {
|
||||||
|
logEvent('AWS Integration: Account viewed', {
|
||||||
|
cloudAccountId: activeAccount?.cloud_account_id,
|
||||||
|
status: activeAccount?.status,
|
||||||
|
enabledRegions: activeAccount?.config?.regions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [activeAccount]);
|
||||||
|
|
||||||
const selectOptions: SelectProps['options'] = useMemo(
|
const selectOptions: SelectProps['options'] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -196,8 +219,8 @@ function AccountActions(): JSX.Element {
|
|||||||
navigate({ search: urlQuery.toString() });
|
navigate({ search: urlQuery.toString() });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onIntegrationModalOpen={(): void => setIsIntegrationModalOpen(true)}
|
onIntegrationModalOpen={startAccountConnectionAttempt}
|
||||||
onAccountSettingsModalOpen={(): void => setIsAccountSettingsModalOpen(true)}
|
onAccountSettingsModalOpen={openAccountSettings}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isIntegrationModalOpen && (
|
{isIntegrationModalOpen && (
|
||||||
|
@ -12,6 +12,7 @@ import history from 'lib/history';
|
|||||||
import { Dispatch, SetStateAction, useCallback } from 'react';
|
import { Dispatch, SetStateAction, useCallback } from 'react';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
|
|
||||||
|
import logEvent from '../../../../api/common/logEvent';
|
||||||
import { CloudAccount } from '../../ServicesSection/types';
|
import { CloudAccount } from '../../ServicesSection/types';
|
||||||
import { RegionSelector } from './RegionSelector';
|
import { RegionSelector } from './RegionSelector';
|
||||||
import RemoveIntegrationAccount from './RemoveIntegrationAccount';
|
import RemoveIntegrationAccount from './RemoveIntegrationAccount';
|
||||||
@ -50,6 +51,11 @@ function AccountSettingsModal({
|
|||||||
urlQuery.delete('cloudAccountId');
|
urlQuery.delete('cloudAccountId');
|
||||||
handleClose();
|
handleClose();
|
||||||
history.replace({ search: urlQuery.toString() });
|
history.replace({ search: urlQuery.toString() });
|
||||||
|
|
||||||
|
logEvent('AWS Integration: Account removed', {
|
||||||
|
id: account?.id,
|
||||||
|
cloudAccountId: account?.cloud_account_id,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderRegionSelector = useCallback(() => {
|
const renderRegionSelector = useCallback(() => {
|
||||||
|
@ -106,7 +106,7 @@ function CloudAccountSetupModal({
|
|||||||
// Handle success state first
|
// Handle success state first
|
||||||
if (modalState === ModalStateEnum.SUCCESS) {
|
if (modalState === ModalStateEnum.SUCCESS) {
|
||||||
return {
|
return {
|
||||||
title: 'AWS Webservice Integration',
|
title: 'AWS Integration',
|
||||||
okText: (
|
okText: (
|
||||||
<div className="cloud-account-setup-success-view__footer-button">
|
<div className="cloud-account-setup-success-view__footer-button">
|
||||||
Continue
|
Continue
|
||||||
|
@ -5,6 +5,7 @@ import { useRef } from 'react';
|
|||||||
import { AccountStatusResponse } from 'types/api/integrations/aws';
|
import { AccountStatusResponse } from 'types/api/integrations/aws';
|
||||||
import { regions } from 'utils/regions';
|
import { regions } from 'utils/regions';
|
||||||
|
|
||||||
|
import logEvent from '../../../../api/common/logEvent';
|
||||||
import { ModalStateEnum, RegionFormProps } from '../types';
|
import { ModalStateEnum, RegionFormProps } from '../types';
|
||||||
import AlertMessage from './AlertMessage';
|
import AlertMessage from './AlertMessage';
|
||||||
import {
|
import {
|
||||||
@ -41,7 +42,7 @@ export function RegionForm({
|
|||||||
}: RegionFormProps): JSX.Element {
|
}: RegionFormProps): JSX.Element {
|
||||||
const startTimeRef = useRef(Date.now());
|
const startTimeRef = useRef(Date.now());
|
||||||
const refetchInterval = 10 * 1000;
|
const refetchInterval = 10 * 1000;
|
||||||
const errorTimeout = 5 * 60 * 1000;
|
const errorTimeout = 10 * 60 * 1000;
|
||||||
|
|
||||||
const { isLoading: isAccountStatusLoading } = useAccountStatus(accountId, {
|
const { isLoading: isAccountStatusLoading } = useAccountStatus(accountId, {
|
||||||
refetchInterval,
|
refetchInterval,
|
||||||
@ -49,9 +50,15 @@ export function RegionForm({
|
|||||||
onSuccess: (data: AccountStatusResponse) => {
|
onSuccess: (data: AccountStatusResponse) => {
|
||||||
if (data.data.status.integration.last_heartbeat_ts_ms !== null) {
|
if (data.data.status.integration.last_heartbeat_ts_ms !== null) {
|
||||||
setModalState(ModalStateEnum.SUCCESS);
|
setModalState(ModalStateEnum.SUCCESS);
|
||||||
|
logEvent('AWS Integration: Account connected', {
|
||||||
|
cloudAccountId: data?.data?.cloud_account_id,
|
||||||
|
status: data?.data?.status,
|
||||||
|
});
|
||||||
} else if (Date.now() - startTimeRef.current >= errorTimeout) {
|
} else if (Date.now() - startTimeRef.current >= errorTimeout) {
|
||||||
// 5 minutes in milliseconds
|
|
||||||
setModalState(ModalStateEnum.ERROR);
|
setModalState(ModalStateEnum.ERROR);
|
||||||
|
logEvent('AWS Integration: Account connection attempt timed out', {
|
||||||
|
id: accountId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
|
@ -11,6 +11,8 @@ import { useUpdateServiceConfig } from 'hooks/integration/aws/useUpdateServiceCo
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useQueryClient } from 'react-query';
|
import { useQueryClient } from 'react-query';
|
||||||
|
|
||||||
|
import logEvent from '../../../api/common/logEvent';
|
||||||
|
|
||||||
interface IConfigureServiceModalProps {
|
interface IConfigureServiceModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@ -82,6 +84,13 @@ function ConfigureServiceModal({
|
|||||||
serviceId,
|
serviceId,
|
||||||
]);
|
]);
|
||||||
onClose();
|
onClose();
|
||||||
|
|
||||||
|
logEvent('AWS Integration: Service settings saved', {
|
||||||
|
cloudAccountId,
|
||||||
|
serviceId,
|
||||||
|
logsEnabled: values?.logs,
|
||||||
|
metricsEnabled: values?.metrics,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error('Failed to update service config:', error);
|
console.error('Failed to update service config:', error);
|
||||||
|
@ -7,8 +7,9 @@ import { IServiceStatus } from 'container/CloudIntegrationPage/ServicesSection/t
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useServiceDetails } from 'hooks/integration/aws/useServiceDetails';
|
import { useServiceDetails } from 'hooks/integration/aws/useServiceDetails';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
import { useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import logEvent from '../../../api/common/logEvent';
|
||||||
import ConfigureServiceModal from './ConfigureServiceModal';
|
import ConfigureServiceModal from './ConfigureServiceModal';
|
||||||
|
|
||||||
const getStatus = (
|
const getStatus = (
|
||||||
@ -57,6 +58,13 @@ function ServiceDetails(): JSX.Element | null {
|
|||||||
const [isConfigureServiceModalOpen, setIsConfigureServiceModalOpen] = useState(
|
const [isConfigureServiceModalOpen, setIsConfigureServiceModalOpen] = useState(
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
const openServiceConfigModal = (): void => {
|
||||||
|
setIsConfigureServiceModalOpen(true);
|
||||||
|
logEvent('AWS Integration: Service settings viewed', {
|
||||||
|
cloudAccountId,
|
||||||
|
serviceId,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const { data: serviceDetailsData, isLoading } = useServiceDetails(
|
const { data: serviceDetailsData, isLoading } = useServiceDetails(
|
||||||
serviceId || '',
|
serviceId || '',
|
||||||
@ -80,6 +88,16 @@ function ServiceDetails(): JSX.Element | null {
|
|||||||
[config],
|
[config],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// log telemetry event on visiting details of a service.
|
||||||
|
useEffect(() => {
|
||||||
|
if (serviceId) {
|
||||||
|
logEvent('AWS Integration: Service viewed', {
|
||||||
|
cloudAccountId,
|
||||||
|
serviceId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [cloudAccountId, serviceId]);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <Spinner size="large" height="50vh" />;
|
return <Spinner size="large" height="50vh" />;
|
||||||
}
|
}
|
||||||
@ -119,7 +137,7 @@ function ServiceDetails(): JSX.Element | null {
|
|||||||
(isAnySignalConfigured ? (
|
(isAnySignalConfigured ? (
|
||||||
<Button
|
<Button
|
||||||
className="configure-button configure-button--default"
|
className="configure-button configure-button--default"
|
||||||
onClick={(): void => setIsConfigureServiceModalOpen(true)}
|
onClick={openServiceConfigModal}
|
||||||
>
|
>
|
||||||
Configure ({enabledSignals}/{totalSupportedSignals})
|
Configure ({enabledSignals}/{totalSupportedSignals})
|
||||||
</Button>
|
</Button>
|
||||||
@ -127,7 +145,7 @@ function ServiceDetails(): JSX.Element | null {
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
className="configure-button configure-button--primary"
|
className="configure-button configure-button--primary"
|
||||||
onClick={(): void => setIsConfigureServiceModalOpen(true)}
|
onClick={openServiceConfigModal}
|
||||||
>
|
>
|
||||||
Enable Service
|
Enable Service
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -14,6 +14,8 @@ import {
|
|||||||
import { AccountConfigPayload } from 'types/api/integrations/aws';
|
import { AccountConfigPayload } from 'types/api/integrations/aws';
|
||||||
import { regions } from 'utils/regions';
|
import { regions } from 'utils/regions';
|
||||||
|
|
||||||
|
import logEvent from '../../../api/common/logEvent';
|
||||||
|
|
||||||
interface UseAccountSettingsModalProps {
|
interface UseAccountSettingsModalProps {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
account: CloudAccount;
|
account: CloudAccount;
|
||||||
@ -84,8 +86,14 @@ export function useAccountSettingsModal({
|
|||||||
{ accountId: account?.id, payload },
|
{ accountId: account?.id, payload },
|
||||||
{
|
{
|
||||||
onSuccess: (response) => {
|
onSuccess: (response) => {
|
||||||
setActiveAccount(response.data);
|
const newActiveAccount = response?.data;
|
||||||
|
setActiveAccount(newActiveAccount);
|
||||||
onClose();
|
onClose();
|
||||||
|
|
||||||
|
logEvent('AWS Integration: Account settings Updated', {
|
||||||
|
cloudAccountId: newActiveAccount?.cloud_account_id,
|
||||||
|
enabledRegions: newActiveAccount?.config?.regions,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
} from 'types/api/integrations/aws';
|
} from 'types/api/integrations/aws';
|
||||||
import { regions } from 'utils/regions';
|
import { regions } from 'utils/regions';
|
||||||
|
|
||||||
|
import logEvent from '../../../api/common/logEvent';
|
||||||
import { useConnectionParams } from './useConnectionParams';
|
import { useConnectionParams } from './useConnectionParams';
|
||||||
import { useGenerateConnectionUrl } from './useGenerateConnectionUrl';
|
import { useGenerateConnectionUrl } from './useGenerateConnectionUrl';
|
||||||
|
|
||||||
@ -117,6 +118,9 @@ export function useIntegrationModal({
|
|||||||
(payload: GenerateConnectionUrlPayload): void => {
|
(payload: GenerateConnectionUrlPayload): void => {
|
||||||
generateUrl(payload, {
|
generateUrl(payload, {
|
||||||
onSuccess: (data: ConnectionUrlResponse) => {
|
onSuccess: (data: ConnectionUrlResponse) => {
|
||||||
|
logEvent('AWS Integration: Account connection attempt redirected to AWS', {
|
||||||
|
id: data.account_id,
|
||||||
|
});
|
||||||
window.open(data.connection_url, '_blank');
|
window.open(data.connection_url, '_blank');
|
||||||
setModalState(ModalStateEnum.WAITING);
|
setModalState(ModalStateEnum.WAITING);
|
||||||
setAccountId(data.account_id);
|
setAccountId(data.account_id);
|
||||||
|
@ -26,6 +26,7 @@ export interface AccountStatusResponse {
|
|||||||
status: 'success';
|
status: 'success';
|
||||||
data: {
|
data: {
|
||||||
id: string;
|
id: string;
|
||||||
|
cloud_account_id: string;
|
||||||
status: {
|
status: {
|
||||||
integration: {
|
integration: {
|
||||||
last_heartbeat_ts_ms: number | null;
|
last_heartbeat_ts_ms: number | null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user