Adding changes to frontend for interleaving chaos events on litmus-ui graphs. (#2521)
* Adding interleaving for chaos events. Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * Fixes for interleaving Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * Minor fix. Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * Upgrading to litmus-ui version 1.0.1 Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * Minor fix Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * npm install fix Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * minor fix for events Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * Updated git ignore to add build folder also updated litmus-ui version to 1.0.2 Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * Updated litmus-ui to 1.0.3 Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * minor fix Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * minor fix Signed-off-by: ishangupta-ds <ishan@chaosnative.com> * minor fix Signed-off-by: ishangupta-ds <ishan@chaosnative.com>
This commit is contained in:
parent
32e35ad4fb
commit
cbe2eb12e7
|
@ -4,6 +4,7 @@
|
|||
.nyc_output
|
||||
__pycache__/
|
||||
**/node_modules/
|
||||
**/build/
|
||||
**/cypress/videos/
|
||||
**/cypress/screenshots/
|
||||
**/.nyc_output/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,7 @@
|
|||
"jsonwebtoken": "^8.5.1",
|
||||
"jspdf": "^2.1.1",
|
||||
"jspdf-autotable": "^3.5.13",
|
||||
"litmus-ui": "^0.1.4",
|
||||
"litmus-ui": "^1.0.3",
|
||||
"localforage": "^1.7.3",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.27.0",
|
||||
|
|
|
@ -246,6 +246,7 @@ analyticsDashboard:
|
|||
seconds: seconds
|
||||
minutes: minutes
|
||||
hours: hours
|
||||
days: days
|
||||
few: few
|
||||
|
||||
error:
|
||||
|
|
|
@ -9,7 +9,7 @@ export default [
|
|||
information:
|
||||
'This dashboard visualizes Node and Pod level CPU and memory utilization metrics interleaved with chaos events.',
|
||||
chaosEventQueryTemplate:
|
||||
'heptio_eventrouter_normal_total{reason="ChaosInject", involved_object_name="#{}", involved_object_namespace="*{}", involved_object_kind="ChaosEngine"} - on () (heptio_eventrouter_normal_total{reason="ChaosEngineCompleted", involved_object_name="#{}", involved_object_namespace="*{}", involved_object_kind="ChaosEngine"} OR on() vector(0))',
|
||||
'litmuschaos_awaited_experiments{chaosresult_name="#{}",chaosresult_namespace="*{}", job="chaos-exporter"}',
|
||||
panelGroupMap: [
|
||||
{
|
||||
groupName: 'CPU Usage Metrics',
|
||||
|
@ -52,7 +52,7 @@ export default [
|
|||
prom_queries: [
|
||||
{
|
||||
queryid: uuidv4(),
|
||||
prom_query_name: 'instance:node_cpu_utilisation:rate1m',
|
||||
prom_query_name: 'instance:node_cpu_utilisation:rate1m*100',
|
||||
legend: '{{instance}}',
|
||||
resolution: '1/2',
|
||||
minstep: '5',
|
||||
|
@ -104,7 +104,7 @@ export default [
|
|||
prom_queries: [
|
||||
{
|
||||
queryid: uuidv4(),
|
||||
prom_query_name: 'instance:node_memory_utilisation:ratio',
|
||||
prom_query_name: 'instance:node_memory_utilisation:ratio*100',
|
||||
legend: '{{instance}}',
|
||||
resolution: '1/2',
|
||||
minstep: '5',
|
||||
|
@ -279,7 +279,7 @@ export default [
|
|||
information:
|
||||
'This dashboard visualizes Sock Shop application metrics metrics interleaved with chaos events and chaos exporter metrics.',
|
||||
chaosEventQueryTemplate:
|
||||
'heptio_eventrouter_normal_total{reason="ChaosInject", involved_object_name="#{}", involved_object_namespace="*{}", involved_object_kind="ChaosEngine"} - on () (heptio_eventrouter_normal_total{reason="ChaosEngineCompleted", involved_object_name="#{}", involved_object_namespace="*{}", involved_object_kind="ChaosEngine"} OR on() vector(0))',
|
||||
'litmuschaos_awaited_experiments{chaosresult_name="#{}",chaosresult_namespace="*{}", job="chaos-exporter"}',
|
||||
panelGroupMap: [
|
||||
{
|
||||
groupName: 'Orders Metrics',
|
||||
|
|
|
@ -42,7 +42,7 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.secondary.light,
|
||||
backgroundColor: theme.palette.primary.light,
|
||||
color: theme.palette.secondary.contrastText,
|
||||
'& path': {
|
||||
fill: theme.palette.secondary.contrastText,
|
||||
|
|
|
@ -212,7 +212,7 @@ function App() {
|
|||
}
|
||||
}, [token]);
|
||||
return (
|
||||
<LitmusThemeProvider platform="litmus-portal">
|
||||
<LitmusThemeProvider>
|
||||
<Suspense fallback={<Loader />}>
|
||||
<Router history={history}>
|
||||
<div className={classes.root}>
|
||||
|
|
|
@ -181,8 +181,9 @@ const DashboardConfigurePage: React.FC<DashboardConfigurePageProps> = ({
|
|||
const check: number = chaosEngineNamesAndNamespacesMap.filter(
|
||||
(data, index) => {
|
||||
if (
|
||||
data.engineName ===
|
||||
parsedEmbeddedYaml.metadata.name &&
|
||||
data.engineName.includes(
|
||||
parsedEmbeddedYaml.metadata.name
|
||||
) &&
|
||||
data.engineNamespace === engineNamespace
|
||||
) {
|
||||
matchIndex = index;
|
||||
|
@ -193,7 +194,7 @@ const DashboardConfigurePage: React.FC<DashboardConfigurePageProps> = ({
|
|||
).length;
|
||||
if (check === 0) {
|
||||
chaosEngineNamesAndNamespacesMap.push({
|
||||
engineName: parsedEmbeddedYaml.metadata.name,
|
||||
engineName: `${parsedEmbeddedYaml.metadata.name}-${parsedEmbeddedYaml.spec.experiments[0].name}`,
|
||||
engineNamespace,
|
||||
workflowName: workflowYaml.metadata.name,
|
||||
});
|
||||
|
|
|
@ -7,11 +7,7 @@ interface ThemeWrapperProps {
|
|||
}
|
||||
|
||||
const ThemeWrapper: React.FC<ThemeWrapperProps> = ({ children }) => {
|
||||
return (
|
||||
<LitmusThemeProvider platform="litmus-portal">
|
||||
{children}
|
||||
</LitmusThemeProvider>
|
||||
);
|
||||
return <LitmusThemeProvider>{children}</LitmusThemeProvider>;
|
||||
};
|
||||
|
||||
export default ThemeWrapper;
|
||||
|
|
|
@ -3,12 +3,12 @@ import { ChaosEngineNamesAndNamespacesMap } from '../models/dashboardsData';
|
|||
const getEngineNameAndNamespace = (chaosQueryString: string) => {
|
||||
const parsedChaosInfoMap: ChaosEngineNamesAndNamespacesMap = {
|
||||
engineName: chaosQueryString
|
||||
.split(',')[1]
|
||||
.split(',')[0]
|
||||
.trim()
|
||||
.split('=')[1]
|
||||
.slice(1, -1),
|
||||
engineNamespace: chaosQueryString
|
||||
.split(',')[2]
|
||||
.split(',')[1]
|
||||
.trim()
|
||||
.split('=')[1]
|
||||
.slice(1, -1),
|
||||
|
|
|
@ -181,7 +181,9 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
|||
const check: number = chaosEngineNamesAndNamespacesMap.filter(
|
||||
(data, index) => {
|
||||
if (
|
||||
data.engineName === parsedEmbeddedYaml.metadata.name &&
|
||||
data.engineName.includes(
|
||||
parsedEmbeddedYaml.metadata.name
|
||||
) &&
|
||||
data.engineNamespace === engineNamespace
|
||||
) {
|
||||
matchIndex = index;
|
||||
|
@ -192,7 +194,7 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
|||
).length;
|
||||
if (check === 0) {
|
||||
chaosEngineNamesAndNamespacesMap.push({
|
||||
engineName: parsedEmbeddedYaml.metadata.name,
|
||||
engineName: `${parsedEmbeddedYaml.metadata.name}-${parsedEmbeddedYaml.spec.experiments[0].name}`,
|
||||
engineNamespace,
|
||||
workflowName: workflowYaml.metadata.name,
|
||||
});
|
||||
|
@ -217,7 +219,7 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
|||
(existingPromQuery: PromQuery) => {
|
||||
if (
|
||||
existingPromQuery.prom_query_name.startsWith(
|
||||
'heptio_eventrouter_normal_total{reason="ChaosInject"'
|
||||
'litmuschaos_awaited_experiments'
|
||||
)
|
||||
) {
|
||||
const chaosDetails: ChaosEngineNamesAndNamespacesMap = getEngineNameAndNamespace(
|
||||
|
@ -229,8 +231,9 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
|||
index: number
|
||||
) => {
|
||||
if (
|
||||
chaosDetailsFomSchedule.engineName ===
|
||||
chaosDetails.engineName &&
|
||||
chaosDetailsFomSchedule.engineName.includes(
|
||||
chaosDetails.engineName
|
||||
) &&
|
||||
chaosDetailsFomSchedule.engineNamespace ===
|
||||
chaosDetails.engineNamespace
|
||||
) {
|
||||
|
@ -254,9 +257,7 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
|||
panel.prom_queries.forEach((query: PromQuery) => {
|
||||
let updatedLegend: string = query.legend;
|
||||
if (
|
||||
query.prom_query_name.startsWith(
|
||||
'heptio_eventrouter_normal_total{reason="ChaosInject"'
|
||||
)
|
||||
query.prom_query_name.startsWith('litmuschaos_awaited_experiments')
|
||||
) {
|
||||
const chaosDetails: ChaosEngineNamesAndNamespacesMap = getEngineNameAndNamespace(
|
||||
query.prom_query_name
|
||||
|
@ -264,8 +265,9 @@ const TableData: React.FC<TableDataProps> = ({ data }) => {
|
|||
chaosEngineNamesAndNamespacesMap.forEach(
|
||||
(chaosDetailsFomSchedule: ChaosEngineNamesAndNamespacesMap) => {
|
||||
if (
|
||||
chaosDetailsFomSchedule.engineName ===
|
||||
chaosDetails.engineName &&
|
||||
chaosDetailsFomSchedule.engineName.includes(
|
||||
chaosDetails.engineName
|
||||
) &&
|
||||
chaosDetailsFomSchedule.engineNamespace ===
|
||||
chaosDetails.engineNamespace &&
|
||||
!query.legend.includes(chaosDetailsFomSchedule.workflowName)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { useQuery } from '@apollo/client';
|
||||
import { Typography } from '@material-ui/core';
|
||||
import useTheme from '@material-ui/core/styles/useTheme';
|
||||
import { DateValue, GraphMetric, LineAreaGraph } from 'litmus-ui';
|
||||
import { GraphMetric, LineAreaGraph } from 'litmus-ui';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Loader from '../../../components/Loader';
|
||||
|
@ -20,20 +20,11 @@ import {
|
|||
import { RootState } from '../../../redux/reducers';
|
||||
import useStyles from './styles';
|
||||
|
||||
const filterUndefinedData = (data: GraphMetric[]): GraphMetric[] =>
|
||||
data
|
||||
? data
|
||||
.filter((elem) => elem && elem.data && elem.data.length)
|
||||
.filter((elem) =>
|
||||
elem.data.filter(
|
||||
(d: DateValue) =>
|
||||
d &&
|
||||
d.date &&
|
||||
typeof d.date === 'number' &&
|
||||
typeof d.value === 'number'
|
||||
)
|
||||
)
|
||||
: data;
|
||||
interface PrometheusQueryDataInterface {
|
||||
promInput: PrometheusQueryInput;
|
||||
chaosInput: string[];
|
||||
}
|
||||
|
||||
const PanelContent: React.FC<PanelResponse> = ({
|
||||
panel_id,
|
||||
panel_name,
|
||||
|
@ -46,18 +37,20 @@ const PanelContent: React.FC<PanelResponse> = ({
|
|||
}) => {
|
||||
const { palette } = useTheme();
|
||||
const classes = useStyles();
|
||||
const lineGraph: string[] = Object.values(palette.graph.line).map((elem) =>
|
||||
typeof elem === 'string' ? elem : palette.graph.dashboard.lightBlue
|
||||
);
|
||||
const lineGraph: string[] = palette.graph.line;
|
||||
const areaGraph: string[] = palette.graph.area;
|
||||
|
||||
const [
|
||||
prometheusQueryData,
|
||||
setPrometheusQueryData,
|
||||
] = React.useState<PrometheusQueryInput>({
|
||||
url: '',
|
||||
start: '',
|
||||
end: '',
|
||||
queries: [],
|
||||
] = React.useState<PrometheusQueryDataInterface>({
|
||||
promInput: {
|
||||
url: '',
|
||||
start: '',
|
||||
end: '',
|
||||
queries: [],
|
||||
},
|
||||
chaosInput: [],
|
||||
});
|
||||
|
||||
const [updateQueries, setUpdateQueries] = React.useState<boolean>(false);
|
||||
|
@ -77,14 +70,18 @@ const PanelContent: React.FC<PanelResponse> = ({
|
|||
PrometheusResponse,
|
||||
PrometheusQueryVars
|
||||
>(PROM_QUERY, {
|
||||
variables: { prometheusInput: prometheusQueryData },
|
||||
// fetchPolicy: 'cache-and-network',
|
||||
variables: { prometheusInput: prometheusQueryData.promInput },
|
||||
fetchPolicy: 'cache-and-network',
|
||||
pollInterval: selectedDashboard.refreshRate,
|
||||
});
|
||||
|
||||
const generatePrometheusQueryData = () => {
|
||||
const promQueries: promQueryInput[] = [];
|
||||
const chaosQueries: string[] = [];
|
||||
prom_queries.forEach((query: PromQuery) => {
|
||||
if (query.prom_query_name.startsWith('litmuschaos_awaited_experiments')) {
|
||||
chaosQueries.push(query.queryid);
|
||||
}
|
||||
promQueries.push({
|
||||
queryid: query.queryid,
|
||||
query: query.prom_query_name,
|
||||
|
@ -99,25 +96,18 @@ const PanelContent: React.FC<PanelResponse> = ({
|
|||
end: `${Math.round(new Date().getTime() / 1000)}`,
|
||||
queries: promQueries,
|
||||
};
|
||||
setPrometheusQueryData(prometheusQueryInput);
|
||||
setPrometheusQueryData({
|
||||
promInput: prometheusQueryInput,
|
||||
chaosInput: chaosQueries,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (firstLoad === true && updateQueries === false) {
|
||||
generatePrometheusQueryData();
|
||||
setFirstLoad(false);
|
||||
setUpdateQueries(true);
|
||||
}
|
||||
if (updateQueries === true && firstLoad === false) {
|
||||
setTimeout(() => {
|
||||
generatePrometheusQueryData();
|
||||
}, selectedDashboard.refreshRate);
|
||||
}
|
||||
}, [prometheusQueryData]);
|
||||
|
||||
let seriesData: Array<GraphMetric> = [
|
||||
{ metricName: '', data: [{ date: NaN, value: NaN }] },
|
||||
];
|
||||
let eventData: Array<GraphMetric> = [
|
||||
{ metricName: '', data: [{ date: NaN, value: NaN }] },
|
||||
];
|
||||
if (
|
||||
prometheusData &&
|
||||
prometheusData.GetPromQuery.length &&
|
||||
|
@ -133,9 +123,36 @@ const PanelContent: React.FC<PanelResponse> = ({
|
|||
})),
|
||||
baseColor: lineGraph[index % lineGraph.length],
|
||||
}));
|
||||
prometheusData.GetPromQuery.forEach((queryResponse) => {
|
||||
if (prometheusQueryData.chaosInput.includes(queryResponse.queryid)) {
|
||||
if (queryResponse.legends && queryResponse.legends[0]) {
|
||||
eventData = queryResponse.legends.map((elem, index) => ({
|
||||
metricName: elem[0] ?? 'test',
|
||||
data: queryResponse.tsvs[index].map((dataPoint) => ({
|
||||
date: parseInt(dataPoint.timestamp ?? '0', 10) * 1000,
|
||||
value: parseInt(dataPoint.value ?? '0', 10),
|
||||
})),
|
||||
baseColor: areaGraph[index % areaGraph.length],
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (error || !seriesData) {
|
||||
useEffect(() => {
|
||||
if (firstLoad === true && updateQueries === false) {
|
||||
generatePrometheusQueryData();
|
||||
setFirstLoad(false);
|
||||
setUpdateQueries(true);
|
||||
}
|
||||
if (updateQueries === true && firstLoad === false) {
|
||||
setTimeout(() => {
|
||||
generatePrometheusQueryData();
|
||||
}, selectedDashboard.refreshRate);
|
||||
}
|
||||
}, [prometheusQueryData]);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className={classes.rootPanel}>
|
||||
<Typography>{panel_name}</Typography>
|
||||
|
@ -144,8 +161,6 @@ const PanelContent: React.FC<PanelResponse> = ({
|
|||
);
|
||||
}
|
||||
|
||||
// console.log(seriesData);
|
||||
|
||||
return (
|
||||
<div className={classes.rootPanel}>
|
||||
<div>
|
||||
|
@ -172,11 +187,16 @@ const PanelContent: React.FC<PanelResponse> = ({
|
|||
<div className={classes.singleGraph}>
|
||||
<LineAreaGraph
|
||||
legendTableHeight={120}
|
||||
openSeries={filterUndefinedData(seriesData)}
|
||||
openSeries={seriesData}
|
||||
eventSeries={eventData}
|
||||
showPoints={false}
|
||||
showLegendTable
|
||||
showTips
|
||||
margin={{ left: 50, right: 20, top: 20, bottom: 10 }}
|
||||
showEventMarkers
|
||||
unit={unit}
|
||||
yLabel={y_axis_left}
|
||||
yLabelOffset={50}
|
||||
margin={{ left: 70, right: 20, top: 20, bottom: 10 }}
|
||||
/>
|
||||
</div>
|
||||
{/* <Typography>
|
||||
|
|
|
@ -39,7 +39,7 @@ const useStyles = makeStyles((theme) => ({
|
|||
title: {
|
||||
fontWeight: 700,
|
||||
fontSize: '0.9rem',
|
||||
color: theme.palette.primary.contrastText,
|
||||
color: theme.palette.text.primary,
|
||||
textAlign: 'center',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
paddingTop: theme.spacing(2.5),
|
||||
|
|
|
@ -149,7 +149,9 @@ const TableDashboardData: React.FC<TableDashboardData> = ({
|
|||
const check: number = chaosEngineNamesAndNamespacesMap.filter(
|
||||
(data, index) => {
|
||||
if (
|
||||
data.engineName === parsedEmbeddedYaml.metadata.name &&
|
||||
data.engineName.includes(
|
||||
parsedEmbeddedYaml.metadata.name
|
||||
) &&
|
||||
data.engineNamespace === engineNamespace
|
||||
) {
|
||||
matchIndex = index;
|
||||
|
@ -160,7 +162,7 @@ const TableDashboardData: React.FC<TableDashboardData> = ({
|
|||
).length;
|
||||
if (check === 0) {
|
||||
chaosEngineNamesAndNamespacesMap.push({
|
||||
engineName: parsedEmbeddedYaml.metadata.name,
|
||||
engineName: `${parsedEmbeddedYaml.metadata.name}-${parsedEmbeddedYaml.spec.experiments[0].name}`,
|
||||
engineNamespace,
|
||||
workflowName: workflowYaml.metadata.name,
|
||||
});
|
||||
|
@ -185,7 +187,7 @@ const TableDashboardData: React.FC<TableDashboardData> = ({
|
|||
(existingPromQuery: PromQuery) => {
|
||||
if (
|
||||
existingPromQuery.prom_query_name.startsWith(
|
||||
'heptio_eventrouter_normal_total{reason="ChaosInject"'
|
||||
'litmuschaos_awaited_experiments'
|
||||
)
|
||||
) {
|
||||
const chaosDetails: ChaosEngineNamesAndNamespacesMap = getEngineNameAndNamespace(
|
||||
|
@ -197,8 +199,9 @@ const TableDashboardData: React.FC<TableDashboardData> = ({
|
|||
index: number
|
||||
) => {
|
||||
if (
|
||||
chaosDetailsFomSchedule.engineName ===
|
||||
chaosDetails.engineName &&
|
||||
chaosDetailsFomSchedule.engineName.includes(
|
||||
chaosDetails.engineName
|
||||
) &&
|
||||
chaosDetailsFomSchedule.engineNamespace ===
|
||||
chaosDetails.engineNamespace
|
||||
) {
|
||||
|
@ -222,9 +225,7 @@ const TableDashboardData: React.FC<TableDashboardData> = ({
|
|||
panel.prom_queries.forEach((query: PromQuery) => {
|
||||
let updatedLegend: string = query.legend;
|
||||
if (
|
||||
query.prom_query_name.startsWith(
|
||||
'heptio_eventrouter_normal_total{reason="ChaosInject"'
|
||||
)
|
||||
query.prom_query_name.startsWith('litmuschaos_awaited_experiments')
|
||||
) {
|
||||
const chaosDetails: ChaosEngineNamesAndNamespacesMap = getEngineNameAndNamespace(
|
||||
query.prom_query_name
|
||||
|
@ -232,8 +233,9 @@ const TableDashboardData: React.FC<TableDashboardData> = ({
|
|||
chaosEngineNamesAndNamespacesMap.forEach(
|
||||
(chaosDetailsFomSchedule: ChaosEngineNamesAndNamespacesMap) => {
|
||||
if (
|
||||
chaosDetailsFomSchedule.engineName ===
|
||||
chaosDetails.engineName &&
|
||||
chaosDetailsFomSchedule.engineName.includes(
|
||||
chaosDetails.engineName
|
||||
) &&
|
||||
chaosDetailsFomSchedule.engineNamespace ===
|
||||
chaosDetails.engineNamespace &&
|
||||
!query.legend.includes(chaosDetailsFomSchedule.workflowName)
|
||||
|
|
|
@ -140,10 +140,10 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
marginLeft: 'auto',
|
||||
},
|
||||
avatarBackground: {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.primary.light,
|
||||
width: '2.56rem',
|
||||
height: '2.56rem',
|
||||
color: theme.palette.text.primary,
|
||||
color: theme.palette.secondary.contrastText,
|
||||
alignContent: 'right',
|
||||
marginRight: theme.spacing(2.5),
|
||||
[theme.breakpoints.down('sm')]: {
|
||||
|
|
Loading…
Reference in New Issue