Skip to content

Commit

Permalink
[Profiling] Adding normalize by time and scale factor on Diff TopN fu…
Browse files Browse the repository at this point in the history
…nctions page (#159394)

Relevant changes:
- Adding **Normalize by** field on the Diff TopN functions page.
- Refactoring functions route/pages.


<img width="1469" alt="Screenshot 2023-06-09 at 2 34 48 PM"
src="https://github.com/elastic/kibana/assets/55978943/b2c824bd-94ff-4f8b-a6b2-b9c30c51881e">


<img width="1353" alt="Screenshot 2023-06-09 at 2 34 58 PM"
src="https://github.com/elastic/kibana/assets/55978943/9d1de932-8669-4ddf-968a-057199211931">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
cauemarcondes and kibanamachine authored Jun 14, 2023
1 parent b85d92c commit c6bca36
Show file tree
Hide file tree
Showing 16 changed files with 524 additions and 364 deletions.
10 changes: 0 additions & 10 deletions x-pack/plugins/profiling/common/flamegraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ import { createFrameGroupID } from './frame_group';
import { fnv1a64 } from './hash';
import { createStackFrameMetadata, getCalleeLabel } from './profiling';

export enum FlameGraphComparisonMode {
Absolute = 'absolute',
Relative = 'relative',
}

export enum FlameGraphNormalizationMode {
Scale = 'scale',
Time = 'time',
}

export interface BaseFlameGraph {
Size: number;
Edges: number[][];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import { EuiButtonGroup, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { FlameGraphComparisonMode } from '../../../common/flamegraph';
import { ComparisonMode } from '../normalization_menu';

interface Props {
comparisonMode: FlameGraphComparisonMode;
onChange: (nextComparisonMode: FlameGraphComparisonMode) => void;
comparisonMode: ComparisonMode;
onChange: (nextComparisonMode: ComparisonMode) => void;
}
export function DifferentialComparisonMode({ comparisonMode, onChange }: Props) {
return (
Expand All @@ -20,45 +20,37 @@ export function DifferentialComparisonMode({ comparisonMode, onChange }: Props)
<EuiFlexItem grow={false}>
<EuiTitle size="xxs">
<h3>
{i18n.translate(
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeTitle',
{ defaultMessage: 'Format' }
)}
{i18n.translate('xpack.profiling.differentialComparisonMode.title', {
defaultMessage: 'Format',
})}
</h3>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonGroup
legend={i18n.translate(
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeLegend',
{
defaultMessage:
'This switch allows you to switch between an absolute and relative comparison between both graphs',
}
)}
legend={i18n.translate('xpack.profiling.differentialComparisonMode.legend', {
defaultMessage:
'This switch allows you to switch between an absolute and relative comparison between both graphs',
})}
type="single"
buttonSize="s"
idSelected={comparisonMode}
onChange={(nextComparisonMode) => {
onChange(nextComparisonMode as FlameGraphComparisonMode);
onChange(nextComparisonMode as ComparisonMode);
}}
options={[
{
id: FlameGraphComparisonMode.Absolute,
id: ComparisonMode.Absolute,
label: i18n.translate(
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeAbsoluteButtonLabel',
{
defaultMessage: 'Abs',
}
'xpack.profiling.differentialComparisonMode.absoluteButtonLabel',
{ defaultMessage: 'Abs' }
),
},
{
id: FlameGraphComparisonMode.Relative,
id: ComparisonMode.Relative,
label: i18n.translate(
'xpack.profiling.flameGraphsView.differentialFlameGraphComparisonModeRelativeButtonLabel',
{
defaultMessage: 'Rel',
}
'xpack.profiling.differentialComparisonMode.relativeButtonLabel',
{ defaultMessage: 'Rel' }
),
},
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import { Chart, Datum, Flame, FlameLayerValue, PartialTheme, Settings } from '@e
import { EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui';
import { Maybe } from '@kbn/observability-plugin/common/typings';
import React, { useEffect, useMemo, useState } from 'react';
import { ElasticFlameGraph, FlameGraphComparisonMode } from '../../../common/flamegraph';
import { ElasticFlameGraph } from '../../../common/flamegraph';
import { getFlamegraphModel } from '../../utils/get_flamegraph_model';
import { FlameGraphLegend } from './flame_graph_legend';
import { FrameInformationWindow } from '../frame_information_window';
import { FrameInformationTooltip } from '../frame_information_window/frame_information_tooltip';
import { FlameGraphTooltip } from './flamegraph_tooltip';
import { ComparisonMode } from '../normalization_menu';

interface Props {
id: string;
comparisonMode: FlameGraphComparisonMode;
comparisonMode: ComparisonMode;
primaryFlamegraph?: ElasticFlameGraph;
comparisonFlamegraph?: ElasticFlameGraph;
baseline?: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,41 @@ import {
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import React, { useEffect, useState } from 'react';
import { FlameGraphNormalizationMode } from '../../../common/flamegraph';

export interface FlameGraphNormalizationOptions {
export interface NormalizationOptions {
baselineScale: number;
baselineTime: number;
comparisonScale: number;
comparisonTime: number;
}

export enum ComparisonMode {
Absolute = 'absolute',
Relative = 'relative',
}

export enum NormalizationMode {
Scale = 'scale',
Time = 'time',
}

interface Props {
mode: FlameGraphNormalizationMode;
options: FlameGraphNormalizationOptions;
onChange: (mode: FlameGraphNormalizationMode, options: FlameGraphNormalizationOptions) => void;
mode: NormalizationMode;
options: NormalizationOptions;
onChange: (mode: NormalizationMode, options: NormalizationOptions) => void;
}

const SCALE_LABEL = i18n.translate('xpack.profiling.flameGraphNormalizationMenu.scale', {
const SCALE_LABEL = i18n.translate('xpack.profiling.normalizationMenu.scale', {
defaultMessage: 'Scale factor',
});

const TIME_LABEL = i18n.translate('xpack.profiling.flameGraphNormalizationMenu.time', {
const TIME_LABEL = i18n.translate('xpack.profiling.normalizationMenu.time', {
defaultMessage: 'Time',
});

const NORMALIZE_BY_LABEL = i18n.translate(
'xpack.profiling.flameGraphNormalizationMenu.normalizeBy',
{
defaultMessage: 'Normalize by',
}
);
const NORMALIZE_BY_LABEL = i18n.translate('xpack.profiling.normalizationMenu.normalizeBy', {
defaultMessage: 'Normalize by',
});

export function NormalizationMenu(props: Props) {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
Expand All @@ -72,7 +78,7 @@ export function NormalizationMenu(props: Props) {
}, [props.mode, props.options]);

const { baseline, comparison } =
mode === FlameGraphNormalizationMode.Time
mode === NormalizationMode.Time
? { comparison: options.comparisonTime, baseline: options.baselineTime }
: { comparison: options.comparisonScale, baseline: options.baselineScale };

Expand Down Expand Up @@ -110,7 +116,7 @@ export function NormalizationMenu(props: Props) {
padding: '0 16px',
}}
>
{props.mode === FlameGraphNormalizationMode.Scale ? SCALE_LABEL : TIME_LABEL}
{props.mode === NormalizationMode.Scale ? SCALE_LABEL : TIME_LABEL}
</EuiFlexItem>
</EuiFormControlLayout>
}
Expand All @@ -129,24 +135,18 @@ export function NormalizationMenu(props: Props) {
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<span>
{i18n.translate(
'xpack.profiling.flameGraphNormalizationMenu.normalizeByTimeTooltip',
{
defaultMessage:
'Select Normalize by Scale factor and set your Baseline and Comparison scale factors to compare a set of machines of different sizes. For example, you can compare a deployment of 10% of machines to a deployment of 90% of machines.',
}
)}
{i18n.translate('xpack.profiling.normalizationMenu.normalizeByTimeTooltip', {
defaultMessage:
'Select Normalize by Scale factor and set your Baseline and Comparison scale factors to compare a set of machines of different sizes. For example, you can compare a deployment of 10% of machines to a deployment of 90% of machines.',
})}
</span>
</EuiFlexItem>
<EuiFlexItem>
<span>
{i18n.translate(
'xpack.profiling.flameGraphNormalizationMenu.normalizeByScaleTooltip',
{
defaultMessage:
'Select Normalize by Time to compare a set of machines across different time periods. For example, if you compare the last hour to the last 24 hours, the shorter timeframe (1 hour) is multiplied to match the longer timeframe (24 hours).',
}
)}
{i18n.translate('xpack.profiling.normalizationMenu.normalizeByScaleTooltip', {
defaultMessage:
'Select Normalize by Time to compare a set of machines across different time periods. For example, if you compare the last hour to the last 24 hours, the shorter timeframe (1 hour) is multiplied to match the longer timeframe (24 hours).',
})}
</span>
</EuiFlexItem>
</EuiFlexGroup>
Expand All @@ -160,19 +160,19 @@ export function NormalizationMenu(props: Props) {
buttonSize="compressed"
isFullWidth
onChange={(id, value) => {
setMode(id as FlameGraphNormalizationMode);
setMode(id as NormalizationMode);
}}
legend={i18n.translate('xpack.profiling.flameGraphNormalizationMode.selectModeLegend', {
legend={i18n.translate('xpack.profiling.normalizationMode.selectModeLegend', {
defaultMessage: 'Select a normalization mode for the flamegraph',
})}
idSelected={mode}
options={[
{
id: FlameGraphNormalizationMode.Scale,
id: NormalizationMode.Scale,
label: SCALE_LABEL,
},
{
id: FlameGraphNormalizationMode.Time,
id: NormalizationMode.Time,
label: TIME_LABEL,
},
]}
Expand All @@ -195,14 +195,14 @@ export function NormalizationMenu(props: Props) {
id={baselineScaleFactorInputId}
value={baseline}
onChange={(e) => {
if (mode === FlameGraphNormalizationMode.Scale) {
if (mode === NormalizationMode.Scale) {
setOptions((prevOptions) => ({
...prevOptions,
baselineScale: e.target.valueAsNumber,
}));
}
}}
disabled={mode === FlameGraphNormalizationMode.Time}
disabled={mode === NormalizationMode.Time}
/>
</EuiFormControlLayout>
<EuiSpacer size="m" />
Expand All @@ -223,14 +223,14 @@ export function NormalizationMenu(props: Props) {
id={comparisonScaleFactorInputId}
value={comparison}
onChange={(e) => {
if (mode === FlameGraphNormalizationMode.Scale) {
if (mode === NormalizationMode.Scale) {
setOptions((prevOptions) => ({
...prevOptions,
comparisonScale: e.target.valueAsNumber,
}));
}
}}
disabled={mode === FlameGraphNormalizationMode.Time}
disabled={mode === NormalizationMode.Time}
/>
</EuiFormControlLayout>
<EuiSpacer size="m" />
Expand Down
59 changes: 42 additions & 17 deletions x-pack/plugins/profiling/public/components/topn_functions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function SampleStat({
diffSamples?: number;
totalSamples: number;
}) {
const samplesLabel = `${samples.toLocaleString()}`;
const samplesLabel = samples.toLocaleString();

if (diffSamples === undefined || diffSamples === 0 || totalSamples === 0) {
return <>{samplesLabel}</>;
Expand Down Expand Up @@ -142,6 +142,12 @@ interface Props {
comparisonTopNFunctions?: TopNFunctions;
totalSeconds: number;
isDifferentialView: boolean;
baselineScaleFactor?: number;
comparisonScaleFactor?: number;
}

function scaleValue({ value, scaleFactor = 1 }: { value: number; scaleFactor?: number }) {
return value * scaleFactor;
}

export function TopNFunctionsTable({
Expand All @@ -152,6 +158,8 @@ export function TopNFunctionsTable({
comparisonTopNFunctions,
totalSeconds,
isDifferentialView,
baselineScaleFactor,
comparisonScaleFactor,
}: Props) {
const [selectedRow, setSelectedRow] = useState<Row | undefined>();

Expand All @@ -175,6 +183,11 @@ export function TopNFunctionsTable({
return topNFunctions.TopN.filter((topN) => topN.CountExclusive > 0).map((topN, i) => {
const comparisonRow = comparisonDataById?.[topN.Id];

const topNCountExclusiveScaled = scaleValue({
value: topN.CountExclusive,
scaleFactor: baselineScaleFactor,
});

const inclusiveCPU = (topN.CountInclusive / topNFunctions.TotalCount) * 100;
const exclusiveCPU = (topN.CountExclusive / topNFunctions.TotalCount) * 100;
const totalSamples = topN.CountExclusive;
Expand All @@ -189,31 +202,43 @@ export function TopNFunctionsTable({
})
: undefined;

const diff =
comparisonTopNFunctions && comparisonRow
? {
rank: topN.Rank - comparisonRow.Rank,
samples: topN.CountExclusive - comparisonRow.CountExclusive,
exclusiveCPU:
exclusiveCPU -
(comparisonRow.CountExclusive / comparisonTopNFunctions.TotalCount) * 100,
inclusiveCPU:
inclusiveCPU -
(comparisonRow.CountInclusive / comparisonTopNFunctions.TotalCount) * 100,
}
: undefined;
function calculateDiff() {
if (comparisonTopNFunctions && comparisonRow) {
const comparisonCountExclusiveScaled = scaleValue({
value: comparisonRow.CountExclusive,
scaleFactor: comparisonScaleFactor,
});

return {
rank: topN.Rank - comparisonRow.Rank,
samples: topNCountExclusiveScaled - comparisonCountExclusiveScaled,
exclusiveCPU:
exclusiveCPU -
(comparisonRow.CountExclusive / comparisonTopNFunctions.TotalCount) * 100,
inclusiveCPU:
inclusiveCPU -
(comparisonRow.CountInclusive / comparisonTopNFunctions.TotalCount) * 100,
};
}
}

return {
rank: topN.Rank,
frame: topN.Frame,
samples: topN.CountExclusive,
samples: topNCountExclusiveScaled,
exclusiveCPU,
inclusiveCPU,
impactEstimates,
diff,
diff: calculateDiff(),
};
});
}, [topNFunctions, comparisonTopNFunctions, totalSeconds]);
}, [
topNFunctions,
comparisonTopNFunctions,
totalSeconds,
comparisonScaleFactor,
baselineScaleFactor,
]);

const theme = useEuiTheme();

Expand Down
Loading

0 comments on commit c6bca36

Please sign in to comment.