added spider stats

This commit is contained in:
Marvin Zhang
2019-07-26 17:07:24 +08:00
parent 1e8afe6923
commit 946bb7ceba
22 changed files with 763 additions and 451 deletions

View File

@@ -74,4 +74,8 @@ export default {
width: 100%;
text-align: right;
}
.el-table {
min-height: 360px;
}
</style>

View File

@@ -87,23 +87,9 @@ export default {
}
},
methods: {
getIcon (type) {
if (type === 1) {
return 'fa-file-o'
} else if (type === 2) {
return 'fa-folder'
}
},
onEdit () {
this.isEdit = true
},
onChange (path) {
this.$store.commit('file/SET_CURRENT_PATH', path)
},
onChangeSubmit () {
this.isEdit = false
this.$store.dispatch('file/getFileList', { path: this.currentPath })
},
onItemClick (item) {
if (item.is_dir) {
// 目录

View File

@@ -13,24 +13,33 @@
<status-tag :status="taskForm.status"/>
</el-form-item>
<el-form-item :label="$t('Log File Path')">
<el-input v-model="taskForm.log_stdout_path" placeholder="Log File Path" disabled></el-input>
<el-input v-model="taskForm.log_path" placeholder="Log File Path" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Create Timestamp')">
<el-input v-model="taskForm.create_ts" placeholder="Create Timestamp" disabled></el-input>
<el-form-item :label="$t('Create Time')">
<el-input :value="getTime(taskForm.create_ts)" placeholder="Create Time" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Finish Timestamp')">
<el-input v-model="taskForm.finish_ts" placeholder="Finish Timestamp" disabled></el-input>
<el-form-item :label="$t('Start Time')">
<el-input :value="getTime(taskForm.start_ts)" placeholder="Start Time" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Duration (sec)')">
<el-input v-model="taskForm.duration" placeholder="Duration" disabled></el-input>
<el-form-item :label="$t('Finish Time')">
<el-input :value="getTime(taskForm.finish_ts)" placeholder="Finish Time" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Wait Duration (sec)')">
<el-input :value="getWaitDuration(taskForm)" placeholder="Wait Duration" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Runtime Duration (sec)')">
<el-input :value="getRuntimeDuration(taskForm)" placeholder="Runtime Duration" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Total Duration (sec)')">
<el-input :value="getTotalDuration(taskForm)" placeholder="Runtime Duration" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Results Count')">
<el-input v-model="taskForm.num_results" placeholder="Results Count" disabled></el-input>
</el-form-item>
<el-form-item :label="$t('Average Results Count per Second')">
<el-input v-model="taskForm.avg_num_results" placeholder="Average Results Count per Second" disabled>
</el-input>
<el-input v-model="taskForm.result_count" placeholder="Results Count" disabled></el-input>
</el-form-item>
<!--<el-form-item :label="$t('Average Results Count per Second')">-->
<!--<el-input v-model="taskForm.avg_num_results" placeholder="Average Results Count per Second" disabled>-->
<!--</el-input>-->
<!--</el-form-item>-->
<el-form-item :label="$t('Error Message')" v-if="taskForm.status === 'error'">
<div class="error-message">
{{ taskForm.error }}
@@ -50,6 +59,7 @@ import {
mapState
} from 'vuex'
import StatusTag from '../Status/StatusTag'
import dayjs from 'dayjs'
export default {
name: 'NodeInfoView',
@@ -70,6 +80,22 @@ export default {
.then(() => {
this.$message.success(`Task "${this.$route.params.id}" has been sent signal to stop`)
})
},
getTime (str) {
if (!str || str.match('^0001')) return 'NA'
return dayjs(str).format('YYYY-MM-DD HH:mm:ss')
},
getWaitDuration (row) {
if (row.start_ts.match('^0001')) return 'NA'
return dayjs(row.start_ts).diff(row.create_ts, 'second')
},
getRuntimeDuration (row) {
if (row.finish_ts.match('^0001')) return 'NA'
return dayjs(row.finish_ts).diff(row.start_ts, 'second')
},
getTotalDuration (row) {
if (row.finish_ts.match('^0001')) return 'NA'
return dayjs(row.finish_ts).diff(row.create_ts, 'second')
}
}
}

View File

@@ -100,14 +100,14 @@ export default {
if (this.masterNode.id === this.nodes[i].id) continue
// master
links.push({
source: this.masterNode.id,
target: this.nodes[i].id,
value: 0.5,
lineStyle: {
color: '#409EFF'
}
})
// links.push({
// source: this.masterNode.id,
// target: this.nodes[i].id,
// value: 0.5,
// lineStyle: {
// color: '#409EFF'
// }
// })
}
return links
}
@@ -120,6 +120,7 @@ export default {
},
tooltip: {
formatter: params => {
if (!params.data.name) return
let str = '<span style="margin-right:5px;display:inline-block;height:12px;width:12px;border-radius:6px;background:' + params.color + '"></span>'
if (params.data.name) str += '<span>' + params.data.name + '</span><br>'
if (params.data.ip) str += '<span>IP: ' + params.data.ip + '</span><br>'

View File

@@ -27,7 +27,6 @@ export default {
default: ''
},
value: {
type: String,
default: ''
},
type: {

View File

@@ -17,20 +17,14 @@
type="success"/>
<metric-card :label="$t('Avg Duration (sec)')"
icon="fa fa-hourglass"
:value="getDecimal(overviewStats.avg_duration)"
:value="getDecimal(overviewStats.avg_runtime_duration)"
type="warning"/>
</div>
</el-row>
<!--./overall stats-->
<el-row>
<el-col :span="8">
<el-card class="chart-wrapper" style="margin-right: 20px;">
<h4>{{$t('Tasks by Status')}}</h4>
<div id="task-pie-status" class="chart"></div>
</el-card>
</el-col>
<el-col :span="16">
<el-col :span="24">
<el-card class="chart-wrapper">
<h4>{{$t('Daily Tasks')}}</h4>
<div id="task-line" class="chart"></div>
@@ -39,13 +33,7 @@
</el-row>
<el-row>
<el-col :span="8">
<el-card class="chart-wrapper" style="margin-right: 20px;">
<h4>{{$t('Tasks by Node')}}</h4>
<div id="task-pie-node" class="chart"></div>
</el-card>
</el-col>
<el-col :span="16">
<el-col :span="24">
<el-card class="chart-wrapper">
<h4>{{$t('Daily Avg Duration (sec)')}}</h4>
<div id="duration-line" class="chart"></div>
@@ -71,64 +59,6 @@ export default {
}
},
methods: {
renderTaskPieStatus () {
const chart = echarts.init(this.$el.querySelector('#task-pie-status'))
const option = {
tooltip: {
show: true
},
series: [{
name: '',
type: 'pie',
// radius: ['50%', '70%'],
data: this.statusStats.map(d => {
let color
if (d.name === 'SUCCESS') {
color = '#67c23a'
} else if (d.name === 'STARTED') {
color = '#e6a23c'
} else if (d.name === 'FAILURE') {
color = '#f56c6c'
} else {
color = 'grey'
}
return {
name: this.$t(d.name),
value: d.value,
itemStyle: {
color
}
}
})
}]
}
chart.setOption(option)
},
renderTaskPieNode () {
const chart = echarts.init(this.$el.querySelector('#task-pie-node'))
const option = {
tooltip: {
show: true
},
series: [{
name: '',
type: 'pie',
// radius: ['50%', '70%'],
data: this.nodeStats.map(d => {
return {
name: d.name,
value: d.value
// itemStyle: {
// color
// }
}
})
}]
}
chart.setOption(option)
},
renderTaskLine () {
const chart = echarts.init(this.$el.querySelector('#task-line'))
const option = {
@@ -145,7 +75,7 @@ export default {
},
series: [{
type: 'line',
data: this.dailyStats.map(d => d.count),
data: this.dailyStats.map(d => d.task_count),
areaStyle: {},
smooth: true
}],
@@ -173,7 +103,7 @@ export default {
},
series: [{
type: 'line',
data: this.dailyStats.map(d => d.duration),
data: this.dailyStats.map(d => d.avg_runtime_duration),
areaStyle: {},
smooth: true
}],
@@ -186,9 +116,7 @@ export default {
},
render () {
this.renderTaskPieStatus()
this.renderTaskLine()
this.renderTaskPieNode()
this.renderDurationLine()
},

View File

@@ -4,7 +4,7 @@
<h5 class="title">{{title}}</h5>
<el-button type="success" plain class="small-btn" size="mini" icon="fa fa-refresh" @click="onRefresh"></el-button>
</el-row>
<el-table border height="480px" :data="taskList">
<el-table border height="480px" :data="taskList" @row-click="onClickTask">
<el-table-column property="node" :label="$t('Node')" width="120" align="left">
<template slot-scope="scope">
<a class="a-tag" @click="onClickNode(scope.row)">{{scope.row.node_name}}</a>
@@ -15,6 +15,11 @@
<a class="a-tag" @click="onClickSpider(scope.row)">{{scope.row.spider_name}}</a>
</template>
</el-table-column>
<el-table-column property="result_count" :label="$t('Results Count')" width="60" align="right">
<template slot-scope="scope">
<span>{{scope.row.result_count}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('Status')"
align="left"
width="100">
@@ -23,7 +28,7 @@
</template>
</el-table-column>
<!--<el-table-column property="create_ts" label="Create Time" width="auto" align="center"></el-table-column>-->
<el-table-column property="create_ts" :label="$t('Create Time')" width="auto" align="left">
<el-table-column property="create_ts" :label="$t('Create Time')" width="150" align="left">
<template slot-scope="scope">
<a href="javascript:" class="a-tag" @click="onClickTask(scope.row)">
{{getTime(scope.row.create_ts).format('YYYY-MM-DD HH:mm:ss')}}
@@ -48,7 +53,9 @@ export default {
data () {
return {
// setInterval handle
handle: undefined
handle: undefined,
// 防抖
clicked: false
}
},
props: {
@@ -64,13 +71,21 @@ export default {
},
methods: {
onClickSpider (row) {
this.clicked = true
setTimeout(() => {
this.clicked = false
}, 100)
this.$router.push(`/spiders/${row.spider_id}`)
},
onClickNode (row) {
this.clicked = true
setTimeout(() => {
this.clicked = false
}, 100)
this.$router.push(`/nodes/${row.node_id}`)
},
onClickTask (row) {
this.$router.push(`/tasks/${row._id}`)
if (!this.clicked) this.$router.push(`/tasks/${row._id}`)
},
onRefresh () {
if (this.$route.path.split('/')[1] === 'spiders') {
@@ -114,4 +129,8 @@ export default {
margin: 0;
padding: 5px;
}
.el-table >>> tr {
cursor: pointer;
}
</style>

View File

@@ -166,6 +166,9 @@ export default {
'Error Message': '错误信息',
'Results Count': '结果数',
'Average Results Count per Second': '抓取速度(个/秒)',
'Wait Duration (sec)': '等待时长(秒)',
'Runtime Duration (sec)': '运行时长(秒)',
'Total Duration (sec)': '总时长(秒)',
// 任务列表
'Node': '节点',
@@ -231,5 +234,6 @@ export default {
'Are you sure to delete this spider?': '你确定要删除该爬虫?',
'Spider info has been saved successfully': '爬虫信息已成功保存',
'Do you allow us to collect some statistics to improve Crawlab?': '您允许我们收集统计数据以更好地优化Crawlab',
'Saved file successfully': '成功保存文件'
'Saved file successfully': '成功保存文件',
'An error happened when fetching the data': '请求数据时出错'
}

View File

@@ -129,12 +129,12 @@ const actions = {
return request.post('/spiders/import/github', { url })
},
getSpiderStats ({ state, commit }) {
return request.get('/stats/get_spider_stats?spider_id=' + state.spiderForm._id)
return request.get(`/spiders/${state.spiderForm._id}/stats`)
.then(response => {
commit('SET_OVERVIEW_STATS', response.data.overview)
commit('SET_STATUS_STATS', response.data.task_count_by_status)
commit('SET_DAILY_STATS', response.data.daily_stats)
commit('SET_NODE_STATS', response.data.task_count_by_node)
commit('SET_OVERVIEW_STATS', response.data.data.overview)
// commit('SET_STATUS_STATS', response.data.task_count_by_status)
commit('SET_DAILY_STATS', response.data.data.daily)
// commit('SET_NODE_STATS', response.data.task_count_by_node)
})
},
getPreviewCrawlData ({ state, commit }) {

View File

@@ -5,7 +5,8 @@
<li class="metric-item" v-for="m in metrics" @click="onClickMetric(m)" :key="m.name">
<el-card class="metric-card" shadow="hover">
<el-col :span="6" class="icon-col">
<i :class="m.icon" :style="{color:m.color}"></i>
<font-awesome-icon :icon="m.icon" :color="m.color"/>
<!--<i :class="m.icon" :style="{color:m.color}"></i>-->
</el-col>
<el-col :span="18" class="text-col">
<el-row>
@@ -40,10 +41,10 @@ export default {
overviewStats: {},
dailyTasks: [],
metrics: [
{ name: 'task_count', label: 'Total Tasks', icon: 'fa fa-play', color: '#f56c6c', path: 'tasks' },
{ name: 'spider_count', label: 'Spiders', icon: 'fa fa-bug', color: '#67c23a', path: 'spiders' },
{ name: 'node_count', label: 'Active Nodes', icon: 'fa fa-server', color: '#409EFF', path: 'nodes' },
{ name: 'deploy_count', label: 'Total Deploys', icon: 'fa fa-cloud', color: '#409EFF', path: 'deploys' }
{ name: 'task_count', label: 'Total Tasks', icon: ['fa', 'play'], color: '#f56c6c', path: 'tasks' },
{ name: 'spider_count', label: 'Spiders', icon: ['fa', 'bug'], color: '#67c23a', path: 'spiders' },
{ name: 'active_node_count', label: 'Active Nodes', icon: ['fa', 'server'], color: '#409EFF', path: 'nodes' },
{ name: 'schedule_count', label: 'Schedules', icon: ['fa', 'clock'], color: '#409EFF', path: 'schedules' }
]
}
},
@@ -58,7 +59,7 @@ export default {
type: 'value'
},
series: [{
data: this.dailyTasks.map(d => d.count),
data: this.dailyTasks.map(d => d.task_count),
type: 'line',
areaStyle: {},
smooth: true
@@ -76,13 +77,13 @@ export default {
}
},
created () {
request.get('/stats/get_home_stats')
request.get('/stats/home')
.then(response => {
// overview stats
this.overviewStats = response.data.overview_stats
this.overviewStats = response.data.data.overview
// daily tasks
this.dailyTasks = response.data.daily_tasks
this.dailyTasks = response.data.data.daily
this.initEchartsDailyTasks()
})
},
@@ -160,4 +161,9 @@ export default {
.el-card {
/*border: 1px solid lightgrey;*/
}
.svg-inline--fa {
width: 100%;
height: 100%;
}
</style>

View File

@@ -80,49 +80,53 @@
<vcrontab @hide="showCron=false" @fill="onCrontabFill" :expression="expression"></vcrontab>
</el-dialog>
<!--filter-->
<div class="filter">
<div class="right">
<el-button type="primary"
icon="el-icon-plus"
class="refresh"
@click="onAdd">
{{$t('Add Schedule')}}
</el-button>
<el-card style="border-radius: 0">
<!--filter-->
<div class="filter">
<div class="right">
<el-button type="primary"
icon="el-icon-plus"
class="refresh"
@click="onAdd">
{{$t('Add Schedule')}}
</el-button>
</div>
</div>
</div>
<!--./filter-->
<!--table list-->
<el-table :data="filteredTableData"
class="table"
:header-cell-style="{background:'rgb(48, 65, 86)',color:'white'}"
border>
<template v-for="col in columns">
<el-table-column :key="col.name"
:property="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<!--table list-->
<el-table :data="filteredTableData"
class="table"
:header-cell-style="{background:'rgb(48, 65, 86)',color:'white'}"
border>
<template v-for="col in columns">
<el-table-column :key="col.name"
:property="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{$t(scope.row[col.name])}}
</template>
</el-table-column>
</template>
<el-table-column :label="$t('Action')" align="left" width="250" fixed="right">
<template slot-scope="scope">
{{$t(scope.row[col.name])}}
<el-tooltip :content="$t('Edit')" placement="top">
<el-button type="warning" icon="el-icon-edit" size="mini" @click="onEdit(scope.row)"></el-button>
</el-tooltip>
<el-tooltip :content="$t('Remove')" placement="top">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="onRemove(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-if="isShowRun(scope.row)" :content="$t('Run')" placement="top">
<el-button type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</template>
<el-table-column :label="$t('Action')" align="left" width="250" fixed="right">
<template slot-scope="scope">
<el-tooltip :content="$t('Edit')" placement="top">
<el-button type="warning" icon="el-icon-edit" size="mini" @click="onEdit(scope.row)"></el-button>
</el-tooltip>
<el-tooltip :content="$t('Remove')" placement="top">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="onRemove(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-if="isShowRun(scope.row)" :content="$t('Run')" placement="top">
<el-button type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</el-table>
<!--./table list-->
</el-card>
</div>
</template>
@@ -276,6 +280,7 @@ export default {
}
.table {
min-height: 360px;
margin-top: 10px;
}
</style>

View File

@@ -9,7 +9,7 @@
</div>
<!--tabs-->
<el-tabs v-model="activeTabName" @tab-click="onTabClick" type="card">
<el-tabs v-model="activeTabName" @tab-click="onTabClick" type="border-card">
<el-tab-pane :label="$t('Overview')" name="overview">
<spider-overview/>
</el-tab-pane>
@@ -107,18 +107,31 @@ export default {
display: flex;
align-items: center;
position: absolute;
right: 20px;
right: 48px;
/*float: right;*/
z-index: 999;
margin-top: -7px;
margin-top: 5px;
}
.selector .el-select {
height: 30px;
line-height: 30px;
padding-left: 10px;
width: 180px;
border-radius: 0;
}
.selector .el-select >>> .el-input__icon,
.selector .el-select >>> .el-input__inner {
border-radius: 0;
height: 30px;
line-height: 30px;
}
.label {
text-align: right;
width: 80px;
color: #909399;
font-weight: 100;
}
</style>

View File

@@ -94,41 +94,6 @@
</el-dialog>
<!--./customized spider dialog-->
<!--filter-->
<div class="filter">
<!--<el-input prefix-icon="el-icon-search"-->
<!--:placeholder="$t('Search')"-->
<!--class="filter-search"-->
<!--v-model="filter.keyword"-->
<!--@change="onSearch">-->
<!--</el-input>-->
<div class="left">
<el-autocomplete v-model="filterSite"
:placeholder="$t('Site')"
clearable
:fetch-suggestions="fetchSiteSuggestions"
@select="onSiteSelect">
</el-autocomplete>
</div>
<div class="right">
<el-button type="primary" icon="fa fa-download" @click="openImportDialog">
{{$t('Import Spiders')}}
</el-button>
<el-button type="success"
icon="el-icon-plus"
class="btn add"
@click="onAdd">
{{$t('Add Spider')}}
</el-button>
<el-button type="success"
icon="el-icon-refresh"
class="btn refresh"
@click="onRefresh">
{{$t('Refresh')}}
</el-button>
</div>
</div>
<!--crawl confirm dialog-->
<crawl-confirm-dialog
:visible="crawlConfirmDialogVisible"
@@ -137,89 +102,128 @@
/>
<!--./crawl confirm dialog-->
<!--table list-->
<el-table :data="filteredTableData"
class="table"
:header-cell-style="{background:'rgb(48, 65, 86)',color:'white'}"
border>
<template v-for="col in columns">
<el-table-column v-if="col.name === 'type'"
:key="col.name"
:label="$t(col.label)"
align="left"
:width="col.width">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.type === 'configurable'">{{$t('Configurable')}}</el-tag>
<el-tag type="primary" v-else-if="scope.row.type === 'customized'">{{$t('Customized')}}</el-tag>
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'last_5_errors'"
:key="col.name"
:label="$t(col.label)"
:width="col.width"
align="center">
<template slot-scope="scope">
<div :style="{color:scope.row[col.name]>0?'red':''}">
{{scope.row[col.name]}}
</div>
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'cmd'"
:key="col.name"
:label="$t(col.label)"
:width="col.width"
align="left">
<template slot-scope="scope">
<el-input v-model="scope.row[col.name]"></el-input>
</template>
</el-table-column>
<el-table-column v-else-if="col.name.match(/_ts$/)"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getTime(scope.row[col.name])}}
</template>
</el-table-column>
<el-table-column v-else
:key="col.name"
:property="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align || 'left'"
:width="col.width">
</el-table-column>
</template>
<el-table-column :label="$t('Action')" align="left" width="auto" fixed="right">
<template slot-scope="scope">
<el-tooltip :content="$t('View')" placement="top">
<el-button type="primary" icon="el-icon-search" size="mini" @click="onView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip :content="$t('Remove')" placement="top">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="onRemove(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-if="!isShowRun(scope.row)" :content="$t('No command line')" placement="top">
<el-button disabled type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-else :content="$t('Run')" placement="top">
<el-button type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row)"></el-button>
</el-tooltip>
<el-card style="border-radius: 0">
<!--filter-->
<div class="filter">
<!--<el-input prefix-icon="el-icon-search"-->
<!--:placeholder="$t('Search')"-->
<!--class="filter-search"-->
<!--v-model="filter.keyword"-->
<!--@change="onSearch">-->
<!--</el-input>-->
<div class="left">
<el-autocomplete v-model="filterSite"
:placeholder="$t('Site')"
clearable
:fetch-suggestions="fetchSiteSuggestions"
@select="onSiteSelect">
</el-autocomplete>
</div>
<div class="right">
<el-button v-if="false" type="primary" icon="fa fa-download" @click="openImportDialog">
{{$t('Import Spiders')}}
</el-button>
<el-button type="success"
icon="el-icon-plus"
class="btn add"
@click="onAdd">
{{$t('Add Spider')}}
</el-button>
<el-button type="success"
icon="el-icon-refresh"
class="btn refresh"
@click="onRefresh">
{{$t('Refresh')}}
</el-button>
</div>
</div>
<!--./filter-->
<!--table list-->
<el-table :data="filteredTableData"
class="table"
:header-cell-style="{background:'rgb(48, 65, 86)',color:'white'}"
border>
<template v-for="col in columns">
<el-table-column v-if="col.name === 'type'"
:key="col.name"
:label="$t(col.label)"
align="left"
:width="col.width">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.type === 'configurable'">{{$t('Configurable')}}</el-tag>
<el-tag type="primary" v-else-if="scope.row.type === 'customized'">{{$t('Customized')}}</el-tag>
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'last_5_errors'"
:key="col.name"
:label="$t(col.label)"
:width="col.width"
align="center">
<template slot-scope="scope">
<div :style="{color:scope.row[col.name]>0?'red':''}">
{{scope.row[col.name]}}
</div>
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'cmd'"
:key="col.name"
:label="$t(col.label)"
:width="col.width"
align="left">
<template slot-scope="scope">
<el-input v-model="scope.row[col.name]"></el-input>
</template>
</el-table-column>
<el-table-column v-else-if="col.name.match(/_ts$/)"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getTime(scope.row[col.name])}}
</template>
</el-table-column>
<el-table-column v-else
:key="col.name"
:property="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align || 'left'"
:width="col.width">
</el-table-column>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
@current-change="onPageChange"
@size-change="onPageChange"
:current-page.sync="pagination.pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size.sync="pagination.pageSize"
layout="sizes, prev, pager, next"
:total="spiderList.length">
</el-pagination>
</div>
<el-table-column :label="$t('Action')" align="left" width="auto" fixed="right">
<template slot-scope="scope">
<el-tooltip :content="$t('View')" placement="top">
<el-button type="primary" icon="el-icon-search" size="mini" @click="onView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip :content="$t('Remove')" placement="top">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="onRemove(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-if="!isShowRun(scope.row)" :content="$t('No command line')" placement="top">
<el-button disabled type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-else :content="$t('Run')" placement="top">
<el-button type="success" icon="fa fa-bug" size="mini" @click="onCrawl(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
@current-change="onPageChange"
@size-change="onPageChange"
:current-page.sync="pagination.pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size.sync="pagination.pageSize"
layout="sizes, prev, pager, next"
:total="spiderList.length">
</el-pagination>
</div>
<!--./table list-->
</el-card>
</div>
</template>

View File

@@ -1,142 +1,146 @@
<template>
<div class="app-container">
<!--filter-->
<div class="filter">
<div class="left">
<el-select class="filter-select"
v-model="filter.node_id"
:placeholder="$t('Node')"
filterable
clearable
@change="onSelectNode">
<el-option v-for="op in nodeList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
<el-select class="filter-select"
v-model="filter.spider_id"
:placeholder="$t('Spider')"
filterable
clearable
@change="onSelectSpider">
<el-option v-for="op in spiderList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
<el-button type="success"
icon="el-icon-search"
class="refresh"
@click="onRefresh">
{{$t('Search')}}
</el-button>
<el-card style="border-radius: 0">
<!--filter-->
<div class="filter">
<div class="left">
<el-select class="filter-select"
v-model="filter.node_id"
:placeholder="$t('Node')"
filterable
clearable
@change="onSelectNode">
<el-option v-for="op in nodeList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
<el-select class="filter-select"
v-model="filter.spider_id"
:placeholder="$t('Spider')"
filterable
clearable
@change="onSelectSpider">
<el-option v-for="op in spiderList" :key="op._id" :value="op._id" :label="op.name"></el-option>
</el-select>
<el-button type="success"
icon="el-icon-search"
class="refresh"
@click="onRefresh">
{{$t('Search')}}
</el-button>
</div>
<!--<div class="right">-->
<!--</div>-->
</div>
<!--<div class="right">-->
<!--</div>-->
</div>
<!--./filter-->
<!--table list-->
<el-table :data="filteredTableData"
class="table"
:header-cell-style="{background:'rgb(48, 65, 86)',color:'white'}"
border>
<template v-for="col in columns">
<el-table-column v-if="col.name === 'spider_name'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
<a href="javascript:" class="a-tag" @click="onClickSpider(scope.row)">{{scope.row[col.name]}}</a>
</template>
</el-table-column>
<el-table-column v-else-if="col.name.match(/_ts$/)"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getTime(scope.row[col.name])}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'wait_duration'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getWaitDuration(scope.row)}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'runtime_duration'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getRuntimeDuration(scope.row)}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'total_duration'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getTotalDuration(scope.row)}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'node_name'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
<a href="javascript:" class="a-tag" @click="onClickNode(scope.row)">{{scope.row[col.name]}}</a>
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'status'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
<status-tag :status="scope.row[col.name]"/>
</template>
</el-table-column>
<el-table-column v-else
:key="col.name"
:property="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
</el-table-column>
</template>
<el-table-column :label="$t('Action')" align="left" width="150" fixed="right">
<template slot-scope="scope">
<el-tooltip :content="$t('View')" placement="top">
<el-button type="primary" icon="el-icon-search" size="mini" @click="onView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip :content="$t('Remove')" placement="top">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="onRemove(scope.row)"></el-button>
</el-tooltip>
<!--table list-->
<el-table :data="filteredTableData"
class="table"
:header-cell-style="{background:'rgb(48, 65, 86)',color:'white'}"
border>
<template v-for="col in columns">
<el-table-column v-if="col.name === 'spider_name'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
<a href="javascript:" class="a-tag" @click="onClickSpider(scope.row)">{{scope.row[col.name]}}</a>
</template>
</el-table-column>
<el-table-column v-else-if="col.name.match(/_ts$/)"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getTime(scope.row[col.name])}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'wait_duration'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getWaitDuration(scope.row)}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'runtime_duration'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getRuntimeDuration(scope.row)}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'total_duration'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
{{getTotalDuration(scope.row)}}
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'node_name'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
<a href="javascript:" class="a-tag" @click="onClickNode(scope.row)">{{scope.row[col.name]}}</a>
</template>
</el-table-column>
<el-table-column v-else-if="col.name === 'status'"
:key="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
<template slot-scope="scope">
<status-tag :status="scope.row[col.name]"/>
</template>
</el-table-column>
<el-table-column v-else
:key="col.name"
:property="col.name"
:label="$t(col.label)"
:sortable="col.sortable"
:align="col.align"
:width="col.width">
</el-table-column>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
@current-change="onPageChange"
@size-change="onPageChange"
:current-page.sync="pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size.sync="pageSize"
layout="sizes, prev, pager, next"
:total="taskListTotalCount">
</el-pagination>
</div>
<el-table-column :label="$t('Action')" align="left" width="150" fixed="right">
<template slot-scope="scope">
<el-tooltip :content="$t('View')" placement="top">
<el-button type="primary" icon="el-icon-search" size="mini" @click="onView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip :content="$t('Remove')" placement="top">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="onRemove(scope.row)"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
@current-change="onPageChange"
@size-change="onPageChange"
:current-page.sync="pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size.sync="pageSize"
layout="sizes, prev, pager, next"
:total="taskListTotalCount">
</el-pagination>
</div>
<!--./table list-->
</el-card>
</div>
</template>
@@ -172,7 +176,7 @@ export default {
{ name: 'wait_duration', label: 'Wait Duration (sec)', width: '80', align: 'right' },
{ name: 'runtime_duration', label: 'Runtime Duration (sec)', width: '80', align: 'right' },
{ name: 'total_duration', label: 'Total Duration (sec)', width: '80', align: 'right' },
{ name: 'num_results', label: 'Results Count', width: '80' }
{ name: 'result_count', label: 'Results Count', width: '80' }
// { name: 'avg_num_results', label: 'Average Results Count per Second', width: '80' }
]
}