mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-07 18:50:26 +08:00
对统计指标进行分表
This commit is contained in:
@@ -26,5 +26,5 @@ const (
|
|||||||
ReportNodeVersion = "0.1.0"
|
ReportNodeVersion = "0.1.0"
|
||||||
|
|
||||||
// SQLVersion SQL版本号
|
// SQLVersion SQL版本号
|
||||||
SQLVersion = "5"
|
SQLVersion = "6"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -34,6 +35,9 @@ func NewMetricItemDAO() *MetricItemDAO {
|
|||||||
|
|
||||||
var SharedMetricItemDAO *MetricItemDAO
|
var SharedMetricItemDAO *MetricItemDAO
|
||||||
|
|
||||||
|
var metricItemLastTimeCacheMap = map[int64]string{} // itemId => time
|
||||||
|
var metricItemLastTimeCacheLocker = &sync.Mutex{}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
dbs.OnReady(func() {
|
dbs.OnReady(func() {
|
||||||
SharedMetricItemDAO = NewMetricItemDAO()
|
SharedMetricItemDAO = NewMetricItemDAO()
|
||||||
@@ -330,6 +334,32 @@ func (this *MetricItemDAO) FindItemVersion(tx *dbs.Tx, itemId int64) (int32, err
|
|||||||
return types.Int32(version), nil
|
return types.Int32(version), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateMetricLastTime 更新指标最新数据的时间
|
||||||
|
func (this *MetricItemDAO) UpdateMetricLastTime(tx *dbs.Tx, itemId int64, lastTime string) error {
|
||||||
|
metricItemLastTimeCacheLocker.Lock()
|
||||||
|
cachedTime, ok := metricItemLastTimeCacheMap[itemId]
|
||||||
|
if ok && cachedTime == lastTime {
|
||||||
|
metricItemLastTimeCacheLocker.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
metricItemLastTimeCacheMap[itemId] = lastTime
|
||||||
|
metricItemLastTimeCacheLocker.Unlock()
|
||||||
|
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(itemId).
|
||||||
|
Set("lastTime", lastTime).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindMetricLastTime 读取指标最新数据的时间
|
||||||
|
func (this *MetricItemDAO) FindMetricLastTime(tx *dbs.Tx, itemId int64) (string, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Result("lastTime").
|
||||||
|
Pk(itemId).
|
||||||
|
FindStringCol("")
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *MetricItemDAO) NotifyUpdate(tx *dbs.Tx, itemId int64, isPublic bool) error {
|
func (this *MetricItemDAO) NotifyUpdate(tx *dbs.Tx, itemId int64, isPublic bool) error {
|
||||||
if isPublic {
|
if isPublic {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type MetricItem struct {
|
|||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
Version uint32 `field:"version"` // 版本号
|
Version uint32 `field:"version"` // 版本号
|
||||||
IsPublic bool `field:"isPublic"` // 是否为公用
|
IsPublic bool `field:"isPublic"` // 是否为公用
|
||||||
|
LastTime string `field:"lastTime"` // 最新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
type MetricItemOperator struct {
|
type MetricItemOperator struct {
|
||||||
@@ -37,6 +38,7 @@ type MetricItemOperator struct {
|
|||||||
State interface{} // 状态
|
State interface{} // 状态
|
||||||
Version interface{} // 版本号
|
Version interface{} // 版本号
|
||||||
IsPublic interface{} // 是否为公用
|
IsPublic interface{} // 是否为公用
|
||||||
|
LastTime interface{} // 最新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMetricItemOperator() *MetricItemOperator {
|
func NewMetricItemOperator() *MetricItemOperator {
|
||||||
|
|||||||
@@ -11,8 +11,12 @@ import (
|
|||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -33,6 +37,8 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MetricStatTablePartials = 20 // 表格Partial数量
|
||||||
|
|
||||||
func NewMetricStatDAO() *MetricStatDAO {
|
func NewMetricStatDAO() *MetricStatDAO {
|
||||||
return dbs.NewDAO(&MetricStatDAO{
|
return dbs.NewDAO(&MetricStatDAO{
|
||||||
DAOObject: dbs.DAOObject{
|
DAOObject: dbs.DAOObject{
|
||||||
@@ -65,7 +71,8 @@ func (this *MetricStatDAO) CreateStat(tx *dbs.Tx, hash string, clusterId int64,
|
|||||||
} else {
|
} else {
|
||||||
keysString = "[]"
|
keysString = "[]"
|
||||||
}
|
}
|
||||||
return this.Query(tx).
|
err := this.Query(tx).
|
||||||
|
Table(this.partialTable(serverId)).
|
||||||
Param("value", value).
|
Param("value", value).
|
||||||
InsertOrUpdateQuickly(maps.Map{
|
InsertOrUpdateQuickly(maps.Map{
|
||||||
"hash": hash,
|
"hash": hash,
|
||||||
@@ -81,29 +88,42 @@ func (this *MetricStatDAO) CreateStat(tx *dbs.Tx, hash string, clusterId int64,
|
|||||||
}, maps.Map{
|
}, maps.Map{
|
||||||
"value": value,
|
"value": value,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return SharedMetricItemDAO.UpdateMetricLastTime(tx, itemId, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteOldVersionItemStats 删除以前版本的统计数据
|
// DeleteOldVersionItemStats 删除以前版本的统计数据
|
||||||
func (this *MetricStatDAO) DeleteOldVersionItemStats(tx *dbs.Tx, itemId int64, version int32) error {
|
func (this *MetricStatDAO) DeleteOldVersionItemStats(tx *dbs.Tx, itemId int64, version int32) error {
|
||||||
|
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Where("version<:version").
|
Where("version<:version").
|
||||||
Param("version", version).
|
Param("version", version).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteItemStats 删除某个指标相关的统计数据
|
// DeleteItemStats 删除某个指标相关的统计数据
|
||||||
func (this *MetricStatDAO) DeleteItemStats(tx *dbs.Tx, itemId int64) error {
|
func (this *MetricStatDAO) DeleteItemStats(tx *dbs.Tx, itemId int64) error {
|
||||||
|
return this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Delete()
|
Delete()
|
||||||
return err
|
return err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteNodeItemStats 删除某个节点的统计数据
|
// DeleteNodeItemStats 删除某个节点的统计数据
|
||||||
func (this *MetricStatDAO) DeleteNodeItemStats(tx *dbs.Tx, nodeId int64, serverId int64, itemId int64, time string) error {
|
func (this *MetricStatDAO) DeleteNodeItemStats(tx *dbs.Tx, nodeId int64, serverId int64, itemId int64, time string) error {
|
||||||
|
if serverId > 0 {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
|
Table(this.partialTable(serverId)).
|
||||||
Attr("nodeId", nodeId).
|
Attr("nodeId", nodeId).
|
||||||
Attr("serverId", serverId).
|
Attr("serverId", serverId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
@@ -112,17 +132,49 @@ func (this *MetricStatDAO) DeleteNodeItemStats(tx *dbs.Tx, nodeId int64, serverI
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
|
Attr("nodeId", nodeId).
|
||||||
|
Attr("serverId", serverId).
|
||||||
|
Attr("itemId", itemId).
|
||||||
|
Attr("time", time).
|
||||||
|
Delete()
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// CountItemStats 计算统计数据数量
|
// CountItemStats 计算统计数据数量
|
||||||
func (this *MetricStatDAO) CountItemStats(tx *dbs.Tx, itemId int64, version int32) (int64, error) {
|
func (this *MetricStatDAO) CountItemStats(tx *dbs.Tx, itemId int64, version int32) (int64, error) {
|
||||||
return this.Query(tx).
|
var total int64 = 0
|
||||||
|
|
||||||
|
err := this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
count, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
Count()
|
Count()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
atomic.AddInt64(&total, count)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListItemStats 列出单页统计数据
|
// ListItemStats 列出单页统计数据
|
||||||
func (this *MetricStatDAO) ListItemStats(tx *dbs.Tx, itemId int64, version int32, offset int64, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) ListItemStats(tx *dbs.Tx, itemId int64, version int32, offset int64, size int64) (result []*MetricStat, err error) {
|
||||||
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
var partialResult = []*MetricStat{}
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
@@ -130,8 +182,33 @@ func (this *MetricStatDAO) ListItemStats(tx *dbs.Tx, itemId int64, version int32
|
|||||||
Desc("time").
|
Desc("time").
|
||||||
Desc("serverId").
|
Desc("serverId").
|
||||||
Desc("value").
|
Desc("value").
|
||||||
Slice(&result).
|
Slice(&partialResult).
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, partialResult...)
|
||||||
|
locker.Unlock()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
if result[i].Time > result[j].Time {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if result[i].ServerId > result[j].ServerId {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if result[i].Value > result[j].Value {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,21 +216,15 @@ func (this *MetricStatDAO) ListItemStats(tx *dbs.Tx, itemId int64, version int32
|
|||||||
// 适合每条数据中包含不同的Key的场景
|
// 适合每条数据中包含不同的Key的场景
|
||||||
func (this *MetricStatDAO) FindItemStatsAtLastTime(tx *dbs.Tx, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindItemStatsAtLastTime(tx *dbs.Tx, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
// 最近一次时间
|
// 最近一次时间
|
||||||
statOne, err := this.Query(tx).
|
lastTime, err := SharedMetricItemDAO.FindMetricLastTime(tx, itemId)
|
||||||
Attr("itemId", itemId).
|
if err != nil || len(lastTime) == 0 {
|
||||||
Attr("version", version).
|
|
||||||
DescPk().
|
|
||||||
Find()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if statOne == nil {
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
return nil, nil
|
var partialResult = []*MetricStat{}
|
||||||
}
|
|
||||||
var lastStat = statOne.(*MetricStat)
|
|
||||||
var lastTime = lastStat.Time
|
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
Attr("time", lastTime).
|
Attr("time", lastTime).
|
||||||
@@ -163,42 +234,57 @@ func (this *MetricStatDAO) FindItemStatsAtLastTime(tx *dbs.Tx, itemId int64, ign
|
|||||||
Desc("value").
|
Desc("value").
|
||||||
Group("keys").
|
Group("keys").
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result)
|
Slice(&partialResult)
|
||||||
if ignoreEmptyKeys {
|
if ignoreEmptyKeys {
|
||||||
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
||||||
}
|
}
|
||||||
if len(ignoreKeys) > 0 {
|
if len(ignoreKeys) > 0 {
|
||||||
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
||||||
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
||||||
}
|
}
|
||||||
_, err = query.
|
_, err = query.
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, partialResult...)
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].Value > result[j].Value
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindItemStatsWithClusterIdAndLastTime 取得集群最近一次计时前 N 个数据
|
// FindItemStatsWithClusterIdAndLastTime 取得集群最近一次计时前 N 个数据
|
||||||
// 适合每条数据中包含不同的Key的场景
|
// 适合每条数据中包含不同的Key的场景
|
||||||
func (this *MetricStatDAO) FindItemStatsWithClusterIdAndLastTime(tx *dbs.Tx, clusterId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindItemStatsWithClusterIdAndLastTime(tx *dbs.Tx, clusterId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
// 最近一次时间
|
lastTime, err := SharedMetricItemDAO.FindMetricLastTime(tx, itemId)
|
||||||
statOne, err := this.Query(tx).
|
if err != nil || len(lastTime) == 0 {
|
||||||
Attr("itemId", itemId).
|
|
||||||
Attr("version", version).
|
|
||||||
DescPk().
|
|
||||||
Find()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if statOne == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
var lastStat = statOne.(*MetricStat)
|
|
||||||
var lastTime = lastStat.Time
|
|
||||||
|
|
||||||
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
var partialResult = []*MetricStat{}
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
UseIndex("cluster_item_time").
|
UseIndex("cluster_item_time").
|
||||||
Attr("clusterId", clusterId).
|
Attr("clusterId", clusterId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
@@ -210,14 +296,14 @@ func (this *MetricStatDAO) FindItemStatsWithClusterIdAndLastTime(tx *dbs.Tx, clu
|
|||||||
Desc("value").
|
Desc("value").
|
||||||
Group("keys").
|
Group("keys").
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result)
|
Slice(&partialResult)
|
||||||
if ignoreEmptyKeys {
|
if ignoreEmptyKeys {
|
||||||
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
||||||
}
|
}
|
||||||
if len(ignoreKeys) > 0 {
|
if len(ignoreKeys) > 0 {
|
||||||
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
||||||
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
||||||
@@ -225,6 +311,28 @@ func (this *MetricStatDAO) FindItemStatsWithClusterIdAndLastTime(tx *dbs.Tx, clu
|
|||||||
|
|
||||||
_, err = query.
|
_, err = query.
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, partialResult...)
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].Value > result[j].Value
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,20 +340,15 @@ func (this *MetricStatDAO) FindItemStatsWithClusterIdAndLastTime(tx *dbs.Tx, clu
|
|||||||
// 适合每条数据中包含不同的Key的场景
|
// 适合每条数据中包含不同的Key的场景
|
||||||
func (this *MetricStatDAO) FindItemStatsWithNodeIdAndLastTime(tx *dbs.Tx, nodeId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindItemStatsWithNodeIdAndLastTime(tx *dbs.Tx, nodeId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
// 最近一次时间
|
// 最近一次时间
|
||||||
statOne, err := this.Query(tx).
|
lastTime, err := SharedMetricItemDAO.FindMetricLastTime(tx, itemId)
|
||||||
Attr("itemId", itemId).
|
|
||||||
Attr("version", version).
|
|
||||||
DescPk().
|
|
||||||
Find()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if statOne == nil {
|
|
||||||
return nil, nil
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
}
|
var partialResult = []*MetricStat{}
|
||||||
var lastStat = statOne.(*MetricStat)
|
|
||||||
var lastTime = lastStat.Time
|
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
UseIndex("node_item_time").
|
UseIndex("node_item_time").
|
||||||
Attr("nodeId", nodeId).
|
Attr("nodeId", nodeId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
@@ -257,14 +360,14 @@ func (this *MetricStatDAO) FindItemStatsWithNodeIdAndLastTime(tx *dbs.Tx, nodeId
|
|||||||
Desc("value").
|
Desc("value").
|
||||||
Group("keys").
|
Group("keys").
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result)
|
Slice(&partialResult)
|
||||||
if ignoreEmptyKeys {
|
if ignoreEmptyKeys {
|
||||||
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
||||||
}
|
}
|
||||||
if len(ignoreKeys) > 0 {
|
if len(ignoreKeys) > 0 {
|
||||||
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
||||||
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
||||||
@@ -272,28 +375,43 @@ func (this *MetricStatDAO) FindItemStatsWithNodeIdAndLastTime(tx *dbs.Tx, nodeId
|
|||||||
|
|
||||||
_, err = query.
|
_, err = query.
|
||||||
FindAll()
|
FindAll()
|
||||||
return
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindItemStatsWithServerIdAndLastTime 取得节点最近一次计时前 N 个数据
|
locker.Lock()
|
||||||
// 适合每条数据中包含不同的Key的场景
|
result = append(result, partialResult...)
|
||||||
func (this *MetricStatDAO) FindItemStatsWithServerIdAndLastTime(tx *dbs.Tx, serverId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
locker.Unlock()
|
||||||
// 最近一次时间
|
|
||||||
statOne, err := this.Query(tx).
|
return nil
|
||||||
Attr("itemId", itemId).
|
})
|
||||||
Attr("version", version).
|
|
||||||
DescPk().
|
|
||||||
Find()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if statOne == nil {
|
|
||||||
return nil, nil
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].Value > result[j].Value
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindItemStatsWithServerIdAndLastTime 取得服务最近一次计时前 N 个数据
|
||||||
|
// 适合每条数据中包含不同的Key的场景
|
||||||
|
func (this *MetricStatDAO) FindItemStatsWithServerIdAndLastTime(tx *dbs.Tx, serverId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
|
// 最近一次时间
|
||||||
|
lastTime, err := SharedMetricItemDAO.FindMetricLastTime(tx, itemId)
|
||||||
|
if err != nil || len(lastTime) == 0 {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
var lastStat = statOne.(*MetricStat)
|
|
||||||
var lastTime = lastStat.Time
|
|
||||||
|
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(this.partialTable(serverId)).
|
||||||
UseIndex("server_item_time").
|
UseIndex("server_item_time").
|
||||||
Attr("serverId", serverId).
|
Attr("serverId", serverId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
@@ -326,7 +444,10 @@ func (this *MetricStatDAO) FindItemStatsWithServerIdAndLastTime(tx *dbs.Tx, serv
|
|||||||
// FindLatestItemStats 取得所有集群上最近 N 个时间的数据
|
// FindLatestItemStats 取得所有集群上最近 N 个时间的数据
|
||||||
// 适合同个Key在不同时间段的变化场景
|
// 适合同个Key在不同时间段的变化场景
|
||||||
func (this *MetricStatDAO) FindLatestItemStats(tx *dbs.Tx, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindLatestItemStats(tx *dbs.Tx, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
var partialResult = []*MetricStat{}
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
// TODO 增加更多聚合算法,比如 AVG、MEDIAN、MIN、MAX 等
|
// TODO 增加更多聚合算法,比如 AVG、MEDIAN、MIN、MAX 等
|
||||||
@@ -335,14 +456,14 @@ func (this *MetricStatDAO) FindLatestItemStats(tx *dbs.Tx, itemId int64, ignoreE
|
|||||||
Desc("time").
|
Desc("time").
|
||||||
Group("time").
|
Group("time").
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result)
|
Slice(&partialResult)
|
||||||
if ignoreEmptyKeys {
|
if ignoreEmptyKeys {
|
||||||
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
||||||
}
|
}
|
||||||
if len(ignoreKeys) > 0 {
|
if len(ignoreKeys) > 0 {
|
||||||
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
||||||
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
||||||
@@ -350,17 +471,41 @@ func (this *MetricStatDAO) FindLatestItemStats(tx *dbs.Tx, itemId int64, ignoreE
|
|||||||
|
|
||||||
_, err = query.
|
_, err = query.
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, partialResult...)
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].Time > result[j].Time
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
lists.Reverse(result)
|
lists.Reverse(result)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindLatestItemStatsWithClusterId 取得集群最近 N 个时间的数据
|
// FindLatestItemStatsWithClusterId 取得集群最近 N 个时间的数据
|
||||||
// 适合同个Key在不同时间段的变化场景
|
// 适合同个Key在不同时间段的变化场景
|
||||||
func (this *MetricStatDAO) FindLatestItemStatsWithClusterId(tx *dbs.Tx, clusterId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindLatestItemStatsWithClusterId(tx *dbs.Tx, clusterId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
var partialResult = []*MetricStat{}
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("clusterId", clusterId).
|
Attr("clusterId", clusterId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
@@ -370,14 +515,14 @@ func (this *MetricStatDAO) FindLatestItemStatsWithClusterId(tx *dbs.Tx, clusterI
|
|||||||
Desc("time").
|
Desc("time").
|
||||||
Group("time").
|
Group("time").
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result)
|
Slice(&partialResult)
|
||||||
if ignoreEmptyKeys {
|
if ignoreEmptyKeys {
|
||||||
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
||||||
}
|
}
|
||||||
if len(ignoreKeys) > 0 {
|
if len(ignoreKeys) > 0 {
|
||||||
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
||||||
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
||||||
@@ -385,9 +530,29 @@ func (this *MetricStatDAO) FindLatestItemStatsWithClusterId(tx *dbs.Tx, clusterI
|
|||||||
|
|
||||||
_, err = query.
|
_, err = query.
|
||||||
FindAll()
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, partialResult...)
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].Time > result[j].Time
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
lists.Reverse(result)
|
lists.Reverse(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -395,7 +560,10 @@ func (this *MetricStatDAO) FindLatestItemStatsWithClusterId(tx *dbs.Tx, clusterI
|
|||||||
// FindLatestItemStatsWithNodeId 取得节点最近 N 个时间的数据
|
// FindLatestItemStatsWithNodeId 取得节点最近 N 个时间的数据
|
||||||
// 适合同个Key在不同时间段的变化场景
|
// 适合同个Key在不同时间段的变化场景
|
||||||
func (this *MetricStatDAO) FindLatestItemStatsWithNodeId(tx *dbs.Tx, nodeId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindLatestItemStatsWithNodeId(tx *dbs.Tx, nodeId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
|
err = this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
|
var partialResult = []*MetricStat{}
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("nodeId", nodeId).
|
Attr("nodeId", nodeId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
@@ -405,14 +573,14 @@ func (this *MetricStatDAO) FindLatestItemStatsWithNodeId(tx *dbs.Tx, nodeId int6
|
|||||||
Desc("time").
|
Desc("time").
|
||||||
Group("time").
|
Group("time").
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Slice(&result)
|
Slice(&partialResult)
|
||||||
if ignoreEmptyKeys {
|
if ignoreEmptyKeys {
|
||||||
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
query.Where("NOT JSON_CONTAINS(`keys`, '\"\"')")
|
||||||
}
|
}
|
||||||
if len(ignoreKeys) > 0 {
|
if len(ignoreKeys) > 0 {
|
||||||
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
ignoreKeysJSON, err := json.Marshal(ignoreKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
query.Where("NOT JSON_CONTAINS(:ignoredKeys, JSON_EXTRACT(`keys`, '$[0]'))") // TODO $[0] 需要换成keys中的primary key位置
|
||||||
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
query.Param("ignoredKeys", string(ignoreKeysJSON))
|
||||||
@@ -421,8 +589,24 @@ func (this *MetricStatDAO) FindLatestItemStatsWithNodeId(tx *dbs.Tx, nodeId int6
|
|||||||
_, err = query.
|
_, err = query.
|
||||||
FindAll()
|
FindAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, partialResult...)
|
||||||
|
locker.Unlock()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].Time > result[j].Time
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
lists.Reverse(result)
|
lists.Reverse(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -431,6 +615,7 @@ func (this *MetricStatDAO) FindLatestItemStatsWithNodeId(tx *dbs.Tx, nodeId int6
|
|||||||
// 适合同个Key在不同时间段的变化场景
|
// 适合同个Key在不同时间段的变化场景
|
||||||
func (this *MetricStatDAO) FindLatestItemStatsWithServerId(tx *dbs.Tx, serverId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
func (this *MetricStatDAO) FindLatestItemStatsWithServerId(tx *dbs.Tx, serverId int64, itemId int64, ignoreEmptyKeys bool, ignoreKeys []string, version int32, size int64) (result []*MetricStat, err error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
|
Table(this.partialTable(serverId)).
|
||||||
Attr("serverId", serverId).
|
Attr("serverId", serverId).
|
||||||
Attr("itemId", itemId).
|
Attr("itemId", itemId).
|
||||||
Attr("version", version).
|
Attr("version", version).
|
||||||
@@ -480,12 +665,16 @@ func (this *MetricStatDAO) Clean(tx *dbs.Tx) error {
|
|||||||
ExpiresPeriod: int(item.ExpiresPeriod),
|
ExpiresPeriod: int(item.ExpiresPeriod),
|
||||||
}
|
}
|
||||||
var expiresDay = config.ServerExpiresDay()
|
var expiresDay = config.ServerExpiresDay()
|
||||||
|
err := this.runBatch(func(table string, locker *sync.Mutex) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
Attr("itemId", item.Id).
|
Attr("itemId", item.Id).
|
||||||
Lte("createdDay", expiresDay).
|
Lte("createdDay", expiresDay).
|
||||||
UseIndex("createdDay").
|
UseIndex("createdDay").
|
||||||
Limit(100_000). // 一次性不要删除太多,防止阻塞其他操作
|
Limit(10_000). // 一次性不要删除太多,防止阻塞其他操作
|
||||||
Delete()
|
Delete()
|
||||||
|
return err
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -500,3 +689,29 @@ func (this *MetricStatDAO) Clean(tx *dbs.Tx) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取分区表
|
||||||
|
func (this *MetricStatDAO) partialTable(serverId int64) string {
|
||||||
|
return this.Table + "_" + types.String(serverId%int64(MetricStatTablePartials))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量执行
|
||||||
|
func (this *MetricStatDAO) runBatch(f func(table string, locker *sync.Mutex) error) error {
|
||||||
|
var locker = &sync.Mutex{}
|
||||||
|
var wg = sync.WaitGroup{}
|
||||||
|
wg.Add(MetricStatTablePartials)
|
||||||
|
var resultErr error
|
||||||
|
for i := 0; i < MetricStatTablePartials; i++ {
|
||||||
|
var table = this.partialTable(int64(i))
|
||||||
|
go func(table string) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
err := f(table, locker)
|
||||||
|
if err != nil {
|
||||||
|
resultErr = err
|
||||||
|
}
|
||||||
|
}(table)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return resultErr
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package models
|
package models_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -8,11 +9,12 @@ import (
|
|||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewMetricStatDAO_InsertMany(t *testing.T) {
|
func TestNewMetricStatDAO_InsertMany(t *testing.T) {
|
||||||
for i := 0; i <= 1; i++ {
|
for i := 0; i <= 1; i++ {
|
||||||
err := NewMetricStatDAO().CreateStat(nil, types.String(i)+"_v1", 18, int64(rands.Int(0, 10000)), int64(rands.Int(0, 10000)), int64(rands.Int(0, 100)), []string{"/html" + types.String(i)}, 1, timeutil.Format("Ymd"), 0)
|
err := models.NewMetricStatDAO().CreateStat(nil, types.String(i)+"_v1", 18, int64(rands.Int(0, 10000)), int64(rands.Int(0, 10000)), int64(rands.Int(0, 100)), []string{"/html" + types.String(i)}, 1, timeutil.Format("Ymd"), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -23,12 +25,38 @@ func TestNewMetricStatDAO_InsertMany(t *testing.T) {
|
|||||||
t.Log("done")
|
t.Log("done")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMetricStatDAO_Clean(t *testing.T) {
|
func TestMetricStatDAO_Clean2(t *testing.T) {
|
||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
err := NewMetricStatDAO().Clean(nil)
|
err := models.NewMetricStatDAO().Clean(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMetricStatDAO_DeleteNodeItemStats(t *testing.T) {
|
||||||
|
var dao = models.NewMetricStatDAO()
|
||||||
|
var before = time.Now()
|
||||||
|
defer func() {
|
||||||
|
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||||
|
}()
|
||||||
|
err := dao.DeleteNodeItemStats(nil, 1, 0, 1, timeutil.Format("Ymd"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetricStatDAO_CountItemStats(t *testing.T) {
|
||||||
|
var dao = models.NewMetricStatDAO()
|
||||||
|
var before = time.Now()
|
||||||
|
defer func() {
|
||||||
|
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||||
|
}()
|
||||||
|
count, err := dao.CountItemStats(nil, 1, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("count:", count)
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user