1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

feat: add database size metric

This commit is contained in:
Ferdinand Mütsch
2022-03-18 18:20:13 +01:00
parent 91b4cb2c13
commit e4814431e0
4 changed files with 82 additions and 20 deletions

View File

@ -58,6 +58,7 @@ var (
summaryRepository repositories.ISummaryRepository summaryRepository repositories.ISummaryRepository
keyValueRepository repositories.IKeyValueRepository keyValueRepository repositories.IKeyValueRepository
diagnosticsRepository repositories.IDiagnosticsRepository diagnosticsRepository repositories.IDiagnosticsRepository
metricsRepository *repositories.MetricsRepository
) )
var ( var (
@ -149,6 +150,7 @@ func main() {
summaryRepository = repositories.NewSummaryRepository(db) summaryRepository = repositories.NewSummaryRepository(db)
keyValueRepository = repositories.NewKeyValueRepository(db) keyValueRepository = repositories.NewKeyValueRepository(db)
diagnosticsRepository = repositories.NewDiagnosticsRepository(db) diagnosticsRepository = repositories.NewDiagnosticsRepository(db)
metricsRepository = repositories.NewMetricsRepository(db)
// Services // Services
mailService = mail.NewMailService() mailService = mail.NewMailService()
@ -178,7 +180,7 @@ func main() {
healthApiHandler := api.NewHealthApiHandler(db) healthApiHandler := api.NewHealthApiHandler(db)
heartbeatApiHandler := api.NewHeartbeatApiHandler(userService, heartbeatService, languageMappingService) heartbeatApiHandler := api.NewHeartbeatApiHandler(userService, heartbeatService, languageMappingService)
summaryApiHandler := api.NewSummaryApiHandler(userService, summaryService) summaryApiHandler := api.NewSummaryApiHandler(userService, summaryService)
metricsHandler := api.NewMetricsHandler(userService, summaryService, heartbeatService, keyValueService) metricsHandler := api.NewMetricsHandler(userService, summaryService, heartbeatService, keyValueService, metricsRepository)
diagnosticsHandler := api.NewDiagnosticsApiHandler(userService, diagnosticsService) diagnosticsHandler := api.NewDiagnosticsApiHandler(userService, diagnosticsService)
avatarHandler := api.NewAvatarHandler() avatarHandler := api.NewAvatarHandler()

View File

@ -4,7 +4,7 @@ import "fmt"
type CounterMetric struct { type CounterMetric struct {
Name string Name string
Value int Value int64
Desc string Desc string
Labels Labels Labels Labels
} }

43
repositories/metrics.go Normal file
View File

@ -0,0 +1,43 @@
package repositories
import (
"github.com/muety/wakapi/config"
"gorm.io/gorm"
)
type MetricsRepository struct {
config *config.Config
db *gorm.DB
}
const sizeTplMysql = `
SELECT SUM(data_length + index_length)
FROM information_schema.tables
WHERE table_schema = ?
GROUP BY table_schema`
const sizeTplPostgres = `SELECT pg_database_size('%s');`
const sizeTplSqlite = `
SELECT page_count * page_size as size
FROM pragma_page_count(), pragma_page_size();`
func NewMetricsRepository(db *gorm.DB) *MetricsRepository {
return &MetricsRepository{config: config.Get(), db: db}
}
func (srv *MetricsRepository) GetDatabaseSize() (size int64, err error) {
cfg := srv.config.Db
query := srv.db.Raw("SELECT 0")
if cfg.IsMySQL() {
query = srv.db.Raw(sizeTplMysql, cfg.Name)
} else if cfg.IsPostgres() {
query = srv.db.Raw(sizeTplPostgres, cfg.Name)
} else if cfg.IsSQLite() {
query = srv.db.Raw(sizeTplSqlite)
}
err = query.Scan(&size).Error
return size, err
}

View File

@ -9,6 +9,7 @@ import (
"github.com/muety/wakapi/models" "github.com/muety/wakapi/models"
v1 "github.com/muety/wakapi/models/compat/wakatime/v1" v1 "github.com/muety/wakapi/models/compat/wakatime/v1"
mm "github.com/muety/wakapi/models/metrics" mm "github.com/muety/wakapi/models/metrics"
"github.com/muety/wakapi/repositories"
"github.com/muety/wakapi/services" "github.com/muety/wakapi/services"
"github.com/muety/wakapi/utils" "github.com/muety/wakapi/utils"
"net/http" "net/http"
@ -39,6 +40,7 @@ const (
DescMemAllocTotal = "Total number of bytes allocated for heap" DescMemAllocTotal = "Total number of bytes allocated for heap"
DescMemSysTotal = "Total number of bytes obtained from the OS" DescMemSysTotal = "Total number of bytes obtained from the OS"
DescGoroutines = "Total number of running goroutines" DescGoroutines = "Total number of running goroutines"
DescDatabaseSize = "Total database size in bytes"
) )
type MetricsHandler struct { type MetricsHandler struct {
@ -47,14 +49,16 @@ type MetricsHandler struct {
summarySrvc services.ISummaryService summarySrvc services.ISummaryService
heartbeatSrvc services.IHeartbeatService heartbeatSrvc services.IHeartbeatService
keyValueSrvc services.IKeyValueService keyValueSrvc services.IKeyValueService
metricsRepo *repositories.MetricsRepository
} }
func NewMetricsHandler(userService services.IUserService, summaryService services.ISummaryService, heartbeatService services.IHeartbeatService, keyValueService services.IKeyValueService) *MetricsHandler { func NewMetricsHandler(userService services.IUserService, summaryService services.ISummaryService, heartbeatService services.IHeartbeatService, keyValueService services.IKeyValueService, metricsRepo *repositories.MetricsRepository) *MetricsHandler {
return &MetricsHandler{ return &MetricsHandler{
userSrvc: userService, userSrvc: userService,
summarySrvc: summaryService, summarySrvc: summaryService,
heartbeatSrvc: heartbeatService, heartbeatSrvc: heartbeatService,
keyValueSrvc: keyValueService, keyValueSrvc: keyValueService,
metricsRepo: metricsRepo,
config: conf.Get(), config: conf.Get(),
} }
} }
@ -141,21 +145,21 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_cumulative_seconds_total", Name: MetricsPrefix + "_cumulative_seconds_total",
Desc: DescAllTime, Desc: DescAllTime,
Value: int(v1.NewAllTimeFrom(summaryAllTime).Data.TotalSeconds), Value: int64(v1.NewAllTimeFrom(summaryAllTime).Data.TotalSeconds),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_seconds_total", Name: MetricsPrefix + "_seconds_total",
Desc: DescTotal, Desc: DescTotal,
Value: int(summaryToday.TotalTime().Seconds()), Value: int64(summaryToday.TotalTime().Seconds()),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_heartbeats_total", Name: MetricsPrefix + "_heartbeats_total",
Desc: DescHeartbeats, Desc: DescHeartbeats,
Value: int(heartbeatCount), Value: int64(heartbeatCount),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
@ -163,7 +167,7 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_project_seconds_total", Name: MetricsPrefix + "_project_seconds_total",
Desc: DescProjects, Desc: DescProjects,
Value: int(summaryToday.TotalTimeByKey(models.SummaryProject, p.Key).Seconds()), Value: int64(summaryToday.TotalTimeByKey(models.SummaryProject, p.Key).Seconds()),
Labels: []mm.Label{{Key: "name", Value: p.Key}}, Labels: []mm.Label{{Key: "name", Value: p.Key}},
}) })
} }
@ -172,7 +176,7 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_language_seconds_total", Name: MetricsPrefix + "_language_seconds_total",
Desc: DescLanguages, Desc: DescLanguages,
Value: int(summaryToday.TotalTimeByKey(models.SummaryLanguage, l.Key).Seconds()), Value: int64(summaryToday.TotalTimeByKey(models.SummaryLanguage, l.Key).Seconds()),
Labels: []mm.Label{{Key: "name", Value: l.Key}}, Labels: []mm.Label{{Key: "name", Value: l.Key}},
}) })
} }
@ -181,7 +185,7 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_editor_seconds_total", Name: MetricsPrefix + "_editor_seconds_total",
Desc: DescEditors, Desc: DescEditors,
Value: int(summaryToday.TotalTimeByKey(models.SummaryEditor, e.Key).Seconds()), Value: int64(summaryToday.TotalTimeByKey(models.SummaryEditor, e.Key).Seconds()),
Labels: []mm.Label{{Key: "name", Value: e.Key}}, Labels: []mm.Label{{Key: "name", Value: e.Key}},
}) })
} }
@ -190,7 +194,7 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_operating_system_seconds_total", Name: MetricsPrefix + "_operating_system_seconds_total",
Desc: DescOperatingSystems, Desc: DescOperatingSystems,
Value: int(summaryToday.TotalTimeByKey(models.SummaryOS, o.Key).Seconds()), Value: int64(summaryToday.TotalTimeByKey(models.SummaryOS, o.Key).Seconds()),
Labels: []mm.Label{{Key: "name", Value: o.Key}}, Labels: []mm.Label{{Key: "name", Value: o.Key}},
}) })
} }
@ -199,7 +203,7 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_machine_seconds_total", Name: MetricsPrefix + "_machine_seconds_total",
Desc: DescMachines, Desc: DescMachines,
Value: int(summaryToday.TotalTimeByKey(models.SummaryMachine, m.Key).Seconds()), Value: int64(summaryToday.TotalTimeByKey(models.SummaryMachine, m.Key).Seconds()),
Labels: []mm.Label{{Key: "name", Value: m.Key}}, Labels: []mm.Label{{Key: "name", Value: m.Key}},
}) })
} }
@ -208,7 +212,7 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_label_seconds_total", Name: MetricsPrefix + "_label_seconds_total",
Desc: DescLabels, Desc: DescLabels,
Value: int(summaryToday.TotalTimeByKey(models.SummaryLabel, m.Key).Seconds()), Value: int64(summaryToday.TotalTimeByKey(models.SummaryLabel, m.Key).Seconds()),
Labels: []mm.Label{{Key: "name", Value: m.Key}}, Labels: []mm.Label{{Key: "name", Value: m.Key}},
}) })
} }
@ -220,21 +224,34 @@ func (h *MetricsHandler) getUserMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_goroutines_total", Name: MetricsPrefix + "_goroutines_total",
Desc: DescGoroutines, Desc: DescGoroutines,
Value: runtime.NumGoroutine(), Value: int64(runtime.NumGoroutine()),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_mem_alloc_total", Name: MetricsPrefix + "_mem_alloc_total",
Desc: DescMemAllocTotal, Desc: DescMemAllocTotal,
Value: int(memStats.Alloc), Value: int64(memStats.Alloc),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_mem_sys_total", Name: MetricsPrefix + "_mem_sys_total",
Desc: DescMemSysTotal, Desc: DescMemSysTotal,
Value: int(memStats.Sys), Value: int64(memStats.Sys),
Labels: []mm.Label{},
})
// Database metrics
dbSize, err := h.metricsRepo.GetDatabaseSize()
if err != nil {
logbuch.Warn("failed to get database size (%v)", err)
}
metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_db_total_bytes",
Desc: DescDatabaseSize,
Value: dbSize,
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
@ -267,28 +284,28 @@ func (h *MetricsHandler) getAdminMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_admin_seconds_total", Name: MetricsPrefix + "_admin_seconds_total",
Desc: DescAdminTotalTime, Desc: DescAdminTotalTime,
Value: totalSeconds, Value: int64(totalSeconds),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_admin_heartbeats_total", Name: MetricsPrefix + "_admin_heartbeats_total",
Desc: DescAdminTotalHeartbeats, Desc: DescAdminTotalHeartbeats,
Value: int(totalHeartbeats), Value: totalHeartbeats,
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_admin_users_total", Name: MetricsPrefix + "_admin_users_total",
Desc: DescAdminTotalUsers, Desc: DescAdminTotalUsers,
Value: int(totalUsers), Value: totalUsers,
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_admin_users_active_total", Name: MetricsPrefix + "_admin_users_active_total",
Desc: DescAdminActiveUsers, Desc: DescAdminActiveUsers,
Value: len(activeUsers), Value: int64(len(activeUsers)),
Labels: []mm.Label{}, Labels: []mm.Label{},
}) })
@ -304,7 +321,7 @@ func (h *MetricsHandler) getAdminMetrics(user *models.User) (*mm.Metrics, error)
metrics = append(metrics, &mm.CounterMetric{ metrics = append(metrics, &mm.CounterMetric{
Name: MetricsPrefix + "_admin_user_heartbeats_total", Name: MetricsPrefix + "_admin_user_heartbeats_total",
Desc: DescAdminUserHeartbeats, Desc: DescAdminUserHeartbeats,
Value: int(uc.Count), Value: uc.Count,
Labels: []mm.Label{{Key: "user", Value: uc.User}}, Labels: []mm.Label{{Key: "user", Value: uc.User}},
}) })
} }