|
@@ -1,22 +1,9 @@
|
|
|
-import { Card, Table} from 'antd'
|
|
|
+import { Card, Table, Tree } from 'antd'
|
|
|
import React, { useEffect, useState } from 'react'
|
|
|
import { useLocation } from 'react-router-dom'
|
|
|
import styled from 'styled-components'
|
|
|
-// import { getOnceJoblog } from '../services/index'
|
|
|
+import { getLogInfo, getJobLog } from '../services/index'
|
|
|
|
|
|
-/* const LogWrapper = styled.div`
|
|
|
- padding: 30px;
|
|
|
- width: 100%;
|
|
|
- height: 800px;
|
|
|
- background-color: #fff;
|
|
|
- .log {
|
|
|
- background-color: #012b36;
|
|
|
- height: 100%;
|
|
|
- overflow-y: scroll;
|
|
|
- color: #638691;
|
|
|
- padding: 8px 10px;
|
|
|
- }
|
|
|
-` */
|
|
|
const LogWrapper = styled.div`
|
|
|
padding: 20px;
|
|
|
display: flex;
|
|
@@ -26,7 +13,7 @@ const LogWrapper = styled.div`
|
|
|
flex: 1;
|
|
|
}
|
|
|
.log-info {
|
|
|
- width: 920px
|
|
|
+ width: 920px;
|
|
|
}
|
|
|
.log {
|
|
|
background-color: #012b36;
|
|
@@ -35,31 +22,51 @@ const LogWrapper = styled.div`
|
|
|
overflow-y: scroll;
|
|
|
color: #638691;
|
|
|
padding: 8px 10px;
|
|
|
+ ::-webkit-scrollbar {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .node_list {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ .node_table {
|
|
|
+ overflow: auto;
|
|
|
+ height: 650px
|
|
|
+ ::-webkit-scrollbar {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
}
|
|
|
.ant-table-selection-column {
|
|
|
display: none !important;
|
|
|
}
|
|
|
`
|
|
|
|
|
|
+const { DirectoryTree } = Tree
|
|
|
|
|
|
const TaskLogWatcher = () => {
|
|
|
const { state } = useLocation()
|
|
|
- const [logData, setLogData] = useState(null)
|
|
|
- // 初始化作业列表
|
|
|
+ const [logData, setLogData] = useState('请选择节点查看任务')
|
|
|
+ // 初始化节点列表
|
|
|
const [jobList, setJobList] = useState([])
|
|
|
// 选中的作业
|
|
|
const [selectJob, setSelectJob] = useState(null)
|
|
|
+ // 单/多作业类型
|
|
|
+ const [taskType, setTaskType] = useState(null)
|
|
|
+
|
|
|
+ const [treeData, setTreeData] = useState([])
|
|
|
|
|
|
const columns = [
|
|
|
{
|
|
|
title: '序号',
|
|
|
dataIndex: 'index',
|
|
|
- key: 'index'
|
|
|
+ key: 'index',
|
|
|
},
|
|
|
{
|
|
|
title: '作业名称',
|
|
|
dataIndex: 'jobName',
|
|
|
- key: 'jobName'
|
|
|
+ key: 'jobName',
|
|
|
},
|
|
|
{
|
|
|
title: '执行结果',
|
|
@@ -77,84 +84,111 @@ const TaskLogWatcher = () => {
|
|
|
]
|
|
|
|
|
|
const fetchOnceJoblog = async () => {
|
|
|
- // const { data } = await getOnceJoblog(state.id)
|
|
|
- // if (data.code === 200) {
|
|
|
- // setLogData(data.data.handle_msg)
|
|
|
- // }
|
|
|
- setLogData(`2022-08-17 09:28:30,1761 "/opt/conda/envs/py38/lib/python3.8/site-packages/pyhive/hive.py",line 449, INFO:USE default
|
|
|
-2022-08-17 09:28:30,1871 "/opt/conda/envs/py38/lib/python3.8/site-packages/pyhive/hive.py",line 449, INFO:USE default
|
|
|
-2022-08-17 09:28:30,2161 "/opt/conda/envs/py38/lib/python3.8/site-packages/pyhive/hive.py",line 449, INFO:describe default.my_test_p
|
|
|
-2022-08-17 09:28:30,2401 "/opt/conda/envs/py38/lib/python3.8/site-packages/pyhive/hive.py",line 449, INFO:describe default.my_test_p
|
|
|
-`)
|
|
|
- setJobList([
|
|
|
- {
|
|
|
- key: '1',
|
|
|
- index: '1',
|
|
|
- jobName: '作业名称1',
|
|
|
- handleResult: 1
|
|
|
- },
|
|
|
- {
|
|
|
- key: '2',
|
|
|
- index: '2',
|
|
|
- jobName: '作业名称2',
|
|
|
- handleResult: 0
|
|
|
- },
|
|
|
- {
|
|
|
- key: '3',
|
|
|
- index: '3',
|
|
|
- jobName: '作业名称3',
|
|
|
- handleResult: 1
|
|
|
- },
|
|
|
- {
|
|
|
- key: '4',
|
|
|
- index: '4',
|
|
|
- jobName: '作业名称4',
|
|
|
- handleResult: 1
|
|
|
- },
|
|
|
- ])
|
|
|
+ const { data } = await getLogInfo(state.id)
|
|
|
+ if (data.code === 200) {
|
|
|
+ setTaskType(data.data.job_type)
|
|
|
+ if (data.data.job_type === '单作业离线任务')
|
|
|
+ formatSingleTask(data.data.logs)
|
|
|
+ if (data.data.job_type === '多作业离线任务')
|
|
|
+ formatMultiTask(data.data.logs)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const formatSingleTask = data => {
|
|
|
+ const list = data.map((item, index) => ({
|
|
|
+ key: item.id,
|
|
|
+ index: index + 1,
|
|
|
+ jobName: item.node_name,
|
|
|
+ job_log_uri: item.job_log_uri,
|
|
|
+ handleResult: item.executor_result,
|
|
|
+ }))
|
|
|
+ setJobList(list)
|
|
|
+ onClickTableNode(list[0])
|
|
|
+ }
|
|
|
+
|
|
|
+ const formatMultiTask = data => {
|
|
|
+ const list = data.map((item, index) => {
|
|
|
+ const children = item.nodes.map((node, i) => {
|
|
|
+ return {
|
|
|
+ title: node.node_name,
|
|
|
+ key: `${index}-${i}`,
|
|
|
+ uri: node.job_log_uri,
|
|
|
+ isLeaf: true,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ title: item.homework_name,
|
|
|
+ key: String(index),
|
|
|
+ children,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ setTreeData(list)
|
|
|
+ }
|
|
|
+
|
|
|
+ const fetchJobLogInfo = async uri => {
|
|
|
+ const { data } = await getJobLog(uri)
|
|
|
+ setLogData(data)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onClickTableNode = record => {
|
|
|
+ setSelectJob(record.key)
|
|
|
+ fetchJobLogInfo(record.job_log_uri)
|
|
|
+ }
|
|
|
+
|
|
|
+ const onClickTreeNode = (_, info) => {
|
|
|
+ console.log('$$$', _, info)
|
|
|
+ if (info.node.uri) fetchJobLogInfo(info.node.uri)
|
|
|
}
|
|
|
|
|
|
useEffect(() => {
|
|
|
fetchOnceJoblog()
|
|
|
}, [state])
|
|
|
|
|
|
+ const singleTable = (
|
|
|
+ <Table
|
|
|
+ columns={columns}
|
|
|
+ dataSource={jobList}
|
|
|
+ showHeader={false}
|
|
|
+ className="node_table"
|
|
|
+ pagination={{ position: ['none', 'none'] }}
|
|
|
+ onRow={record => {
|
|
|
+ return {
|
|
|
+ onClick: () => onClickTableNode(record),
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ rowSelection={{
|
|
|
+ type: 'radio',
|
|
|
+ columnWidth: '0',
|
|
|
+ selectedRowKeys: [selectJob],
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ const multiTree = (
|
|
|
+ <DirectoryTree onSelect={onClickTreeNode} treeData={treeData} />
|
|
|
+ )
|
|
|
+
|
|
|
return (
|
|
|
<LogWrapper>
|
|
|
{/* <pre className="log">{logData}</pre> */}
|
|
|
- <div className='job-list'>
|
|
|
+ <div className="job-list">
|
|
|
<Card
|
|
|
- size='small'
|
|
|
- title='作业列表'
|
|
|
+ size="small"
|
|
|
+ title="节点列表"
|
|
|
bordered={false}
|
|
|
- style={{height: '100%', width: '100%'}}
|
|
|
- headStyle={{padding: '6px 10px', fontSize: '13px'}}
|
|
|
- >
|
|
|
- <Table
|
|
|
- columns={columns}
|
|
|
- dataSource={jobList}
|
|
|
- showHeader={false}
|
|
|
- onRow={record => {
|
|
|
- return {
|
|
|
- onClick: e => {
|
|
|
- setSelectJob(record.key)
|
|
|
- setLogData('test: ' + record.jobName)
|
|
|
- }
|
|
|
- }
|
|
|
- }}
|
|
|
- rowSelection={{
|
|
|
- type: 'radio',
|
|
|
- columnWidth: '0',
|
|
|
- selectedRowKeys: [selectJob]
|
|
|
- }}
|
|
|
- />
|
|
|
+ className="node_list"
|
|
|
+ headStyle={{
|
|
|
+ padding: '10px 15px',
|
|
|
+ fontSize: '14px',
|
|
|
+ fontWeight: '700',
|
|
|
+ }}>
|
|
|
+ {taskType === '单作业离线任务' ? singleTable : multiTree}
|
|
|
</Card>
|
|
|
</div>
|
|
|
- <div className='log-info'>
|
|
|
+ <div className="log-info">
|
|
|
<Card
|
|
|
bordered={false}
|
|
|
- style={{height: '100%', width: '100%'}}
|
|
|
- bodyStyle={{height: '100%', width: '100%'}}
|
|
|
- >
|
|
|
+ style={{ height: '100%', width: '100%' }}
|
|
|
+ bodyStyle={{ height: '100%', width: '100%' }}>
|
|
|
<pre className="log">{logData}</pre>
|
|
|
</Card>
|
|
|
</div>
|