Skip to content

Commit

Permalink
[Profiling] Enhancing the diff topN functions (elastic#173397)
Browse files Browse the repository at this point in the history
- Removes Co2/Cost settings to use Kibana calculations instead of the
values from the APIs
- Refactoring Frame information flyout
<img width="1314" alt="Screenshot 2023-12-14 at 15 25 47"
src="https://github.com/elastic/kibana/assets/55978943/b14a860b-433c-4195-b9e7-d008538f0526">

## How to test it:
- Open Flamegraph or Diff Flamegraph and click on `Show more
information` in the Tooltip.
- Open Functions or Diff Functions and click on the icon on the left
side of the table.
  • Loading branch information
cauemarcondes authored Dec 21, 2023
1 parent 42353e7 commit b62f3b7
Show file tree
Hide file tree
Showing 25 changed files with 720 additions and 693 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -601,10 +601,6 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'observability:profilingUseLegacyCo2Calculation': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'observability:profilingCostPervCPUPerHour': {
type: 'integer',
_meta: { description: 'Non-default value of setting.' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ export interface UsageStats {
'observability:profilingPervCPUWattArm64': number;
'observability:profilingCo2PerKWH': number;
'observability:profilingDatacenterPUE': number;
'observability:profilingUseLegacyCo2Calculation': boolean;
'observability:profilingCostPervCPUPerHour': number;
'observability:profilingAWSCostDiscountRate': number;
}
6 changes: 0 additions & 6 deletions src/plugins/telemetry/schema/oss_plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -10091,12 +10091,6 @@
"description": "Non-default value of setting."
}
},
"observability:profilingUseLegacyCo2Calculation": {
"type": "boolean",
"_meta": {
"description": "Non-default value of setting."
}
},
"observability:profilingCostPervCPUPerHour": {
"type": "integer",
"_meta": {
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/observability/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export {
profilingCo2PerKWH,
profilingDatacenterPUE,
profilingPervCPUWattX86,
profilingUseLegacyCo2Calculation,
profilingPervCPUWattArm64,
profilingAWSCostDiscountRate,
profilingCostPervCPUPerHour,
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/observability/common/ui_settings_keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@ export const profilingPervCPUWattX86 = 'observability:profilingPerVCPUWattX86';
export const profilingPervCPUWattArm64 = 'observability:profilingPervCPUWattArm64';
export const profilingCo2PerKWH = 'observability:profilingCo2PerKWH';
export const profilingDatacenterPUE = 'observability:profilingDatacenterPUE';
export const profilingUseLegacyCo2Calculation = 'observability:profilingUseLegacyCo2Calculation';
export const profilingAWSCostDiscountRate = 'observability:profilingAWSCostDiscountRate';
export const profilingCostPervCPUPerHour = 'observability:profilingCostPervCPUPerHour';
9 changes: 0 additions & 9 deletions x-pack/plugins/observability/server/ui_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
profilingCo2PerKWH,
profilingDatacenterPUE,
profilingPervCPUWattX86,
profilingUseLegacyCo2Calculation,
profilingPervCPUWattArm64,
profilingAWSCostDiscountRate,
profilingCostPervCPUPerHour,
Expand Down Expand Up @@ -479,14 +478,6 @@ export const uiSettings: Record<string, UiSettings> = {
schema: schema.number({ min: 0 }),
requiresPageReload: true,
},
[profilingUseLegacyCo2Calculation]: {
category: [observabilityFeatureId],
name: i18n.translate('xpack.observability.profilingUseLegacyCo2Calculation', {
defaultMessage: 'Use legacy CO2 and Dollar cost calculations in Universal Profiling',
}),
value: false,
schema: schema.boolean(),
},
[profilingAWSCostDiscountRate]: {
category: [observabilityFeatureId],
name: i18n.translate('xpack.observability.profilingAWSCostDiscountRateUiSettingName', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,8 @@ describe('Functions page', () => {
cy.get(firstRowSelector).eq(2).contains('/');
});

// skipping this for now until the values are passed to the ES plugin
describe.skip('Test changing CO2 settings', () => {
afterEach(() => {
describe('Test changing CO2 settings', () => {
after(() => {
cy.updateAdvancedSettings({
[profilingCo2PerKWH]: 0.000379069,
[profilingDatacenterPUE]: 1.7,
Expand All @@ -190,7 +189,7 @@ describe('Functions page', () => {
const firstRowSelector = '[data-grid-row-index="0"] [data-test-subj="dataGridRowCell"]';
cy.get(firstRowSelector).eq(1).contains('1');
cy.get(firstRowSelector).eq(2).contains('vmlinux');
cy.get(firstRowSelector).eq(5).contains('1.84 lbs / 0.84 kg');
cy.get(firstRowSelector).eq(5).contains('4.07 lbs / 1.84 kg');
cy.contains('Settings').click();
cy.contains('Advanced Settings');
cy.get(`[data-test-subj="advancedSetting-editField-${profilingCo2PerKWH}"]`)
Expand All @@ -209,22 +208,22 @@ describe('Functions page', () => {
});
cy.go('back');
cy.wait('@getTopNFunctions');
cy.get(firstRowSelector).eq(5).contains('24.22k lbs / 10.99k');
cy.get(firstRowSelector).eq(5).contains('1.87k lbs / 847.83 kg');
const firstRowSelectorActionButton =
'[data-grid-row-index="0"] [data-test-subj="dataGridRowCell"] .euiButtonIcon';
cy.get(firstRowSelectorActionButton).click();
[
{ parentKey: 'impactEstimates', key: 'co2Emission', value: '0.02 lbs / 0.01 kg' },
{ parentKey: 'impactEstimates', key: 'selfCo2Emission', value: '0.02 lbs / 0.01 kg' },
{ parentKey: 'impactEstimates', key: 'co2Emission', value: '~0.00 lbs / ~0.00 kg' },
{ parentKey: 'impactEstimates', key: 'selfCo2Emission', value: '~0.00 lbs / ~0.00 kg' },
{
parentKey: 'impactEstimates',
key: 'annualizedCo2Emission',
value: '24.22k lbs / 10.99k kg',
value: '1.87k lbs / 847.83 kg',
},
{
parentKey: 'impactEstimates',
key: 'annualizedSelfCo2Emission',
value: '24.22k lbs / 10.99k kg',
value: '1.87k lbs / 847.83 kg',
},
].forEach(({ parentKey, key, value }) => {
cy.get(`[data-test-subj="${parentKey}_${key}"]`).contains(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
*/

import {
EuiButtonIcon,
EuiDataGrid,
EuiDataGridCellValueElementProps,
EuiDataGridColumn,
EuiDataGridSorting,
EuiScreenReaderOnly,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
Expand All @@ -24,8 +26,14 @@ import {
import { orderBy } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates';
import { FrameInformationTooltip } from '../frame_information_window/frame_information_tooltip';
import { FunctionRow } from '../topn_functions/function_row';
import { getFunctionsRows, IFunctionRow } from '../topn_functions/utils';
import {
convertRowToFrame,
getFunctionsRows,
getTotalCount,
IFunctionRow,
} from '../topn_functions/utils';
import { getColumns } from './get_columns';
import { getCompareFrameAction } from './get_compare_frame_action';

Expand Down Expand Up @@ -83,34 +91,35 @@ interface Props {
comparisonSortDirection: 'asc' | 'desc';
comparisonSortField: TopNComparisonFunctionSortField;
totalSeconds: number;
comparisonTotalSeconds: number;
}

export function DifferentialTopNFunctionsGrid({
base,
baselineScaleFactor,
comparison,
comparisonScaleFactor,
comparisonSortDirection,
comparisonSortField,
comparisonTotalSeconds,
onChangePage,
onChangeSort,
onFrameClick,
pageIndex,
sortDirection,
sortField,
totalSeconds,
onFrameClick,
comparisonSortDirection,
comparisonSortField,
}: Props) {
const theme = useEuiTheme();
const calculateImpactEstimates = useCalculateImpactEstimate();
const [selectedFrame, setSelectedFrame] = useState<SelectedFrame | undefined>();
const theme = useEuiTheme();

const totalCount = useMemo(() => {
if (!base || !base.TotalCount) {
return 0;
}
const [rowsInformation, setRowsInformation] = useState<
{ baseRow: IFunctionRow; comparisonRow?: IFunctionRow } | undefined
>();

return base.TotalCount;
}, [base]);
const { totalCount, comparisonTotalCount } = useMemo(() => {
return { totalCount: getTotalCount(base), comparisonTotalCount: getTotalCount(comparison) };
}, [base, comparison]);

function onSort(newSortingColumns: EuiDataGridSorting['columns']) {
// As newSortingColumns is an array and we only sort by a single field for both base and comparison
Expand Down Expand Up @@ -151,7 +160,7 @@ export function DifferentialTopNFunctionsGrid({
comparisonScaleFactor,
comparisonTopNFunctions: base,
topNFunctions: comparison,
totalSeconds,
totalSeconds: comparisonTotalSeconds,
}),
};
}, [
Expand All @@ -160,6 +169,7 @@ export function DifferentialTopNFunctionsGrid({
calculateImpactEstimates,
comparison,
comparisonScaleFactor,
comparisonTotalSeconds,
totalSeconds,
]);

Expand Down Expand Up @@ -224,42 +234,109 @@ export function DifferentialTopNFunctionsGrid({
const rowCount = Math.min(Math.max(sortedBaseRows.length, sortedComparisonRows.length), 100);

return (
<EuiDataGrid
data-test-subj="profilingDiffTopNFunctionsGrid"
css={css`
.thickBorderLeft {
border-left: ${theme.euiTheme.border.thick} !important;
}
`}
aria-label={i18n.translate('xpack.profiling.onWeelkDiffTopN.euiDataGrid.topNFunctionsLabel', {
defaultMessage: 'TopN functions',
})}
columns={columns}
columnVisibility={{ visibleColumns, setVisibleColumns }}
rowCount={rowCount}
renderCellValue={CellValue}
sorting={{
columns: [
{ id: sortField, direction: sortDirection },
{ id: comparisonSortField, direction: comparisonSortDirection },
],
onSort,
}}
pagination={{
pageIndex,
pageSize: 50,
// Left it empty on purpose as it is a required property on the pagination
onChangeItemsPerPage: () => {},
onChangePage,
pageSizeOptions: [],
}}
rowHeightsOptions={{ defaultHeight: 'auto' }}
toolbarVisibility={{
showColumnSelector: false,
showKeyboardShortcuts: false,
showDisplaySelector: false,
showSortSelector: false,
}}
/>
<>
<EuiDataGrid
data-test-subj="profilingDiffTopNFunctionsGrid"
css={css`
.thickBorderLeft {
border-left: ${theme.euiTheme.border.thick} !important;
}
`}
aria-label={i18n.translate(
'xpack.profiling.onWeelkDiffTopN.euiDataGrid.topNFunctionsLabel',
{
defaultMessage: 'TopN functions',
}
)}
columns={columns}
leadingControlColumns={[
{
id: 'actions',
width: 40,
headerCellRender() {
return (
<EuiScreenReaderOnly>
<span>
{i18n.translate('xpack.profiling.topNFunctionsGrid.span.controlsLabel', {
defaultMessage: 'Controls',
})}
</span>
</EuiScreenReaderOnly>
);
},
rowCellRender: function RowCellRender({ rowIndex }) {
function handleOnClick() {
const row = sortedBaseRows[rowIndex];
const currentFrameId = getFrameIdentification(row.frame);
const compareRow = sortedComparisonRows.find(
(item) => getFrameIdentification(item.frame) === currentFrameId
);
setRowsInformation({
baseRow: row,
comparisonRow: compareRow,
});
}
return (
<EuiButtonIcon
data-test-subj="profilingTopNFunctionsGridButton"
aria-label={i18n.translate(
'xpack.profiling.topNFunctionsGrid.euiButtonIcon.showActionsLabel',
{ defaultMessage: 'Show actions' }
)}
iconType="expand"
color="text"
onClick={handleOnClick}
/>
);
},
},
]}
columnVisibility={{ visibleColumns, setVisibleColumns }}
rowCount={rowCount}
renderCellValue={CellValue}
sorting={{
columns: [
{ id: sortField, direction: sortDirection },
{ id: comparisonSortField, direction: comparisonSortDirection },
],
onSort,
}}
pagination={{
pageIndex,
pageSize: 50,
// Left it empty on purpose as it is a required property on the pagination
onChangeItemsPerPage: () => {},
onChangePage,
pageSizeOptions: [],
}}
rowHeightsOptions={{ defaultHeight: 'auto' }}
toolbarVisibility={{
showColumnSelector: false,
showKeyboardShortcuts: false,
showDisplaySelector: false,
showSortSelector: false,
}}
/>
{rowsInformation && (
<FrameInformationTooltip
compressed
comparisonRank={rowsInformation.comparisonRow?.rank}
comparisonFrame={
rowsInformation.comparisonRow
? convertRowToFrame(rowsInformation.comparisonRow)
: undefined
}
comparisonTotalSamples={comparisonTotalCount}
comparisonTotalSeconds={comparisonTotalSeconds}
rank={rowsInformation.baseRow.rank}
frame={convertRowToFrame(rowsInformation.baseRow)}
totalSamples={totalCount}
totalSeconds={totalSeconds}
onClose={() => {
setRowsInformation(undefined);
}}
/>
)}
</>
);
}
Loading

0 comments on commit b62f3b7

Please sign in to comment.