add functions to calculate stats

This commit is contained in:
BCedric
2017-06-16 17:20:43 +02:00
parent f879e2ace0
commit b5ff695c74
3 changed files with 235 additions and 27 deletions

View File

@@ -955,6 +955,9 @@ var messages = {
'attachVmButton': 'new VM',
'vmsBootOrder': 'Boot order',
// ----- VM-Group stats Tab -----
'vmGroupAllVm': 'All VMs',
// ----- Self -----
resourceSets: 'Resource sets',
noResourceSets: 'No resource sets.',

View File

@@ -8,6 +8,7 @@ import {
find,
flatten,
floor,
forEach,
map,
max,
size,
@@ -16,7 +17,7 @@ import {
} from 'lodash'
import propTypes from '../prop-types-decorator'
import { computeArraysSum } from '../xo-stats'
import { computeArraysSum, computeArraysAvg } from '../xo-stats'
import { formatSize } from '../utils'
import styles from './index.css'
@@ -214,6 +215,54 @@ export const PoolCpuLineChart = injectIntl(propTypes({
)
}))
export const VmGroupCpuLineChart = injectIntl(propTypes({
addSumSeries: propTypes.bool,
data: propTypes.object.isRequired,
options: propTypes.object
})(({ addSumSeries, data, options = {}, intl }) => {
const firstVmData = data[0]
const length = getStatsLength(firstVmData.stats.cpus)
if (!length) {
return templateError
}
const series = map(data, ({ vm, stats }) => ({
name: vm,
data: computeArraysSum(stats.cpus)
}))
if (addSumSeries) {
series.push({
name: intl.formatMessage(messages.vmGroupAllVm),
data: computeArraysSum(map(series, 'data')),
className: styles.dashedLine
})
}
const nbCpusByVm = map(data, ({ stats }) => stats.cpus.length)
return (
<ChartistGraph
type='Line'
data={{
series
}}
options={{
...makeOptions({
intl,
nValues: length,
endTimestamp: firstVmData.endTimestamp,
interval: firstVmData.interval,
valueTransform: value => `${floor(value)}%`
}),
high: 100 * (addSumSeries ? sum(nbCpusByVm) : max(nbCpusByVm)),
...options
}}
/>
)
}))
export const MemoryLineChart = injectIntl(propTypes({
data: propTypes.object.isRequired,
options: propTypes.object
@@ -302,6 +351,57 @@ export const PoolMemoryLineChart = injectIntl(propTypes({
)
}))
export const VmGroupMemoryLineChart = injectIntl(propTypes({
addSumSeries: propTypes.bool,
data: propTypes.object.isRequired,
options: propTypes.object
})(({ addSumSeries, data, options = {}, intl }) => {
const firstVmData = data[0]
const {
memory,
memoryUsed
} = firstVmData.stats
if (!memory || !memoryUsed) {
return templateError
}
const series = map(data, ({ vm, stats }) => ({
name: vm,
data: stats.memoryUsed
}))
if (addSumSeries) {
series.push({
name: intl.formatMessage(messages.vmGroupAllVm),
data: computeArraysSum(map(data, 'stats.memoryUsed')),
className: styles.dashedLine
})
}
const currentMemoryByHost = map(data, ({ stats }) => stats.memory[stats.memory.length - 1])
return (
<ChartistGraph
type='Line'
data={{
series
}}
options={{
...makeOptions({
intl,
nValues: firstVmData.stats.memoryUsed.length,
endTimestamp: firstVmData.endTimestamp,
interval: firstVmData.interval,
valueTransform: formatSize
}),
high: addSumSeries ? sum(currentMemoryByHost) : max(currentMemoryByHost),
...options
}}
/>
)
}))
export const XvdLineChart = injectIntl(propTypes({
addSumSeries: propTypes.bool,
data: propTypes.object.isRequired,
@@ -334,6 +434,60 @@ export const XvdLineChart = injectIntl(propTypes({
)
}))
export const VmGroupXvdLineChart = injectIntl(propTypes({
addSumSeries: propTypes.bool,
data: propTypes.object.isRequired,
options: propTypes.object
})(({ addSumSeries, data, options = {}, intl }) => {
const firstVmData = data[0]
const {
memory,
memoryUsed
} = firstVmData.stats
if (!memory || !memoryUsed) {
return templateError
}
const series = flatten(map(data, ({ stats, vm }) =>
map(stats.xvds, (xvd, key) => {
return {
name: `${vm} (${key})`,
data: computeArraysAvg(stats.xvds[key])
}
})
))
const datas = []
forEach(series, ({ data }) => datas.push(data))
if (addSumSeries) {
series.push({
name: intl.formatMessage(messages.vmGroupAllVm),
data: computeArraysSum(datas),
className: styles.dashedLine
})
}
return (
<ChartistGraph
type='Line'
data={{
series
}}
options={{
...makeOptions({
intl,
nValues: firstVmData.stats.xvds.r.length,
endTimestamp: data.endTimestamp,
interval: data.interval,
valueTransform: formatSize
}),
...options
}}
/>
)
}))
export const VifLineChart = injectIntl(propTypes({
addSumSeries: propTypes.bool,
data: propTypes.object.isRequired,
@@ -443,6 +597,48 @@ export const PoolPifLineChart = injectIntl(propTypes({
)
}))
export const VmGroupVifLineChart = injectIntl(propTypes({
addSumSeries: propTypes.bool,
data: propTypes.object.isRequired,
options: propTypes.object
})(({ addSumSeries, data, options = {}, intl }) => {
const firstVmData = data[0]
const length = firstVmData.stats && getStatsLength(firstVmData.stats.vifs.rx)
if (!length) {
return templateError
}
const series = addSumSeries
? map(ios, io => ({
name: `${intl.formatMessage(messages.vmGroupAllVm)} (${io})`,
data: computeArraysSum(map(data, ({ stats }) => computeArraysSum(stats.vifs[io])))
}))
: flatten(map(data, ({ stats, vm }) =>
map(ios, io => ({
name: `${vm} (${io})`,
data: computeArraysSum(stats.vifs[io])
}))
))
return (
<ChartistGraph
type='Line'
data={{
series
}}
options={{
...makeOptions({
intl,
nValues: length,
endTimestamp: firstVmData.endTimestamp,
interval: firstVmData.interval,
valueTransform: formatSize
}),
...options
}}
/>
)
}))
export const LoadLineChart = injectIntl(propTypes({
data: propTypes.object.isRequired,
options: propTypes.object

View File

@@ -1,16 +1,19 @@
import _ from 'intl'
import Component from 'base-component'
import filter from 'lodash/filter'
import Icon from 'icon'
import map from 'lodash/map'
import React from 'react'
import Tooltip from 'tooltip'
import Upgrade from 'xoa-upgrade'
import { Container, Row, Col } from 'grid'
import { Toggle } from 'form'
import { fetchVmGroupStats } from 'xo'
import { fetchVmStats } from 'xo'
import {
CpuLineChart,
MemoryLineChart,
PifLineChart,
LoadLineChart
VmGroupCpuLineChart,
VmGroupMemoryLineChart,
VmGroupVifLineChart,
VmGroupXvdLineChart
} from 'xo-line-chart'
export default class TabStats extends Component {
@@ -27,20 +30,27 @@ export default class TabStats extends Component {
let cancelled = false
this.cancel = () => { cancelled = true }
// fetchVmGroupStats(vmGroup, this.state.granularity).then(stats => {
// if (cancelled) {
// return
// }
// this.cancel = null
//
// clearTimeout(this.timeout)
// this.setState({
// stats,
// selectStatsLoading: false
// }, () => {
// this.timeout = setTimeout(this.loop, stats.interval * 1000)
// })
// })
Promise.all(map(filter(this.props.vms, vm => vm.power_state === 'Running'), vm =>
fetchVmStats(vm, this.state.granularity).then(
stats => ({
vm: vm.name_label,
...stats
})
)
)).then(stats => {
if (cancelled || !stats[0]) {
return
}
this.cancel = null
clearTimeout(this.timeout)
this.setState({
stats,
selectStatsLoading: false
}, () => {
this.timeout = setTimeout(this.loop, stats[0].interval * 1000)
})
})
}
loop = ::this.loop
@@ -70,8 +80,7 @@ export default class TabStats extends Component {
stats,
useCombinedValues
} = this.state
const {vmGroup} = this.props
return !vmGroup
return !stats
? <p>No stats.</p>
: process.env.XOA_PLAN > 2
? <Container>
@@ -104,11 +113,11 @@ export default class TabStats extends Component {
<Row>
<Col mediumSize={6}>
<h5 className='text-xs-center'><Icon icon='cpu' size={1} /> {_('statsCpu')}</h5>
{/* <CpuLineChart addSumSeries={useCombinedValues} data={stats} /> */}
<VmGroupCpuLineChart addSumSeries={useCombinedValues} data={stats} />
</Col>
<Col mediumSize={6}>
<h5 className='text-xs-center'><Icon icon='memory' size={1} /> {_('statsMemory')}</h5>
{/* <MemoryLineChart data={stats} /> */}
<VmGroupMemoryLineChart addSumSeries={useCombinedValues} data={stats} />
</Col>
</Row>
<br />
@@ -116,11 +125,11 @@ export default class TabStats extends Component {
<Row>
<Col mediumSize={6}>
<h5 className='text-xs-center'><Icon icon='network' size={1} /> {_('statsNetwork')}</h5>
{/* <PifLineChart addSumSeries={useCombinedValues} data={stats} /> */}
<VmGroupVifLineChart key={useCombinedValues ? 'stacked' : 'unstacked'} addSumSeries={useCombinedValues} data={stats} />
</Col>
<Col mediumSize={6}>
<h5 className='text-xs-center'><Icon icon='disk' size={1} /> {_('statLoad')}</h5>
{/* <LoadLineChart data={stats} /> */}
<h5 className='text-xs-center'><Icon icon='disk' size={1} /> {_('statDisk')}</h5>
<VmGroupXvdLineChart addSumSeries={useCombinedValues} data={stats} />
</Col>
</Row>
</Container>