Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add single process metric #114

Merged
merged 1 commit into from
Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 39 additions & 34 deletions src/pages/ServiceDashboard/Detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import {
getMaxNum,
getMetricsUniqName,
getMachineRouterPath,
AggregationType,
} from '@/utils/dashboard';
import { IDispatch, IRootState } from '@/store';
import { VALUE_TYPE } from '@/utils/promQL';
import { IMetricOption, MetricScene, ServiceMetricsPanelValue } from '@/utils/interface';
import { IMetricOption, IServiceMetricItem, MetricScene, ServiceMetricsPanelValue } from '@/utils/interface';

import LineChart from '@/components/Charts/LineChart';
import { configDetailChart, updateDetailChart } from '@/utils/chart/chart';
Expand Down Expand Up @@ -87,42 +88,36 @@ function ServiceDetail(props: IProps) {
}
}, [metricsFilterValues.timeRange, cluster])

const metricOptions = useMemo<IMetricOption[]>(() => {
const metricOptions = useMemo<IServiceMetricItem[]>(() => {
if (serviceMetric.graphd.length === 0
|| serviceMetric.storaged.length === 0
|| serviceMetric.metad.length === 0) {
return [];
}
let options = [];
let options: IServiceMetricItem[] = [];
if (serviceType) {
options = serviceMetric[`${serviceType}d`].map(item => {
return {
metric: item.metric,
isSpaceMetric: item.isSpaceMetric,
metricType: item.metricType,
valueType: item.valueType,
}
})
options = serviceMetric[`${serviceType}d`];
}
return options;
}, [serviceType, serviceMetric.graphd, serviceMetric.metad, serviceMetric.storaged]);

const metricTypeMap = useMemo(() => {
const map = {};
const metricTypeMap: Map<AggregationType, IServiceMetricItem[]> = useMemo(() => {
const map: Map<AggregationType, IServiceMetricItem[]> = {} as any;
metricOptions.forEach(option => {
option.metricType.forEach(type => {
const { key, value } = type;
const metricItem = {
metric: option.metric,
isSpaceMetric: option.isSpaceMetric,
metricType: option.metricType,
valueType: option.valueType,
metricFunction: value,
};
if (!map[key]) {
map[key] = [metricItem];
option.aggregations.forEach(type => {
// const { key, value } = type;
// const metricItem: IServiceMetricItem = {
// metric: option.metric,
// isSpaceMetric: option.isSpaceMetric,
// metricType: option.metricType,
// valueType: option.valueType,
// isRawMetric: option.isRawMetric,
// metricFunction: value,
// };
if (!map[type]) {
map[type] = [option];
} else {
map[key].push(metricItem)
map[type].push(option)
}
})
})
Expand All @@ -133,7 +128,7 @@ function ServiceDetail(props: IProps) {
(metricOptions || []).map((metric) => metric.metric)
), [metricOptions]);

const [curMetricOptions, setMetricOptions] = useState<IMetricOption[]>(metricOptions);
const [curMetricOptions, setMetricOptions] = useState<IServiceMetricItem[]>(metricOptions);

useEffect(() => {
const match = /(\w+)-metrics/g.exec(location.pathname);
Expand All @@ -147,12 +142,22 @@ function ServiceDetail(props: IProps) {
const metricCharts: any = useMemo(() => {
if (Object.keys(metricTypeMap).length === 0) return [];
const { metricType } = metricsFilterValues;
const charts = metricTypeMap[metricType].map((metric, i) => ({
metric,
chartInstance: undefined,
index: i,
baseLine: undefined,
}));
let charts: any = [];
if (metricType === 'all') {
charts = metricOptions.map((metric, i) => ({
metric,
chartInstance: undefined,
index: i,
baseLine: undefined,
}))
} else {
charts = metricTypeMap[metricType].map((metric, i) => ({
metric,
chartInstance: undefined,
index: i,
baseLine: undefined,
}));
}
return charts;
}, [metricTypeMap, metricsFilterValues.metricType])

Expand Down Expand Up @@ -194,9 +199,9 @@ function ServiceDetail(props: IProps) {
const [startTime, endTime] = calcTimeRange(timeRange);
const getPromise = (chart) => {
return new Promise((resolve, reject) => {
const item = metricTypeMap[metricType].find(metricItem => metricItem.metric === chart.metric.metric);
const item: IServiceMetricItem = metricTypeMap[metricType].find(metricItem => metricItem.metric === chart.metric.metric);
asyncFetchMetricsData({
query: item.metricFunction + period,
query: item.isRawMetric ? item.prefixMetric : `${item.prefixMetric}_${metricType}_${period}`,
start: startTime,
end: endTime,
space: serviceType === 'graph' ? space : undefined,
Expand Down
11 changes: 10 additions & 1 deletion src/utils/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ export const CARD_RANGE = 60 * 60 * 24 * 1000;
export const CARD_POLLING_INTERVAL = 10000 * 1000;
export const MAX_STEP_ALLOW = 11000;
export const TIME_INTERVAL_OPTIONS = [5, 60, 600, 3600];
export const AGGREGATION_OPTIONS = ['sum', 'rate', 'avg', 'p75', 'p95', 'p99', 'p999'];
export enum AggregationType {
Sum = 'sum',
Rate = 'rate',
Avg = 'avg',
P75 = 'p75',
P95 = 'p95',
P99 = 'p99',
P999 = 'p999',
}
export const AGGREGATION_OPTIONS = Object.values(AggregationType);

export const THRESHOLDS = {
low: 60,
Expand Down
12 changes: 11 additions & 1 deletion src/utils/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface IMetricOption {
metric: string;
isSpaceMetric: boolean;
metricType: IMetricType[];
valueType: string;
valueType: VALUE_TYPE;
}

export interface MetricsPanelValue {
Expand Down Expand Up @@ -88,4 +88,14 @@ export enum MetricScene {
export interface IMachineMetricOption {
metric: string;
valueType: VALUE_TYPE;
}

export interface IServiceMetricItem {
metric: string;
valueType: VALUE_TYPE;
isSpaceMetric: boolean;
isRawMetric: boolean;
aggregations: string[];
prefixMetric: string;
metricFunction?: string;
}
51 changes: 29 additions & 22 deletions src/utils/metric.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import _ from 'loadsh';
import { VALUE_TYPE } from '@/utils/promQL';
import { INTERVAL_FREQUENCY_LIST, SERVICE_QUERY_PERIOD } from './service';
import { AGGREGATION_OPTIONS, TIME_OPTION_TYPE } from './dashboard';
import { AggregationType, AGGREGATION_OPTIONS, TIME_OPTION_TYPE } from './dashboard';
import { IServiceMetricItem } from './interface';

export const METRICS_DESCRIPTION: any = {
num_queries: 'num_queries description',
Expand All @@ -22,6 +23,8 @@ export const METRICS_DESCRIPTION: any = {

export const METRIC_SERVICE_TYPES = ['graph', 'storage', 'meta'];

export const METRIC_FUNCTIONS: AggregationType[] = Object.values(AggregationType);

export const FILTER_METRICS = [
// <= v2.5.1
'get_prop_latency_us',
Expand Down Expand Up @@ -80,21 +83,29 @@ export const FILTER_METRICS = [

export const METRIC_PROCESS_TYPES = ['graphd', 'storaged', 'metad'];

export const calcMetricInfo = (rawMetric: string) => {
if (METRIC_FUNCTIONS.some(fn => rawMetric.includes(fn))) {
const metricFieldArr = rawMetric.split(`_`);
const key: AggregationType = metricFieldArr?.splice(-2, 2)[0] as AggregationType; // sum / avg / p99 ~
const metricValue = metricFieldArr.join('_'); // nebula_graphd_num_queries
return { key, metricValue }
} else {
return { metricValue: rawMetric }
}
}

export const filterServiceMetrics = (payload: {
metricList: string[];
spaceMetricList: string[];
version?: string;
componentType: string;
}) => {
const { metricList, spaceMetricList = [], componentType } = payload;
const metrics = [] as any;
// const metricValue = item.slice(0, item.lastIndexOf(`_${componentType}_`));
const metrics: IServiceMetricItem[] = [];
metricList.map(item => {
const [metricFieldType, metricFields] = item.split(`_${componentType}_`); // Example: nebula_graphd_num_queries_sum_60 => nebula, num_queries_sum_60
if (metricFieldType && metricFields) {
const metricFieldArr = metricFields.split(`_`);
const key = metricFieldArr?.splice(-2, 2)[0]; // sum / avg / p99 ~
const metricValue = metricFieldArr.join('_'); // nebula_graphd_num_queries
const { key, metricValue } = calcMetricInfo(metricFields)
const metricItem = _.find(metrics, m => m.metric === metricValue);

if (_.includes(FILTER_METRICS, metricValue)) {
Expand All @@ -104,29 +115,25 @@ export const filterServiceMetrics = (payload: {
const isSpaceMetric = _.findLast(spaceMetricList, metric =>
metric.includes(metricValue),
);
// push data in metrics
// push data into metrics
if (metricItem) {
const metricTypeItem = _.find(
metricItem.metricType,
_item => _item.key === key,
);
if (!metricTypeItem) {
metricItem.metricType.push({
key,
value: `${metricFieldType}_${componentType}_${metricValue}_${key}_`,
});
if (key) {
const metricTypeItem = _.find(
metricItem.aggregations,
_item => _item === key,
);
if (!metricTypeItem) {
metricItem.aggregations.push(key);
}
}
} else {
metrics.push({
metric: metricValue,
valueType: VALUE_TYPE.number,
isSpaceMetric: !!isSpaceMetric,
metricType: [
{
key,
value: `${metricFieldType}_${componentType}_${metricValue}_${key}_`,
},
],
isRawMetric: !key, // if metrics don't have sum / avg / p99
prefixMetric: `${metricFieldType}_${componentType}_${metricValue}`,
aggregations: key ? [key] : METRIC_FUNCTIONS,
});
}
}
Expand Down