package dao import ( "errors" "github.com/sirupsen/logrus" "hy2xs-admin/model/constant" "hy2xs-admin/model/entity" "hy2xs-admin/model/vo" "time" ) func SaveMetricSample(sample entity.MetricSample) error { if tx := sqliteDB.Save(&sample); tx.Error != nil { logrus.Errorf("%v", tx.Error) return errors.New(constant.SysError) } return nil } func LastMetricSample() (entity.MetricSample, error) { var sample entity.MetricSample if tx := sqliteDB.Model(&entity.MetricSample{}).Order("sampled_at desc").Limit(1).Find(&sample); tx.Error != nil { logrus.Errorf("%v", tx.Error) return sample, errors.New(constant.SysError) } return sample, nil } func CleanupMetricSample(olderThanMs int64) error { if !tableExists("metric_sample") { return nil } if tx := sqliteDB.Exec("DELETE FROM metric_sample WHERE sampled_at < ?", olderThanMs); tx.Error != nil { logrus.Errorf("%v", tx.Error) return errors.New(constant.SysError) } return nil } func DashboardPeerSummary(nowMs int64) (vo.DashboardPeerVo, error) { result := vo.DashboardPeerVo{} type row struct { Total int64 Enabled int64 Disabled int64 Expired int64 } var r row if tx := sqliteDB.Raw(`SELECT COUNT(1) AS total, COALESCE(SUM(CASE WHEN disabled = 0 THEN 1 ELSE 0 END),0) AS enabled, COALESCE(SUM(CASE WHEN disabled = 1 THEN 1 ELSE 0 END),0) AS disabled, COALESCE(SUM(CASE WHEN expires_at > 0 AND expires_at < ? THEN 1 ELSE 0 END),0) AS expired FROM peer`, nowMs).Scan(&r); tx.Error != nil { logrus.Errorf("%v", tx.Error) return result, errors.New(constant.SysError) } result.Total = r.Total result.Enabled = r.Enabled result.Disabled = r.Disabled result.Expired = r.Expired return result, nil } func DashboardTrafficSummary() (vo.DashboardTrafficVo, error) { result := vo.DashboardTrafficVo{} type row struct { Download int64 Upload int64 } var r row if tx := sqliteDB.Raw(`SELECT COALESCE(SUM(download_bytes),0) AS download, COALESCE(SUM(upload_bytes),0) AS upload FROM peer`).Scan(&r); tx.Error != nil { logrus.Errorf("%v", tx.Error) return result, errors.New(constant.SysError) } result.DownloadBytes = r.Download result.UploadBytes = r.Upload result.TotalBytes = r.Download + r.Upload result.SinceResetDownloadBytes = r.Download result.SinceResetUploadBytes = r.Upload now := time.Now().UnixMilli() dayStart := now - (now % int64(24*time.Hour/time.Millisecond)) var today row if tx := sqliteDB.Raw(`SELECT COALESCE(SUM(rx_bytes),0) AS download, COALESCE(SUM(tx_bytes),0) AS upload FROM traffic_sample WHERE sampled_at >= ?`, dayStart).Scan(&today); tx.Error == nil { result.TodayDownloadBytes = today.Download result.TodayUploadBytes = today.Upload } return result, nil } func DashboardTopPeers(fromMs int64, toMs int64, limit int) ([]vo.DashboardTopPeerVo, error) { if limit <= 0 { limit = 10 } rows := make([]vo.DashboardTopPeerVo, 0) if tx := sqliteDB.Raw(`SELECT p.id AS peer_id, p.name AS name, p.remark AS remark, COALESCE(SUM(ts.rx_bytes),0) AS download, COALESCE(SUM(ts.tx_bytes),0) AS upload, COALESCE(SUM(ts.rx_bytes + ts.tx_bytes),0) AS total FROM traffic_sample ts JOIN peer p ON p.id = ts.peer_id WHERE ts.sampled_at BETWEEN ? AND ? GROUP BY p.id, p.name, p.remark ORDER BY total DESC LIMIT ?`, fromMs, toMs, limit).Scan(&rows); tx.Error != nil { logrus.Errorf("%v", tx.Error) return rows, errors.New(constant.SysError) } return rows, nil } func DashboardTrafficTimeseries(fromMs int64, toMs int64) ([]vo.DashboardSeriesPointVo, error) { rows := make([]vo.DashboardSeriesPointVo, 0) if tx := sqliteDB.Raw(`SELECT hour_start AS ts, COALESCE(SUM(rx_bytes),0) AS download, COALESCE(SUM(tx_bytes),0) AS upload FROM traffic_aggregate_hourly WHERE hour_start BETWEEN ? AND ? GROUP BY hour_start ORDER BY hour_start ASC`, fromMs, toMs).Scan(&rows); tx.Error != nil { logrus.Errorf("%v", tx.Error) return rows, errors.New(constant.SysError) } return rows, nil } func DashboardSystemTimeseries(fromMs int64, toMs int64) ([]vo.DashboardSeriesPointVo, error) { rows := make([]vo.DashboardSeriesPointVo, 0) if !tableExists("metric_sample") { return rows, nil } if tx := sqliteDB.Raw(`SELECT sampled_at AS ts, cpu_percent AS cpu, mem_percent AS mem FROM metric_sample WHERE sampled_at BETWEEN ? AND ? ORDER BY sampled_at ASC`, fromMs, toMs).Scan(&rows); tx.Error != nil { logrus.Errorf("%v", tx.Error) return rows, errors.New(constant.SysError) } return rows, nil }