Skip to content

Commit

Permalink
remove functions from rates
Browse files Browse the repository at this point in the history
  • Loading branch information
jpinsonneau committed Nov 2, 2023
1 parent 8a613b1 commit ae9bcf5
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 342 deletions.
15 changes: 15 additions & 0 deletions web/src/api/loki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ export type TotalRateMetrics = {
packets?: TopologyMetrics;
};

export type NetflowMetrics = {
rateMetrics?: RateMetrics;
droppedRateMetrics?: RateMetrics;
totalRateMetric?: TotalRateMetrics;
totalDroppedRateMetric?: TotalRateMetrics;
droppedStateMetrics?: GenericMetric[];
droppedCauseMetrics?: GenericMetric[];
dnsRCodeMetrics?: GenericMetric[];
dnsLatencyMetrics?: FunctionMetrics;
rttMetrics?: FunctionMetrics;
totalDnsLatencyMetric?: TotalFunctionMetrics;
totalDnsCountMetric?: TopologyMetrics;
totalRttMetric?: TotalFunctionMetrics;
};

export const initRateMetricKeys = (ids: string[]) => {
const obj: RateMetrics | TotalRateMetrics = {};
ids.forEach(id => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('<NetflowOverview />', () => {
error: undefined as string | undefined,
loading: false,
recordType: 'flowLog' as RecordType,
metricResults: {},
metrics: {},
filterActionLinks: <></>,
truncateLength: TruncateLength.M
};
Expand All @@ -44,8 +44,8 @@ describe('<NetflowOverview />', () => {
const wrapper = mount(
<NetflowOverview
{...props}
metricResults={{
...props.metricResults,
metrics={{
...props.metrics,
rateMetrics: { bytes: metrics },
droppedRateMetrics: { bytes: droppedMetrics },
totalRateMetric: { bytes: metrics[0] },
Expand Down
173 changes: 58 additions & 115 deletions web/src/components/netflow-overview/netflow-overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,7 @@ import _ from 'lodash';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { LOCAL_STORAGE_OVERVIEW_KEBAB_KEY, useLocalStorage } from '../../utils/local-storage-hook';
import {
GenericMetric,
FunctionMetrics,
RateMetrics,
TopologyMetrics,
TotalFunctionMetrics,
TotalRateMetrics
} from '../../api/loki';
import { NetflowMetrics } from '../../api/loki';
import { RecordType } from '../../model/flow-query';
import { getStat } from '../../model/metrics';
import {
Expand Down Expand Up @@ -50,30 +43,11 @@ type PanelContent = {
doubleWidth?: boolean;
};

export type NetflowOverviewMetrics = {
byteMetrics?: FunctionMetrics;
packetMetrics?: FunctionMetrics;
totalBytesMetric?: TotalFunctionMetrics;
totalPacketsMetric?: TotalFunctionMetrics;
rateMetrics?: RateMetrics;
droppedRateMetrics?: RateMetrics;
totalRateMetric?: TotalRateMetrics;
totalDroppedRateMetric?: TotalRateMetrics;
droppedStateMetrics?: GenericMetric[];
droppedCauseMetrics?: GenericMetric[];
dnsRCodeMetrics?: GenericMetric[];
dnsLatencyMetrics?: FunctionMetrics;
rttMetrics?: FunctionMetrics;
totalDnsLatencyMetric?: TotalFunctionMetrics;
totalDnsCountMetric?: TopologyMetrics;
totalRttMetric?: TotalFunctionMetrics;
};

export type NetflowOverviewProps = {
limit: number;
panels: OverviewPanel[];
recordType: RecordType;
metricResults: NetflowOverviewMetrics;
metrics: NetflowMetrics;
loading?: boolean;
error?: string;
isDark?: boolean;
Expand All @@ -85,7 +59,7 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
limit,
panels,
recordType,
metricResults,
metrics,
loading,
error,
isDark,
Expand All @@ -106,6 +80,23 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
[kebabMap, setKebabMap]
);

const getKebabOptions = React.useCallback(
(id: OverviewPanelId, defaultValue: PanelKebabOptions) => {
const found = kebabMap.get(id);
if (found) {
// ensure localstorage doesn't contains extra fields than default value in case an option has been removed
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const value: any = {};
(Object.keys(defaultValue) as (keyof typeof defaultValue)[]).forEach(k => {
value[k] = found[k];
});
return value as PanelKebabOptions;
}
return defaultValue;
},
[kebabMap]
);

const emptyGraph = React.useCallback(() => {
return (
<div className="emptygraph">
Expand All @@ -132,23 +123,23 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
const getRateMetric = React.useCallback(
(id: OverviewPanelId) => {
if (id.includes('dropped')) {
return metricResults.droppedRateMetrics;
return metrics.droppedRateMetrics;
} else {
return metricResults.rateMetrics;
return metrics.rateMetrics;
}
},
[metricResults.droppedRateMetrics, metricResults.rateMetrics]
[metrics.droppedRateMetrics, metrics.rateMetrics]
);

const getTotalRateMetric = React.useCallback(
(id: OverviewPanelId) => {
if (id.includes('dropped')) {
return metricResults.totalDroppedRateMetric;
return metrics.totalDroppedRateMetric;
} else {
return metricResults.totalRateMetric;
return metrics.totalRateMetric;
}
},
[metricResults.totalDroppedRateMetric, metricResults.totalRateMetric]
[metrics.totalDroppedRateMetric, metrics.totalRateMetric]
);

//skip metrics with sources equals to destinations
Expand Down Expand Up @@ -181,72 +172,52 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
);

const getTopKDroppedStateMetrics = React.useCallback(() => {
return metricResults.droppedStateMetrics?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum')) || [];
}, [metricResults.droppedStateMetrics]);
return metrics.droppedStateMetrics?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum')) || [];
}, [metrics.droppedStateMetrics]);

const getTopKDroppedCauseMetrics = React.useCallback(() => {
return metricResults.droppedCauseMetrics?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum')) || [];
}, [metricResults.droppedCauseMetrics]);
return metrics.droppedCauseMetrics?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum')) || [];
}, [metrics.droppedCauseMetrics]);

const getTopKDnsRCodeMetrics = React.useCallback(() => {
return metricResults.dnsRCodeMetrics?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum')) || [];
}, [metricResults.dnsRCodeMetrics]);
return metrics.dnsRCodeMetrics?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum')) || [];
}, [metrics.dnsRCodeMetrics]);

const getNamedDnsCountTotalMetric = React.useCallback(() => {
const metric = metricResults.totalDnsCountMetric;
const metric = metrics.totalDnsCountMetric;
return metric ? toNamedMetric(t, metric, truncateLength, false, false) : undefined;
}, [metricResults.totalDnsCountMetric, t, truncateLength]);
}, [metrics.totalDnsCountMetric, t, truncateLength]);

const getTopKMetrics = React.useCallback(
(id: OverviewPanelId) => {
let metrics = undefined;
if (id.endsWith('bytes')) {
metrics = metricResults.byteMetrics;
} else if (id.endsWith('packets')) {
metrics = metricResults.packetMetrics;
} else if (id.endsWith('dns_latency')) {
metrics = metricResults.dnsLatencyMetrics;
let m = undefined;
if (id.endsWith('dns_latency')) {
m = metrics.dnsLatencyMetrics;
} else if (id.endsWith('rtt')) {
metrics = metricResults.rttMetrics;
m = metrics.rttMetrics;
}

return (
metrics?.[getFunctionFromId(id)]
m?.[getFunctionFromId(id)]
?.sort((a, b) => getStat(b.stats, 'sum') - getStat(a.stats, 'sum'))
.map(m => toNamedMetric(t, m, truncateLength, true, true)) || []
);
},
[
metricResults.byteMetrics,
metricResults.dnsLatencyMetrics,
metricResults.packetMetrics,
metricResults.rttMetrics,
t,
truncateLength
]
[metrics.dnsLatencyMetrics, metrics.rttMetrics, t, truncateLength]
);

const getTotalMetric = React.useCallback(
(id: OverviewPanelId) => {
let metric = undefined;
if (id.endsWith('bytes')) {
metric = metricResults.totalBytesMetric;
} else if (id.endsWith('packets')) {
metric = metricResults.totalPacketsMetric;
} else if (id.endsWith('dns_latency')) {
metric = metricResults.totalDnsLatencyMetric;
if (id.endsWith('dns_latency')) {
metric = metrics.totalDnsLatencyMetric;
} else if (id.endsWith('rtt')) {
metric = metricResults.totalRttMetric;
metric = metrics.totalRttMetric;
}

return metric?.[getFunctionFromId(id)];
},
[
metricResults.totalBytesMetric,
metricResults.totalDnsLatencyMetric,
metricResults.totalPacketsMetric,
metricResults.totalRttMetric
]
[metrics.totalDnsLatencyMetric, metrics.totalRttMetric]
);

const getNamedTotalMetric = React.useCallback(
Expand All @@ -272,36 +243,20 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
case 'inbound_region':
return { element: <>Inbound flows by region content</> };
case 'top_avg_byte_rates':
case 'top_max_byte_rates':
case 'top_p90_byte_rates':
case 'top_p99_byte_rates':
case 'bottom_min_byte_rates':
case 'top_avg_dropped_byte_rates':
case 'top_max_dropped_byte_rates':
case 'top_p90_dropped_byte_rates':
case 'top_p99_dropped_byte_rates':
case 'bottom_min_dropped_byte_rates':
case 'top_avg_packet_rates':
case 'top_max_packet_rates':
case 'top_p90_packet_rates':
case 'top_p99_packet_rates':
case 'bottom_min_packet_rates':
case 'top_avg_dropped_packet_rates':
case 'top_max_dropped_packet_rates':
case 'top_p90_dropped_packet_rates':
case 'top_p99_dropped_packet_rates':
case 'bottom_min_dropped_packet_rates': {
const options = kebabMap.get(id) || {
case 'top_avg_dropped_packet_rates': {
const options = getKebabOptions(id, {
showOthers: true,
showInternal: true,
showOutOfScope: false,
showLast: false,
graph: {
type: 'donut'
}
};
});
const metricType = id.endsWith('byte_rates') ? 'bytes' : 'packets';
const metrics = options.graph!.type === 'donut' ? getTopKRateMetrics(id) : getNoInternalTopKRateMetrics(id);
const metrics = getTopKRateMetrics(id);
const namedTotalMetric = getNamedTotalRateMetric(id);
return {
element:
Expand Down Expand Up @@ -334,18 +289,17 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
case 'packet_rates':
case 'dropped_packet_rates': {
const isDrop = id.startsWith('dropped');
const options = kebabMap.get(id) || {
showInternal: true,
const options = getKebabOptions(id, {
showOutOfScope: false,
showTop: true,
showApp: { text: t('Show total'), value: !isDrop },
showAppDrop: isDrop ? { text: t('Show total dropped'), value: true } : undefined,
graph: { type: 'bar' }
};
});
const showTopOnly = options.showTop && !options.showApp?.value && !options.showAppDrop?.value;
const showTotalOnly = !options.showTop && options.showApp!.value;
const metricType = id.endsWith('byte_rates') ? 'bytes' : 'packets';
const topKMetrics = getTopKRateMetrics(id);
const topKMetrics = getNoInternalTopKRateMetrics(id);
const namedTotalMetric = getNamedTotalRateMetric(id.replace('dropped_', '') as OverviewPanelId);
const namedTotalDroppedMetric = getNamedTotalRateMetric(id);
return {
Expand Down Expand Up @@ -378,7 +332,6 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
showTop={options.showTop!}
showTotal={options.showApp?.value || false}
showTotalDrop={options.showAppDrop?.value || false}
showInternal={options.showInternal!}
showOutOfScope={options.showOutOfScope!}
smallerTexts={smallerTexts}
showOthers={false}
Expand All @@ -397,12 +350,12 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
const metricType = 'packets'; // TODO: consider adding bytes graphs here
const topKMetrics = isState ? getTopKDroppedStateMetrics() : getTopKDroppedCauseMetrics();
const namedTotalMetric = getNamedTotalRateMetric(id);
const options = kebabMap.get(id) || {
const options = getKebabOptions(id, {
showOthers: true,
showTop: true,
showApp: { text: t('Show total'), value: true },
graph: { options: ['bar_line', 'donut'], type: 'donut' }
};
graph: { options: ['bar_line', 'donut'], type: 'bar_line' }
});
const isDonut = options!.graph!.type === 'donut';
const showTopOnly = isDonut || (options.showTop && !options.showApp!.value);
const showTotalOnly = !options.showTop && options.showApp!.value;
Expand Down Expand Up @@ -459,16 +412,6 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
doubleWidth: options.graph!.type !== 'donut'
};
}
case 'top_avg_bytes':
case 'top_max_bytes':
case 'top_p90_bytes':
case 'top_p99_bytes':
case 'bottom_min_bytes':
case 'top_avg_packets':
case 'top_max_packets':
case 'top_p90_packets':
case 'top_p99_packets':
case 'bottom_min_packets':
case 'top_avg_dns_latency':
case 'top_max_dns_latency':
case 'top_p90_dns_latency':
Expand All @@ -489,14 +432,14 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
: 'flowRtt';
const metrics = getTopKMetrics(id);
const namedTotalMetric = getNamedTotalMetric(id);
const options = kebabMap.get(id) || {
const options = getKebabOptions(id, {
showTop: true,
showApp: { text: t('Show overall'), value: true },
graph: {
options: ['donut', 'line'],
type: isAvg ? 'line' : 'donut'
}
};
});
const isDonut = options!.graph!.type === 'donut';
const showTopOnly = isDonut || (options.showTop && !options.showApp!.value);
const showTotalOnly = !options.showTop && options.showApp!.value;
Expand Down Expand Up @@ -546,12 +489,12 @@ export const NetflowOverview: React.FC<NetflowOverviewProps> = ({
const metricType = 'countDns'; // TODO: consider adding packets graphs here
const topKMetrics = getTopKDnsRCodeMetrics();
const namedTotalMetric = getNamedDnsCountTotalMetric();
const options = kebabMap.get(id) || {
const options = getKebabOptions(id, {
showNoError: true,
showTop: true,
showApp: { text: t('Show total'), value: true },
graph: { options: ['bar_line', 'donut'], type: 'donut' }
};
});
const isDonut = options!.graph!.type === 'donut';
const showTopOnly = isDonut || (options.showTop && !options.showApp!.value);
const showTotalOnly = !options.showTop && options.showApp!.value;
Expand Down
Loading

0 comments on commit ae9bcf5

Please sign in to comment.