mirror of https://github.com/statping/statping
apexcharts - heatmap
parent
652b565d4e
commit
30b6a2df6b
|
@ -244,6 +244,7 @@ func recordFailure(s *Service, issue string) {
|
|||
Issue: issue,
|
||||
PingTime: s.PingTime,
|
||||
CreatedAt: time.Now(),
|
||||
ErrorCode: s.LastStatusCode,
|
||||
}}
|
||||
utils.Log(2, fmt.Sprintf("Service %v Failing: %v | Lookup in: %0.2f ms", s.Name, issue, fail.PingTime*1000))
|
||||
s.CreateFailure(fail)
|
||||
|
|
|
@ -124,6 +124,16 @@ func CountFailures() uint64 {
|
|||
return count
|
||||
}
|
||||
|
||||
// TotalFailuresOnDate returns the total amount of failures for a service on a specific time/date
|
||||
func (s *Service) TotalFailuresOnDate(ago time.Time) (uint64, error) {
|
||||
var count uint64
|
||||
date := ago.UTC().Format("2006-01-02 00:00:00")
|
||||
dateend := ago.UTC().Format("2006-01-02 23:59:59")
|
||||
rows := failuresDB().Where("service = ? AND created_at BETWEEN ? AND ?", s.Id, date, dateend).Not("method = 'checkin'")
|
||||
err := rows.Count(&count)
|
||||
return count, err.Error
|
||||
}
|
||||
|
||||
// TotalFailures24 returns the amount of failures for a service within the last 24 hours
|
||||
func (s *Service) TotalFailures24() (uint64, error) {
|
||||
ago := time.Now().Add(-24 * time.Hour)
|
||||
|
|
|
@ -28,7 +28,7 @@ func InsertSampleData() error {
|
|||
utils.Log(1, "Inserting Sample Data...")
|
||||
|
||||
insertSampleGroups()
|
||||
|
||||
createdOn := time.Now().Add((-24 * 90) * time.Hour).UTC()
|
||||
s1 := ReturnService(&types.Service{
|
||||
Name: "Google",
|
||||
Domain: "https://google.com",
|
||||
|
@ -39,6 +39,7 @@ func InsertSampleData() error {
|
|||
Timeout: 10,
|
||||
Order: 1,
|
||||
GroupId: 1,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
s2 := ReturnService(&types.Service{
|
||||
Name: "Statping Github",
|
||||
|
@ -49,6 +50,7 @@ func InsertSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 20,
|
||||
Order: 2,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
s3 := ReturnService(&types.Service{
|
||||
Name: "JSON Users Test",
|
||||
|
@ -61,6 +63,7 @@ func InsertSampleData() error {
|
|||
Order: 3,
|
||||
Public: types.NewNullBool(true),
|
||||
GroupId: 2,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
s4 := ReturnService(&types.Service{
|
||||
Name: "JSON API Tester",
|
||||
|
@ -75,17 +78,19 @@ func InsertSampleData() error {
|
|||
Order: 4,
|
||||
Public: types.NewNullBool(true),
|
||||
GroupId: 2,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
s5 := ReturnService(&types.Service{
|
||||
Name: "Google DNS",
|
||||
Domain: "8.8.8.8",
|
||||
Interval: 20,
|
||||
Type: "tcp",
|
||||
Port: 53,
|
||||
Timeout: 120,
|
||||
Order: 5,
|
||||
Public: types.NewNullBool(true),
|
||||
GroupId: 1,
|
||||
Name: "Google DNS",
|
||||
Domain: "8.8.8.8",
|
||||
Interval: 20,
|
||||
Type: "tcp",
|
||||
Port: 53,
|
||||
Timeout: 120,
|
||||
Order: 5,
|
||||
Public: types.NewNullBool(true),
|
||||
GroupId: 1,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s1.Create(false)
|
||||
|
@ -249,6 +254,7 @@ func InsertLargeSampleData() error {
|
|||
if err := insertMessages(); err != nil {
|
||||
return err
|
||||
}
|
||||
createdOn := time.Now().Add((-24 * 90) * time.Hour).UTC()
|
||||
s6 := ReturnService(&types.Service{
|
||||
Name: "JSON Lint",
|
||||
Domain: "https://jsonlint.com",
|
||||
|
@ -258,6 +264,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 10,
|
||||
Order: 6,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s7 := ReturnService(&types.Service{
|
||||
|
@ -269,6 +276,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 15,
|
||||
Order: 7,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s8 := ReturnService(&types.Service{
|
||||
|
@ -291,6 +299,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 10,
|
||||
Order: 9,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s10 := ReturnService(&types.Service{
|
||||
|
@ -302,6 +311,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 10,
|
||||
Order: 10,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s11 := ReturnService(&types.Service{
|
||||
|
@ -313,6 +323,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 20,
|
||||
Order: 11,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s12 := ReturnService(&types.Service{
|
||||
|
@ -324,6 +335,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 20,
|
||||
Order: 12,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s13 := ReturnService(&types.Service{
|
||||
|
@ -335,6 +347,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 10,
|
||||
Order: 13,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s14 := ReturnService(&types.Service{
|
||||
|
@ -346,6 +359,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 12,
|
||||
Order: 14,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s15 := ReturnService(&types.Service{
|
||||
|
@ -357,6 +371,7 @@ func InsertLargeSampleData() error {
|
|||
Method: "GET",
|
||||
Timeout: 12,
|
||||
Order: 15,
|
||||
CreatedAt: createdOn,
|
||||
})
|
||||
|
||||
s6.Create(false)
|
||||
|
@ -370,7 +385,7 @@ func InsertLargeSampleData() error {
|
|||
s14.Create(false)
|
||||
s15.Create(false)
|
||||
|
||||
var dayAgo = time.Now().Add(-24 * time.Hour).Add(-10 * time.Minute)
|
||||
var dayAgo = time.Now().Add((-24 * 90) * time.Hour)
|
||||
|
||||
insertHitRecords(dayAgo, 1450)
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ func Router() *mux.Router {
|
|||
r.Handle("/api/reorder", http.HandlerFunc(reorderServiceHandler)).Methods("POST")
|
||||
r.Handle("/api/services/{id}/data", cached("30s", "application/json", http.HandlerFunc(apiServiceDataHandler))).Methods("GET")
|
||||
r.Handle("/api/services/{id}/ping", http.HandlerFunc(apiServicePingDataHandler)).Methods("GET")
|
||||
r.Handle("/api/services/{id}/heatmap", http.HandlerFunc(apiServiceHeatmapHandler)).Methods("GET")
|
||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
|
||||
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
|
||||
r.Handle("/api/services/{id}/failures", http.HandlerFunc(apiServiceFailuresHandler)).Methods("GET")
|
||||
|
|
|
@ -221,6 +221,53 @@ func apiServicePingDataHandler(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(obj)
|
||||
}
|
||||
|
||||
type dataXy struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
}
|
||||
|
||||
type dataXyMonth struct {
|
||||
Date time.Time `json:"date"`
|
||||
Data []*dataXy `json:"data"`
|
||||
}
|
||||
|
||||
func apiServiceHeatmapHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
service := core.SelectService(utils.ToInt(vars["id"]))
|
||||
if service == nil {
|
||||
sendErrorJson(errors.New("service data not found"), w, r)
|
||||
return
|
||||
}
|
||||
|
||||
var monthOutput []*dataXyMonth
|
||||
|
||||
start := service.CreatedAt
|
||||
|
||||
if start.Year() <= 2 {
|
||||
start = service.CreatedAt.Add(time.Duration((-3 * 24) * time.Hour))
|
||||
}
|
||||
|
||||
for y := start; y.Year() == start.Year(); y = y.AddDate(1, 0, 0) {
|
||||
|
||||
for m := y; m.Month() == y.Month(); m = m.AddDate(0, 1, 0) {
|
||||
|
||||
var output []*dataXy
|
||||
|
||||
for day := 1; day <= 31; day++ {
|
||||
date := time.Date(y.Year(), y.Month(), day, 0, 0, 0, 0, time.UTC)
|
||||
failures, _ := service.TotalFailuresOnDate(date)
|
||||
output = append(output, &dataXy{day, int(failures)})
|
||||
}
|
||||
|
||||
monthOutput = append(monthOutput, &dataXyMonth{m, output})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(monthOutput)
|
||||
}
|
||||
|
||||
func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsFullAuthenticated(r) {
|
||||
sendUnauthorizedJson(w, r)
|
||||
|
|
|
@ -139,6 +139,7 @@ HTML, BODY {
|
|||
position: relative;
|
||||
height: 170px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.service-chart-container {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,86 +1,139 @@
|
|||
{{define "charts"}}
|
||||
{{$start := .Start}}
|
||||
{{$end := .End}}
|
||||
|
||||
const axisOptions = {
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
crosshairs: {
|
||||
show: false
|
||||
},
|
||||
lines: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
grid: {
|
||||
show: false
|
||||
},
|
||||
marker: {
|
||||
show: false
|
||||
}
|
||||
};
|
||||
|
||||
let options = {
|
||||
chart: {
|
||||
height: 210,
|
||||
width: "100%",
|
||||
type: "area",
|
||||
animations: {
|
||||
enabled: false,
|
||||
initialAnimation: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
selection: {
|
||||
enabled: false
|
||||
},
|
||||
zoom: {
|
||||
enabled: false
|
||||
},
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false,
|
||||
marker: {
|
||||
show: false,
|
||||
},
|
||||
x: {
|
||||
show: false,
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
floating: true,
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
fill: {
|
||||
colors: ["#48d338"],
|
||||
opacity: 1,
|
||||
type: 'solid'
|
||||
},
|
||||
stroke: {
|
||||
show: true,
|
||||
curve: 'smooth',
|
||||
lineCap: 'butt',
|
||||
colors: ["#3aa82d"],
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "Series 1",
|
||||
data: [
|
||||
{
|
||||
x: "02-10-2017 GMT",
|
||||
y: 34
|
||||
},
|
||||
{
|
||||
x: "02-11-2017 GMT",
|
||||
y: 43
|
||||
},
|
||||
{
|
||||
x: "02-12-2017 GMT",
|
||||
y: 31
|
||||
},
|
||||
{
|
||||
x: "02-13-2017 GMT",
|
||||
y: 43
|
||||
},
|
||||
{
|
||||
x: "02-14-2017 GMT",
|
||||
y: 33
|
||||
},
|
||||
{
|
||||
x: "02-15-2017 GMT",
|
||||
y: 52
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
xaxis: {
|
||||
type: "datetime",
|
||||
...axisOptions
|
||||
},
|
||||
yaxis: {
|
||||
...axisOptions
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
{{ range .Services }}
|
||||
var ctx_{{js .Id}} = document.getElementById("service_{{js .Id}}").getContext('2d');
|
||||
var chartdata_{{js .Id}} = new Chart(ctx_{{js .Id}}, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Response Time (Milliseconds)',
|
||||
data: [],
|
||||
backgroundColor: ['{{if .Online}}rgba(47, 206, 30, 0.92){{else}}rgb(221, 53, 69){{end}}'],
|
||||
borderColor: ['{{if .Online}}rgb(47, 171, 34){{else}}rgb(183, 32, 47){{end}}'],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
scaleShowValues: false,
|
||||
layout: {
|
||||
padding: {
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: -10
|
||||
}
|
||||
},
|
||||
hover: {
|
||||
animationDuration: 0,
|
||||
},
|
||||
responsiveAnimationDuration: 0,
|
||||
animation: {
|
||||
duration: 3500,
|
||||
onComplete: onChartComplete
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltips: {
|
||||
enabled: false
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: false,
|
||||
ticks: {
|
||||
fontSize: 20,
|
||||
display: false,
|
||||
beginAtZero: false
|
||||
},
|
||||
gridLines: {
|
||||
display: false
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
type: 'time',
|
||||
distribution: 'series',
|
||||
autoSkip: false,
|
||||
time: {
|
||||
displayFormats: {
|
||||
'hour': 'MMM DD hA'
|
||||
},
|
||||
source: 'auto'
|
||||
},
|
||||
gridLines: {
|
||||
display: false
|
||||
},
|
||||
ticks: {
|
||||
source: 'auto',
|
||||
stepSize: 1,
|
||||
min: 0,
|
||||
fontColor: "white",
|
||||
fontSize: 20,
|
||||
display: false
|
||||
}
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
point: {
|
||||
radius: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let chart{{.Id}} = new ApexCharts(document.querySelector("#service_{{js .Id}}"), options);
|
||||
|
||||
{{end}}
|
||||
|
||||
function onChartComplete(chart) {
|
||||
|
@ -140,7 +193,7 @@ function onChartComplete(chart) {
|
|||
}
|
||||
|
||||
$( document ).ready(function() {
|
||||
{{ range .Services }}
|
||||
AjaxChart(chartdata_{{js .Id}},{{js .Id}},{{$start}},9999999999,"hour");{{end}}
|
||||
});
|
||||
{{ range .Services }}AjaxChart(chart{{js .Id}}, {{js .Id}}, 0, 9999999999);
|
||||
{{end}}
|
||||
});
|
||||
{{end}}
|
||||
|
|
|
@ -124,11 +124,10 @@ function AjaxChart(chart, service, start=0, end=9999999999, group="hour", retry=
|
|||
} else if (data.data.length === 0) {
|
||||
return;
|
||||
}
|
||||
chart.data.labels.pop();
|
||||
data.data.forEach(function(d) {
|
||||
chart.data.datasets[0].data.push(d);
|
||||
});
|
||||
chart.update();
|
||||
chart.render();
|
||||
chart.updateSeries([{
|
||||
data: data.data
|
||||
}]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -136,6 +136,7 @@ HTML,BODY {
|
|||
position: relative;
|
||||
height: 170px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.service-chart-container {
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<span class="badge bg-danger float-right pulse">OFFLINE</span>
|
||||
{{end}}</h4>
|
||||
|
||||
<div class="row stats_area mt-5 mb-5">
|
||||
<div class="row stats_area mt-5">
|
||||
<div class="col-4">
|
||||
<span class="lg_number">{{.AvgTime}}ms</span>
|
||||
Average Response
|
||||
|
@ -82,7 +82,7 @@
|
|||
</div>
|
||||
{{ if .AvgUptime24 }}
|
||||
<div class="chart-container">
|
||||
<canvas id="service_{{ .Id }}"></canvas>
|
||||
<div id="service_{{ .Id }}"></div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="row lower_canvas full-col-12 text-white{{if not .Online}} bg-danger{{end}}">
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
{{if USE_CDN}}
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
<script src="https://assets.statping.com/main.js"></script>
|
||||
{{ else }}
|
||||
<script src="/js/jquery-3.3.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/Chart.bundle.min.js"></script>
|
||||
<script src="/js/apexcharts.min.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
{{end}}
|
||||
{{block "extra_scripts" .}} {{end}}
|
||||
|
|
|
@ -59,7 +59,11 @@
|
|||
{{end}}
|
||||
|
||||
<div class="service-chart-container">
|
||||
<canvas id="service"></canvas>
|
||||
<div id="service"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div id="service_heatmap"></div>
|
||||
</div>
|
||||
|
||||
<form id="service_date_form" class="col-12 mt-2 mb-3">
|
||||
|
@ -205,69 +209,79 @@
|
|||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
var ctx = document.getElementById("service").getContext('2d');
|
||||
|
||||
var chartdata = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Response Time (Milliseconds)',
|
||||
data: [],
|
||||
backgroundColor: [
|
||||
'rgba(47, 206, 30, 0.92)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgb(47, 171, 34)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
gridLines: {
|
||||
display: true
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
type: 'time',
|
||||
distribution: 'series',
|
||||
time: {
|
||||
displayFormats: {
|
||||
'millisecond': 'MMM DD',
|
||||
'second': 'MMM DD',
|
||||
'minute': 'MMM DD',
|
||||
'hour': 'MMM DD hA',
|
||||
'day': 'MMM DD',
|
||||
'week': 'MMM DD',
|
||||
'month': 'MMM DD',
|
||||
'quarter': 'MMM DD',
|
||||
'year': 'MMM DD',
|
||||
}
|
||||
},
|
||||
gridLines: {
|
||||
display: true
|
||||
},
|
||||
ticks: {
|
||||
source: 'auto'
|
||||
}
|
||||
}],
|
||||
},
|
||||
elements: {
|
||||
point: {
|
||||
radius: 0
|
||||
let options = {
|
||||
chart: {
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
type: "area",
|
||||
animations: {
|
||||
enabled: false,
|
||||
initialAnimation: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
},
|
||||
fill: {
|
||||
colors: ["#48d338"],
|
||||
opacity: 1,
|
||||
type: 'solid'
|
||||
},
|
||||
stroke: {
|
||||
show: true,
|
||||
curve: 'smooth',
|
||||
lineCap: 'butt',
|
||||
colors: ["#3aa82d"],
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "Response Time",
|
||||
data: [
|
||||
{
|
||||
x: "02-10-2017 GMT",
|
||||
y: 34
|
||||
},
|
||||
{
|
||||
x: "02-11-2017 GMT",
|
||||
y: 43
|
||||
},
|
||||
{
|
||||
x: "02-12-2017 GMT",
|
||||
y: 31
|
||||
},
|
||||
{
|
||||
x: "02-13-2017 GMT",
|
||||
y: 43
|
||||
},
|
||||
{
|
||||
x: "02-14-2017 GMT",
|
||||
y: 33
|
||||
},
|
||||
{
|
||||
x: "02-15-2017 GMT",
|
||||
y: 52
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
],
|
||||
xaxis: {
|
||||
type: "datetime",
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
formatter: (value) => {
|
||||
return (value * 0.1).toFixed(0) + "ms"
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
};
|
||||
|
||||
AjaxChart(chartdata,{{$s.Id}},{{.StartUnix}},{{.EndUnix}},"hour");
|
||||
let chart = new ApexCharts(document.querySelector("#service"), options);
|
||||
|
||||
AjaxChart(chart,{{$s.Id}},{{.StartUnix}},{{.EndUnix}},"hour");
|
||||
|
||||
let startDate = $("#service_start").flatpickr({
|
||||
enableTime: false,
|
||||
|
@ -290,6 +304,47 @@ $(document).ready(function() {
|
|||
startDate.open()
|
||||
});
|
||||
|
||||
|
||||
|
||||
var heat_options = {
|
||||
chart: {
|
||||
height: "100%",
|
||||
width: "100%",
|
||||
type: 'heatmap',
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
enableShades: true,
|
||||
shadeIntensity: 0.5,
|
||||
colors: ["#d53a3b"],
|
||||
series: [{}],
|
||||
};
|
||||
|
||||
var heatChart = new ApexCharts(
|
||||
document.querySelector("#service_heatmap"),
|
||||
heat_options
|
||||
);
|
||||
|
||||
var heatmapData = [];
|
||||
|
||||
$.ajax({
|
||||
url: "/api/services/{{$s.Id}}/heatmap",
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
data.forEach(function(d) {
|
||||
var date = new Date(d.date);
|
||||
heatmapData.push({name: date.toLocaleString('en-us', { month: 'long' }), data: d.data});
|
||||
});
|
||||
heatChart.render();
|
||||
heatChart.updateSeries(heatmapData);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// This file was generated by robots at
|
||||
// 2019-01-17 01:23:49.15263 -0800 PST m=+0.644968431
|
||||
// 2019-01-29 04:01:15.747029 -0800 PST m=+0.799396747
|
||||
//
|
||||
// This contains the most recently Markdown source for the Statping Wiki.
|
||||
package source
|
||||
|
|
|
@ -26,6 +26,7 @@ type Failure struct {
|
|||
Issue string `gorm:"column:issue" json:"issue"`
|
||||
Method string `gorm:"column:method" json:"method,omitempty"`
|
||||
MethodId int64 `gorm:"column:method_id" json:"method_id,omitempty"`
|
||||
ErrorCode int `gorm:"column:error_code" json:"error_code"`
|
||||
Service int64 `gorm:"index;column:service" json:"-"`
|
||||
Checkin int64 `gorm:"index;column:checkin" json:"-"`
|
||||
PingTime float64 `gorm:"column:ping_time" json:"ping"`
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.80.39
|
||||
0.80.40
|
||||
|
|
Loading…
Reference in New Issue