mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[APM] Add storage summary stats to report (#163309)
Closes https://github.com/elastic/kibana/issues/160013
This commit is contained in:
parent
f4e62c1c74
commit
863ea15bde
3 changed files with 91 additions and 42 deletions
|
@ -19,18 +19,26 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
|
||||
import { IndexLifecyclePhaseSelect } from './index_lifecycle_phase_select';
|
||||
import { ServicesTable } from './services_table';
|
||||
import { SearchBar } from '../../shared/search_bar/search_bar';
|
||||
import { StorageChart } from './storage_chart';
|
||||
import { PermissionDenied } from './prompts/permission_denied';
|
||||
import { useFetcher, FETCH_STATUS } from '../../../hooks/use_fetcher';
|
||||
import {
|
||||
useFetcher,
|
||||
FETCH_STATUS,
|
||||
isPending,
|
||||
} from '../../../hooks/use_fetcher';
|
||||
import { SummaryStats } from './summary_stats';
|
||||
import { ApmEnvironmentFilter } from '../../shared/environment_filter';
|
||||
import { TipsAndResources } from './resources/tips_and_resources';
|
||||
import { useLocalStorage } from '../../../hooks/use_local_storage';
|
||||
import { getKibanaAdvancedSettingsHref } from './get_storage_explorer_links';
|
||||
import { useProgressiveFetcher } from '../../../hooks/use_progressive_fetcher';
|
||||
import { useApmParams } from '../../../hooks/use_apm_params';
|
||||
import { useTimeRange } from '../../../hooks/use_time_range';
|
||||
|
||||
type CalloutType = 'crossClusterSearch' | 'optimizePerformance';
|
||||
|
||||
|
@ -48,6 +56,11 @@ const dismissButtonText = i18n.translate(
|
|||
|
||||
export function StorageExplorer() {
|
||||
const { core } = useApmPluginContext();
|
||||
const {
|
||||
query: { rangeFrom, rangeTo, environment, kuery, indexLifecyclePhase },
|
||||
} = useApmParams('/storage-explorer');
|
||||
|
||||
const { start, end } = useTimeRange({ rangeFrom, rangeTo });
|
||||
|
||||
const [calloutDismissed, setCalloutDismissed] = useLocalStorage(
|
||||
'apm.storageExplorer.calloutDismissed',
|
||||
|
@ -72,6 +85,28 @@ export function StorageExplorer() {
|
|||
[calloutDismissed]
|
||||
);
|
||||
|
||||
const { data: summaryStatsData, status: summaryStatsStatus } =
|
||||
useProgressiveFetcher(
|
||||
(callApmApi) => {
|
||||
return callApmApi('GET /internal/apm/storage_explorer_summary_stats', {
|
||||
params: {
|
||||
query: {
|
||||
indexLifecyclePhase,
|
||||
environment,
|
||||
kuery,
|
||||
start,
|
||||
end,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
[indexLifecyclePhase, environment, kuery, start, end]
|
||||
);
|
||||
|
||||
const loadingSummaryStats = isPending(summaryStatsStatus);
|
||||
|
||||
const hasSummaryStatsData = !isEmpty(summaryStatsData);
|
||||
|
||||
const loading = hasPrivilegesStatus === FETCH_STATUS.LOADING;
|
||||
|
||||
if (loading) {
|
||||
|
@ -190,12 +225,19 @@ export function StorageExplorer() {
|
|||
)}
|
||||
|
||||
<EuiSpacer />
|
||||
<SummaryStats />
|
||||
<SummaryStats
|
||||
data={summaryStatsData}
|
||||
loading={loadingSummaryStats}
|
||||
hasData={hasSummaryStatsData}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
<EuiPanel hasShadow={false} hasBorder={true}>
|
||||
<StorageChart />
|
||||
<EuiSpacer />
|
||||
<ServicesTable />
|
||||
<ServicesTable
|
||||
summaryStatsData={summaryStatsData}
|
||||
loadingSummaryStats={loadingSummaryStats}
|
||||
/>
|
||||
</EuiPanel>
|
||||
<EuiSpacer />
|
||||
<TipsAndResources />
|
||||
|
|
|
@ -28,7 +28,10 @@ import { isEmpty } from 'lodash';
|
|||
import { downloadJson } from '../../../../utils/download_json';
|
||||
import { AgentName } from '../../../../../typings/es_schemas/ui/fields/agent';
|
||||
import { EnvironmentBadge } from '../../../shared/environment_badge';
|
||||
import { asPercent } from '../../../../../common/utils/formatters';
|
||||
import {
|
||||
asPercent,
|
||||
asTransactionRate,
|
||||
} from '../../../../../common/utils/formatters';
|
||||
import { ServiceLink } from '../../../shared/links/apm/service_link';
|
||||
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
|
||||
import { StorageDetailsPerService } from './storage_details_per_service';
|
||||
|
@ -42,6 +45,7 @@ import { useProgressiveFetcher } from '../../../../hooks/use_progressive_fetcher
|
|||
import { useTimeRange } from '../../../../hooks/use_time_range';
|
||||
import { SizeLabel } from './size_label';
|
||||
import { joinByKey } from '../../../../../common/utils/join_by_key';
|
||||
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
|
||||
|
||||
interface StorageExplorerItem {
|
||||
serviceName: string;
|
||||
|
@ -57,8 +61,15 @@ enum StorageExplorerFieldName {
|
|||
Sampling = 'sampling',
|
||||
Size = 'size',
|
||||
}
|
||||
interface Props {
|
||||
summaryStatsData?: APIReturnType<'GET /internal/apm/storage_explorer_summary_stats'>;
|
||||
loadingSummaryStats: boolean;
|
||||
}
|
||||
|
||||
export function ServicesTable() {
|
||||
export function ServicesTable({
|
||||
summaryStatsData,
|
||||
loadingSummaryStats,
|
||||
}: Props) {
|
||||
const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<
|
||||
Record<string, ReactNode>
|
||||
>({});
|
||||
|
@ -283,6 +294,9 @@ export function ServicesTable() {
|
|||
},
|
||||
];
|
||||
|
||||
const isDownloadButtonDisable =
|
||||
isEmpty(serviceStatisticsItems) || loadingSummaryStats;
|
||||
|
||||
return (
|
||||
<EuiPanel
|
||||
hasShadow={false}
|
||||
|
@ -295,7 +309,7 @@ export function ServicesTable() {
|
|||
<EuiButton
|
||||
data-test-subj="StorageExplorerDownloadReportButton"
|
||||
iconType="download"
|
||||
isDisabled={isEmpty(serviceStatisticsItems)}
|
||||
isDisabled={isDownloadButtonDisable}
|
||||
onClick={() =>
|
||||
downloadJson({
|
||||
fileName: `storage-explorefpr-${moment(Date.now()).format(
|
||||
|
@ -309,6 +323,25 @@ export function ServicesTable() {
|
|||
kuery,
|
||||
indexLifecyclePhase,
|
||||
},
|
||||
summary: {
|
||||
totalSize: asDynamicBytes(summaryStatsData?.totalSize),
|
||||
diskSpaceUsedPct: asPercent(
|
||||
summaryStatsData?.diskSpaceUsedPct,
|
||||
1
|
||||
),
|
||||
estimatedIncrementalSize: asDynamicBytes(
|
||||
summaryStatsData?.estimatedIncrementalSize
|
||||
),
|
||||
dailyDataGeneration: asDynamicBytes(
|
||||
summaryStatsData?.dailyDataGeneration
|
||||
),
|
||||
tracesPerMinute: asTransactionRate(
|
||||
summaryStatsData?.tracesPerMinute
|
||||
),
|
||||
numberOfServices: (
|
||||
summaryStatsData?.numberOfServices ?? 0
|
||||
).toString(),
|
||||
},
|
||||
services: serviceStatisticsItems.map((item) => ({
|
||||
...item,
|
||||
sampling: asPercent(item?.sampling, 1),
|
||||
|
|
|
@ -22,34 +22,29 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { useProgressiveFetcher } from '../../../hooks/use_progressive_fetcher';
|
||||
import { useTimeRange } from '../../../hooks/use_time_range';
|
||||
import { useApmParams } from '../../../hooks/use_apm_params';
|
||||
import { asDynamicBytes, asPercent } from '../../../../common/utils/formatters';
|
||||
import { useApmRouter } from '../../../hooks/use_apm_router';
|
||||
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
|
||||
import { isPending } from '../../../hooks/use_fetcher';
|
||||
|
||||
import { asTransactionRate } from '../../../../common/utils/formatters';
|
||||
import { getIndexManagementHref } from './get_storage_explorer_links';
|
||||
import { APIReturnType } from '../../../services/rest/create_call_apm_api';
|
||||
|
||||
export function SummaryStats() {
|
||||
interface Props {
|
||||
data?: APIReturnType<'GET /internal/apm/storage_explorer_summary_stats'>;
|
||||
loading: boolean;
|
||||
hasData: boolean;
|
||||
}
|
||||
|
||||
export function SummaryStats({ data, loading, hasData }: Props) {
|
||||
const router = useApmRouter();
|
||||
const { core } = useApmPluginContext();
|
||||
|
||||
const {
|
||||
query: {
|
||||
rangeFrom,
|
||||
rangeTo,
|
||||
environment,
|
||||
kuery,
|
||||
indexLifecyclePhase,
|
||||
comparisonEnabled,
|
||||
},
|
||||
query: { rangeFrom, rangeTo, environment, kuery, comparisonEnabled },
|
||||
} = useApmParams('/storage-explorer');
|
||||
|
||||
const { start, end } = useTimeRange({ rangeFrom, rangeTo });
|
||||
|
||||
const serviceInventoryLink = router.link('/services', {
|
||||
query: {
|
||||
rangeFrom,
|
||||
|
@ -61,27 +56,6 @@ export function SummaryStats() {
|
|||
},
|
||||
});
|
||||
|
||||
const { data, status } = useProgressiveFetcher(
|
||||
(callApmApi) => {
|
||||
return callApmApi('GET /internal/apm/storage_explorer_summary_stats', {
|
||||
params: {
|
||||
query: {
|
||||
indexLifecyclePhase,
|
||||
environment,
|
||||
kuery,
|
||||
start,
|
||||
end,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
[indexLifecyclePhase, environment, kuery, start, end]
|
||||
);
|
||||
|
||||
const loading = isPending(status);
|
||||
|
||||
const hasData = !isEmpty(data);
|
||||
|
||||
return (
|
||||
<EuiPanel
|
||||
hasBorder={true}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue