123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- package service
- import (
- "context"
- "go-common/app/admin/main/videoup/model/archive"
- "go-common/app/admin/main/videoup/model/manager"
- "go-common/app/admin/main/videoup/model/monitor"
- "go-common/library/log"
- "strconv"
- "strings"
- "time"
- "github.com/pkg/errors"
- )
- // MonitorResult 获取监控业务的统计结果列表
- func (s *Service) MonitorResult(c context.Context, p *monitor.RuleResultParams) (res []*monitor.RuleResultData, err error) {
- var (
- rules []*monitor.Rule
- mUser *manager.User
- )
- res = []*monitor.RuleResultData{}
- if rules, err = s.monitor.GetRules(c, p.Type, p.Business, true); err != nil {
- return
- }
- for _, v := range rules {
- var stats *monitor.Stats
- if stats, err = s.MonitorStats(c, v); err != nil {
- return
- }
- if mUser, err = s.mng.User(c, v.UID); err != nil {
- mUser = &manager.User{
- ID: v.UID,
- }
- err = nil
- }
- tmp := &monitor.RuleResultData{
- Stats: stats,
- User: mUser,
- Rule: v,
- }
- res = append(res, tmp)
- }
- return
- }
- // MonitorStats 根据business和rule获取统计结果
- func (s *Service) MonitorStats(c context.Context, rule *monitor.Rule) (stats *monitor.Stats, err error) {
- var (
- qualiKeys []string //符合条件的统计redis key
- )
- qualiKeys, err = s.RuleQualifiedKeys(c, rule)
- //根据符合条件的redis key qualiKeys获取数据
- stats = &monitor.Stats{}
- for _, k := range qualiKeys {
- var res *monitor.Stats
- if res, err = s.monitor.StatsResult(c, k, rule.RuleConf); err != nil {
- return
- }
- stats.TotalCount += res.TotalCount
- stats.MoniCount += res.MoniCount
- if res.MaxTime > stats.MaxTime {
- stats.MaxTime = res.MaxTime
- }
- }
- return
- }
- // MonitorRuleUpdate 更新监控规则
- func (s *Service) MonitorRuleUpdate(c context.Context, rule *monitor.Rule) (err error) {
- rule.CTime = time.Now().Format("2006-01-02 15:04:05")
- err = s.monitor.SetRule(c, rule)
- return
- }
- // RuleQualifiedKeys 获取监控业务中符合监控条件的Redis key
- func (s *Service) RuleQualifiedKeys(c context.Context, rule *monitor.Rule) (qualiKeys []string, err error) {
- var (
- allKeys []string //当前业务的所有统计redis key
- //qualiKeys []string //符合条件的统计redis key
- prefix string //当前业务redis 可以前缀
- keyConf *monitor.KeyConf //当前业务redis key 的字段配置信息
- moniCdt = rule.RuleConf.MoniCdt //当前业务中,需要统计的条件
- ok bool
- )
- qualiKeys = []string{}
- if keyConf, ok = monitor.RedisKeyConf[rule.Business]; !ok {
- err = errors.New("Business Not Exists")
- return
- }
- prefix, allKeys, err = s.monitor.BusStatsKeys(c, rule.Business)
- kFields := keyConf.KFields //Redis key中的字段
- for _, fullK := range allKeys {
- k := strings.Replace(fullK, prefix, "", 1) //去掉redis key 中的前缀monitor_stats_{business}_
- ks := strings.Split(k, "_") //redis key 的切割,格式:%d_%d
- if len(ks) != len(kFields) { //KFields中的字段数必须与redis key中数量一致
- err = errors.New("KeyConf 中 KFields 的字段配置错误")
- return
- }
- //把满足条件的Redis key找出来
- qualified := true //当前key是否满足条件
- i := -1
- for kf := range kFields {
- i++
- var (
- fv int64
- )
- fv, err = strconv.ParseInt(ks[i], 10, 64) //Redis key 中第i位的值
- if err != nil {
- return
- }
- if _, ok = moniCdt[kf]; !ok {
- err = errors.New("配置的 moniCdt 中不存在: " + kf)
- return
- }
- switch moniCdt[kf].Comp {
- case monitor.CompE:
- if fv != moniCdt[kf].Value {
- qualified = false
- }
- case monitor.CompNE:
- if fv == moniCdt[kf].Value {
- qualified = false
- }
- case monitor.CompGET:
- if fv < moniCdt[kf].Value {
- qualified = false
- }
- case monitor.CompLET:
- if fv > moniCdt[kf].Value {
- qualified = false
- }
- case monitor.CompGT:
- if fv <= moniCdt[kf].Value {
- qualified = false
- }
- case monitor.CompLT:
- if fv >= moniCdt[kf].Value {
- qualified = false
- }
- default:
- err = errors.New("配置的 MoniCdt 中 comparison 不合法: " + moniCdt[kf].Comp)
- return
- }
- }
- if qualified {
- qualiKeys = append(qualiKeys, fullK)
- }
- }
- return
- }
- // MoniStayOids 获取监控范围内,滞留的oids
- func (s *Service) MoniStayOids(c context.Context, tp, bid int8, id int64) (total int, oidMap map[int64]int, qualiKeys []string, err error) {
- var (
- rule *monitor.Rule
- )
- if rule, err = s.monitor.GetRule(c, tp, bid, id); err != nil {
- return
- }
- //查找符合条件的统计redis key
- if qualiKeys, err = s.RuleQualifiedKeys(c, rule); err != nil {
- return
- }
- oidMap, total, err = s.monitor.StayOids(c, rule, qualiKeys)
- log.Info("MoniStayOids(%d,%d,%d) oidMap(%v)", tp, bid, id, oidMap)
- return
- }
- // MonitorStayOids 获取监控范围内,滞留的oids
- func (s *Service) MonitorStayOids(c context.Context, id int64) (oidMap map[int64]int, err error) {
- return s.data.MonitorOids(c, id)
- }
- // MonitorNotifyResult 获取达到了报警阀值的数据
- func (s *Service) MonitorNotifyResult(c context.Context) (res []*monitor.RuleResultData, err error) {
- var (
- rules []*monitor.Rule
- stats *monitor.Stats
- )
- res = []*monitor.RuleResultData{}
- if rules, err = s.monitor.GetAllRules(c, false); err != nil {
- log.Error("MonitorNotifyCheck() error(%v)", err)
- return
- }
- for _, v := range rules {
- if v.Business == monitor.BusVideo {
- s.MonitorCheckVideoStatus(c, v.Type, v.ID)
- }
- if stats, err = s.MonitorStats(c, v); err != nil {
- log.Error("MonitorNotifyCheck() error(%v)", err)
- err = nil
- continue
- }
- notify := true
- //暂时只有time、count这两个报警条件
- if _, ok := v.RuleConf.NotifyCdt["time"]; ok {
- threshold := v.RuleConf.NotifyCdt["time"].Value
- comp := v.RuleConf.NotifyCdt["time"].Comp
- switch comp {
- case monitor.CompGT:
- if int64(stats.MaxTime) < threshold {
- notify = false
- }
- case monitor.CompLT:
- if int64(stats.MaxTime) > threshold {
- notify = false
- }
- }
- }
- if _, ok := v.RuleConf.NotifyCdt["count"]; ok {
- threshold := v.RuleConf.NotifyCdt["count"].Value
- comp := v.RuleConf.NotifyCdt["count"].Comp
- switch comp {
- case monitor.CompGT:
- if int64(stats.MoniCount) < threshold {
- notify = false
- }
- case monitor.CompLT:
- if int64(stats.MoniCount) > threshold {
- notify = false
- }
- }
- }
- if notify {
- tmp := &monitor.RuleResultData{
- Stats: stats,
- Rule: v,
- }
- res = append(res, tmp)
- }
- }
- return
- }
- // MonitorCheckVideoStatus 检查视频的稿件状态,如果是-100则剔除SortedSet的数据
- func (s *Service) MonitorCheckVideoStatus(c context.Context, tp int8, id int64) (err error) {
- var (
- vidMap map[int64]int
- vidAidMap map[int64]int64
- arcStates map[int64]int
- vids, aids []int64
- bid = monitor.BusVideo
- keys []string
- )
- if _, vidMap, keys, err = s.MoniStayOids(c, tp, bid, id); err != nil {
- log.Error("s.MoniStayOids(%d,%d,%d) error(%v)", tp, bid, id, err)
- return
- }
- for vid := range vidMap {
- vids = append(vids, vid)
- }
- if vidAidMap, err = s.arc.VideoAidMap(c, vids); err != nil {
- log.Error("s.VideoAidMap(%d) error(%v)", vids, err)
- return
- }
- for _, aid := range vidAidMap {
- aids = append(aids, aid)
- }
- if arcStates, err = s.arc.ArcStateMap(c, aids); err != nil {
- log.Error("s.ArcStateMap(%d) error(%v)", aids, err)
- return
- }
- for vid, aid := range vidAidMap {
- if _, ok := arcStates[aid]; !ok {
- continue
- }
- if arcStates[aid] != int(archive.StateForbidUpDelete) && arcStates[aid] != int(archive.StateForbidLock) && arcStates[aid] != int(archive.StateForbidRecycle) {
- continue
- }
- for _, k := range keys {
- if err = s.monitor.RemMonitorStats(c, k, vid); err != nil {
- log.Error("s.monitor.RemMonitorStats(%s,%d) error(%v)", k, vid, err)
- }
- }
- }
- return
- }
|