Use dynamic step when fetching metrics from Prometheus server

This commit is contained in:
Ken Hibino
2021-12-01 17:32:41 -08:00
parent 3a90416b52
commit 36a5ce4a5b
2 changed files with 47 additions and 11 deletions

View File

@@ -80,12 +80,34 @@ func buildPrometheusURL(baseAddr, promQL string, opts *metricsFetchOptions) stri
v.Add("query", promQL)
v.Add("start", unixTimeString(opts.endTime.Add(-opts.duration)))
v.Add("end", unixTimeString(opts.endTime))
v.Add("step", (1 * time.Minute).String())
v.Add("step", strconv.Itoa(int(step(opts).Seconds())))
b.WriteString("?")
b.WriteString(v.Encode())
return b.String()
}
// Returns step to use given the fetch options.
// In general, the longer the duration, longer the each step.
func step(opts *metricsFetchOptions) time.Duration {
if opts.duration <= 6*time.Hour {
// maximum number of data points to return: 6h / 10s = 2160
return 10 * time.Second
}
if opts.duration <= 24*time.Hour {
// maximum number of data points to return: 24h / 1m = 1440
return 1 * time.Minute
}
if opts.duration <= 8*24*time.Hour {
// maximum number of data points to return: (8*24)h / 3m = 3840
return 3 * time.Minute
}
if opts.duration <= 30*24*time.Hour {
// maximum number of data points to return: (30*24)h / 10m = 4320
return 10 * time.Minute
}
return opts.duration / 3000
}
func unixTimeString(t time.Time) string {
return strconv.Itoa(int(t.Unix()))
}

View File

@@ -68,13 +68,25 @@ function MetricsView(props: Props) {
);
const [endTimeOption, setEndTimeOption] = React.useState("real_time");
const [endTimeSec, setEndTimeSec] = React.useState(currentUnixtime());
const [durationOption, setDurationOption] = React.useState("1h");
const [durationSec, setDurationSec] = React.useState(60 * 60); // 1h
const handleEndTimeOptionChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setEndTimeOption((event.target as HTMLInputElement).value);
const selected = (event.target as HTMLInputElement).value;
setEndTimeOption(selected);
switch (selected) {
case "real_time":
setEndTimeSec(currentUnixtime());
break;
case "freeze_at_now":
setEndTimeSec(currentUnixtime());
break;
case "custom":
// TODO:
}
};
const handleDurationOptionChange = (
@@ -115,14 +127,15 @@ function MetricsView(props: Props) {
const id = open ? "control-popover" : undefined;
React.useEffect(() => {
console.log("DEBUG: GETTING metrics", currentUnixtime(), durationSec);
getMetricsAsync(currentUnixtime(), durationSec);
const id = setInterval(() => {
console.log("DEBUG: GETTING metrics", currentUnixtime(), durationSec);
getMetricsAsync(currentUnixtime(), durationSec);
}, pollInterval * 1000);
return () => clearInterval(id);
}, [pollInterval, getMetricsAsync, durationSec]);
getMetricsAsync(endTimeSec, durationSec);
// Only set up polling if end_time option is "real_time"
if (endTimeOption === "real_time") {
const id = setInterval(() => {
getMetricsAsync(currentUnixtime(), durationSec);
}, pollInterval * 1000);
return () => clearInterval(id);
}
}, [pollInterval, getMetricsAsync, durationSec, endTimeSec, endTimeOption]);
return (
<Container maxWidth="lg" className={classes.container}>
@@ -136,7 +149,8 @@ function MetricsView(props: Props) {
color="primary"
onClick={handleClick}
>
Realtime: {durationOption}
{endTimeOption === "real_time" ? "Realtime" : "Historical"}:{" "}
{durationOption}
</Button>
<Popover
id={id}