Unverified Commit d01fa7ef authored by aiwenmo's avatar aiwenmo Committed by GitHub

[Feature-649][admin,web] add taskManager tableForm of DevOps

 [Feature-649][admin,web] add taskManager tableForm of DevOps
parents 902f6802 dc0737d7
package com.dlink.model;
import java.util.Set;
/**
* JobInfoDetail
*
......@@ -15,6 +17,7 @@ public class JobInfoDetail {
private History history;
private JobHistory jobHistory;
private JobManagerConfiguration jobManagerConfiguration;
private Set<TaskManagerConfiguration> taskManagerConfiguration;
private Integer refreshCount;
public JobInfoDetail(Integer id) {
......@@ -61,6 +64,15 @@ public class JobInfoDetail {
return jobManagerConfiguration;
}
public void setTaskManagerConfiguration(Set<TaskManagerConfiguration> taskManagerConfiguration) {
this.taskManagerConfiguration = taskManagerConfiguration;
}
public Set<TaskManagerConfiguration> getTaskManagerConfiguration() {
return taskManagerConfiguration;
}
public History getHistory() {
return history;
}
......
package com.dlink.model;/**
* @program: dlink
* @description:
* @author: zhumingye
* @create: 2022-06-27 11:41
*/
import lombok.Data;
import java.util.Map;
/**
* @program: dlink
* @description:
* @author: zhumingye
* @create: 2022-06-27 11:41
*/
@Data
public class TaskContainerConfigInfo {
private Map<String, String> metrics ;
private String taskManagerLog;
private String taskManagerStdout;
private String taskManagerThreadDump;
}
package com.dlink.model;
import lombok.Data;
/**
* @program: dlink
* @description:
* @author: zhumingye
* @create: 2022-06-27 11:18
*/
@Data
public class TaskManagerConfiguration {
private String containerId;
private String containerPath;
private Integer dataPort;
private Integer jmxPort;
private Long timeSinceLastHeartbeat;
private Integer slotsNumber;
private Integer freeSlots;
private String totalResource;
private String freeResource;
private String hardware;
private String memoryConfiguration;
private TaskContainerConfigInfo taskContainerConfigInfo;
}
......@@ -61,3 +61,18 @@ ol {
margin: 24px;
margin-bottom: 0!important;
}
div .ant-pro-card-body {
padding: 2px;
}
div .ant-pro-page-container{
padding-top: 1px;
}
div .ant-page-header {
padding-top: 0px;
}
div .ant-pro-page-container-children-content{
padding-top: 0px;
}
import {Descriptions, Empty, Tabs} from 'antd';
import CodeShow from "@/components/Common/CodeShow";
const {TabPane} = Tabs;
// TODO: 此页面需要根据设置的3秒刷新时间,自动刷新数据
const JobManagerConfiguration = (props: any) => {
const {job} = props;
const getMetricsConfigForm =() => {
let formList = [];
let tempData = job?.jobManagerConfiguration?.metrics;
for (let key in tempData) {
formList.push(
<Descriptions.Item label={key}>
{tempData[key]}
</Descriptions.Item>
)
}
return formList
}
const getJobManagerConfigForm = () => {
let formList = [];
let tempData = job?.jobManagerConfiguration?.jobManagerConfig;
for (let key in tempData) {
formList.push(
<Descriptions.Item label={key}>
{tempData[key]}
</Descriptions.Item>
)
}
return formList
}
return (
<>
<Tabs defaultActiveKey="metrics" size="small" tabPosition="top" style={{
border: "1px solid #f0f0f0",
}}>
<TabPane tab={<span>&nbsp; Metrics &nbsp;</span>} key="metrics">
<Descriptions bordered size="small" column={1}>
{getMetricsConfigForm()}
</Descriptions>
</TabPane>
<TabPane tab={<span>&nbsp; Configuration &nbsp;</span>} key="configuration">
<Descriptions bordered size="small" column={1}>
{getJobManagerConfigForm()}
</Descriptions>
</TabPane>
<TabPane tab={<span>&nbsp; Logs &nbsp;</span>} key="logs">
{(job?.jobManagerConfiguration?.jobManagerLog === ""|| job?.jobManagerConfig?.jobManagerLog === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={job?.jobManagerConfiguration?.jobManagerLog} language='java' height='500px'/>
}
</TabPane>
<TabPane tab={<span>&nbsp; Stdout &nbsp;</span>} key="stdout">
{(job?.jobManagerConfiguration?.jobManagerStdout === ""|| job?.jobManagerConfig?.jobManagerStdout === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={job?.jobManagerConfiguration?.jobManagerStdout} language='java' height='500px'/>
}
</TabPane>
</Tabs>
</>)
};
export default JobManagerConfiguration;
import {Button, Descriptions, Empty, Tabs} from 'antd';
import CodeShow from "@/components/Common/CodeShow";
import ProTable, {ActionType, ProColumns} from "@ant-design/pro-table";
import {parseByteStr} from "@/components/Common/function";
import {TaskManagerConfiguration} from "@/pages/DevOps/data";
import {useRef, useState} from "react";
import {history} from "@@/core/history";
import {HomeOutlined} from "@ant-design/icons";
const {TabPane} = Tabs;
// TODO: 此页面需要根据设置的3秒刷新时间,自动刷新数据
const TaskManagerConfigurationForm = (props: any) => {
const {job} = props;
const actionRef = useRef<ActionType>();
const [isHistory, setIsHistory] = useState<boolean>(false);
const handleHistorySwicthChange = (checked: boolean) => {
setIsHistory(checked);
};
const taskManagerContainerListDataSource: TaskManagerConfiguration[] = [];
job?.taskManagerConfiguration?.forEach((entity: TaskManagerConfiguration) => {
taskManagerContainerListDataSource.push({
containerId: entity.containerId,
containerPath: entity.containerPath,
dataPort: entity.dataPort,
jmxPort: entity.jmxPort,
timeSinceLastHeartbeat: entity.timeSinceLastHeartbeat,
slotsNumber: entity.slotsNumber,
freeSlots: entity.freeSlots,
totalResource: entity.totalResource,
freeResource: entity.freeResource,
hardware: entity.hardware,
memoryConfiguration: entity.memoryConfiguration,
taskContainerConfigInfo: entity.taskContainerConfigInfo,
});
}
);
const handleBack = () => {
history.goBack();
};
const getMetricsConfigForm =(metrics:any) => {
let formList = [];
for (let key in metrics) {
formList.push(
<Descriptions.Item label={key}>
{metrics[key]}
</Descriptions.Item>
)
}
return formList
}
const buildContainerConfigInfo =(entity: TaskManagerConfiguration) =>{
return (
<>
<div style={{ marginBottom: 16 }}>
<Button title={'返回'} onClick={handleBack}> ← Back<HomeOutlined /> </Button>
</div>
<Tabs defaultActiveKey="metrics" size="small"
tabPosition="top" style={{
border: "1px solid #f0f0f0",
}}>
<TabPane tab={<span>&nbsp; Metrics &nbsp;</span>} key="metrics">
{getMetricsConfigForm(entity?.taskContainerConfigInfo?.metrics)}
</TabPane>
<TabPane tab={<span>&nbsp; Logs &nbsp;</span>} key="logs">
{(entity?.taskContainerConfigInfo?.taskManagerLog === "" || entity?.taskContainerConfigInfo?.taskManagerLog === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={entity?.taskContainerConfigInfo?.taskManagerLog} language='java' height='500px'/>
}
</TabPane>
<TabPane tab={<span>&nbsp; Stdout &nbsp;</span>} key="stdout">
{(entity?.taskContainerConfigInfo?.taskManagerStdout === "" || entity?.taskContainerConfigInfo?.taskManagerLog === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={entity?.taskContainerConfigInfo?.taskManagerStdout} language='java' height='500px'/>
}
</TabPane>
<TabPane tab={<span>&nbsp; Thread Dump &nbsp;</span>} key="threaddump">
{(entity?.taskContainerConfigInfo?.taskManagerThreadDump === "" || entity?.taskContainerConfigInfo?.taskManagerThreadDump === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={entity?.taskContainerConfigInfo?.taskManagerThreadDump} language='java' height='500px'/>
}
</TabPane>
</Tabs>
</>
)
}
// TODO: 点击[containerId]跳转到容器配置信息页面(buildContainerConfigInfo) 容器页面有返回按钮 可以返回到个列表页面
const columns: ProColumns<TaskManagerConfiguration>[] = [
{
title: 'ID,Path',
dataIndex: 'containerId',
copyable: true,
render: (dom, entity) => {
return (
<>
<a style={{ width: 500 }} >{entity.containerId}</a>
<br/>
<span >{entity.containerPath}</span>
</>
);
},
},
{
title: 'Data Port',
align: 'center',
dataIndex: 'dataPort',
},
{
title: 'JMX Port',
align: 'center',
sorter: true,
dataIndex: 'jmxPort',
},
{
title: 'Last Heartbeat',
align: 'center',
sorter: true,
valueType: 'dateTime',
dataIndex: 'timeSinceLastHeartbeat',
},
{
title: 'All Solts',
align: 'center',
sorter: true,
dataIndex: 'slotsNumber',
},
{
title: 'Free Solts',
align: 'center',
sorter: true,
dataIndex: 'freeSlots',
},
{
title: 'CPU Cores',
align: 'center',
sorter: true,
render: (dom, entity) => {
return (JSON.parse(entity.totalResource))['cpuCores'];
},
},
{
title: 'Free Cores',
align: 'center',
sorter: true,
render: (dom, entity) => {
return (JSON.parse(entity.freeResource))['cpuCores'];
},
},
{
title: 'Physical Mem',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.hardware))['physicalMemory']);
},
},
{
title: 'Free Mem',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.hardware))['freeMemory']);
},
},
{
title: 'Hardware ManagedMem',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.hardware))['managedMemory']);
},
},
{
title: 'Total ProcessMem',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.memoryConfiguration))['totalProcessMemory']);
},
},
{
title: 'Total FlinkMem',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.memoryConfiguration))['totalFlinkMemory']);
},
},
{
title: 'Task Heap',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.memoryConfiguration))['taskHeap']);
},
},
{
title: 'JVM Heap',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.hardware))['freeMemory']);
},
},
{
title: 'Flink ManagedMem',
align: 'center',
sorter: true,
render: (dom, entity) => {
return parseByteStr((JSON.parse(entity.hardware))['managedMemory']);
},
},
];
return (
<>
{job?.taskManagerConfiguration?.length > 0 ?
<ProTable<TaskManagerConfiguration>
columns={columns}
style={{width: '100%'}}
dataSource={ taskManagerContainerListDataSource }
onDataSourceChange={(dataSource) => {
actionRef.current?.reload();
}}
actionRef={actionRef}
rowKey="containerId"
pagination={{
pageSize: 8,
}}
toolBarRender={false}
dateFormatter="string"
search={false}
size="small"
/>: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>}
</>
)
};
export default TaskManagerConfigurationForm;
import {Descriptions, Empty, Tabs} from 'antd';
import CodeShow from "@/components/Common/CodeShow";
const {TabPane} = Tabs;
import {useState} from 'react';
import {PageContainer} from '@ant-design/pro-layout';
import ProCard from '@ant-design/pro-card';
import JobManagerConfiguration from "@/pages/DevOps/JobInfo/ClusterConfiguration/JobManager";
import TaskManagerConfigurationForm from "@/pages/DevOps/JobInfo/ClusterConfiguration/TaskManager";
const ClusterConfiguration = (props: any) => {
const {} = props;
const {job} = props;
const [tabKey, setTabKey] = useState<string>('jobmanager');
return (
<PageContainer
header={{title: undefined}}
tabList={[
{
tab: 'Job Manager',
key: 'jobmanager',
closable: false,
},
{
tab: 'Task Managers',
key: 'taskmanager',
closable: false,
},
]}
onTabChange={(key) => {
setTabKey(key);
}}
>
<ProCard >
{tabKey === 'jobmanager' ? <JobManagerConfiguration job={job}/> : undefined}
{tabKey === 'taskmanager' ? <TaskManagerConfigurationForm job={job}/> : undefined}
</ProCard>
</PageContainer>
);
const getMetricsConfigForm =() => {
let formList = [];
let tempData = job?.jobManagerConfiguration?.metrics;
for (let key in tempData) {
formList.push(
<Descriptions.Item label={key}>
{tempData[key]}
</Descriptions.Item>
)
}
return formList
}
const getJobManagerConfigForm = () => {
let formList = [];
let tempData = job?.jobManagerConfiguration?.jobManagerConfig;
for (let key in tempData) {
formList.push(
<Descriptions.Item label={key}>
{tempData[key]}
</Descriptions.Item>
)
}
return formList
}
return (<>
<Tabs defaultActiveKey="metrics" size="small" tabPosition="top" style={{
border: "1px solid #f0f0f0",
}}>
<TabPane tab={<span>&nbsp; Metrics &nbsp;</span>} key="metrics">
<Descriptions bordered size="small" column={1}>
{getMetricsConfigForm()}
</Descriptions>
</TabPane>
<TabPane tab={<span>&nbsp; Configuration &nbsp;</span>} key="configuration">
<Descriptions bordered size="small" column={1}>
{getJobManagerConfigForm()}
</Descriptions>
</TabPane>
<TabPane tab={<span>&nbsp; Logs &nbsp;</span>} key="logs">
{(job?.jobManagerConfiguration?.jobManagerLog === ""|| job?.jobManagerConfig?.jobManagerLog === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={job?.jobManagerConfiguration?.jobManagerLog} language='java' height='500px'/>
}
</TabPane>
<TabPane tab={<span>&nbsp; Stdout &nbsp;</span>} key="stdout">
{(job?.jobManagerConfiguration?.jobManagerStdout === ""|| job?.jobManagerConfig?.jobManagerStdout === null) ?
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>
: <CodeShow code={job?.jobManagerConfiguration?.jobManagerStdout} language='java' height='500px'/>
}
</TabPane>
</Tabs>
</>)
};
export default ClusterConfiguration;
......@@ -2,6 +2,7 @@ import {ClusterTableListItem} from "@/pages/Cluster/data";
import {ClusterConfigurationTableListItem} from "@/pages/ClusterConfiguration/data";
import {HistoryItem} from "@/components/Studio/StudioConsole/StudioHistory/data";
import {JarTableListItem} from "@/pages/Jar/data";
import {List} from "antd";
export type JobInstanceTableListItem = {
id: number,
......@@ -47,6 +48,7 @@ export type JobInfoDetail = {
history: HistoryItem,
jobHistory: JobHistoryItem,
jobManagerConfiguration : JobManagerConfiguration
taskManagerConfiguration : List<TaskManagerConfiguration>
jar: JarTableListItem
}
......@@ -85,3 +87,30 @@ export type JobManagerConfiguration = {
jobManagerStdout: string,
}
export type TaskManagerConfiguration = {
containerId: string ,
containerPath: string,
dataPort : number,
jmxPort: number,
timeSinceLastHeartbeat: number,
slotsNumber: number,
freeSlots: number,
totalResource: string,
freeResource: string,
hardware: string,
memoryConfiguration: string,
taskContainerConfigInfo: TaskContainerConfigInfo,
}
export type TaskContainerConfigInfo = {
metrics: string ,
taskManagerLog: string ,
taskManagerStdout : string,
taskManagerThreadDump: string,
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment