Skip to content

Commit aa077b8

Browse files
Connected user input within settings bar to the requests being sent to the GraphQL server. The server query type was also altered to accept an additional 'prometheusURL' argument. I also began to wrap functionality inside of utility functions to declutter component space
1 parent 2fd413e commit aa077b8

File tree

6 files changed

+71
-55
lines changed

6 files changed

+71
-55
lines changed

ksqLight/server/server.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@ const RootQueryType = new GraphQLObjectType({
4848
metric: { type: GraphQLNonNull(GraphQLString)},
4949
start: { type: GraphQLNonNull(GraphQLInt)},
5050
end: { type: GraphQLNonNull(GraphQLInt)},
51-
resolution: { type: GraphQLNonNull(GraphQLInt)}
51+
resolution: { type: GraphQLNonNull(GraphQLInt)},
52+
prometheusURL: { type: GraphQLNonNull(GraphQLString)}
5253
},
53-
resolve: (parent, {start, end, resolution, metric}) => {
54-
return axios.get(`http://localhost:9090/api/v1/query_range?step=${resolution}s&end=${end}&start=${start}&query=${queryTypes[metric]}`)
54+
resolve: (parent, {start, end, resolution, metric, prometheusURL}) => {
55+
if (prometheusURL[prometheusURL.length] === '/') prometheusURL = prometheusURL.slice(0, prometheusURL.length);
56+
console.log(prometheusURL);
57+
58+
return axios.get(`${prometheusURL}/api/v1/query_range?step=${resolution}s&end=${end}&start=${start}&query=${queryTypes[metric]}`)
5559
.then(res => res.data.data.result[0].values)
5660
.catch(error => error);
5761
}

ksqLight/src/App.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,9 @@ import { CssBaseline } from "@mui/material";
1111
function App() {
1212
const [fetchMetrics, setFetchMetrics] = useState(true);
1313
const [showSettings, setShowSettings] = useState(false);
14-
const [duration, setDuration] = useState({
15-
days: 0,
16-
hours: 0,
17-
minutes: 10
18-
});
19-
const [refreshRate, setRefreshRate] = useState(2);
20-
const [prometheusURL, setPrometheusURL] = useState(null);
21-
const [ksqlDBURL, setksqlDBURL] = useState(null);
2214
const [metricsState, setMetricsState] = useState({
23-
prometheusURL: null,
24-
ksqlDBURL: null,
15+
prometheusURL: "http://localhost:9090/",
16+
ksqlDBURL: "",
2517
duration: {
2618
days: 0,
2719
hours: 0,
@@ -33,7 +25,11 @@ function App() {
3325
return (
3426
<BrowserRouter>
3527
<CssBaseline/>
36-
<Header fetchMetrics={fetchMetrics} setFetchMetrics={setFetchMetrics} showSettings={showSettings} setShowSettings={setShowSettings}/>
28+
<Header
29+
fetchMetrics={fetchMetrics}
30+
setFetchMetrics={setFetchMetrics}
31+
showSettings={showSettings}
32+
setShowSettings={setShowSettings}/>
3733
<SettingsSidebar
3834
showSettings={showSettings}
3935
setShowSettings={setShowSettings}
@@ -42,7 +38,7 @@ function App() {
4238
</SettingsSidebar>
4339
<PermanentDrawer></PermanentDrawer>
4440
<Routes>
45-
<Route path="/" element={<Homepage/>}/>
41+
<Route path="/" element={<Homepage metricsState={metricsState}/>}/>
4642
<Route path="/queryPage" element={<QueryPage/>}/>
4743
</Routes>
4844
</BrowserRouter>

ksqLight/src/components/Homepage.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { Typography, Grid, Toolbar } from "@mui/material";
44
import { Chart } from "./Chart.js";
55
import LineChart from "./LineChart.js";
66

7-
export const Homepage = () => {
7+
export const Homepage = ({ metricsState }) => {
88
const [content, setContent] = useState('Chart placeholder');
99

1010
const queryTypes = [
11-
// ["runningQueries", "Number of Running Queries"],
11+
["runningQueries", "Number of Running Queries"],
1212
// ["rebalancingQueries", "Number of Rebalancing Queries"],
1313
// ["pendingShutdownQueries", "Number of Pending Shutdown Queries"],
1414
// ["pendingErrorQueries", "Number of Pending Error Queries"],
@@ -34,7 +34,7 @@ export const Homepage = () => {
3434
<Toolbar></Toolbar>
3535
<Typography color="primary">Homepage</Typography>
3636
<Grid container spacing={2} justifyContent="flex-start" alignItems="flex-start" sx={{ pl: 28 }}>
37-
{queryTypes.map(([query, description], index) => <LineChart description={description} metric={query} key={index}/>)}
37+
{queryTypes.map(([query, description], index) => <LineChart description={description} metric={query} metricsState={metricsState} key={index}/>)}
3838
</Grid>
3939
</div>
4040

ksqLight/src/components/LineChart.js

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//-----------Import External Modules-----------
12
import React, { useEffect, useState } from "react";
23
import { Grid, Typography } from "@mui/material";
34
import {
@@ -10,21 +11,22 @@ import Chart from "chart.js/auto";
1011
import ChartStreaming from "chartjs-plugin-streaming";
1112
import 'chartjs-adapter-moment';
1213

13-
// import config from './chartConfig.js';
1414

15+
//-----------Import Internal Modules-----------
16+
import {getUnixRange, getDuration} from "../utils/utilityFunctions.js";
1517

1618
Chart.register(ChartStreaming);
1719

20+
1821
const client = new ApolloClient({
1922
uri: "http://localhost:5000/graphql",
2023
cache: new InMemoryCache(),
2124
});
2225

2326
// console.log('test: ', Math.round(new Date().getTime() / 1000));
2427

25-
export default function LineChart({ metric, description }) {
28+
export default function LineChart({ metric, description, metricsState }) {
2629
useEffect(() => {
27-
let delayed;
2830
// define chart context
2931
const ctx = document.getElementById(metric).getContext("2d");
3032

@@ -38,30 +40,17 @@ export default function LineChart({ metric, description }) {
3840
type: 'line',
3941
data: {
4042
datasets: [{
41-
data: [], // empty at the beginning,
42-
borderColor: 'rgba(58, 123, 213, 1)',
43-
pointRadius: 0,
44-
hitRadius: 30,
45-
hoverRadius: 5,
46-
fill: true,
47-
backgroundColor: gradient,
43+
data: [], // empty at the beginning,
44+
borderColor: 'rgba(58, 123, 213, 1)',
45+
pointRadius: 0,
46+
hitRadius: 30,
47+
hoverRadius: 5,
48+
fill: true,
49+
backgroundColor: gradient,
4850
}]
4951
},
5052
options: {
5153
responsive: true,
52-
animation: {
53-
onComplete: () => {
54-
delayed = true;
55-
},
56-
// delay: (context) => {
57-
// let delay = 0;
58-
// if (context.type === "data" && context.mode === "default" && !delayed) {
59-
// delay = context.dataIndex * 300 + context.datasetIndex * 100;
60-
// }
61-
// return delay;
62-
// }
63-
delay: 3,
64-
},
6554
elements: {
6655
line: {
6756
tension: .4
@@ -71,21 +60,22 @@ export default function LineChart({ metric, description }) {
7160
x: {
7261
type: 'realtime', // x axis will auto-scroll from right to left
7362
realtime: { // per-axis options
74-
duration: 200000, // data in the past 20000 ms will be displayed
75-
refresh: 2000, // onRefresh callback will be called every 1000 ms
76-
delay: 2000, // delay of 1000 ms, so upcoming values are known before plotting a line
63+
duration: getDuration(metricsState.duration.days, metricsState.duration.hours, metricsState.duration.minutes), // data in the past duration # of ms will be displayed
64+
refresh: metricsState.refreshRate * 1000, // onRefresh callback will be called every refresh # ms
65+
delay: 1000, // delay of 1000 ms, so upcoming values are known before plotting a line
7766
pause: false, // chart is not paused
7867
ttl: undefined, // data will be automatically deleted as it disappears off the chart
7968
frameRate: 30, // data points are drawn 30 times every second
8069

8170
// a callback to update datasets
8271
onRefresh: chart => {
72+
const [unixStart, unixEnd] = getUnixRange(metricsState.duration.days, metricsState.duration.hours, metricsState.duration.minutes);
8373

8474
// query your data source and get the array of {x: timestamp, y: value} objects
8575
client.query({
8676
query: gql`
8777
query testQuery {
88-
ksqlDBMetrics(metric: "${metric}", resolution: 2, start: ${Math.round(new Date().getTime() / 1000) - 500}, end: ${Math.round(new Date().getTime() / 1000)}) {
78+
ksqlDBMetrics(prometheusURL: "${metricsState.prometheusURL}" metric: "${metric}", resolution: ${metricsState.refreshRate}, start: ${unixStart}, end: ${unixEnd}) {
8979
x,
9080
y
9181
}
@@ -100,6 +90,7 @@ export default function LineChart({ metric, description }) {
10090
y: queryObj.y
10191
}
10292
});
93+
// console.log(data);
10394
chart.data.datasets[0].data = data;
10495
})
10596
.catch(error => console.log(error));
@@ -133,7 +124,11 @@ export default function LineChart({ metric, description }) {
133124
// instantiate new instance of a chart
134125
const realTimeChart = new Chart(ctx, config);
135126

136-
// populate initial data to avoid having to wait for first refresh
127+
// notes on where to go next
128+
// look into Line chart.js - 2 component to pass data to
129+
// look into the first batch of data coming back and compare it to other batches that successfully update the chart
130+
131+
// // populate initial data to avoid having to wait for first refresh
137132
// client.query({
138133
// query: gql`
139134
// query testQuery {
@@ -152,22 +147,27 @@ export default function LineChart({ metric, description }) {
152147
// y: queryObj.y
153148
// }
154149
// });
155-
// console.log('this is a test');
150+
// console.log('this runs within initial fetch');
156151
// realTimeChart.data.datasets[0].data = data;
157-
// realTimeChart.update();
152+
// // realTimeChart.update();
158153
// })
159154
// .catch(error => console.log(error));
160155

161156

162157
// chart teardown on unmount
163158
return () => {
164-
realTimeChart.destroy();
159+
console.log('teardown');
160+
realTimeChart.destroy();
165161
}
166-
}, []);
162+
}, [metricsState]);
167163

168164
return (
169-
<Grid item xs={2}>
170-
<canvas id={metric} width="100%" height="100%"></canvas>
171-
</Grid>
165+
<>
166+
<Grid item xs={2}>
167+
<canvas id={metric} width="100%" height="100%"></canvas>
168+
</Grid>
169+
<Grid item xs={10}>
170+
</Grid>
171+
</>
172172
);
173173
}

ksqLight/src/components/SettingsSidebar.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ export const SettingsSidebar = ({ showSettings, setShowSettings, metricsState, s
8787
event.preventDefault();
8888

8989
// verify prometheus URL
90-
// verify ksqlDB URL
90+
// verify ksqlDB url
91+
// verify metrics exist for duration requested
9192

9293
// idea: set microstates for this component so that values can update on change, but app state does not change until submit
9394

@@ -124,6 +125,7 @@ export const SettingsSidebar = ({ showSettings, setShowSettings, metricsState, s
124125
label="URL"
125126
name="prometheus-url"
126127
onChange={handleLocalMetrics}
128+
value={localMetricsState.prometheusURL}
127129
/>
128130
<hr className="w-full invisible mb-2 mt-2"></hr>
129131
<Typography variant="h6" sx={{color: "#333"}}>ksqlDB Connection</Typography>
@@ -134,6 +136,7 @@ export const SettingsSidebar = ({ showSettings, setShowSettings, metricsState, s
134136
label="URL"
135137
name="ksqldb-url"
136138
onChange={handleLocalMetrics}
139+
value={localMetricsState.ksqlDBURL}
137140
/>
138141
<hr className="w-full invisible mb-2 mt-2"></hr>
139142
<Typography variant="h6" sx={{color: "#333"}}>Duration</Typography>
@@ -217,7 +220,7 @@ export const SettingsSidebar = ({ showSettings, setShowSettings, metricsState, s
217220
<MenuItem value={55}>55</MenuItem>
218221
</Select>
219222
<hr className="w-full invisible mb-2 mt-2"></hr>
220-
<Typography variant="h6" sx={{color: "white"}}>Refresh Rate</Typography>
223+
<Typography variant="h6">Refresh Rate</Typography>
221224
<hr className="w-full mb-3 mt-1"></hr>
222225
<TextField
223226
fullWidth
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const utilityFunctions = {};
2+
3+
utilityFunctions.getUnixRange = (days, hours, minutes) => {
4+
const unixTimeNow = Math.round(new Date().getTime() / 1000);
5+
const unixOffSet = minutes * 60 + hours * 60 * 60 + days * 60 * 60 * 24;
6+
return [unixTimeNow - unixOffSet, unixTimeNow]
7+
};
8+
9+
utilityFunctions.getDuration = (days, hours, minutes) => {
10+
return (minutes * 60 + hours * 60 * 60 + days * 60 * 60 * 24) * 1000;
11+
}
12+
13+
module.exports = utilityFunctions;

0 commit comments

Comments
 (0)