feat: show rate limit warning in services page when total RPS > 100 (#4266)

* feat: show rate limit warning in services page when total rps > 100

* feat: update message

* feat: rate limit message should be shown only to cloud users on trail

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
Yunus M 2023-12-22 00:51:37 +05:30 committed by GitHub
parent 585d6e2a21
commit 2e0fdbb498
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 105 additions and 18 deletions

View File

@ -0,0 +1,3 @@
{
"rps_over_100": "You are sending data at more than 100 RPS, your ingestion may be rate limited. Please reach out to us via Intercom support."
}

View File

@ -0,0 +1,3 @@
{
"rps_over_100": "You are sending data at more than 100 RPS, your ingestion may be rate limited. Please reach out to us via Intercom support."
}

View File

@ -0,0 +1,2 @@
const MAX_RPS_LIMIT = 100;
export { MAX_RPS_LIMIT };

View File

@ -1,12 +1,20 @@
import { WarningFilled } from '@ant-design/icons';
import { Flex, Typography } from 'antd';
import { ResizeTable } from 'components/ResizeTable';
import { MAX_RPS_LIMIT } from 'constants/global';
import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
import { useGetQueriesRange } from 'hooks/queryBuilder/useGetQueriesRange';
import useLicense from 'hooks/useLicense';
import { useNotifications } from 'hooks/useNotifications';
import { useMemo } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';
import { AppState } from 'store/reducers';
import { ServicesList } from 'types/api/metrics/getService';
import { GlobalReducer } from 'types/reducer/globalTime';
import { isCloudUser } from 'utils/app';
import { getTotalRPS } from 'utils/services';
import { getColumns } from '../Columns/ServiceColumn';
import { ServiceMetricsTableProps } from '../types';
@ -22,6 +30,10 @@ function ServiceMetricTable({
>((state) => state.globalTime);
const { notifications } = useNotifications();
const { t: getText } = useTranslation(['services']);
const { data: licenseData, isFetching } = useLicense();
const isCloudUserVal = isCloudUser();
const queries = useGetQueriesRange(queryRangeRequestData, {
queryKey: [
@ -53,14 +65,38 @@ function ServiceMetricTable({
const { search } = useLocation();
const tableColumns = useMemo(() => getColumns(search, true), [search]);
const [RPS, setRPS] = useState(0);
useEffect(() => {
if (!isFetching && licenseData?.payload?.onTrial && isCloudUserVal) {
if (services.length > 0) {
const rps = getTotalRPS(services);
setRPS(rps);
} else {
setRPS(0);
}
}
}, [services, licenseData, isFetching, isCloudUserVal]);
return (
<>
{RPS > MAX_RPS_LIMIT && (
<Flex justify="center">
<Typography.Title level={5} type="warning" style={{ marginTop: 0 }}>
<WarningFilled /> {getText('rps_over_100')}
</Typography.Title>
</Flex>
)}
<ResourceAttributesFilter />
<ResizeTable
columns={tableColumns}
loading={isLoading}
dataSource={services}
rowKey="serviceName"
/>
</>
);
}

View File

@ -1,6 +1,14 @@
import { WarningFilled } from '@ant-design/icons';
import { Flex, Typography } from 'antd';
import { ResizeTable } from 'components/ResizeTable';
import { useMemo } from 'react';
import { MAX_RPS_LIMIT } from 'constants/global';
import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
import useLicense from 'hooks/useLicense';
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';
import { isCloudUser } from 'utils/app';
import { getTotalRPS } from 'utils/services';
import { getColumns } from '../Columns/ServiceColumn';
import ServiceTableProps from '../types';
@ -10,16 +18,43 @@ function ServiceTraceTable({
loading,
}: ServiceTableProps): JSX.Element {
const { search } = useLocation();
const [RPS, setRPS] = useState(0);
const { t: getText } = useTranslation(['services']);
const { data: licenseData, isFetching } = useLicense();
const isCloudUserVal = isCloudUser();
const tableColumns = useMemo(() => getColumns(search, false), [search]);
useEffect(() => {
if (!isFetching && licenseData?.payload?.onTrial && isCloudUserVal) {
if (services.length > 0) {
const rps = getTotalRPS(services);
setRPS(rps);
} else {
setRPS(0);
}
}
}, [services, licenseData, isFetching, isCloudUserVal]);
return (
<>
{RPS > MAX_RPS_LIMIT && (
<Flex justify="flex-end">
<Typography.Text type="warning" style={{ marginTop: 0 }}>
<WarningFilled /> {getText('rps_over_100')}
</Typography.Text>
</Flex>
)}
<ResourceAttributesFilter />
<ResizeTable
columns={tableColumns}
loading={loading}
dataSource={services}
rowKey="serviceName"
/>
</>
);
}

View File

@ -13,7 +13,7 @@ function Services(): JSX.Element {
return (
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
<Container>
<Container style={{ marginTop: 0 }}>
{isSpanMetricEnabled ? <ServiceMetrics /> : <ServiceTraces />}
</Container>
</ErrorBoundary>

View File

@ -6,9 +6,12 @@ import { extractDomain } from 'utils/app';
const useAnalytics = (): any => {
const { user } = useSelector<AppState, AppReducer>((state) => state.app);
// Segment Page View - analytics.page([category], [name], [properties], [options], [callback]);
const trackPageView = (pageName: string): void => {
if (user && user.email) {
window.analytics.page(pageName);
window.analytics.page(null, pageName, {
userId: user.email,
});
}
};
@ -22,6 +25,9 @@ const useAnalytics = (): any => {
groupId: extractDomain(user?.email),
},
};
const updatedPropertes = { ...properties };
updatedPropertes.userId = user.email;
window.analytics.track(eventName, properties, context);
}
};

View File

@ -1,6 +1,5 @@
import { Space } from 'antd';
import ReleaseNote from 'components/ReleaseNote';
import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
import ServicesApplication from 'container/ServiceApplication';
import { useLocation } from 'react-router-dom';
@ -11,7 +10,6 @@ function Metrics(): JSX.Element {
<Space direction="vertical" style={{ width: '100%' }}>
<ReleaseNote path={location.pathname} />
<ResourceAttributesFilter />
<ServicesApplication />
</Space>
);

View File

@ -0,0 +1,4 @@
import { ServicesList } from 'types/api/metrics/getService';
export const getTotalRPS = (services: ServicesList[]): number =>
services.reduce((accumulator, service) => accumulator + service.callRate, 0);