bi_provider_service_get_fail.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // Copyright 2019 getensh.com. All rights reserved.
  2. // Use of this source code is governed by getensh.com.
  3. package access_log
  4. import (
  5. "context"
  6. "gd_statistics/apis"
  7. "gd_statistics/errors"
  8. "fmt"
  9. "strconv"
  10. "github.com/astaxie/beego/orm"
  11. )
  12. type ProviderCodeInfoReq struct {
  13. Start int64
  14. End int64
  15. MerchantId int64
  16. ProviderApiId int64
  17. OnlyFail bool
  18. GroupByApi bool
  19. }
  20. func getProviderCodeInfoFromHour(o orm.Ormer, req *ProviderCodeInfoReq) ([]TGdProviderCodeHour, error) {
  21. if req.End <= req.Start {
  22. return nil, nil
  23. }
  24. sql := fmt.Sprintf("select sum(count) as count, code, msg from t_gd_provider_code_hour where hour >= %d and hour < %d", req.Start, req.End)
  25. if req.GroupByApi {
  26. sql = fmt.Sprintf("select sum(count) as count, code, msg, provider_api_id, provider_api_name, provider_name from t_gd_provider_code_hour where hour >= %d and hour < %d", req.Start, req.End)
  27. }
  28. if req.ProviderApiId > 0 {
  29. sql = fmt.Sprintf("%s and provider_api_id=%d", sql, req.ProviderApiId)
  30. }
  31. if req.OnlyFail == true {
  32. sql = fmt.Sprintf("%s and state = 0", sql)
  33. }
  34. if req.GroupByApi {
  35. sql = fmt.Sprintf("%s group by code, msg, provider_api_id", sql)
  36. } else {
  37. sql = fmt.Sprintf("%s group by code, msg", sql)
  38. }
  39. tabs := []TGdProviderCodeHour{}
  40. _, err := o.Raw(sql).QueryRows(&tabs)
  41. if err != nil && err != orm.ErrNoRows {
  42. return nil, errors.DataBaseError
  43. }
  44. return tabs, nil
  45. }
  46. func getProviderCodeInfoFromToday(o orm.Ormer, req *ProviderCodeInfoReq) ([]TGdProviderCodeHour, error) {
  47. sql := fmt.Sprintf("select count(1) as count, raw_code as code, msg from t_gd_thirdpart_log_day where timestamp >= %d and timestamp < %d", req.Start, req.End)
  48. if req.GroupByApi {
  49. sql = fmt.Sprintf("select count(1) as count, raw_code as code, msg, provider_api_id, provider_api_name, provider_name from t_gd_thirdpart_log_day where timestamp >= %d and timestamp < %d", req.Start, req.End)
  50. }
  51. if req.ProviderApiId > 0 {
  52. sql = fmt.Sprintf("%s and provider_api_id=%d", sql, req.ProviderApiId)
  53. }
  54. if req.OnlyFail == true {
  55. sql = fmt.Sprintf("%s and state = 0", sql)
  56. }
  57. if req.GroupByApi {
  58. sql = fmt.Sprintf("%s group by code, msg, provider_api_id", sql)
  59. } else {
  60. sql = fmt.Sprintf("%s group by code, msg", sql)
  61. }
  62. tabs := []TGdProviderCodeHour{}
  63. _, err := o.Raw(sql).QueryRows(&tabs)
  64. if err != nil && err != orm.ErrNoRows {
  65. return nil, errors.DataBaseError
  66. }
  67. return tabs, nil
  68. }
  69. func sumProviderCode(old []TGdProviderCodeHour, today []TGdProviderCodeHour, groupByApi bool) (ret []TGdProviderCodeHour) {
  70. m := map[string]*TGdProviderCodeHour{}
  71. for i, v := range old {
  72. key := fmt.Sprintf("%s-%s", v.Code, v.Msg)
  73. if groupByApi {
  74. key = fmt.Sprintf("%s-%s-%d", v.Code, v.Msg, v.ProviderApiId)
  75. }
  76. m[key] = &old[i]
  77. }
  78. for i, v := range today {
  79. key := fmt.Sprintf("%s-%s", v.Code, v.Msg)
  80. if groupByApi {
  81. key = fmt.Sprintf("%s-%s-%d", v.Code, v.Msg, v.ProviderApiId)
  82. }
  83. if _, ok := m[key]; ok == false {
  84. m[key] = &today[i]
  85. continue
  86. }
  87. m[key].Count += v.Count
  88. }
  89. ret = make([]TGdProviderCodeHour, len(m))
  90. i := 0
  91. for _, v := range m {
  92. ret[i] = *v
  93. i++
  94. }
  95. return ret
  96. }
  97. func getProviderCodeInfo(req *ProviderCodeInfoReq) ([]TGdProviderCodeHour, error) {
  98. o := orm.NewOrm()
  99. maxHour := int64(0)
  100. err := o.Raw("select max(hour) as max_hour from t_gd_provider_code_hour").QueryRow(&maxHour)
  101. if err != nil && err != orm.ErrNoRows {
  102. return nil, errors.DataBaseError
  103. }
  104. todayInfos := []TGdProviderCodeHour{}
  105. if maxHour+3600 < req.End {
  106. /*
  107. mreq := *req
  108. mreq.Start = maxHour + 3600
  109. todayInfos, err = getProviderCodeInfoFromToday(o, &mreq)
  110. if err != nil {
  111. return nil, err
  112. }
  113. */
  114. }
  115. mreq := *req
  116. mreq.End = maxHour + 3600
  117. oldInfos, err := getProviderCodeInfoFromHour(o, &mreq)
  118. if err != nil {
  119. return nil, err
  120. }
  121. if len(todayInfos) == 0 {
  122. return oldInfos, nil
  123. }
  124. if len(oldInfos) == 0 {
  125. return todayInfos, nil
  126. }
  127. return sumProviderCode(oldInfos, todayInfos, req.GroupByApi), nil
  128. }
  129. func getProviderServiceFailInfo(start, end int64) ([]apis.ProviderServiceFailInfo, error) {
  130. mreq := ProviderCodeInfoReq{}
  131. mreq.GroupByApi = true
  132. mreq.Start = start
  133. mreq.End = end
  134. mreq.OnlyFail = true
  135. codeInfos, err := getProviderCodeInfo(&mreq)
  136. if err != nil {
  137. return nil, err
  138. }
  139. m := map[int64][]*TGdProviderCodeHour{}
  140. for i, v := range codeInfos {
  141. m[v.ProviderApiId] = append(m[v.ProviderApiId], &codeInfos[i])
  142. }
  143. ret := []apis.ProviderServiceFailInfo{}
  144. for _, v := range m {
  145. item := apis.ProviderServiceFailInfo{}
  146. for _, sub := range v {
  147. failItem := apis.ProviderServiceFailDetail{}
  148. item.ProviderApiName = sub.ProviderApiName
  149. item.ProviderName = sub.ProviderName
  150. item.Fail += sub.Count
  151. failItem.Fail = sub.Count
  152. failItem.Msg = sub.Msg
  153. failItem.Code = sub.Code
  154. item.Detail = append(item.Detail, failItem)
  155. }
  156. for i, d := range item.Detail {
  157. if item.Fail == 0 {
  158. item.Detail[i].Rate = "0%"
  159. } else {
  160. item.Detail[i].Rate = strconv.FormatFloat(float64(100*d.Fail/item.Fail), 'f', 2, 64) + "%"
  161. }
  162. }
  163. ret = append(ret, item)
  164. }
  165. return ret, nil
  166. }
  167. func sortProviderFailDetailInfo(array []apis.ProviderServiceFailDetail) []apis.ProviderServiceFailDetail {
  168. length := len(array)
  169. for i := 0; i < length; i++ {
  170. for j := i + 1; j < length; j++ {
  171. if array[i].Fail < array[j].Fail {
  172. tmp := array[i]
  173. array[i] = array[j]
  174. array[j] = tmp
  175. }
  176. }
  177. }
  178. return array
  179. }
  180. func sortProviderFailInfo(array []apis.ProviderServiceFailInfo) []apis.ProviderServiceFailInfo {
  181. length := len(array)
  182. for i := 0; i < length; i++ {
  183. for j := i + 1; j < length; j++ {
  184. if array[i].Fail < array[j].Fail {
  185. tmp := array[i]
  186. array[i] = array[j]
  187. array[j] = tmp
  188. }
  189. }
  190. }
  191. for i, v := range array {
  192. array[i].Detail = sortProviderFailDetailInfo(v.Detail)
  193. }
  194. return array
  195. }
  196. func BiGetProviderServiceFailInfo(ctx context.Context, req *apis.BiGetProviderServiceFailInfoReq, reply *apis.BiGetProviderServiceFailInfoReply) (err error) {
  197. // 参数预处理
  198. if req.PageNumber <= 0 {
  199. req.PageNumber = 1
  200. }
  201. if req.PageSize <= 0 {
  202. req.PageSize = pageSize
  203. }
  204. reply.PageNumber = req.PageNumber
  205. reply.PageSize = req.PageSize
  206. offset := (req.PageNumber - 1) * req.PageSize
  207. limit := req.PageSize
  208. start := int64(0)
  209. end := int64(0)
  210. // 今日,昨日,本周,本月
  211. switch req.TimeType {
  212. case 0:
  213. start, end = getTodayTimestamp()
  214. case 1:
  215. start, end = getYesterdayTimestamp()
  216. case 2:
  217. start, end = getWeekTimestamp()
  218. case 3:
  219. start, end = getMonthTimestamp()
  220. default:
  221. return errors.ArgsError
  222. }
  223. if req.TodayEndTimestamp < end && req.TodayEndTimestamp > 0 {
  224. end = req.TodayEndTimestamp
  225. }
  226. infos, err := getProviderServiceFailInfo(start, end)
  227. if err != nil {
  228. return err
  229. }
  230. reply.Total = int64(len(infos))
  231. infos = sortProviderFailInfo(infos)
  232. reply.Infos = infos
  233. // 分页
  234. switch {
  235. case reply.Total-int64(offset) <= 0:
  236. reply.Infos = []apis.ProviderServiceFailInfo{}
  237. case reply.Total-int64(offset) <= int64(limit):
  238. reply.Infos = reply.Infos[offset:]
  239. case reply.Total-int64(offset) > int64(limit):
  240. reply.Infos = reply.Infos[offset : offset+limit]
  241. }
  242. return nil
  243. }