package services import ( "os" "time" "lokistack/pkg/metrics" "lokistack/repository" ) // InitMetrics 注册指标并启动业务/存储指标的周期刷新。 // // HTTP 层与 DB 落盘由 middleware / repository 直接埋点; // 这里只负责需要"扫 DB 算出来"的指标(记录数、部署/采集器状态分布、DB 大小)。 func InitMetrics(version string) { metrics.Register(version) go func() { ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() refreshGauges() for range ticker.C { refreshGauges() } }() } // refreshGauges 刷新需要遍历 DB 才能得出的指标。 func refreshGauges() { db := repository.GetDB() if db == nil { return } if path := databasePath(); path != "" { if fi, err := os.Stat(path); err == nil { metrics.DBSizeBytes.Set(float64(fi.Size())) } } db.RLock() users := len(db.Users) clusters := len(db.Clusters) hosts := len(db.Hosts) storages := len(db.Storages) deployList := db.Deployments collectorList := db.Collectors alertRules := len(db.AlertRules) auditCount := len(db.AuditLogs) db.RUnlock() metrics.DBRecordsTotal.WithLabelValues("users").Set(float64(users)) metrics.DBRecordsTotal.WithLabelValues("clusters").Set(float64(clusters)) metrics.DBRecordsTotal.WithLabelValues("hosts").Set(float64(hosts)) metrics.DBRecordsTotal.WithLabelValues("storages").Set(float64(storages)) metrics.DBRecordsTotal.WithLabelValues("deployments").Set(float64(len(deployList))) metrics.DBRecordsTotal.WithLabelValues("collectors").Set(float64(len(collectorList))) metrics.DBRecordsTotal.WithLabelValues("alertRules").Set(float64(alertRules)) metrics.DBRecordsTotal.WithLabelValues("auditLogs").Set(float64(auditCount)) // 状态分布:先 Reset 再重算,避免已删除对象留下僵尸时间序列 metrics.DeploymentsTotal.Reset() for _, d := range deployList { status := d.Status if status == "" { status = "unknown" } mode := d.Mode if mode == "" { mode = "unknown" } metrics.DeploymentsTotal.WithLabelValues(status, mode).Inc() } metrics.CollectorsTotal.Reset() for _, c := range collectorList { status := c.Status if status == "" { status = "unknown" } runMode := c.RunMode if runMode == "" { runMode = "unknown" } metrics.CollectorsTotal.WithLabelValues(status, c.Type, runMode).Inc() } } func databasePath() string { if p := os.Getenv("DATABASE_PATH"); p != "" { return p } if p := os.Getenv("DATA_DIR"); p != "" { return p + "/opsxloki.json" } return "/app/data/opsxloki.json" }