Skip to content

Commit

Permalink
F #5928: monitoring graphics (#2260)
Browse files Browse the repository at this point in the history
  • Loading branch information
jloboescalona2 authored Aug 25, 2022
1 parent a09aa7f commit bf27770
Show file tree
Hide file tree
Showing 12 changed files with 2,723 additions and 2,151 deletions.
4,423 changes: 2,275 additions & 2,148 deletions src/fireedge/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/fireedge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"babel-loader": "8.2.1",
"babel-plugin-module-resolver": "4.0.0",
"btoa": "1.2.1",
"chartist": "0.10.1",
"clsx": "1.1.1",
"compression": "1.7.4",
"copy-webpack-plugin": "9.0.1",
Expand Down Expand Up @@ -108,6 +109,7 @@
"qrcode": "1.4.4",
"react": "17.0.2",
"react-beautiful-dnd": "13.1.0",
"react-chartist": "0.14.4",
"react-dom": "17.0.2",
"react-flow-renderer": "9.6.0",
"react-hook-form": "7.18.1",
Expand Down
169 changes: 169 additions & 0 deletions src/fireedge/src/client/components/Charts/Chartist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2022, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { JSXElementConstructor, useMemo } from 'react'
import PropTypes from 'prop-types'
import 'chartist/dist/chartist.min.css'

import {
Grid,
CircularProgress,
Stack,
Paper,
List,
ListItem,
Typography,
} from '@mui/material'
import ChartistGraph from 'react-chartist'
import { FixedScaleAxis } from 'chartist'
import makeStyles from '@mui/styles/makeStyles'

const useStyles = makeStyles(({ palette, typography }) => ({
graphStyle: {
'& .ct-series-a .ct-bar, .ct-series-a .ct-line, .ct-series-a .ct-point, .ct-series-a .ct-slice-donut':
{ stroke: palette.secondary.main, strokeWidth: '1px' },
'& .ct-grid': {
stroke: 'rgba(150,150,150,.1)',
strokeDasharray: '1px',
},
'&': {
width: '100%',
},
},
box: {
paddingBottom: '0px',
},
title: {
fontWeight: typography.fontWeightBold,
borderBottom: `1px solid ${palette.divider}`,
},
}))

/**
* Represents a Chartist Graph.
*
* @param {object} props - Props
* @param {object[]} props.data - Chart data
* @param {Function} props.interpolationX - Chartist interpolation X
* @param {Function} props.interpolationY - Chartist interpolation Y
* @param {string} props.name - Chartist name
* @param {string} props.filter - Chartist filter
* @param {string} props.x - Chartist X
* @param {string} props.y - Chartist X
* @returns {JSXElementConstructor} Chartist component
*/
const Chartist = ({
data = [],
interpolationX,
interpolationY,
name = '',
filter = [],
x = '',
y = '',
}) => {
const classes = useStyles()

const chartOptions = {
fullWidth: true,
reverseData: true,
low: 0,
scaleMinSpace: 10,
axisX: {
type: FixedScaleAxis,
divisor: 10,
},
axisY: {
offset: 70,
},
}

const dataChart = {
name,
}

typeof interpolationX === 'function' &&
(chartOptions.axisX.labelInterpolationFnc = interpolationX)

typeof interpolationY === 'function' &&
(chartOptions.axisY.labelInterpolationFnc = interpolationY)

filter?.length &&
(dataChart.data = useMemo(
() =>
data
?.filter((point) =>
Object.keys(point).find((key) => filter.includes(key))
)
.map((point) => ({
x: +point[x],
y: +point[y],
})),
[data]
))

return (
<Grid item xs={12} sm={6}>
{!data?.length ? (
<Stack direction="row" justifyContent="center" alignItems="center">
<CircularProgress color="secondary" />
</Stack>
) : (
<Paper variant="outlined" sx={{ height: 'fit-content' }}>
<List className={classes.box}>
<ListItem className={classes.title}>
<Typography noWrap>{name}</Typography>
</ListItem>
<ListItem className={classes.title}>
<ChartistGraph
className={classes.graphStyle}
data={{ series: [dataChart] }}
options={chartOptions}
type="Line"
/>
</ListItem>
</List>
</Paper>
)}
</Grid>
)
}

Chartist.propTypes = {
name: PropTypes.string,
filter: PropTypes.arrayOf(PropTypes.string),
data: PropTypes.arrayOf(
PropTypes.shape({
TIMESTAMP: PropTypes.string,
DISK_SIZE: PropTypes.arrayOf(PropTypes.shape({})),
ID: PropTypes.string,
CPU: PropTypes.string,
DISKRDBYTES: PropTypes.string,
DISKRDIOPS: PropTypes.string,
DISKWRBYTES: PropTypes.string,
DISKWRIOPS: PropTypes.string,
MEMORY: PropTypes.string,
NETRX: PropTypes.string,
NETTX: PropTypes.string,
})
),
x: PropTypes.string,
y: PropTypes.string,
interpolationX: PropTypes.func,
interpolationY: PropTypes.func,
}

Chartist.displayName = 'Chartist'

export default Chartist
3 changes: 2 additions & 1 deletion src/fireedge/src/client/components/Charts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
* ------------------------------------------------------------------------- */
import CircleChart from 'client/components/Charts/CircleChart'
import SingleBar from 'client/components/Charts/SingleBar'
import Chartist from 'client/components/Charts/Chartist'

export { CircleChart, SingleBar }
export { CircleChart, SingleBar, Chartist }
76 changes: 76 additions & 0 deletions src/fireedge/src/client/components/Tabs/Vm/Info/graphs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2022, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { ReactElement } from 'react'
import { Grid } from '@mui/material'
import makeStyles from '@mui/styles/makeStyles'
import PropTypes from 'prop-types'
import { DateTime } from 'luxon'

import { useGetMonitoringQuery } from 'client/features/OneApi/vm'
import { Chartist } from 'client/components/Charts'
import { Tr } from 'client/components/HOC'
import { prettyBytes } from 'client/utils'
import { T } from 'client/constants'

const useStyles = makeStyles({
container: {
gridColumn: '1 / -1',
},
})

const interpolationX = (value) => DateTime.fromMillis(value).toFormat('HH:mm')

/**
* Render Graphs Capacity.
*
* @param {object} props - Props
* @param {string} props.id - Virtual machine id
* @returns {ReactElement} Capacity Graphs.
*/
const Graphs = ({ id }) => {
const classes = useStyles()
const { data: monitoring = [] } = useGetMonitoringQuery(id)

return (
<Grid container spacing={1} className={classes.container}>
<Chartist
name={Tr(T.RealCpu)}
filter={['CPU']}
data={monitoring}
y="CPU"
x="TIMESTAMP"
interpolationX={interpolationX}
/>
<Chartist
name={Tr(T.RealMemory)}
filter={['MEMORY']}
data={monitoring}
y="MEMORY"
x="TIMESTAMP"
interpolationY={(value) => prettyBytes(value)}
interpolationX={interpolationX}
/>
</Grid>
)
}

Graphs.propTypes = {
id: PropTypes.string,
}

Graphs.displayName = 'Graphs'

export default Graphs
6 changes: 5 additions & 1 deletion src/fireedge/src/client/components/Tabs/Vm/Info/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
} from 'client/components/Tabs/Common'
import Information from 'client/components/Tabs/Vm/Info/information'
import Capacity from 'client/components/Tabs/Vm/Info/capacity'
import Graphs from 'client/components/Tabs/Vm/Info/graphs'
import { SubmitButton } from 'client/components/FormControl'

import { Tr, Translate } from 'client/components/HOC'
Expand Down Expand Up @@ -183,7 +184,10 @@ const VmInfoTab = ({ tabProps = {}, id }) => {
/>
)}
{capacityPanel?.enabled && (
<Capacity actions={getActions(capacityPanel?.actions)} vm={vm} />
<>
<Capacity actions={getActions(capacityPanel?.actions)} vm={vm} />
<Graphs id={id} />
</>
)}
{attributesPanel?.enabled && attributes && (
<AttributePanel
Expand Down
89 changes: 89 additions & 0 deletions src/fireedge/src/client/components/Tabs/Vm/Network/Graphs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* ------------------------------------------------------------------------- *
* Copyright 2002-2022, OpenNebula Project, OpenNebula Systems *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may *
* not use this file except in compliance with the License. You may obtain *
* a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* ------------------------------------------------------------------------- */
import { ReactElement } from 'react'
import { Grid } from '@mui/material'
import PropTypes from 'prop-types'
import { DateTime } from 'luxon'

import { useGetMonitoringQuery } from 'client/features/OneApi/vm'
import { Chartist } from 'client/components/Charts'
import { Tr } from 'client/components/HOC'
import { T } from 'client/constants'

const interpolationHour = (value) =>
DateTime.fromMillis(value).toFormat('HH:mm')
const interpolationBytesSeg = (value) => `${value}B/s`
const interpolationY = (value) => `${value}B`

/**
* Render Graphs Capacity.
*
* @param {object} props - Props
* @param {string} props.id - Virtual machine id
* @returns {ReactElement} Capacity Graphs.
*/
const Graphs = ({ id }) => {
const { data: monitoring = [] } = useGetMonitoringQuery(id)

return (
<Grid container spacing={1}>
<Chartist
name={Tr(T.NetRX)}
filter={['NETRX']}
data={monitoring}
y="NETRX"
x="TIMESTAMP"
interpolationX={interpolationHour}
interpolationY={interpolationY}
/>
<Chartist
name={Tr(T.NetTX)}
filter={['NETTX']}
data={monitoring}
y="NETTX"
x="TIMESTAMP"
interpolationY={interpolationY}
interpolationX={interpolationHour}
/>
<Chartist
name={Tr(T.NetDownloadSpeed)}
filter={['NETRX']}
data={monitoring}
y="NETRX"
x="TIMESTAMP"
interpolationX={interpolationHour}
interpolationY={interpolationBytesSeg}
/>
<Chartist
name={Tr(T.NetUploadSpeed)}
filter={['NETTX']}
data={monitoring}
y="NETTX"
x="TIMESTAMP"
interpolationX={interpolationHour}
interpolationY={interpolationBytesSeg}
/>
</Grid>
)
}

Graphs.propTypes = {
id: PropTypes.string,
}

Graphs.displayName = 'Graphs'

export default Graphs
3 changes: 2 additions & 1 deletion src/fireedge/src/client/components/Tabs/Vm/Network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
AttachSecGroupAction,
DetachSecGroupAction,
} from 'client/components/Tabs/Vm/Network/Actions'

import Graphs from 'client/components/Tabs/Vm/Network/Graphs'
import {
getNics,
getHypervisor,
Expand Down Expand Up @@ -106,6 +106,7 @@ const VmNetworkTab = ({ tabProps: { actions } = {}, id }) => {
)
})}
</Stack>
<Graphs id={id} />
</div>
)
}
Expand Down
Loading

0 comments on commit bf27770

Please sign in to comment.