Merge pull request #668 from statping/metrics-update

prometheus metric updates
pull/679/head v0.90.53
Hunter Long 2020-06-17 00:18:14 -07:00 committed by GitHub
commit 7432d9cf00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 284 additions and 43 deletions

View File

@ -1,3 +1,8 @@
# 0.90.53 (06-16-2020)
- Modified most of the key's for prometheus metrics
- Added Database Stats in prometheus metrics
- Added object query counts in prometheus metrics
# 0.90.52 (06-15-2020) # 0.90.52 (06-15-2020)
- Fixed NOT NULL sql field - Fixed NOT NULL sql field

View File

@ -9,6 +9,7 @@ import (
"github.com/statping/statping/source" "github.com/statping/statping/source"
"github.com/statping/statping/types/configs" "github.com/statping/statping/types/configs"
"github.com/statping/statping/types/core" "github.com/statping/statping/types/core"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/types/services" "github.com/statping/statping/types/services"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
"os" "os"
@ -174,6 +175,8 @@ func InitApp() error {
if _, err := core.Select(); err != nil { if _, err := core.Select(); err != nil {
return err return err
} }
// init prometheus metrics
metrics.InitMetrics()
// select all services in database and store services in a mapping of Service pointers // select all services in database and store services in a mapping of Service pointers
if _, err := services.SelectAllServices(true); err != nil { if _, err := services.SelectAllServices(true); err != nil {
return err return err

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
"strings" "strings"
"time" "time"
@ -119,6 +120,17 @@ func (it *Db) ChunkSize() int {
} }
} }
func Routine() {
for {
if database.DB() == nil {
time.Sleep(5 * time.Second)
continue
}
metrics.CollectDatabase(database.DB().Stats())
time.Sleep(5 * time.Second)
}
}
func (it *Db) GormDB() *gorm.DB { func (it *Db) GormDB() *gorm.DB {
return it.Database return it.Database
} }
@ -184,6 +196,7 @@ func Openw(dialect string, args ...interface{}) (db Database, err error) {
return nil, err return nil, err
} }
database = Wrap(gormdb) database = Wrap(gormdb)
go Routine()
return database, err return database, err
} }

View File

@ -248,9 +248,9 @@ func TestMainApiRoutes(t *testing.T) {
ExpectedContains: []string{ ExpectedContains: []string{
`go_goroutines`, `go_goroutines`,
`go_memstats_alloc_bytes`, `go_memstats_alloc_bytes`,
`http_duration_seconds_count`, `process_cpu_seconds_total`,
`http_response_bytes_count`, `promhttp_metric_handler_requests_total`,
`service_success`, `go_threads`,
}, },
}, },
} }

View File

@ -7,9 +7,9 @@ import (
"fmt" "fmt"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/statping/statping/types/core" "github.com/statping/statping/types/core"
"github.com/statping/statping/types/errors" "github.com/statping/statping/types/errors"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
"io" "io"
"net/http" "net/http"
@ -19,12 +19,8 @@ import (
) )
var ( var (
authUser string authUser string
authPass string authPass string
httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "http_duration_seconds",
Help: "Duration of HTTP requests.",
}, []string{"path"})
) )
// Gzip Compression // Gzip Compression
@ -178,7 +174,7 @@ func prometheusMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
route := mux.CurrentRoute(r) route := mux.CurrentRoute(r)
path, _ := route.GetPathTemplate() path, _ := route.GetPathTemplate()
timer := prometheus.NewTimer(httpDuration.WithLabelValues(path)) timer := prometheus.NewTimer(metrics.Timer(path))
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
timer.ObserveDuration() timer.ObserveDuration()
}) })

View File

@ -26,7 +26,7 @@ type scope struct {
scope string scope string
} }
// MarshalJSON for Scopr // TODO: make a better way to parse
func (s scope) MarshalJSON() ([]byte, error) { func (s scope) MarshalJSON() ([]byte, error) {
svc := reflect.ValueOf(s.data) svc := reflect.ValueOf(s.data)
if svc.Kind() == reflect.Slice { if svc.Kind() == reflect.Slice {
@ -40,6 +40,7 @@ func (s scope) MarshalJSON() ([]byte, error) {
return json.Marshal(SafeJson(svc, s.scope)) return json.Marshal(SafeJson(svc, s.scope))
} }
// TODO: make a better way to parse
func SafeJson(val reflect.Value, scope string) map[string]interface{} { func SafeJson(val reflect.Value, scope string) map[string]interface{} {
thisData := make(map[string]interface{}) thisData := make(map[string]interface{})
if val.Kind() == reflect.Interface && !val.IsNil() { if val.Kind() == reflect.Interface && !val.IsNil() {
@ -89,6 +90,7 @@ func SafeJson(val reflect.Value, scope string) map[string]interface{} {
return thisData return thisData
} }
// TODO: make a better way to parse
func forTag(tags []string, scope string) bool { func forTag(tags []string, scope string) bool {
for _, v := range tags { for _, v := range tags {
if v == scope { if v == scope {

View File

@ -2,6 +2,7 @@ package checkins
import ( import (
"github.com/statping/statping/database" "github.com/statping/statping/database"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
) )
@ -13,6 +14,10 @@ func SetDB(database database.Database) {
dbHits = database.Model(&CheckinHit{}) dbHits = database.Model(&CheckinHit{})
} }
func (c *Checkin) AfterFind() {
metrics.Query("checkin", "find")
}
func Find(id int64) (*Checkin, error) { func Find(id int64) (*Checkin, error) {
var checkin Checkin var checkin Checkin
q := db.Where("id = ?", id).Find(&checkin) q := db.Where("id = ?", id).Find(&checkin)

View File

@ -3,6 +3,7 @@ package core
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/statping/statping/database" "github.com/statping/statping/database"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/types/null" "github.com/statping/statping/types/null"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
) )
@ -13,6 +14,10 @@ func SetDB(database database.Database) {
db = database.Model(&Core{}) db = database.Model(&Core{})
} }
func (c *Core) AfterFind() {
metrics.Query("core", "find")
}
func Select() (*Core, error) { func Select() (*Core, error) {
var c Core var c Core
// SelectCore will return the CoreApp global variable and the settings/configs for Statping // SelectCore will return the CoreApp global variable and the settings/configs for Statping

View File

@ -15,14 +15,27 @@ func DB() database.Database {
return db return db
} }
func All() []*Failure { func (f *Failure) AfterFind() {
var failures []*Failure metrics.Query("failure", "find")
db.Find(&failures) }
return failures
func (f *Failure) AfterUpdate() {
metrics.Query("failure", "update")
}
func (f *Failure) AfterDelete() {
metrics.Query("failure", "delete")
} }
func (f *Failure) AfterCreate() { func (f *Failure) AfterCreate() {
metrics.Inc("failure", f.Service) metrics.Inc("failure", f.Service)
metrics.Query("failure", "create")
}
func All() []*Failure {
var failures []*Failure
db.Find(&failures)
return failures
} }
func (f *Failure) Create() error { func (f *Failure) Create() error {

View File

@ -3,6 +3,7 @@ package groups
import ( import (
"github.com/statping/statping/database" "github.com/statping/statping/database"
"github.com/statping/statping/types/errors" "github.com/statping/statping/types/errors"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
"sort" "sort"
) )
@ -16,6 +17,22 @@ func SetDB(database database.Database) {
db = database.Model(&Group{}) db = database.Model(&Group{})
} }
func (g *Group) AfterFind() {
metrics.Query("group", "find")
}
func (g *Group) AfterUpdate() {
metrics.Query("group", "update")
}
func (g *Group) AfterDelete() {
metrics.Query("group", "delete")
}
func (g *Group) AfterCreate() {
metrics.Query("group", "create")
}
func Find(id int64) (*Group, error) { func Find(id int64) (*Group, error) {
var group Group var group Group
q := db.Where("id = ?", id).Find(&group) q := db.Where("id = ?", id).Find(&group)

View File

@ -14,8 +14,21 @@ func SetDB(database database.Database) {
db = database.Model(&Hit{}) db = database.Model(&Hit{})
} }
func (h *Hit) AfterFind() {
metrics.Query("hit", "find")
}
func (h *Hit) AfterUpdate() {
metrics.Query("hit", "update")
}
func (h *Hit) AfterDelete() {
metrics.Query("hit", "delete")
}
func (h *Hit) AfterCreate() { func (h *Hit) AfterCreate() {
metrics.Inc("success", h.Service) metrics.Inc("success", h.Service)
metrics.Query("hit", "create")
} }
func (h *Hit) Create() error { func (h *Hit) Create() error {

View File

@ -2,6 +2,7 @@ package incidents
import ( import (
"github.com/statping/statping/database" "github.com/statping/statping/database"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
) )
@ -16,6 +17,38 @@ func SetDB(database database.Database) {
dbUpdate = database.Model(&IncidentUpdate{}) dbUpdate = database.Model(&IncidentUpdate{})
} }
func (i *Incident) AfterFind() {
metrics.Query("incident", "find")
}
func (i *Incident) AfterCreate() {
metrics.Query("incident", "create")
}
func (i *Incident) AfterUpdate() {
metrics.Query("incident", "update")
}
func (i *Incident) AfterDelete() {
metrics.Query("incident", "delete")
}
func (i *IncidentUpdate) AfterFind() {
metrics.Query("incident_update", "find")
}
func (i *IncidentUpdate) AfterCreate() {
metrics.Query("incident_update", "create")
}
func (i *IncidentUpdate) AfterUpdate() {
metrics.Query("incident_update", "update")
}
func (i *IncidentUpdate) AfterDelete() {
metrics.Query("incident_update", "delete")
}
func FindUpdate(uid int64) (*IncidentUpdate, error) { func FindUpdate(uid int64) (*IncidentUpdate, error) {
var update IncidentUpdate var update IncidentUpdate
q := dbUpdate.Where("id = ?", uid).Find(&update) q := dbUpdate.Where("id = ?", uid).Find(&update)

View File

@ -1,6 +1,7 @@
package messages package messages
import ( import (
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
) )
@ -12,3 +13,19 @@ func (m *Message) BeforeCreate() (err error) {
} }
return return
} }
func (m *Message) AfterFind() {
metrics.Query("message", "find")
}
func (m *Message) AfterCreate() {
metrics.Query("message", "create")
}
func (m *Message) AfterUpdate() {
metrics.Query("message", "update")
}
func (m *Message) AfterDelete() {
metrics.Query("message", "delete")
}

40
types/metrics/database.go Normal file
View File

@ -0,0 +1,40 @@
package metrics
import (
"database/sql"
"github.com/prometheus/client_golang/prometheus"
)
var (
// service is online if set to 1, offline if 0
databaseStats = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: "statping",
Name: "database",
Help: "If service is online",
}, []string{"metric"},
)
queryStats = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: "statping",
Name: "query",
Help: "If service is online",
}, []string{"type", "method"},
)
)
func Query(objType, method string) {
queryStats.WithLabelValues(objType, method).Inc()
}
func CollectDatabase(stats sql.DBStats) {
databaseStats.WithLabelValues("max_open_connections").Set(float64(stats.MaxOpenConnections))
databaseStats.WithLabelValues("open_connections").Set(float64(stats.OpenConnections))
databaseStats.WithLabelValues("in_use_connections").Set(float64(stats.InUse))
databaseStats.WithLabelValues("idle_connections").Set(float64(stats.Idle))
databaseStats.WithLabelValues("wait_count").Set(float64(stats.WaitCount))
databaseStats.WithLabelValues("wait_duration_seconds").Set(stats.WaitDuration.Seconds())
databaseStats.WithLabelValues("idle_connections_closed").Set(float64(stats.MaxIdleClosed))
databaseStats.WithLabelValues("lifetime_connections_closed").Set(float64(stats.MaxLifetimeClosed))
}

View File

@ -8,37 +8,47 @@ import (
var ( var (
utilsHttpRequestDur = prometheus.NewHistogramVec( utilsHttpRequestDur = prometheus.NewHistogramVec(
prometheus.HistogramOpts{ prometheus.HistogramOpts{
Name: "http_requests_duration", Namespace: "statping",
Help: "How many successful requests for a service", Name: "http_requests_duration",
Help: "Duration for h",
}, },
[]string{"url", "method"}, []string{"url", "method"},
) )
utilsHttpRequestBytes = prometheus.NewHistogramVec( utilsHttpRequestBytes = prometheus.NewHistogramVec(
prometheus.HistogramOpts{ prometheus.HistogramOpts{
Name: "http_response_bytes", Namespace: "statping",
Help: "How many successful requests for a service", Name: "http_response_bytes",
Help: "Response in bytes for a HTTP services",
}, },
[]string{"url", "method"}, []string{"url", "method"},
) )
httpDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: "statping",
Name: "http_duration_seconds",
Help: "Duration of HTTP requests from the utils package",
}, []string{"path"})
) )
func init() { func InitMetrics() {
prometheus.MustRegister( prometheus.MustRegister(
serviceOnline, serviceOnline,
serviceFailures, serviceFailures,
serviceSuccess, serviceSuccess,
serviceStatusCode, serviceStatusCode,
serviceLatencyDuration, serviceDuration,
utilsHttpRequestDur, utilsHttpRequestDur,
utilsHttpRequestBytes, utilsHttpRequestBytes,
httpDuration,
databaseStats,
queryStats,
) )
} }
func Histo(method string, value float64, labels ...interface{}) { func Histo(method string, value float64, labels ...interface{}) {
switch method { switch method {
case "latency":
serviceLatencyDuration.WithLabelValues(convert(labels)...).Observe(value)
case "duration": case "duration":
utilsHttpRequestDur.WithLabelValues(convert(labels)...).Observe(value) utilsHttpRequestDur.WithLabelValues(convert(labels)...).Observe(value)
case "bytes": case "bytes":
@ -46,9 +56,17 @@ func Histo(method string, value float64, labels ...interface{}) {
} }
} }
func Timer(labels ...interface{}) prometheus.Observer {
return httpDuration.WithLabelValues(convert(labels)...)
}
func ServiceTimer(labels ...interface{}) prometheus.Observer {
return serviceDuration.WithLabelValues(convert(labels)...)
}
func Gauge(method string, value float64, labels ...interface{}) { func Gauge(method string, value float64, labels ...interface{}) {
switch method { switch method {
case "service": case "status_code":
serviceStatusCode.WithLabelValues(convert(labels)...).Set(value) serviceStatusCode.WithLabelValues(convert(labels)...).Set(value)
case "online": case "online":
serviceOnline.WithLabelValues(convert(labels)...).Set(value) serviceOnline.WithLabelValues(convert(labels)...).Set(value)

View File

@ -6,17 +6,19 @@ var (
// service is online if set to 1, offline if 0 // service is online if set to 1, offline if 0
serviceOnline = prometheus.NewGaugeVec( serviceOnline = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "service_online", Namespace: "statping",
Help: "If service is online", Name: "service_online",
Help: "If service is online",
}, },
[]string{"service"}, []string{"service", "name", "type"},
) )
// service failures // service failures
serviceFailures = prometheus.NewCounterVec( serviceFailures = prometheus.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "service_failures", Namespace: "statping",
Help: "How many failures occur for a service", Name: "service_failures",
Help: "How many failures occur for a service",
}, },
[]string{"service"}, []string{"service"},
) )
@ -24,17 +26,19 @@ var (
// successful hits for a service // successful hits for a service
serviceSuccess = prometheus.NewCounterVec( serviceSuccess = prometheus.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "service_success", Namespace: "statping",
Help: "How many successful requests for a service", Name: "service_success",
Help: "How many successful requests for a service",
}, },
[]string{"service"}, []string{"service"},
) )
// service check latency // service check latency
serviceLatencyDuration = prometheus.NewHistogramVec( serviceDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{ prometheus.HistogramOpts{
Name: "service_latency", Namespace: "statping",
Help: "How many successful requests for a service", Name: "service_duration",
Help: "Service request duration for a success response",
}, },
[]string{"service"}, []string{"service"},
) )
@ -42,8 +46,9 @@ var (
// http status code for a service // http status code for a service
serviceStatusCode = prometheus.NewGaugeVec( serviceStatusCode = prometheus.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "service_status_code", Namespace: "statping",
Help: "HTTP Status code for a service", Name: "service_status_code",
Help: "HTTP Status code for a service",
}, },
[]string{"service"}, []string{"service"},
) )

View File

@ -1,10 +1,26 @@
package notifications package notifications
import "github.com/statping/statping/utils" import (
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils"
)
// AfterFind for Notification will set the timezone // AfterFind for Notification will set the timezone
func (n *Notification) AfterFind() (err error) { func (n *Notification) AfterFind() (err error) {
n.CreatedAt = utils.Now() n.CreatedAt = utils.Now()
n.UpdatedAt = utils.Now() n.UpdatedAt = utils.Now()
metrics.Query("notifier", "find")
return return
} }
func (n *Notification) AfterCreate() {
metrics.Query("notifier", "create")
}
func (n *Notification) AfterUpdate() {
metrics.Query("notifier", "update")
}
func (n *Notification) AfterDelete() {
metrics.Query("notifier", "delete")
}

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/statping/statping/database" "github.com/statping/statping/database"
"github.com/statping/statping/types/errors" "github.com/statping/statping/types/errors"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
"sort" "sort"
) )
@ -14,6 +15,18 @@ var (
allServices map[int64]*Service allServices map[int64]*Service
) )
func (s *Service) AfterFind() {
metrics.Query("service", "find")
}
func (s *Service) AfterUpdate() {
metrics.Query("service", "update")
}
func (s *Service) AfterDelete() {
metrics.Query("service", "delete")
}
func init() { func init() {
allServices = make(map[int64]*Service) allServices = make(map[int64]*Service)
} }
@ -65,6 +78,7 @@ func (s *Service) Create() error {
func (s *Service) AfterCreate() error { func (s *Service) AfterCreate() error {
allServices[s.Id] = s allServices[s.Id] = s
metrics.Query("service", "create")
return nil return nil
} }

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/statping/statping/types/metrics" "github.com/statping/statping/types/metrics"
"google.golang.org/grpc" "google.golang.org/grpc"
"net" "net"
@ -87,6 +88,8 @@ func isIPv6(address string) bool {
// checkIcmp will send a ICMP ping packet to the service // checkIcmp will send a ICMP ping packet to the service
func CheckIcmp(s *Service, record bool) (*Service, error) { func CheckIcmp(s *Service, record bool) (*Service, error) {
defer s.updateLastCheck() defer s.updateLastCheck()
timer := prometheus.NewTimer(metrics.ServiceTimer(s.Id))
defer timer.ObserveDuration()
if err := utils.Ping(s.Domain, s.Timeout); err != nil { if err := utils.Ping(s.Domain, s.Timeout); err != nil {
if record { if record {
@ -102,6 +105,8 @@ func CheckIcmp(s *Service, record bool) (*Service, error) {
// CheckGrpc will check a gRPC service // CheckGrpc will check a gRPC service
func CheckGrpc(s *Service, record bool) (*Service, error) { func CheckGrpc(s *Service, record bool) (*Service, error) {
defer s.updateLastCheck() defer s.updateLastCheck()
timer := prometheus.NewTimer(metrics.ServiceTimer(s.Id))
defer timer.ObserveDuration()
dnsLookup, err := dnsCheck(s) dnsLookup, err := dnsCheck(s)
if err != nil { if err != nil {
@ -147,6 +152,8 @@ func CheckGrpc(s *Service, record bool) (*Service, error) {
// checkTcp will check a TCP service // checkTcp will check a TCP service
func CheckTcp(s *Service, record bool) (*Service, error) { func CheckTcp(s *Service, record bool) (*Service, error) {
defer s.updateLastCheck() defer s.updateLastCheck()
timer := prometheus.NewTimer(metrics.ServiceTimer(s.Id))
defer timer.ObserveDuration()
dnsLookup, err := dnsCheck(s) dnsLookup, err := dnsCheck(s)
if err != nil { if err != nil {
@ -212,6 +219,8 @@ func (s *Service) updateLastCheck() {
// checkHttp will check a HTTP service // checkHttp will check a HTTP service
func CheckHttp(s *Service, record bool) (*Service, error) { func CheckHttp(s *Service, record bool) (*Service, error) {
defer s.updateLastCheck() defer s.updateLastCheck()
timer := prometheus.NewTimer(metrics.ServiceTimer(s.Id))
defer timer.ObserveDuration()
dnsLookup, err := dnsCheck(s) dnsLookup, err := dnsCheck(s)
if err != nil { if err != nil {
@ -273,10 +282,10 @@ func CheckHttp(s *Service, record bool) (*Service, error) {
return s, err return s, err
} }
s.Latency = utils.Now().Sub(t1).Microseconds() s.Latency = utils.Now().Sub(t1).Microseconds()
metrics.Histo("latency", utils.Now().Sub(t1).Seconds(), s.Id)
s.LastResponse = string(content) s.LastResponse = string(content)
s.LastStatusCode = res.StatusCode s.LastStatusCode = res.StatusCode
metrics.Gauge("service", float64(res.StatusCode), s.Id)
metrics.Gauge("status_code", float64(res.StatusCode), s.Id)
if s.Expected.String != "" { if s.Expected.String != "" {
match, err := regexp.MatchString(s.Expected.String, string(content)) match, err := regexp.MatchString(s.Expected.String, string(content))
@ -320,9 +329,9 @@ func recordSuccess(s *Service) {
fmt.Sprintf("Service #%d '%v' Successful Response: %s | Lookup in: %s | Online: %v | Interval: %d seconds", s.Id, s.Name, humanMicro(hit.Latency), humanMicro(hit.PingTime), s.Online, s.Interval)) fmt.Sprintf("Service #%d '%v' Successful Response: %s | Lookup in: %s | Online: %v | Interval: %d seconds", s.Id, s.Name, humanMicro(hit.Latency), humanMicro(hit.PingTime), s.Online, s.Interval))
s.LastLookupTime = hit.PingTime s.LastLookupTime = hit.PingTime
s.LastLatency = hit.Latency s.LastLatency = hit.Latency
metrics.Gauge("online", 1., s.Id, s.Name, s.Type)
sendSuccess(s) sendSuccess(s)
s.SuccessNotified = true s.SuccessNotified = true
metrics.Gauge("online", 1., s.Id)
} }
func AddNotifier(n ServiceNotifier) { func AddNotifier(n ServiceNotifier) {
@ -374,8 +383,8 @@ func recordFailure(s *Service, issue string) {
s.Online = false s.Online = false
s.SuccessNotified = false s.SuccessNotified = false
s.DownText = s.DowntimeText() s.DownText = s.DowntimeText()
metrics.Gauge("online", 0., s.Id, s.Name, s.Type)
sendFailure(s, fail) sendFailure(s, fail)
metrics.Gauge("online", 0., s.Id)
} }
func sendFailure(s *Service, f *failures.Failure) { func sendFailure(s *Service, f *failures.Failure) {

View File

@ -2,6 +2,7 @@ package users
import ( import (
"github.com/statping/statping/database" "github.com/statping/statping/database"
"github.com/statping/statping/types/metrics"
"github.com/statping/statping/utils" "github.com/statping/statping/utils"
) )
@ -14,6 +15,22 @@ func SetDB(database database.Database) {
db = database.Model(&User{}) db = database.Model(&User{})
} }
func (u *User) AfterFind() {
metrics.Query("user", "find")
}
func (u *User) AfterCreate() {
metrics.Query("user", "create")
}
func (u *User) AfterUpdate() {
metrics.Query("user", "update")
}
func (u *User) AfterDelete() {
metrics.Query("user", "delete")
}
func Find(id int64) (*User, error) { func Find(id int64) (*User, error) {
var user User var user User
q := db.Where("id = ?", id).Find(&user) q := db.Where("id = ?", id).Find(&user)

View File

@ -1 +1 @@
0.90.52 0.90.53