This is an automated email from the ASF dual-hosted git repository.
dockerzhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git
The following commit(s) were added to refs/heads/master by this push:
new b2a25b57a9 [INLONG-8548][Dashboard] Data access supports displaying
transmission delay (#8555)
b2a25b57a9 is described below
commit b2a25b57a96db02421d3c1a639cff7dd3b60a785
Author: Lizhen <[email protected]>
AuthorDate: Tue Jul 18 17:39:27 2023 +0800
[INLONG-8548][Dashboard] Data access supports displaying transmission delay
(#8555)
Co-authored-by: Charles Zhang <[email protected]>
Co-authored-by: healchow <[email protected]>
---
inlong-dashboard/src/ui/locales/cn.json | 4 +
inlong-dashboard/src/ui/locales/en.json | 4 +
.../src/ui/pages/GroupDetail/Audit/index.tsx | 2 -
.../src/ui/pages/GroupDetail/Delay/config.tsx | 211 +++++++++++++++++++++
.../pages/GroupDetail/{Audit => Delay}/index.tsx | 64 ++++++-
.../src/ui/pages/GroupDetail/index.tsx | 7 +
6 files changed, 287 insertions(+), 5 deletions(-)
diff --git a/inlong-dashboard/src/ui/locales/cn.json
b/inlong-dashboard/src/ui/locales/cn.json
index e2d567bbae..67d8004dc8 100644
--- a/inlong-dashboard/src/ui/locales/cn.json
+++ b/inlong-dashboard/src/ui/locales/cn.json
@@ -617,6 +617,7 @@
"pages.GroupDetail.Sinks": "数据目标",
"pages.GroupDetail.Audit": "审计对账",
"pages.GroupDetail.Resource": "资源详情",
+ "pages.GroupDetail.Delay": "传输时延",
"pages.GroupDetail.Resource.Info": " 信息",
"pages.GroupDetail.Audit.DataStream": "数据流",
"pages.GroupDetail.Audit.StartDate": "开始日期",
@@ -631,6 +632,9 @@
"pages.GroupDetail.Audit.Hour": "小时",
"pages.GroupDetail.Audit.Day": "天",
"pages.GroupDetail.Audit.Sink": "数据目标",
+ "pages.GroupDetail.Delay.QueryDate": "查询日期",
+ "pages.GroupDetail.Delay.AverageTitle": "平均传输时延 (ms)",
+ "pages.GroupDetail.Delay.RealTimeTitle": "传输时延 (ms)",
"pages.GroupDetail.Stream.Preview": "数据预览",
"pages.GroupDetail.Stream.Dt": "数据时间 (dt)",
"pages.GroupDetail.Stream.Content": "数据内容",
diff --git a/inlong-dashboard/src/ui/locales/en.json
b/inlong-dashboard/src/ui/locales/en.json
index 4542a6bd57..60e49aa8df 100644
--- a/inlong-dashboard/src/ui/locales/en.json
+++ b/inlong-dashboard/src/ui/locales/en.json
@@ -616,6 +616,7 @@
"pages.GroupDetail.Sources": "Sources",
"pages.GroupDetail.Sinks": "Sinks",
"pages.GroupDetail.Audit": "Audit",
+ "pages.GroupDetail.Delay": "Transmission Delay",
"pages.GroupDetail.Resource": "Resource Detail",
"pages.GroupDetail.Resource.Info": " Info",
"pages.GroupDetail.Audit.DataStream": "DataStream",
@@ -631,6 +632,9 @@
"pages.GroupDetail.Audit.Hour": "Hour",
"pages.GroupDetail.Audit.Day": "Day",
"pages.GroupDetail.Audit.Sink": "Sink",
+ "pages.GroupDetail.Delay.QueryDate": "Query Date",
+ "pages.GroupDetail.Delay.AverageTitle": "Average Transmission Delay (ms)",
+ "pages.GroupDetail.Delay.RealTimeTitle": "Transmission Delay (ms)",
"pages.GroupDetail.Stream.Preview": "Data Preview",
"pages.GroupDetail.Stream.Dt": "Data Time(dt)",
"pages.GroupDetail.Stream.Content": "Data Content",
diff --git a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
b/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
index 93d1a26a51..3b368c03ad 100644
--- a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
@@ -81,12 +81,10 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
const output = flatArr.reduce((acc, cur) => {
if (!acc[cur.logTs]) {
acc[cur.logTs] = {};
- acc[cur.delay] = '';
}
acc[cur.logTs] = {
...acc[cur.logTs],
[cur.auditId]: cur.count,
- [cur.delay]: cur.delay,
};
return acc;
}, {});
diff --git a/inlong-dashboard/src/ui/pages/GroupDetail/Delay/config.tsx
b/inlong-dashboard/src/ui/pages/GroupDetail/Delay/config.tsx
new file mode 100644
index 0000000000..67554a1372
--- /dev/null
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/Delay/config.tsx
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import { Button } from 'antd';
+import dayjs from 'dayjs';
+import i18n from '@/i18n';
+import { sinks } from '@/plugins/sinks';
+
+export const timeStaticsDimList = [
+ {
+ label: i18n.t('pages.GroupDetail.Audit.Min'),
+ value: 'MINUTE',
+ },
+ {
+ label: i18n.t('pages.GroupDetail.Audit.Hour'),
+ value: 'HOUR',
+ },
+];
+
+const auditList = ['Agent', 'DataProxy', 'Sort'].reduce((acc, item, index) => {
+ return acc.concat([
+ {
+ label: `${item} ${i18n.t('pages.GroupDetail.Audit.Receive')}`,
+ value: index * 2 + 3,
+ },
+ {
+ label: `${item} ${i18n.t('pages.GroupDetail.Audit.Send')}`,
+ value: index * 2 + 4,
+ },
+ ]);
+}, []);
+
+const auditMap = auditList.reduce(
+ (acc, cur) => ({
+ ...acc,
+ [cur.value]: cur,
+ }),
+ {},
+);
+
+function getAuditLabel(auditId: number, nodeType?: string) {
+ const id = +auditId;
+ const item = id >= 9 ? auditMap[id % 2 ? 7 : 8] : auditMap[id];
+ const label = item?.label || id;
+ const sinkLabel = sinks.find(c => c.value === nodeType)?.label;
+ return nodeType ? `${label}(${sinkLabel})` : label;
+}
+
+export const toChartData = (source, sourceDataMap) => {
+ const xAxisData = Object.keys(sourceDataMap);
+ return {
+ legend: {
+ data: source.map(item => getAuditLabel(item.auditId, item.nodeType)),
+ },
+ tooltip: {
+ trigger: 'axis',
+ },
+ xAxis: {
+ type: 'category',
+ data: xAxisData,
+ },
+ yAxis: {
+ type: 'value',
+ },
+ series: source.map(item => ({
+ name: getAuditLabel(item.auditId, item.nodeType),
+ type: 'line',
+ data: xAxisData.map(logTs => sourceDataMap[logTs]?.[item.auditId] || 0),
+ })),
+ };
+};
+
+export const toTableData = (source, sourceDataMap) => {
+ return Object.keys(sourceDataMap)
+ .reverse()
+ .map(logTs => ({
+ ...sourceDataMap[logTs],
+ logTs,
+ }));
+};
+
+export const getFormContent = (inlongGroupId, initialValues, onSearch,
onDataStreamSuccess) => [
+ {
+ type: 'select',
+ label: i18n.t('pages.GroupDetail.Audit.DataStream'),
+ name: 'inlongStreamId',
+ props: {
+ dropdownMatchSelectWidth: false,
+ options: {
+ requestAuto: true,
+ requestService: {
+ url: '/stream/list',
+ method: 'POST',
+ data: {
+ pageNum: 1,
+ pageSize: 1000,
+ inlongGroupId,
+ },
+ },
+ requestParams: {
+ formatResult: result =>
+ result?.list.map(item => ({
+ label: item.inlongStreamId,
+ value: item.inlongStreamId,
+ })) || [],
+ onSuccess: onDataStreamSuccess,
+ },
+ },
+ },
+ rules: [{ required: true }],
+ },
+ {
+ type: 'select',
+ label: i18n.t('pages.GroupDetail.Audit.Sink'),
+ name: 'sinkId',
+ props: values => ({
+ dropdownMatchSelectWidth: false,
+ options: {
+ requestService: {
+ url: '/sink/list',
+ method: 'POST',
+ data: {
+ pageNum: 1,
+ pageSize: 1000,
+ inlongGroupId,
+ inlongStreamId: values.inlongStreamId,
+ },
+ },
+ requestParams: {
+ formatResult: result =>
+ result?.list.map(item => ({
+ label: item.sinkName + ` ( ${sinks.find(c => c.value ===
item.sinkType)?.label} )`,
+ value: item.id,
+ })) || [],
+ },
+ },
+ }),
+ },
+ {
+ type: 'datepicker',
+ label: i18n.t('pages.GroupDetail.Delay.QueryDate'),
+ name: 'startDate',
+ initialValue: dayjs(initialValues.startDate),
+ props: {
+ allowClear: false,
+ format: 'YYYY-MM-DD',
+ },
+ },
+ {
+ type: 'select',
+ label: i18n.t('pages.GroupDetail.Audit.TimeStaticsDim'),
+ name: 'timeStaticsDim',
+ initialValue: initialValues.timeStaticsDim,
+ props: {
+ dropdownMatchSelectWidth: false,
+ options: timeStaticsDimList,
+ },
+ },
+ {
+ type: (
+ <Button type="primary" onClick={onSearch}>
+ {i18n.t('pages.GroupDetail.Audit.Search')}
+ </Button>
+ ),
+ },
+];
+
+export const getTableColumns = source => {
+ const data = source.map(item => ({
+ title: getAuditLabel(item.auditId, item.nodeType),
+ dataIndex: item.auditId,
+ render: text => text || 0,
+ }));
+ return [
+ {
+ title: i18n.t('pages.GroupDetail.Audit.Time'),
+ dataIndex: 'logTs',
+ },
+ ].concat(data);
+};
+
+export const getDelayColumns = source => {
+ const data = source.map(item => ({
+ title: getAuditLabel(item.auditId, item.nodeType),
+ dataIndex: item.auditId,
+ render: text => text || 0,
+ }));
+ return [
+ {
+ title: i18n.t('pages.GroupDetail.Audit.Time'),
+ dataIndex: 'logTs',
+ },
+ ].concat(data);
+};
diff --git a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
b/inlong-dashboard/src/ui/pages/GroupDetail/Delay/index.tsx
similarity index 67%
copy from inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
copy to inlong-dashboard/src/ui/pages/GroupDetail/Delay/index.tsx
index 93d1a26a51..1aa6d96237 100644
--- a/inlong-dashboard/src/ui/pages/GroupDetail/Audit/index.tsx
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/Delay/index.tsx
@@ -31,6 +31,8 @@ import {
getTableColumns,
timeStaticsDimList,
} from './config';
+import { Divider, Table } from 'antd';
+import i18n from '@/i18n';
type Props = CommonInterface;
@@ -61,6 +63,24 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
},
);
+ const { data: dayData = [], run: getDayData } = useRequest(
+ {
+ url: '/audit/list',
+ method: 'POST',
+ data: {
+ ...query,
+ timeStaticsDim: 'DAY',
+ startDate: timestampFormat(query.startDate, 'yyyy-MM-dd'),
+ endDate: timestampFormat(query.startDate, 'yyyy-MM-dd'),
+ inlongGroupId,
+ },
+ },
+ {
+ ready: Boolean(query.inlongStreamId),
+ formatResult: result => result.sort((a, b) => (a.auditId - b.auditId > 0
? 1 : -1)),
+ },
+ );
+
const sourceDataMap = useMemo(() => {
const flatArr = sourceData
.reduce(
@@ -81,21 +101,50 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
const output = flatArr.reduce((acc, cur) => {
if (!acc[cur.logTs]) {
acc[cur.logTs] = {};
- acc[cur.delay] = '';
}
acc[cur.logTs] = {
...acc[cur.logTs],
- [cur.auditId]: cur.count,
- [cur.delay]: cur.delay,
+ [cur.auditId]: cur.count === 0 ? cur.delay : Math.floor(cur.delay /
cur.count),
};
return acc;
}, {});
return output;
}, [sourceData, query.timeStaticsDim]);
+ const dayDataMap = useMemo(() => {
+ const flatArr = dayData
+ .reduce(
+ (acc, cur) =>
+ acc.concat(
+ cur.auditSet.map(item => ({
+ ...item,
+ auditId: cur.auditId,
+ })),
+ ),
+ [],
+ )
+ .sort((a, b) => {
+ const aT = +new Date(query.timeStaticsDim === 'HOUR' ? `${a.logTs}:00`
: a.logTs);
+ const bT = +new Date(query.timeStaticsDim === 'HOUR' ? `${b.logTs}:00`
: b.logTs);
+ return aT - bT;
+ });
+ const output = flatArr.reduce((acc, cur) => {
+ if (!acc[cur.logTs]) {
+ acc[cur.logTs] = {};
+ }
+ acc[cur.logTs] = {
+ ...acc[cur.logTs],
+ [cur.auditId]: cur.count === 0 ? cur.delay : Math.floor(cur.delay /
cur.count),
+ };
+ return acc;
+ }, {});
+ return output;
+ }, [dayData, query.timeStaticsDim]);
+
const onSearch = async () => {
await form.validateFields();
run();
+ getDayData();
};
const onDataStreamSuccess = data => {
@@ -104,6 +153,7 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
form.setFieldsValue({ inlongStreamId: defaultDataStream });
setQuery(prev => ({ ...prev, inlongStreamId: defaultDataStream }));
run();
+ getDayData();
}
};
@@ -126,6 +176,14 @@ const Comp: React.FC<Props> = ({ inlongGroupId }) => {
<Charts height={400} option={toChartData(sourceData, sourceDataMap)} />
</div>
+ <Divider>{i18n.t('pages.GroupDetail.Delay.AverageTitle')}</Divider>
+ <Table
+ columns={getTableColumns(dayData)}
+ dataSource={toTableData(dayData, dayDataMap)}
+ pagination={false}
+ />
+
+ <Divider style={{ marginTop: 50
}}>{i18n.t('pages.GroupDetail.Delay.RealTimeTitle')}</Divider>
<HighTable
table={{
columns: getTableColumns(sourceData),
diff --git a/inlong-dashboard/src/ui/pages/GroupDetail/index.tsx
b/inlong-dashboard/src/ui/pages/GroupDetail/index.tsx
index 98704a094d..f42fc8d433 100644
--- a/inlong-dashboard/src/ui/pages/GroupDetail/index.tsx
+++ b/inlong-dashboard/src/ui/pages/GroupDetail/index.tsx
@@ -28,6 +28,7 @@ import Info from './Info';
import DataStream from './DataStream';
import Audit from './Audit';
import ResourceInfo from './ResourceInfo';
+import Delay from './Delay';
const Comp: React.FC = () => {
const { t } = useTranslation();
@@ -83,6 +84,12 @@ const Comp: React.FC = () => {
content: ResourceInfo,
hidden: isReadonly || isCreate,
},
+ {
+ label: t('pages.GroupDetail.Delay'),
+ value: 'Delay',
+ content: Delay,
+ hidden: isReadonly || isCreate,
+ },
].filter(item => !item.hidden),
[isReadonly, isCreate, t],
);