Commit 5aa636ac by zhaochengxiang

采集日志

parent 2d61d825
import React from 'react';
export const DatasourceContext = React.createContext();
\ No newline at end of file
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useContext } from 'react';
import { Row, Col, Typography, Divider, Spin, Empty } from 'antd'; import { Row, Col, Typography, Divider, Spin, Empty } from 'antd';
import TaskItem from './TaskItem'; import TaskItem from './TaskItem';
import { dispatch } from '../../../../model'; import { dispatch } from '../../../../model';
import { DatasourceContext } from './ContextManager';
import './DatasourceItem.less'; import './DatasourceItem.less';
const DatasourceItem = (props) => { const DatasourceItem = (props) => {
const { data, onStartTask, onEditTask, onDeleteTask, expanded, refresh, refreshSuccess, scope } = props; const { data, expanded, refresh, scope } = props;
const [ tasks, setTasks ] = useState(null); const [ tasks, setTasks ] = useState(null);
const [ loading, setLoading ] = useState(false); const [ loading, setLoading ] = useState(false);
const { refreshTasksSuccess } = useContext(DatasourceContext);
useEffect(() => { useEffect(() => {
if (expanded && !tasks) { if (expanded && !tasks) {
getTasks(); getTasks();
...@@ -42,7 +45,7 @@ const DatasourceItem = (props) => { ...@@ -42,7 +45,7 @@ const DatasourceItem = (props) => {
callback: data => { callback: data => {
setLoading(false); setLoading(false);
setTasks(data); setTasks(data);
refresh && refreshSuccess && refreshSuccess(); refresh && refreshTasksSuccess && refreshTasksSuccess();
}, },
error: () => { error: () => {
setLoading(false); setLoading(false);
...@@ -93,9 +96,6 @@ const DatasourceItem = (props) => { ...@@ -93,9 +96,6 @@ const DatasourceItem = (props) => {
<TaskItem <TaskItem
key={index} key={index}
data={task} data={task}
onStart={onStartTask}
onEdit={onEditTask}
onDelete={onDeleteTask}
/> />
</Col> </Col>
); );
......
...@@ -6,7 +6,7 @@ import DatasourceItem from './DatasourceItem'; ...@@ -6,7 +6,7 @@ import DatasourceItem from './DatasourceItem';
const DatasourceList = (props) => { const DatasourceList = (props) => {
const { loading, data, onEdit, onAddTask, onDelete, onStartTask, onEditTask, onDeleteTask, idBindTasksNeedRefresh, refreshTasksSuccess, scope } = props; const { loading, data, onEdit, onAddTask, onDelete, idBindTasksNeedRefresh, scope } = props;
const [ expandedBindId, setExpandedBindId ] = useState({}); const [ expandedBindId, setExpandedBindId ] = useState({});
...@@ -69,7 +69,7 @@ const DatasourceList = (props) => { ...@@ -69,7 +69,7 @@ const DatasourceList = (props) => {
</Space> </Space>
</div> </div>
} }
description={ <DatasourceItem data={item} scope={scope} expanded={expanded} refresh={idBindTasksNeedRefresh===item.id} onStartTask={onStartTask} onEditTask={onEditTask} onDeleteTask={onDeleteTask} refreshSuccess={refreshTasksSuccess} /> } description={ <DatasourceItem data={item} scope={scope} expanded={expanded} refresh={idBindTasksNeedRefresh===item.id} /> }
/> />
</List.Item> </List.Item>
); );
......
import React from 'react'; import React, { useContext } from 'react';
import { Card, Typography, Space, Button, Tooltip } from 'antd'; import { Card, Typography, Space, Button, Tooltip } from 'antd';
import { EditOutlined, DeleteOutlined, DatabaseOutlined } from '@ant-design/icons'; import { EditOutlined, DeleteOutlined, DatabaseOutlined, FileOutlined } from '@ant-design/icons';
import { DatasourceContext } from './ContextManager';
import './TaskItem.less'; import './TaskItem.less';
const TaskItem = (props) => { const TaskItem = (props) => {
const { data, onStart, onEdit, onDelete } = props; const { data } = props;
const { onStartTask, onLogTask, onEditTask, onDeleteTask } = useContext(DatasourceContext);
return ( return (
<Card className='task-item'> <Card className='task-item'>
<div style={{ height: 80, overflow: 'auto' }}> <div style={{ height: 80, overflow: 'auto' }}>
...@@ -23,13 +26,16 @@ const TaskItem = (props) => { ...@@ -23,13 +26,16 @@ const TaskItem = (props) => {
<div className='d-flex mt-2'> <div className='d-flex mt-2'>
<Space style={{ marginLeft: 'auto' }}> <Space style={{ marginLeft: 'auto' }}>
<Tooltip placement='bottom' title='抽取'> <Tooltip placement='bottom' title='抽取'>
<Button icon={<DatabaseOutlined />} size='small' onClick={() => { onStart && onStart(data); }} /> <Button icon={<DatabaseOutlined />} size='small' onClick={() => { onStartTask && onStartTask(data); }} />
</Tooltip>
<Tooltip placement='bottom' title='日志'>
<Button icon={<FileOutlined />} size='small' onClick={() => { onLogTask && onLogTask(data); }} />
</Tooltip> </Tooltip>
<Tooltip placement='bottom' title='修改'> <Tooltip placement='bottom' title='修改'>
<Button icon={<EditOutlined />} size='small' onClick={() => { onEdit && onEdit(data); }} /> <Button icon={<EditOutlined />} size='small' onClick={() => { onEditTask && onEditTask(data); }} />
</Tooltip> </Tooltip>
<Tooltip placement='bottom' title='删除'> <Tooltip placement='bottom' title='删除'>
<Button icon={<DeleteOutlined />} size='small' onClick={() => { onDelete && onDelete(data); }} /> <Button icon={<DeleteOutlined />} size='small' onClick={() => { onDeleteTask && onDeleteTask(data); }} />
</Tooltip> </Tooltip>
</Space> </Space>
</div> </div>
......
import React, { useState, useEffect } from 'react';
import { Modal, Table, Typography, Spin, Empty, Button } from 'antd';
import { dispatch } from '../../../../model';
const TaskLogModal = (props) => {
const { visible, onCancel, id } = props;
const [ stateDatas, setStateDatas ] = useState([]);
const [ taskTracersBindStateId, setTaskTracersBindStateId ] = useState([]);
const [ expandedRowKeys, setExpandedRowKeys ] = useState([]);
const columns = [
{
title: '序号',
dataIndex: 'key',
render: (text, record, index) => {
return (index+1).toString();
},
width:80
},
{
title: '执行状态',
dataIndex: 'stateDesc',
ellipsis: true,
},
{
title: '开始时间',
dataIndex: 'tsDate',
ellipsis: true,
},
{
title: '结束时间',
dataIndex: 'etsDate',
ellipsis: true
}
];
useEffect(() => {
if (visible) {
getTaskStates();
}
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [ visible ])
const getTaskStates = () => {
dispatch({
type: 'datasource.getTaskStates',
payload: {
harvestingTaskId: id
},
callback: data => {
setStateDatas(data||[]);
}
})
}
const reset = () => {
setStateDatas([]);
setTaskTracersBindStateId([]);
setExpandedRowKeys([]);
}
return (
<Modal
className='task-report-modal'
forceRender
title={'日志详情'}
visible={visible}
width={1000}
onCancel={() => {
reset();
onCancel && onCancel()
}}
footer = {
<Button
key="1"
type="primary"
onClick={() => {
reset();
onCancel && onCancel()
}}
>
取消
</Button>
}
>
<Table
className='mt-5'
columns={columns}
rowKey={'id'}
dataSource={stateDatas||[]}
pagination={false}
sticky
expandable={{
expandedRowRender: record => {
let _tracer = null;
(taskTracersBindStateId||[]).forEach(item => {
if (item.key === record.id) {
_tracer = item.value||[];
}
})
return (
<Spin spinning={_tracer===null}>
{
(_tracer||[]).length === 0 && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无日志" />
}
{
_tracer && _tracer.map((_item, index) => {
return (
<Typography.Paragraph key={index} >
{_item.value||''}
</Typography.Paragraph>
)
})
}
</Spin>
);
},
expandedRowKeys,
onExpand: (expanded, record) => {
let exsit = false;
(taskTracersBindStateId||[]).forEach(item => {
if (item.key === record.id) {
exsit = true;
}
})
const newExpandedKeys = [...expandedRowKeys];
if (expanded) {
newExpandedKeys.push(record.id||'');
} else {
const index = newExpandedKeys.indexOf(record.id||'');
newExpandedKeys.splice(index, 1);
}
setExpandedRowKeys([...newExpandedKeys]);
if (expanded && !exsit) {
setTaskTracersBindStateId([...taskTracersBindStateId, { key: record.id, value: record.executionTraces||[] }]);
}
}
}}
/>
</Modal>
);
}
export default TaskLogModal;
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Modal, Row, Col, Card, Table, Typography, Spin, Empty, Button, DatePicker } from 'antd'; import { Modal, Row, Col, Card, Table, Typography, Spin, Empty, Button, DatePicker, Input } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import 'moment/locale/zh-cn'; import 'moment/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN'; import locale from 'antd/es/date-picker/locale/zh_CN';
import { dispatch, dispatchLatest } from '../../../../model'; import { dispatch, dispatchLatest } from '../../../../model';
import './TaskReportModal.less'; import './TaskLogsModal.less';
const { Meta } = Card; const { Meta } = Card;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const TaskReportModal = (props) => { const TaskLogsModal = (props) => {
const { visible, onCancel, scope, scopes } = props; const { visible, onCancel, scope, scopes } = props;
const [ summaryDatas, setSummaryDatas ] = useState([]); const [ summaryDatas, setSummaryDatas ] = useState([]);
...@@ -19,6 +19,8 @@ const TaskReportModal = (props) => { ...@@ -19,6 +19,8 @@ const TaskReportModal = (props) => {
const [ taskTracersBindStateId, setTaskTracersBindStateId ] = useState([]); const [ taskTracersBindStateId, setTaskTracersBindStateId ] = useState([]);
const [ rangeValue, setRangeValue ] = useState([]); const [ rangeValue, setRangeValue ] = useState([]);
const [ expandedRowKeys, setExpandedRowKeys ] = useState([]); const [ expandedRowKeys, setExpandedRowKeys ] = useState([]);
const [ keyword, setKeyword ] = useState('');
const [ filterReportData, setFilterReportData ] = useState([]);
useEffect(() => { useEffect(() => {
...@@ -108,6 +110,8 @@ const TaskReportModal = (props) => { ...@@ -108,6 +110,8 @@ const TaskReportModal = (props) => {
}) })
setReportDetail(data||{}); setReportDetail(data||{});
setFilterReportData(data?(data.datas||[]).filter(item => (item.scope||'').indexOf(keyword)!==-1 || (item.databaseName).indexOf(keyword)!==-1):[]);
} }
}) })
} }
...@@ -148,16 +152,23 @@ const TaskReportModal = (props) => { ...@@ -148,16 +152,23 @@ const TaskReportModal = (props) => {
setTaskTracersBindStateId([]); setTaskTracersBindStateId([]);
setCurrentSummaryData(item); setCurrentSummaryData(item);
setExpandedRowKeys([]); setExpandedRowKeys([]);
getTaskReportDetail(item.params); getTaskReportDetail(item.params, (rangeValue.length)>=1?rangeValue[0]: null, (rangeValue.length)===2?rangeValue[1]: null);
} }
} }
const onSearchInputChange = (e) => {
setKeyword(e.target.value||'');
setFilterReportData((reportDetail.datas||[]).filter(item => (item.scope||'').indexOf(e.target.value||'')!==-1 || (item.databaseName||'').indexOf(e.target.value||'')!==-1));
}
const reset = () => { const reset = () => {
setSummaryDatas([]); setSummaryDatas([]);
setCurrentSummaryData({}); setCurrentSummaryData({});
setReportDetail({}); setReportDetail({});
setTaskTracersBindStateId([]); setTaskTracersBindStateId([]);
setExpandedRowKeys([]); setExpandedRowKeys([]);
setFilterReportData([]);
setKeyword('');
} }
return ( return (
...@@ -224,11 +235,21 @@ const TaskReportModal = (props) => { ...@@ -224,11 +235,21 @@ const TaskReportModal = (props) => {
}) })
} }
</Row> </Row>
<div className='d-flex mt-5' style={{ alignItems: 'center' }}>
<span className='mr-3'>日志搜索:</span>
<Input
placeholder="请输入系统名称或者数据源名称"
allowClear
value={keyword}
onChange={onSearchInputChange}
style={{ width: 250 }}
/>
</div>
<Table <Table
className='mt-5' className='mt-3'
columns={reportDetail.title||[]} columns={reportDetail.title||[]}
rowKey={'taskStateId'} rowKey={'taskStateId'}
dataSource={reportDetail.datas||[]} dataSource={filterReportData||[]}
pagination={false} pagination={false}
sticky sticky
expandable={{ expandable={{
...@@ -288,4 +309,4 @@ const TaskReportModal = (props) => { ...@@ -288,4 +309,4 @@ const TaskReportModal = (props) => {
); );
} }
export default TaskReportModal; export default TaskLogsModal;
\ No newline at end of file \ No newline at end of file
...@@ -3,10 +3,12 @@ import { Space, Select, Button, Modal, Cascader } from 'antd'; ...@@ -3,10 +3,12 @@ import { Space, Select, Button, Modal, Cascader } from 'antd';
import DatasourceList from './Component/DatasourceList'; import DatasourceList from './Component/DatasourceList';
import UpdateDatasourceModal from './Component/UpdateDatasourceModal'; import UpdateDatasourceModal from './Component/UpdateDatasourceModal';
import TaskReportModal from './Component/TaskReportModal'; import TaskLogsModal from './Component/TaskLogsModal';
import TaskLogModal from './Component/TaskLogModal';
import UpdateTaskModal from './Component/UpdateTaskModal'; import UpdateTaskModal from './Component/UpdateTaskModal';
import { dispatch } from '../../../model'; import { dispatch } from '../../../model';
import { showMessage } from '../../../util'; import { showMessage } from '../../../util';
import { DatasourceContext } from './Component/ContextManager.js';
import './index.less'; import './index.less';
...@@ -27,7 +29,8 @@ const DatasourceManage = () => { ...@@ -27,7 +29,8 @@ const DatasourceManage = () => {
const [ updateDatasourceModalAction, setUpdateDatasourceModalAction ] = useState(''); const [ updateDatasourceModalAction, setUpdateDatasourceModalAction ] = useState('');
const [ updateTaskModalVisible, setUpdateTaskModalVisible ] = useState(false); const [ updateTaskModalVisible, setUpdateTaskModalVisible ] = useState(false);
const [ updateTaskModalAction, setUpdateTaskModalAction ] = useState(''); const [ updateTaskModalAction, setUpdateTaskModalAction ] = useState('');
const [ taskReportModalVisible, setTaskReportModalVisible ] = useState(false); const [ taskLogsModalVisible, setTaskLogsModalVisible ] = useState(false);
const [ taskLogModalVisible, setTaskLogModalVisible ] = useState(false);
const [ currentDatasourceId, setCurrentDatasourceId ] = useState(''); const [ currentDatasourceId, setCurrentDatasourceId ] = useState('');
const [ currentDatasourceIdBindTasksNeedRefresh, setCurrentDatasourceIdBindTasksNeedRefresh ] = useState(''); const [ currentDatasourceIdBindTasksNeedRefresh, setCurrentDatasourceIdBindTasksNeedRefresh ] = useState('');
const [ currentTaskId, setCurrentTaskId ] = useState(''); const [ currentTaskId, setCurrentTaskId ] = useState('');
...@@ -136,18 +139,18 @@ const DatasourceManage = () => { ...@@ -136,18 +139,18 @@ const DatasourceManage = () => {
setFilterDatasources((datasources||[]).filter(item=>value==='all'||item.type===value)); setFilterDatasources((datasources||[]).filter(item=>value==='all'||item.type===value));
} }
const showTaskReport = () => { const showTaskLogs = () => {
if (loadingDatabases) { if (loadingDatabases) {
showMessage('info', '正在获取系统信息,请稍后'); showMessage('info', '正在获取系统信息,请稍后');
return; return;
} }
setTaskReportModalVisible(true); setTaskLogsModalVisible(true);
} }
const onTaskReportModalCancel = () => { const onTaskLogsModalCancel = () => {
setTaskReportModalVisible(false); setTaskLogsModalVisible(false);
} }
const addDatasource = () => { const addDatasource = () => {
...@@ -224,6 +227,11 @@ const DatasourceManage = () => { ...@@ -224,6 +227,11 @@ const DatasourceManage = () => {
setUpdateTaskModalVisible(true); setUpdateTaskModalVisible(true);
} }
const logTask = (task) => {
setCurrentTaskId(task.id);
setTaskLogModalVisible(true);
}
const deleteTask = (task) => { const deleteTask = (task) => {
modal.confirm({ modal.confirm({
title: '是否确认删除该任务?', title: '是否确认删除该任务?',
...@@ -249,11 +257,22 @@ const DatasourceManage = () => { ...@@ -249,11 +257,22 @@ const DatasourceManage = () => {
refresh && setCurrentDatasourceIdBindTasksNeedRefresh(currentDatasourceId); refresh && setCurrentDatasourceIdBindTasksNeedRefresh(currentDatasourceId);
} }
const onTaskLogModalCancel = () => {
setTaskLogModalVisible(false);
}
const refreshTasksSuccess = () => { const refreshTasksSuccess = () => {
setCurrentDatasourceIdBindTasksNeedRefresh(''); setCurrentDatasourceIdBindTasksNeedRefresh('');
} }
return ( return (
<DatasourceContext.Provider value={{
refreshTasksSuccess: refreshTasksSuccess,
onStartTask: startTask,
onLogTask: logTask,
onEditTask: editTask,
onDeleteTask: deleteTask,
}}>
<div className='datasource-manage' style={{ backgroundColor: '#fff' }}> <div className='datasource-manage' style={{ backgroundColor: '#fff' }}>
<div <div
className='d-flex p-3' className='d-flex p-3'
...@@ -288,7 +307,7 @@ const DatasourceManage = () => { ...@@ -288,7 +307,7 @@ const DatasourceManage = () => {
</Select> </Select>
</Space> </Space>
<Space> <Space>
<Button type='primary' onClick={showTaskReport}>日志报告</Button> <Button type='primary' onClick={showTaskLogs}>日志报告</Button>
<Button type='primary' onClick={addDatasource}>新增数据源</Button> <Button type='primary' onClick={addDatasource}>新增数据源</Button>
</Space> </Space>
</div> </div>
...@@ -302,18 +321,14 @@ const DatasourceManage = () => { ...@@ -302,18 +321,14 @@ const DatasourceManage = () => {
onEdit={editDatasource} onEdit={editDatasource}
onAddTask={addTask} onAddTask={addTask}
onDelete={deleteDatasource} onDelete={deleteDatasource}
onStartTask={startTask}
onEditTask={editTask}
onDeleteTask={deleteTask}
refreshTasksSuccess={refreshTasksSuccess}
/> />
</div> </div>
<TaskReportModal <TaskLogsModal
visible={taskReportModalVisible} visible={taskLogsModalVisible}
scope={selectedScope} scope={selectedScope}
scopes={scopes} scopes={scopes}
onCancel={onTaskReportModalCancel} onCancel={onTaskLogsModalCancel}
/> />
<UpdateDatasourceModal <UpdateDatasourceModal
...@@ -332,9 +347,16 @@ const DatasourceManage = () => { ...@@ -332,9 +347,16 @@ const DatasourceManage = () => {
action={updateTaskModalAction} action={updateTaskModalAction}
onCancel={onUpdateTaskModalVisibleCancel} onCancel={onUpdateTaskModalVisibleCancel}
/> />
<TaskLogModal
visible={taskLogModalVisible}
id={currentTaskId}
onCancel={onTaskLogModalCancel}
/>
{contextHolder} {contextHolder}
</div> </div>
</DatasourceContext.Provider>
); );
} }
......
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