2018-06-30 00:57:05 +00:00
package core
2018-06-10 01:31:13 +00:00
import (
"encoding/json"
"fmt"
2018-06-30 00:57:05 +00:00
"github.com/hunterlong/statup/types"
"github.com/hunterlong/statup/utils"
2018-06-11 00:20:42 +00:00
"strconv"
2018-06-10 01:31:13 +00:00
"time"
2018-06-22 04:02:57 +00:00
"upper.io/db.v3"
2018-06-10 01:31:13 +00:00
)
2018-06-30 00:57:05 +00:00
type Failure types . Failure
2018-06-10 03:44:47 +00:00
2018-06-10 01:31:13 +00:00
type Service struct {
2018-06-18 09:53:18 +00:00
Id int64 ` db:"id,omitempty" json:"id" `
Name string ` db:"name" json:"name" `
Domain string ` db:"domain" json:"domain" `
Expected string ` db:"expected" json:"expected" `
ExpectedStatus int ` db:"expected_status" json:"expected_status" `
Interval int ` db:"check_interval" json:"check_interval" `
Type string ` db:"check_type" json:"type" `
Method string ` db:"method" json:"method" `
2018-06-23 00:10:37 +00:00
PostData string ` db:"post_data" json:"post_data" `
2018-06-18 09:53:18 +00:00
Port int ` db:"port" json:"port" `
CreatedAt time . Time ` db:"created_at" json:"created_at" `
2018-06-15 04:30:10 +00:00
Online bool ` json:"online" `
Latency float64 ` json:"latency" `
Online24Hours float32 ` json:"24_hours_online" `
AvgResponse string ` json:"avg_response" `
TotalUptime string ` json:"uptime" `
2018-06-23 00:10:37 +00:00
OrderId int64 ` json:"order_id" `
2018-06-15 04:30:10 +00:00
Failures [ ] * Failure ` json:"failures" `
2018-06-22 06:56:44 +00:00
Checkins [ ] * Checkin ` json:"checkins" `
2018-06-23 00:10:37 +00:00
runRoutine bool
2018-06-23 08:42:50 +00:00
LastResponse string
LastStatusCode int
LastOnline time . Time
2018-06-10 01:31:13 +00:00
}
2018-06-22 04:02:57 +00:00
func serviceCol ( ) db . Collection {
2018-06-30 00:57:05 +00:00
return DbSession . Collection ( "services" )
2018-06-22 04:02:57 +00:00
}
2018-06-23 00:10:37 +00:00
func SelectService ( id int64 ) * Service {
2018-06-30 00:57:05 +00:00
for _ , s := range CoreApp . Services {
2018-06-23 00:10:37 +00:00
if s . Id == id {
return s
}
}
return nil
2018-06-10 01:31:13 +00:00
}
2018-06-15 04:30:10 +00:00
func SelectAllServices ( ) ( [ ] * Service , error ) {
2018-06-23 00:10:37 +00:00
var srvcs [ ] * Service
2018-06-22 04:02:57 +00:00
col := serviceCol ( ) . Find ( )
2018-06-23 00:10:37 +00:00
err := col . All ( & srvcs )
2018-06-30 00:57:05 +00:00
if err != nil {
utils . Log ( 3 , err )
}
2018-06-23 00:10:37 +00:00
for _ , s := range srvcs {
2018-06-22 06:56:44 +00:00
s . Checkins = s . SelectAllCheckins ( )
2018-06-23 00:10:37 +00:00
s . Failures = s . SelectAllFailures ( )
2018-06-22 06:56:44 +00:00
}
2018-06-30 00:57:05 +00:00
CoreApp . Services = srvcs
2018-06-23 00:10:37 +00:00
return srvcs , err
2018-06-10 01:31:13 +00:00
}
func ( s * Service ) AvgTime ( ) float64 {
2018-06-15 04:30:10 +00:00
total , _ := s . TotalHits ( )
if total == 0 {
return float64 ( 0 )
}
sum , _ := s . Sum ( )
2018-06-10 01:31:13 +00:00
avg := sum / float64 ( total ) * 100
2018-06-15 04:30:10 +00:00
amount := fmt . Sprintf ( "%0.0f" , avg * 10 )
val , _ := strconv . ParseFloat ( amount , 10 )
return val
2018-06-10 01:31:13 +00:00
}
2018-06-11 00:20:42 +00:00
func ( s * Service ) Online24 ( ) float32 {
2018-06-15 04:30:10 +00:00
total , _ := s . TotalHits ( )
failed , _ := s . TotalFailures24Hours ( )
2018-06-10 03:44:47 +00:00
if failed == 0 {
s . Online24Hours = 100.00
return s . Online24Hours
}
2018-06-10 04:21:12 +00:00
if total == 0 {
s . Online24Hours = 0
return s . Online24Hours
}
2018-06-10 03:44:47 +00:00
avg := float64 ( failed ) / float64 ( total ) * 100
2018-06-11 00:20:42 +00:00
avg = 100 - avg
if avg < 0 {
avg = 0
}
amount , _ := strconv . ParseFloat ( fmt . Sprintf ( "%0.2f" , avg ) , 10 )
s . Online24Hours = float32 ( amount )
return s . Online24Hours
2018-06-10 03:44:47 +00:00
}
2018-06-24 11:51:07 +00:00
type DateScan struct {
CreatedAt time . Time ` json:"x" `
2018-06-24 20:56:58 +00:00
Value int64 ` json:"y" `
2018-06-24 11:51:07 +00:00
}
2018-06-30 03:40:00 +00:00
func ( s * Service ) SmallText ( ) string {
last := s . LimitedFailures ( )
hits , _ := s . LimitedHits ( )
if ! s . Online {
2018-06-30 03:48:55 +00:00
if len ( last ) > 0 {
return fmt . Sprintf ( "%v at %v" , last [ 0 ] . ParseError ( ) , last [ 0 ] . CreatedAt . Format ( "Monday 3:04PM, Jan _2 2006" ) )
} else {
return fmt . Sprintf ( "%v is currently offline" , s . Name )
}
2018-06-30 03:40:00 +00:00
} else {
if len ( last ) == 0 {
return fmt . Sprintf ( "Online since %v" , s . CreatedAt . Format ( "Monday 3:04PM, Jan _2 2006" ) )
} else {
return fmt . Sprintf ( "Online, last failure was %v" , hits [ 0 ] . CreatedAt . Format ( "Monday 3:04PM, Jan _2 2006" ) )
}
}
return fmt . Sprintf ( "No Failures in the last 24 hours! %v" , hits [ 0 ] )
}
2018-06-10 01:31:13 +00:00
func ( s * Service ) GraphData ( ) string {
2018-06-24 11:51:07 +00:00
var d [ ] DateScan
2018-06-27 06:45:00 +00:00
increment := "minute"
since := time . Now ( ) . Add ( time . Hour * - 12 + time . Minute * 0 + time . Second * 0 )
sql := fmt . Sprintf ( "SELECT date_trunc('%v', created_at), AVG(latency)*1000 AS value FROM hits WHERE service=%v AND created_at > '%v' GROUP BY 1 ORDER BY date_trunc ASC;" , increment , s . Id , since . Format ( time . RFC3339 ) )
2018-06-30 00:57:05 +00:00
dated , err := DbSession . Query ( db . Raw ( sql ) )
2018-06-24 11:51:07 +00:00
if err != nil {
2018-06-30 00:57:05 +00:00
utils . Log ( 2 , err )
2018-06-25 06:21:18 +00:00
return ""
2018-06-10 01:31:13 +00:00
}
2018-06-24 11:51:07 +00:00
for dated . Next ( ) {
var gd DateScan
var ff float64
dated . Scan ( & gd . CreatedAt , & ff )
gd . Value = int64 ( ff )
d = append ( d , gd )
}
2018-06-25 06:21:18 +00:00
data , err := json . Marshal ( d )
2018-06-24 11:51:07 +00:00
if err != nil {
2018-06-30 00:57:05 +00:00
utils . Log ( 2 , err )
2018-06-25 06:21:18 +00:00
return ""
2018-06-24 11:51:07 +00:00
}
2018-06-19 04:48:25 +00:00
return string ( data )
2018-06-10 01:31:13 +00:00
}
2018-06-11 00:20:42 +00:00
func ( s * Service ) AvgUptime ( ) string {
2018-06-15 04:30:10 +00:00
failed , _ := s . TotalFailures ( )
total , _ := s . TotalHits ( )
2018-06-10 01:31:13 +00:00
if failed == 0 {
2018-06-22 04:02:57 +00:00
s . TotalUptime = "100"
2018-06-10 01:31:13 +00:00
return s . TotalUptime
}
2018-06-10 04:21:12 +00:00
if total == 0 {
2018-06-11 00:20:42 +00:00
s . TotalUptime = "0"
2018-06-10 04:21:12 +00:00
return s . TotalUptime
}
2018-06-10 01:31:13 +00:00
percent := float64 ( failed ) / float64 ( total ) * 100
2018-06-11 00:20:42 +00:00
percent = 100 - percent
if percent < 0 {
percent = 0
}
s . TotalUptime = fmt . Sprintf ( "%0.2f" , percent )
2018-06-22 04:02:57 +00:00
if s . TotalUptime == "100.00" {
s . TotalUptime = "100"
}
2018-06-11 00:20:42 +00:00
return s . TotalUptime
2018-06-10 01:31:13 +00:00
}
2018-06-23 00:10:37 +00:00
func ( u * Service ) RemoveArray ( ) [ ] * Service {
var srvcs [ ] * Service
2018-06-30 00:57:05 +00:00
for _ , s := range CoreApp . Services {
2018-06-23 00:10:37 +00:00
if s . Id != u . Id {
srvcs = append ( srvcs , s )
}
}
2018-06-30 00:57:05 +00:00
CoreApp . Services = srvcs
2018-06-23 00:10:37 +00:00
return srvcs
}
2018-06-15 04:30:10 +00:00
func ( u * Service ) Delete ( ) error {
2018-06-22 04:02:57 +00:00
res := serviceCol ( ) . Find ( "id" , u . Id )
2018-06-15 04:30:10 +00:00
err := res . Delete ( )
2018-06-30 00:57:05 +00:00
if err != nil {
utils . Log ( 3 , fmt . Sprintf ( "Failed to delete service %v. %v" , u . Name , err ) )
return err
}
2018-06-23 00:10:37 +00:00
u . RemoveArray ( )
2018-06-19 04:48:25 +00:00
OnDeletedService ( u )
2018-06-15 04:30:10 +00:00
return err
2018-06-11 03:41:02 +00:00
}
func ( u * Service ) Update ( ) {
2018-06-19 04:48:25 +00:00
OnUpdateService ( u )
2018-06-11 03:41:02 +00:00
}
2018-06-15 04:30:10 +00:00
func ( u * Service ) Create ( ) ( int64 , error ) {
u . CreatedAt = time . Now ( )
2018-06-22 04:02:57 +00:00
uuid , err := serviceCol ( ) . Insert ( u )
2018-06-15 04:30:10 +00:00
if uuid == nil {
2018-06-30 00:57:05 +00:00
utils . Log ( 3 , fmt . Sprintf ( "Failed to create service %v. %v" , u . Name , err ) )
2018-06-15 04:30:10 +00:00
return 0 , err
2018-06-10 03:44:47 +00:00
}
2018-06-22 08:48:47 +00:00
u . Id = uuid . ( int64 )
2018-06-30 00:57:05 +00:00
CoreApp . Services = append ( CoreApp . Services , u )
2018-06-23 00:10:37 +00:00
go u . CheckQueue ( )
2018-06-19 04:48:25 +00:00
OnNewService ( u )
2018-06-15 04:30:10 +00:00
return uuid . ( int64 ) , err
2018-06-10 01:31:13 +00:00
}
2018-06-11 00:20:42 +00:00
func CountOnline ( ) int {
amount := 0
2018-06-30 00:57:05 +00:00
for _ , v := range CoreApp . Services {
2018-06-11 00:20:42 +00:00
if v . Online {
amount ++
}
}
return amount
2018-06-25 07:09:31 +00:00
}