Adding response time graph

This commit is contained in:
Axel 2021-12-26 19:03:13 +01:00
parent 2c415cd08b
commit bae507328b
3 changed files with 183 additions and 63 deletions

View file

@ -67,21 +67,21 @@ class ApiController extends Controller
if (! is_null($task)) { if (! is_null($task)) {
// First, we get the first date of the stats // First, we get the first date of the stats
// In this case, one month ago // In this case, one month ago
$last_days = Carbon::now()->subDays($days); $first_day = Carbon::now()->startOfDay()->subDays($days);
// Then we get all history for the past month // Then we get all history for the past month
$history = $task $history = $task
->history() ->history()
->orderBy('created_at', 'desc') ->orderBy('created_at', 'desc')
->where('created_at', '>', $last_days->toDateString()) ->where('created_at', '>', $first_day->toDateString())
->selectRaw('id, date(created_at) as date, created_at, status, duration, output') ->selectRaw('id, date(created_at) as date, created_at, status, duration, output')
->get() ->get()
; ;
// Then we start building an array for the entire month // Then we start building an array for the entire month
$stats = []; $stats = $times = [];
$tmpdate = Carbon::now()->subDays($days); $tmpdate = Carbon::now()->subDays($days);
do { do {
$stats[$tmpdate->toDateString()] = [ $stats['uptime'][$tmpdate->toDateString()] = [
'up' => 0, 'up' => 0,
'down' => 0 'down' => 0
]; ];
@ -90,42 +90,46 @@ class ApiController extends Controller
while ($tmpdate->lt(Carbon::now())); while ($tmpdate->lt(Carbon::now()));
// Then we populate the stats data // Then we populate the stats data
$prev = null;
if (! is_null($history)) { if (! is_null($history)) {
foreach ($history as $r) { foreach ($history as $k => $r) {
if (empty($stats[$r->date])) { if (empty($stats['uptime'][$r->date])) {
$stats[$r->date] = [ $stats['uptime'][$r->date] = [
'up' => 0, 'up' => 0,
'down' => 0 'down' => 0
]; ];
} }
// Populating the stats
if ($r->status == 1) { if ($r->status == 1) {
++$stats[$r->date]['up']; ++$stats['uptime'][$r->date]['up'];
} }
else { else {
++$stats[$r->date]['down']; ++$stats['uptime'][$r->date]['down'];
} }
}
}
// Then we populate the history data // Populating the response times
if (! is_null($history)) { if ($r->status == 1) {
$prev = null; array_push($times, [
'date' => $r->created_at->toDateTimeString(),
'duration' => $r->duration ?? 0
]);
}
foreach ($history as $k => $h) {
// We only take tasks when status has changed between them // We only take tasks when status has changed between them
if (! is_null($prev) && $h->status == $prev) { if (! is_null($prev) && $r->status == $prev) {
unset($history[$k]); unset($history[$k]);
} }
$prev = $h->status; $prev = $r->status;
} }
} }
$stats['times'] = array_reverse($times);
// Getting the notifications sent // Getting the notifications sent
$notifications = $task $notifications = $task
->notifications() ->notifications()
->with('contact') ->with('contact')
->where('notifications.created_at', '>', $last_days->toDateString()) ->where('notifications.created_at', '>', $first_day->toDateString())
->orderBy('notifications.created_at', 'desc') ->orderBy('notifications.created_at', 'desc')
->get() ->get()
; ;
@ -134,7 +138,8 @@ class ApiController extends Controller
'task' => $task, 'task' => $task,
'stats' => $stats, 'stats' => $stats,
'history' => $history, 'history' => $history,
'notifications' => $notifications 'notifications' => $notifications,
'first_day' => $first_day->toDateTimeString()
]); ]);
} }
} }

File diff suppressed because one or more lines are too long

View file

@ -10,7 +10,7 @@
Show: Show:
<select <select
v-model="chart.days" v-model="days"
@change="refreshTask" @change="refreshTask"
> >
<option value="7">7 days</option> <option value="7">7 days</option>
@ -18,17 +18,27 @@
<option value="30">30 days</option> <option value="30">30 days</option>
</select> </select>
<!-- Chart block --> <!-- Uptime chart block -->
<div id="chart" class="round"> <div id="chart" class="round">
<h3>Uptime: past {{ chart.days }} days</h3> <h3>Last {{ days }} days uptime</h3>
<div class="block-content"> <div class="block-content">
<apexchart class="graph" v-if="chart.render" type="bar" height="350" :options="chartOptions" :series="series"></apexchart> <apexchart class="graph" v-if="charts.uptime.render" type="bar" height="350" :options="charts.uptime.options" :series="charts.uptime.series"></apexchart>
</div> </div>
</div> </div>
<!-- Response time chart block -->
<div id="chart" class="round">
<h3>Last {{ days }} days response time</h3>
<div class="block-content">
<apexchart class="graph" v-if="charts.response.render" type="area" height="350" :options="charts.response.options" :series="charts.response.series"></apexchart>
</div>
</div>
<!-- History backlog --> <!-- History backlog -->
<div class="round"> <div class="round">
<h3>Last {{ chart.days }} days history log</h3> <h3>Last {{ days }} days history log</h3>
<div class="block-content" v-if="history"> <div class="block-content" v-if="history">
<p><i>Showing only records where status has changed</i></p> <p><i>Showing only records where status has changed</i></p>
<table id="tasks_tbl"> <table id="tasks_tbl">
@ -72,7 +82,7 @@
<!-- Notifications block --> <!-- Notifications block -->
<div class="round"> <div class="round">
<h3>Last {{ chart.days }} days notifications log</h3> <h3>Last {{ days }} days notifications log</h3>
<div class="block-content" v-if="notifications"> <div class="block-content" v-if="notifications">
<table id="tasks_tbl"> <table id="tasks_tbl">
<thead> <thead>
@ -118,36 +128,68 @@
notifications: null, notifications: null,
refresh: null, refresh: null,
loader: null, loader: null,
days: 15,
first_day: null,
chart: { charts: {
render: false, uptime: {
days: 15 render: false,
}, series: [{
data: []
series: [{ }],
data: [] noData: {
}], text: 'Loading...'
noData: { },
text: 'Loading...'
},
chartOptions: {
responsive: [{
breakpoint: 480,
options: { options: {
legend: { responsive: [{
position: 'bottom', breakpoint: 480,
offsetX: -10, options: {
offsetY: 0 legend: {
} position: 'bottom',
offsetX: -10,
offsetY: 0
}
}
}],
xaxis: {
categories: [],
},
fill: {
opacity: .9
},
},
},
response: {
render: true,
series: [{
data: [10, 20, 30]
}],
noData: {
text: 'Loading...'
},
options: {
responsive: [{
breakpoint: 480,
options: {
legend: {
position: 'bottom',
offsetX: -10,
offsetY: 0
}
}
}],
xaxis: {
categories: [
'oct', 'nov', 'dev'
],
},
fill: {
opacity: .9
},
} }
}], }
xaxis: { }
categories: [],
},
fill: {
opacity: .9
},
},
} }
}, },
methods: { methods: {
@ -165,13 +207,15 @@
}, },
refreshTask: function(callback) { refreshTask: function(callback) {
this.$http.post('/api/getTask/'+this.task.id, { this.$http.post('/api/getTask/'+this.task.id, {
days: this.chart.days days: this.days
}) })
.then(response => { .then(response => {
this.task = response.data.task this.task = response.data.task
this.history = response.data.history this.history = response.data.history
this.first_day = new Date(response.data.first_day).getTime();
this.notifications = response.data.notifications this.notifications = response.data.notifications
this.refreshGraph(response.data.stats) this.refreshUptimeGraph(response.data.stats.uptime)
this.refreshResponseTimeGraph(response.data.stats.times)
this.loader.hide() this.loader.hide()
}) })
.then(() => { .then(() => {
@ -185,24 +229,95 @@
this.loader.hide() this.loader.hide()
}) })
}, },
refreshGraph: function(stats) { refreshResponseTimeGraph: function(stats) {
let data = [];
let xaxis = [];
for (let i in stats) {
xaxis.push(stats[i]['date'])
data.push(stats[i]['duration'])
}
console.log(xaxis)
this.charts.response.options = {
xaxis: {
//type: 'datetime',
//min: this.first_day,
categories: xaxis,
//tickAmount: 6,
labels: {
show: true,
rotate: -45,
//rotateAlways: true,
}
},
tooltip: {
x: {
format: "dd MMM yyyy"
}
},
chart: {
type: 'line',
height: 350,
stacked: false
},
legend: {
position: 'right',
offsetX: 0,
offsetY: 50
},
fill: {
colors: [function({ value, seriesIndex, w }) {
if(value < 1) {
return '#2acdc7'
}
else if (value >= 1 && value < 3) {
return '#e97a39'
}
else {
return '#e93949'
}
}],
type: "gradient",
gradient: {
shadeIntensity: 1,
opacityFrom: 0.7,
opacityTo: 0.9,
stops: [0, 100]
}
}
}
this.charts.response.series = [{
name: 'Response time',
data: data
}]
},
refreshUptimeGraph: function(stats) {
let xaxis = []; let xaxis = [];
let new_data_a = []; let new_data_a = [];
let new_data_b = []; let new_data_b = [];
for (let date in stats) { for (let date in stats) {
xaxis.push(date) xaxis.push(new Date(date).getTime())
new_data_a.push(stats[date]['up']) new_data_a.push(stats[date]['up'])
new_data_b.push(stats[date]['down']) new_data_b.push(stats[date]['down'])
} }
this.chartOptions = { this.charts.uptime.options = {
xaxis: { xaxis: {
type: 'datetime',
min: this.first_day,
categories: xaxis, categories: xaxis,
tickAmount: 6,
labels: { labels: {
show: true, show: true,
rotate: -45, rotate: -45,
rotateAlways: true, //rotateAlways: true,
}
},
tooltip: {
x: {
format: "yyyy MMM dd"
} }
}, },
chart: { chart: {
@ -217,7 +332,7 @@
offsetY: 50 offsetY: 50
}, },
} }
this.series = [{ this.charts.uptime.series = [{
name: 'UP', name: 'UP',
data: new_data_a, data: new_data_a,
color: '#00955c' color: '#00955c'
@ -228,11 +343,11 @@
color: '#ef3232' color: '#ef3232'
}] }]
this.chart.render = true this.charts.uptime.render = true
}, },
}, },
mounted: function() { mounted: function() {
this.loader = this.$loading.show() //this.loader = this.$loading.show()
this.task.id = this.$route.params.id ?? null this.task.id = this.$route.params.id ?? null
if (this.task.id != null) { if (this.task.id != null) {