mirror of https://github.com/statping/statping
Merge pull request #668 from statping/metrics-update
prometheus metric updatespull/679/head v0.90.53
commit
7432d9cf00
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
})
|
})
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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"},
|
||||||
)
|
)
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.90.52
|
0.90.53
|
||||||
|
|
Loading…
Reference in New Issue