event.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package service
  2. import (
  3. "fmt"
  4. aModel "go-admin/app/admin/models"
  5. "go-admin/app/observe/models"
  6. "go-admin/app/observe/service/dto"
  7. cDto "go-admin/common/dto"
  8. "go-admin/utils"
  9. "time"
  10. "github.com/pkg/errors"
  11. "gorm.io/gorm"
  12. )
  13. type Event struct {
  14. utils.OtService
  15. }
  16. func (e *Event) GetPage(c *dto.EventListReq, result *[]dto.EventListResp, count *int64) error {
  17. db := e.ChOrm.Table(models.TableNameEvent)
  18. if c.AppId > 0 {
  19. db.Where("AppId", c.AppId)
  20. }
  21. if c.AlertStatus == 2 || c.AlertStatus == 4 {
  22. db.Where("AlertStatus", c.AlertStatus)
  23. }
  24. // db.Scopes(cDto.MakeCondition(*c))
  25. if c.StartTime > 0 {
  26. db.Where("AppendTime>=?", c.StartTime)
  27. }
  28. if c.EndTime > 0 {
  29. db.Where("AppendTime<?", c.EndTime)
  30. }
  31. if c.ExceptionName != "" {
  32. db.Where("ExceptionName LIKE ?", fmt.Sprintf("%%%s%%", c.ExceptionName))
  33. }
  34. err := db.Debug().Scopes(cDto.Paginate(c.GetPageSize(), c.GetPageIndex())).Order("AppendTime DESC").Find(result).
  35. Limit(-1).Offset(-1).Count(count).Error
  36. if err != nil {
  37. if err == gorm.ErrRecordNotFound {
  38. return nil
  39. }
  40. return errors.Wrap(err, "查询事件信息列表失败")
  41. }
  42. return nil
  43. }
  44. func (e *Event) ExceptionNums(c *dto.EventExceptionNumsReq, result *[]dto.EventExceptionNumsResp, count *int64) error {
  45. db := e.Orm.Model(&aModel.OtFireEvents{}).Scopes(
  46. cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
  47. ).Select("app_id", "app_alias", "app_name", "COUNT(1) AS exception_num").
  48. Where("is_know = 0 AND is_resolve = 0 AND is_ignore = 0")
  49. if c.StartTime > 0 {
  50. db.Where("created_at>=?", time.Unix(c.StartTime, 0).Format(time.DateTime))
  51. }
  52. if c.EndTime > 0 {
  53. db.Where("created_at<?", time.Unix(c.EndTime, 0).Format(time.DateTime))
  54. }
  55. appAliases := c.GetAppAliases()
  56. if len(appAliases) > 0 {
  57. db.Where("app_alias in ?", appAliases)
  58. } else { // 兼容旧逻辑, 后期去掉
  59. appIds := c.GetAppIds()
  60. if len(appIds) > 0 {
  61. db.Where("app_id IN ?", appIds)
  62. }
  63. }
  64. if err := db.Debug().Group("app_id, app_alias, app_name").Find(result).Limit(-1).Offset(-1).Count(count).Error; err != nil {
  65. return errors.Wrap(err, "执行查询应用异常数量失败")
  66. }
  67. return nil
  68. }
  69. func (e *Event) ExceptionNumByID(c *dto.EventExecptionNumGetByIDReq, count *int64) error {
  70. tbl := aModel.OtFireEvents{}.TableName()
  71. db := e.Orm.Table(fmt.Sprintf("%s t", tbl))
  72. db.Select([]string{
  73. "app_id",
  74. "COUNT(*) AS exception_num",
  75. })
  76. db.Where("app_id = ?", c.Id)
  77. db.Where("is_know = 0 AND is_resolve = 0 AND is_ignore = 0")
  78. if err := db.Count(count).Error; err != nil {
  79. return errors.Wrap(err, "执行查询业务异常数量失败")
  80. }
  81. return nil
  82. }
  83. func (e *Event) EventStatistic(c *dto.EventStatisticReq, result *[]dto.EventStatisticResp) error {
  84. db := e.ChOrm.Table(models.TableNameTracesError)
  85. db.Select([]string{
  86. "toTimeZone(toStartOfFiveMinutes(Timestamp), 'Asia/Shanghai') AS StartTime",
  87. "COUNT() AS Total",
  88. })
  89. db.Where("AppAlias = ?", c.AppAlias)
  90. db.Where("Timestamp >= ? AND Timestamp <= ?", c.StartTime, c.EndTime)
  91. db.Where("StatusCode='STATUS_CODE_ERROR' and StatusMessage!='' and StatusMessage != 'status code:0'")
  92. if c.Kind != "" && c.SubconditionValue != "" {
  93. switch c.Kind {
  94. case "app":
  95. db.Where("((ParentSpanId='' and SpanKind='SPAN_KIND_SERVER' and SpanAttributes['http.method'] != '' and SpanAttributes['rpc.system']='') OR SpanAttributes['db.system'] != '')") // 要求 只要http请求 和数据库 两种异常
  96. case "biz":
  97. // 改为错误分布, 与错误率*业务请求总数对上
  98. start := time.Unix(c.StartTime, 0).Truncate(time.Hour).Format(time.DateTime)
  99. end := time.Unix(c.EndTime, 0).Truncate(time.Hour).Add(time.Hour).Format(time.DateTime)
  100. return e.Orm.Model(&models.BizStatsHourly{}).
  101. Select("start_time, sum(error_num) as total").
  102. Where("biz_hash=?", c.BizHash).
  103. Where("start_time>=? and end_time<?", start, end).
  104. Group("start_time").Order("start_time").Find(result).Error
  105. case "interface":
  106. case "service":
  107. db.Where("ServiceName = ", c.SubconditionValue)
  108. default:
  109. }
  110. }
  111. // db.Where("StatusCode = 'STATUS_CODE_ERROR' AND StatusMessage != '' AND StatusMessage != 'status code:0'")
  112. db.Group("StartTime")
  113. if err := db.Order("StartTime Desc").Find(&result).Error; err != nil {
  114. return errors.Wrap(err, "计算范围时间内的异常失败")
  115. }
  116. return nil
  117. }
  118. func (e *Event) EventLists(c *dto.EventStatisticReq, result *[]dto.EventListsResp) error {
  119. res := make([]dto.EventListsResp, 0)
  120. db := e.ChOrm.Table(models.TableNameTracesError)
  121. db.Select(
  122. "ServiceName AS ServiceName",
  123. "any(if(SpanAttributes['db.system'] != '', '数据库异常', '业务异常')) AS ErrorType",
  124. "any(StatusMessage) as StatusMessage1",
  125. "COUNT() AS StatusMessageCount",
  126. )
  127. if c.AppAlias != "" {
  128. db.Where("AppAlias = ?", c.AppAlias)
  129. }
  130. if c.Kind != "" && c.SubconditionValue != "" {
  131. switch c.Kind {
  132. case "app":
  133. case "biz":
  134. case "interface":
  135. db.Where("")
  136. case "service":
  137. db.Where("ServiceName = ", c.SubconditionValue)
  138. default:
  139. }
  140. }
  141. db.Where("Timestamp >= ? AND Timestamp <= ?", c.StartTime, c.EndTime)
  142. // db.Where("StatusCode = 'STATUS_CODE_ERROR' AND StatusMessage != '' AND StatusMessage != 'status code:0'")
  143. db.Where("StatusCode='STATUS_CODE_ERROR' AND StatusMessage!='' and StatusMessage != 'status code:0'").
  144. Where("((ParentSpanId='' and SpanKind='SPAN_KIND_SERVER' and SpanAttributes['http.method'] != '' and SpanAttributes['rpc.system']='') OR SpanAttributes['db.system'] != '')") // 要求 只要root span和数据库 两种异常
  145. db.Group("substring(StatusMessage, 1, 15)")
  146. db.Group("ServiceName")
  147. if err := db.Order("StatusMessageCount DESC;").Find(&res).Error; err != nil {
  148. return errors.Wrap(err, "统计范围时间内的具体异常失败")
  149. }
  150. svcNodes := []struct {
  151. ServiceName string
  152. Name string
  153. Id int64
  154. }{}
  155. if err := e.Orm.Model(&models.ServiceNode{}).Where("app_alias", c.AppAlias).Find(&svcNodes).Error; err != nil {
  156. return errors.Wrap(err, "获取服务列表失败")
  157. }
  158. svcMap := map[string]string{}
  159. svcId := map[string]int64{}
  160. for _, node := range svcNodes {
  161. svcMap[node.ServiceName] = node.Name
  162. svcId[node.ServiceName] = node.Id
  163. }
  164. for _, r := range res {
  165. r.ServiceNameCN = svcMap[r.ServiceName]
  166. r.ServiceId = svcId[r.ServiceName]
  167. *result = append(*result, r)
  168. }
  169. return nil
  170. }