mirror of
https://github.com/TwiN/gatus.git
synced 2024-12-14 11:58:04 +00:00
Start working on replacing SSR chart by chart.js
This commit is contained in:
parent
c4ef56511d
commit
ed4fa94fc2
4 changed files with 94 additions and 2 deletions
|
@ -1,6 +1,7 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
|
@ -117,3 +118,41 @@ func ResponseTimeChart(writer http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
func ResponseTime(writer http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
duration := vars["duration"]
|
||||
var from time.Time
|
||||
switch duration {
|
||||
case "7d":
|
||||
from = time.Now().Truncate(time.Hour).Add(-24 * 7 * time.Hour)
|
||||
case "24h":
|
||||
from = time.Now().Truncate(time.Hour).Add(-24 * time.Hour)
|
||||
default:
|
||||
http.Error(writer, "Durations supported: 7d, 24h", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
hourlyAverageResponseTime, err := store.Get().GetHourlyAverageResponseTimeByKey(vars["key"], from, time.Now())
|
||||
if err != nil {
|
||||
if err == common.ErrEndpointNotFound {
|
||||
http.Error(writer, err.Error(), http.StatusNotFound)
|
||||
} else if err == common.ErrInvalidTimeRange {
|
||||
http.Error(writer, err.Error(), http.StatusBadRequest)
|
||||
} else {
|
||||
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
if len(hourlyAverageResponseTime) == 0 {
|
||||
http.Error(writer, "", http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
data, err := json.Marshal(hourlyAverageResponseTime)
|
||||
if err != nil {
|
||||
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
writer.Header().Add("Content-Type", "application/json")
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
_, _ = writer.Write(data)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ func CreateRouter(staticFolder string, securityConfig *security.Config, uiConfig
|
|||
router.HandleFunc("/api/v1/endpoints/{key}/uptimes/{duration}/badge.svg", UptimeBadge).Methods("GET")
|
||||
router.HandleFunc("/api/v1/endpoints/{key}/response-times/{duration}/badge.svg", ResponseTimeBadge).Methods("GET")
|
||||
router.HandleFunc("/api/v1/endpoints/{key}/response-times/{duration}/chart.svg", ResponseTimeChart).Methods("GET")
|
||||
router.HandleFunc("/api/v1/endpoints/{key}/response-times/{duration}", ResponseTime).Methods("GET")
|
||||
// XXX: Remove the lines between this and the next XXX comment in v4.0.0
|
||||
router.HandleFunc("/api/v1/services/statuses", secureIfNecessary(securityConfig, EndpointStatuses)).Methods("GET") // No GzipHandler for this one, because we cache the content as Gzipped already
|
||||
router.HandleFunc("/api/v1/services/{key}/statuses", secureIfNecessary(securityConfig, GzipHandlerFunc(EndpointStatus))).Methods("GET")
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"core-js": "^3.19.1",
|
||||
"vue": "3.2.21",
|
||||
"vue-chart-3": "^0.5.11",
|
||||
"vue-router": "^4.0.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
<div v-if="endpointStatus && endpointStatus.key" class="mt-12">
|
||||
<h1 class="text-xl xl:text-3xl font-mono text-gray-400">RESPONSE TIME</h1>
|
||||
<hr/>
|
||||
|
||||
<LineChart :chartData="chartData" :options="chartOptions" />
|
||||
|
||||
<img :src="generateResponseTimeChartImageURL()" alt="response time chart" class="mt-6" />
|
||||
<div class="flex space-x-4 text-center text-2xl mt-6 relative bottom-2 mb-10">
|
||||
<div class="flex-1">
|
||||
|
@ -92,17 +95,24 @@ import {SERVER_URL} from "@/main.js";
|
|||
import {helper} from "@/mixins/helper.js";
|
||||
import Pagination from "@/components/Pagination";
|
||||
|
||||
import { LineChart } from 'vue-chart-3';
|
||||
import { Chart, CategoryScale, LineController, LinearScale, LineElement, PointElement, TimeScale, Title, Tooltip} from 'chart.js';
|
||||
Chart.register(LineController, CategoryScale, LinearScale, LineElement, PointElement, TimeScale, Title, Tooltip);
|
||||
|
||||
|
||||
export default {
|
||||
name: 'Details',
|
||||
components: {
|
||||
Pagination,
|
||||
Endpoint,
|
||||
Settings,
|
||||
LineChart,
|
||||
},
|
||||
emits: ['showTooltip'],
|
||||
mixins: [helper],
|
||||
methods: {
|
||||
fetchData() {
|
||||
// XXX: This should probably be called every 15 minutes or so
|
||||
//console.log("[Details][fetchData] Fetching data");
|
||||
fetch(`${this.serverUrl}/api/v1/endpoints/${this.$route.params.key}/statuses?page=${this.currentPage}`)
|
||||
.then(response => response.json())
|
||||
|
@ -140,8 +150,39 @@ export default {
|
|||
}
|
||||
this.events = events;
|
||||
}
|
||||
this.fetchUptimeChartData();
|
||||
});
|
||||
},
|
||||
fetchUptimeChartData() {
|
||||
fetch(`${this.serverUrl}/api/v1/endpoints/${this.$route.params.key}/response-times/24h`).then(response => {
|
||||
response.json().then(data => {
|
||||
let chart = {
|
||||
labels: [],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Average response time (ms)',
|
||||
data: [],
|
||||
borderColor: 'rgb(75, 192, 192)',
|
||||
},
|
||||
]
|
||||
};
|
||||
let latest = null;
|
||||
for (const [key] of Object.entries(data)) {
|
||||
latest = key;
|
||||
}
|
||||
for (let i = 24; i >= 0; i--) {
|
||||
let date = new Date((latest*1000)-(i*3600000));
|
||||
chart.labels.push(date.toLocaleTimeString().replaceAll(":00", ""));
|
||||
if (data[date.getTime()/1000]) {
|
||||
chart.datasets[0].data.push(data[date.getTime()/1000]);
|
||||
} else {
|
||||
chart.datasets[0].data.push(0);
|
||||
}
|
||||
}
|
||||
this.chartData = chart;
|
||||
})
|
||||
});
|
||||
},
|
||||
generateUptimeBadgeImageURL(duration) {
|
||||
return `${this.serverUrl}/api/v1/endpoints/${this.endpointStatus.key}/uptimes/${duration}/badge.svg`;
|
||||
},
|
||||
|
@ -182,8 +223,18 @@ export default {
|
|||
serverUrl: SERVER_URL === '.' ? '..' : SERVER_URL,
|
||||
currentPage: 1,
|
||||
showAverageResponseTime: true,
|
||||
chartLabels: [],
|
||||
chartValues: [],
|
||||
chartData: {labels: [], datasets: [{data: []}]},
|
||||
chartOptions: {
|
||||
scales: {
|
||||
y: {
|
||||
min: 0,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Average response time (ms)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
Loading…
Reference in a new issue