635 lines
18 KiB
TypeScript
635 lines
18 KiB
TypeScript
import React from 'react'
|
|
import {amisRender, commonInfo, crudCommonOptions, readOnlyDialogOptions} from '../../util/amis.tsx'
|
|
|
|
const color = (number: number) => {
|
|
let color = 'text-success'
|
|
if (number > 30) {
|
|
color = 'text-primary'
|
|
}
|
|
if (number > 90) {
|
|
color = 'text-danger'
|
|
}
|
|
return color
|
|
}
|
|
|
|
const versionDetailDialog = (variable: string, target: string) => {
|
|
return {
|
|
disabledOn: `${variable} === 0`,
|
|
type: 'action',
|
|
label: '详情',
|
|
level: 'link',
|
|
size: 'sm',
|
|
actionType: 'dialog',
|
|
dialog: {
|
|
title: '详情',
|
|
actions: [],
|
|
size: 'md',
|
|
closeOnEsc: false,
|
|
closeOnOutside: false,
|
|
body: [
|
|
{
|
|
type: 'service',
|
|
api: {
|
|
method: 'get',
|
|
url: `${commonInfo.baseUrl}/overview/version_detail`,
|
|
data: {
|
|
target: target,
|
|
version: '${version}',
|
|
},
|
|
},
|
|
body: [
|
|
{
|
|
type: 'table',
|
|
source: '${items}',
|
|
affixHeader: false,
|
|
columns: [
|
|
{
|
|
label: 'Flink job id',
|
|
fixed: 'left',
|
|
type: 'wrapper',
|
|
size: 'none',
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '${id}',
|
|
},
|
|
{
|
|
type: 'action',
|
|
level: 'link',
|
|
label: '',
|
|
icon: 'fa fa-copy',
|
|
size: 'xs',
|
|
actionType: 'copy',
|
|
content: '${id}',
|
|
tooltip: '复制 ID',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: '别名',
|
|
type: 'wrapper',
|
|
fixed: 'left',
|
|
size: 'none',
|
|
className: 'nowrap',
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '${alias}',
|
|
},
|
|
{
|
|
type: 'action',
|
|
level: 'link',
|
|
label: '',
|
|
icon: 'fa fa-copy',
|
|
size: 'xs',
|
|
actionType: 'copy',
|
|
content: '${alias}',
|
|
tooltip: '复制别名',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
}
|
|
}
|
|
|
|
const tableDetailDialog = (variable: string, targetList: any) => {
|
|
return {
|
|
disabledOn: `${variable} === 0`,
|
|
type: 'action',
|
|
label: '详情',
|
|
level: 'link',
|
|
size: 'sm',
|
|
actionType: 'dialog',
|
|
dialog: {
|
|
title: '详情',
|
|
size: 'md',
|
|
...readOnlyDialogOptions(),
|
|
body: [
|
|
{
|
|
type: 'table',
|
|
source: `\${${targetList}}`,
|
|
affixHeader: false,
|
|
columns: [
|
|
{
|
|
label: 'Flink job id',
|
|
fixed: 'left',
|
|
type: 'wrapper',
|
|
size: 'none',
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '${id}',
|
|
},
|
|
{
|
|
type: 'action',
|
|
level: 'link',
|
|
label: '',
|
|
icon: 'fa fa-copy',
|
|
size: 'xs',
|
|
actionType: 'copy',
|
|
content: '${id}',
|
|
tooltip: '复制 ID',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: '别名',
|
|
type: 'wrapper',
|
|
fixed: 'left',
|
|
size: 'none',
|
|
className: 'nowrap',
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '${alias}',
|
|
},
|
|
{
|
|
type: 'action',
|
|
level: 'link',
|
|
label: '',
|
|
icon: 'fa fa-copy',
|
|
size: 'xs',
|
|
actionType: 'copy',
|
|
content: '${alias}',
|
|
tooltip: '复制别名',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
}
|
|
}
|
|
|
|
const overviewYarnJob = (cluster: string, search: string, queue: string | undefined, yarnQueue: string) => {
|
|
return {
|
|
className: 'text-base leading-none',
|
|
type: 'table-view',
|
|
border: false,
|
|
padding: '0 10px 0 15px',
|
|
trs: [
|
|
{
|
|
tds: [
|
|
{
|
|
body: `${cluster}`,
|
|
},
|
|
{
|
|
padding: '0px',
|
|
body: queue === undefined ? {} : {
|
|
type: 'service',
|
|
api: `${commonInfo.baseUrl}/overview/queue?queue=${queue}`,
|
|
interval: 10000,
|
|
silentPolling: true,
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '${size}',
|
|
},
|
|
],
|
|
},
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
padding: '0px',
|
|
width: 200,
|
|
body: {
|
|
type: 'service',
|
|
api: {
|
|
method: 'get',
|
|
url: `${commonInfo.baseUrl}/overview/yarn-cluster`,
|
|
data: {
|
|
cluster: cluster,
|
|
queue: yarnQueue,
|
|
},
|
|
// @ts-ignore
|
|
adaptor: function (payload, response) {
|
|
let rootUsed = (payload['data']['root']['usedCapacity'] * 100 / payload['data']['root']['capacity'])
|
|
let targetUsed = (payload['data']['target']['absoluteUsedCapacity'] * 100 / payload['data']['target']['absoluteMaxCapacity'])
|
|
return {
|
|
...payload,
|
|
data: {
|
|
...payload.data,
|
|
rootUsed: rootUsed,
|
|
rootUsedColor: color(rootUsed),
|
|
targetUsed: targetUsed,
|
|
targetUsedColor: color(targetUsed),
|
|
},
|
|
}
|
|
},
|
|
},
|
|
interval: 10000,
|
|
silentPolling: true,
|
|
body: {
|
|
type: 'table-view',
|
|
border: false,
|
|
trs: [
|
|
{
|
|
tds: [
|
|
{
|
|
body: {
|
|
type: 'tpl',
|
|
tpl: '<span class="font-bold ${rootUsedColor}">${ROUND(rootUsed, 0)}%</span>',
|
|
},
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
body: {
|
|
type: 'tpl',
|
|
tpl: '<span class="font-bold ${targetUsedColor}">${ROUND(targetUsed, 0)}%</span>',
|
|
},
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
padding: '0px',
|
|
width: 200,
|
|
body: {
|
|
type: 'service',
|
|
api: {
|
|
url: `${commonInfo.baseUrl}/overview/yarn-job`,
|
|
data: {
|
|
cluster: cluster,
|
|
search: search,
|
|
},
|
|
},
|
|
interval: 10000,
|
|
silentPolling: true,
|
|
body: {
|
|
type: 'table-view',
|
|
border: false,
|
|
trs: [
|
|
{
|
|
tds: [
|
|
{
|
|
body: {
|
|
type: 'tpl',
|
|
tpl: '<span class=\'font-bold text-cyan-300\'>${scheduling}</span>',
|
|
},
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
body: {
|
|
type: 'tpl',
|
|
tpl: '<span class="font-bold text-success">${running}</span>',
|
|
},
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
}
|
|
|
|
const Overview: React.FC = () => {
|
|
return (
|
|
<div className="hudi-overview">
|
|
{amisRender(
|
|
{
|
|
type: 'wrapper',
|
|
body: [
|
|
{
|
|
type: 'service',
|
|
// language=JavaScript
|
|
dataProvider: 'const timer = setInterval(() => {\n setData({date: new Date().toLocaleString()})\n}, 1000)\nreturn () => {\n clearInterval(timer)\n}',
|
|
body: [
|
|
'当前时间:',
|
|
{
|
|
type: 'tpl',
|
|
className: 'font-bold',
|
|
tpl: '${date}',
|
|
},
|
|
],
|
|
},
|
|
{type: 'divider'},
|
|
{
|
|
type: 'crud',
|
|
title: '同步表数量',
|
|
api: `${commonInfo.baseUrl}/overview`,
|
|
...crudCommonOptions(),
|
|
interval: 60000,
|
|
columns: [
|
|
{
|
|
name: 'type',
|
|
label: '表类型',
|
|
},
|
|
{
|
|
name: 'total',
|
|
label: '总表数',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
name: 'focus',
|
|
label: '重点表',
|
|
className: 'text-danger font-bold',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
label: '普通表',
|
|
type: 'tpl',
|
|
tpl: '${total - focus}',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'crud',
|
|
title: '同步表数量',
|
|
api: `${commonInfo.baseUrl}/overview/sync_running_status`,
|
|
...crudCommonOptions(),
|
|
interval: 10000,
|
|
columns: [
|
|
{
|
|
name: 'type',
|
|
label: '类型',
|
|
},
|
|
{
|
|
name: 'total',
|
|
label: '任务数',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
name: 'running',
|
|
label: '运行中',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
name: 'stopped',
|
|
label: '已停止',
|
|
className: 'text-danger font-bold',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
type: 'operation',
|
|
label: '操作',
|
|
width: 100,
|
|
align: 'center',
|
|
buttons: [
|
|
tableDetailDialog('stopped', 'list'),
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
className: 'pl-2 my-5',
|
|
type: 'wrapper',
|
|
size: 'none',
|
|
body: {
|
|
type: 'tpl',
|
|
tpl: '同步集群资源用量情况',
|
|
},
|
|
},
|
|
{
|
|
type: 'table-view',
|
|
border: false,
|
|
trs: [
|
|
{
|
|
background: '#F9F9F9',
|
|
tds: [
|
|
{
|
|
bold: true,
|
|
body: '集群',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '集群资源',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '队列资源',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '调度中',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '运行中',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
overviewYarnJob(commonInfo.clusters.sync_names(), 'Sync', undefined, 'default'),
|
|
{type: 'divider'},
|
|
{
|
|
className: 'pl-2 my-5',
|
|
type: 'wrapper',
|
|
size: 'none',
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '压缩集群资源用量情况',
|
|
},
|
|
{
|
|
className: 'mt-2',
|
|
type: 'service',
|
|
api: `${commonInfo.baseUrl}/overview/queue?queue=compaction-queue-pre`,
|
|
interval: 10000,
|
|
silentPolling: true,
|
|
body: [
|
|
{
|
|
type: 'tpl',
|
|
tpl: '预调度队列:<span class="font-bold">${size}</span>',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'table-view',
|
|
border: false,
|
|
bold: true,
|
|
trs: [
|
|
{
|
|
background: '#F9F9F9',
|
|
tds: [
|
|
{
|
|
bold: true,
|
|
body: '集群',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '队列',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '集群资源',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '队列资源',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '调度中',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
bold: true,
|
|
body: '运行中',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
// @ts-ignore
|
|
...Object.keys(commonInfo.clusters.compaction).map(name => overviewYarnJob(name, 'Compaction', `compaction-queue-${name}`, commonInfo.clusters.compaction[name])),
|
|
{type: 'divider'},
|
|
{
|
|
type: 'service',
|
|
api: `${commonInfo.baseUrl}/overview/version`,
|
|
interval: 10000,
|
|
silentPolling: true,
|
|
body: [
|
|
{
|
|
type: 'table',
|
|
title: '跨天情况 (${version})',
|
|
source: '${items}',
|
|
...crudCommonOptions(),
|
|
headerToolbar: [
|
|
'${version}',
|
|
],
|
|
columns: [
|
|
{
|
|
name: 'type',
|
|
label: '类型',
|
|
},
|
|
{
|
|
name: 'unReceive',
|
|
label: '未接收',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
type: 'operation',
|
|
label: '操作',
|
|
width: 100,
|
|
align: 'center',
|
|
buttons: [
|
|
versionDetailDialog('unReceive', 'unReceive_${key}'),
|
|
],
|
|
},
|
|
{
|
|
name: 'unScheduled',
|
|
label: '未跨天',
|
|
className: 'text-danger font-bold',
|
|
width: 100,
|
|
align: 'center',
|
|
},
|
|
{
|
|
type: 'operation',
|
|
label: '操作',
|
|
width: 100,
|
|
align: 'center',
|
|
buttons: [
|
|
versionDetailDialog('unScheduled', 'unScheduled_${key}'),
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'crud',
|
|
title: '调度策略',
|
|
api: `${commonInfo.baseUrl}/overview/schedule_jobs`,
|
|
...crudCommonOptions(),
|
|
interval: 60000,
|
|
loadDataOnce: true,
|
|
columns: [
|
|
{
|
|
name: 'job',
|
|
label: '策略描述',
|
|
},
|
|
{
|
|
name: 'trigger',
|
|
label: 'Cron表达式',
|
|
className: 'font-mono',
|
|
width: 250,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'crud',
|
|
title: '监控指标运行进度',
|
|
api: `${commonInfo.baseUrl}/overview/monitor_progress`,
|
|
...crudCommonOptions(),
|
|
interval: 2000,
|
|
loadDataOnce: true,
|
|
columns: [
|
|
{
|
|
name: 'name',
|
|
label: '名称',
|
|
width: 150,
|
|
},
|
|
{
|
|
name: 'running',
|
|
label: '状态',
|
|
type: 'mapping',
|
|
width: 70,
|
|
map: {
|
|
'true': '运行中',
|
|
'false': '未运行',
|
|
},
|
|
},
|
|
{
|
|
label: '进度',
|
|
type: 'progress',
|
|
value: '${ROUND(progress * 100)}',
|
|
map: 'bg-primary',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Overview |