log_query_user_access_business_export.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Copyright 2019 getensh.com. All rights reserved.
  2. // Use of this source code is governed by getensh.com.
  3. package crontab
  4. import (
  5. "context"
  6. "gd_crontab/apis"
  7. "gd_crontab/errors"
  8. "gd_crontab/rpc_apis"
  9. "gd_crontab/rpc_apis/gd_management"
  10. "fmt"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "github.com/astaxie/beego/orm"
  15. )
  16. // getBusinessWhereExport 商务报表where子句
  17. func getBusinessWhereExport(req *apis.LogQueryUserAccessBusinessExportReq) (w string, s []interface{}) {
  18. if req.EndTimestamp != 0 && req.StartTimestamp != 0 {
  19. w += " and " + "timestamp >=" + " ? and timestamp < ?"
  20. s = append(s, req.StartTimestamp, req.EndTimestamp)
  21. } else {
  22. nowTime := time.Now()
  23. zeroTime := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, nowTime.Location())
  24. startTimeStamp := zeroTime.Unix()
  25. endTimeStamp := nowTime.Unix()
  26. w += " and " + "timestamp >= " + " ? and timestamp < ?"
  27. s = append(s, startTimeStamp, endTimeStamp)
  28. }
  29. if len(req.ApiIdList) != 0 {
  30. w += " and api_id in (" + strings.Replace(strings.Trim(fmt.Sprint(req.ApiIdList), "[]"), " ", ",", -1) + ")"
  31. }
  32. if req.MerchantId != 0 {
  33. //strings.Replace(strings.Trim(fmt.Sprint(array_or_slice), "[]"), " ", ",", -1)
  34. w += " and " + "merchant_id" + " = ?"
  35. s = append(s, req.MerchantId)
  36. }
  37. if len(s) > 0 {
  38. //有条件才截取最前面的and
  39. w = string([]byte(w)[4:])
  40. w = " where" + w + " and merchant_data_api_id > 0"
  41. return w, s
  42. } else {
  43. return " where merchant_data_api_id > 0", nil
  44. }
  45. }
  46. // getBusinessExportSql 商务报表统计sql
  47. func getBusinessExportSql(req *apis.LogQueryUserAccessBusinessExportReq, where string) string {
  48. sqlStr := "select create_time as date, merchant_name, api_id, merchant_id, group_concat(distinct merchant_data_api_id) as merchant_data_api_id, api_name,count(state) as total ," +
  49. "count(distinct case when (code <> 0 and code <> 1100 and code <> 1107) then search end) as unvalid_unredundant," +
  50. "sum(code<>0 and code <> 1100 and code <> 1107) as unvalid ," +
  51. "sum(code=0) as success," +
  52. "count(distinct case when (code = 1100 or code = 1107) then search end) as norecord_unredundant," +
  53. "count(distinct case when (code <> 0) then search end) as failed_unredundant," +
  54. "count(distinct case when code=1102 then search end) as args_format_error," +
  55. "sum(code=1023) as args_unsupport," +
  56. "sum(raw_code=1100) as no_record, " +
  57. "sum(is_reuse=1 and code=0) as reuse," +
  58. "sum(raw_code=1101 or raw_code = 1108 or raw_code=1109 or raw_code = 1105 or raw_code=1106) as provider_error, " +
  59. "sum(raw_code=1107 or raw_code= 1110) as platform_error" +
  60. " from " + req.TabName + " as a %s group by create_time, merchant_id, api_id order by timestamp"
  61. sqlStr = fmt.Sprintf(sqlStr, where)
  62. return sqlStr
  63. }
  64. // getBusinessCountCodeInfo 获取计费码
  65. func getBusinessCountCodeInfo(req *apis.LogQueryUserAccessBusinessExportReq) (map[string]gd_management.UserMerchantCountCode, []gd_management.UserMerchantCountCode, error) {
  66. mReq := gd_management.MangementGetUserMerchantCountCodeReq{}
  67. mreply, err := rpc_apis.Management.MangementGetUserMerchantCountCode(context.Background(), &mReq)
  68. if err != nil {
  69. return nil,nil, err
  70. }
  71. countMap := make(map[string]gd_management.UserMerchantCountCode, len(mreply.UserMerchantCountCode))
  72. for _, v := range mreply.UserMerchantCountCode {
  73. countMap[strconv.Itoa(int(v.MerchantDataApiId))+strconv.Itoa(int(v.ApiId))] = v
  74. }
  75. return countMap, mreply.UserMerchantCountCode, nil
  76. }
  77. // computeBusinessCharge 计费计算
  78. // 计费方式为即查时,计费量等于总调用量
  79. // 计费方式为查得时,如果计费码为空,计费量为0
  80. // 计费方式为查得时,如果计费码不为空,计费量根据计费码统计
  81. func computeBusinessCharge(req *apis.LogQueryUserAccessBusinessExportReq,
  82. info *apis.LogQueryUserAcessBusinessExport, countMap map[string]gd_management.UserMerchantCountCode) {
  83. sqlStr := ""
  84. mdids := strings.Split(info.MerchantDataApiId, ",")
  85. for _, mdid := range mdids {
  86. v, ok := countMap[mdid+fmt.Sprintf("%d", info.ApiId)]
  87. if ok == false {
  88. continue
  89. }
  90. count := 0
  91. chargeReuseCount := 0
  92. switch {
  93. case v.CountType == 0 && len(mdids) == 1:
  94. chargeReuseCount = info.Reuse
  95. count = info.Total
  96. case v.CountType == 0 && (len(mdids) > 1):
  97. sqlStr = "select count(id), sum(is_reuse) from " + req.TabName + " where merchant_data_api_id = %s and api_id = %d and timestamp >= ? and timestamp < ?"
  98. sqlStr = fmt.Sprintf(sqlStr, mdid, info.ApiId)
  99. start, end := getStartEndTimestamp(req.StartTimestamp, req.EndTimestamp, info.Date)
  100. orm.NewOrm().Raw(sqlStr, start, end).QueryRow(&count, &chargeReuseCount)
  101. default:
  102. if v.CountCode == "" {
  103. count = 0
  104. chargeReuseCount = 0
  105. } else {
  106. if strings.Contains(v.CountCode, "1100") {
  107. v.CountCode = fmt.Sprintf("%s,1105,1106,1107,1108,1109,1110", v.CountCode)
  108. }
  109. start, end := getStartEndTimestamp(req.StartTimestamp, req.EndTimestamp, info.Date)
  110. sqlStr = "select count(id), sum(is_reuse) from " + req.TabName + " where merchant_data_api_id = %s and api_id = %d and raw_code in (%s) and timestamp >= ? and timestamp < ?"
  111. sqlStr = fmt.Sprintf(sqlStr, mdid, info.ApiId, v.CountCode)
  112. orm.NewOrm().Raw(sqlStr, start, end).QueryRow(&count, &chargeReuseCount)
  113. }
  114. }
  115. info.Charge += count
  116. info.ChargeReuse += chargeReuseCount
  117. }
  118. if info.Valid == 0 {
  119. info.ChargeRate = "0%"
  120. } else {
  121. info.ChargeRate = strconv.FormatFloat(float64(100*info.Charge)/float64(info.Valid), 'f', 2, 64) + "%"
  122. }
  123. info.ChargeRate = computeBusinessPercent(float64(info.Charge), float64(info.Valid))
  124. info.ChargeReuseRate = computeBusinessPercent(float64(info.ChargeReuse), float64(info.Charge))
  125. }
  126. // 设置默认统计时间段
  127. func setBusinessSearchTimestamp(req *apis.LogQueryUserAccessBusinessExportReq) {
  128. if req.EndTimestamp == 0 || req.StartTimestamp == 0 {
  129. nowTime := time.Now()
  130. zeroTime := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, nowTime.Location())
  131. req.StartTimestamp = zeroTime.Unix()
  132. req.EndTimestamp = nowTime.Unix()
  133. }
  134. }
  135. // computeBusinessTimeout 计算超时信息
  136. func computeBusinessTimeout(info *apis.LogQueryUserAcessBusinessExport, timeoutInfo map[string]int, tabname string) {
  137. mdids := strings.Split(info.MerchantDataApiId, ",")
  138. info.TimeoutConf = "0s"
  139. for _, mdid := range mdids {
  140. count := 0
  141. if t, ok := timeoutInfo[mdid+fmt.Sprintf("%d", info.ApiId)]; ok {
  142. if t > 0 {
  143. if info.TimeoutConf == "0s" {
  144. info.TimeoutConf = fmt.Sprintf("%ds", t)
  145. } else {
  146. info.TimeoutConf = fmt.Sprintf("%s,%ds", t, info.TimeoutConf)
  147. }
  148. sqlStr := "select count(id) from " + tabname + " where merchant_data_api_id = %s and api_id = %d and elapsed >= %d and create_time = ?"
  149. sqlStr = fmt.Sprintf(sqlStr, mdid, info.ApiId, t)
  150. orm.NewOrm().Raw(sqlStr, info.Date).QueryRow(&count)
  151. }
  152. }
  153. info.TimeoutCount += count
  154. }
  155. info.TimeoutRate = computeBusinessPercent(float64(info.TimeoutCount), float64(info.Total))
  156. }
  157. // computeBusinessPercent 计算百分率,参数依次为分子和分母
  158. func computeBusinessPercent(Numerator float64, denominator float64) string {
  159. if denominator == 0 {
  160. return "0.00%"
  161. }
  162. return strconv.FormatFloat(100.0*Numerator/denominator, 'f', 2, 64) + "%"
  163. }
  164. func logQueryUserAccessBusinessExport(req *apis.LogQueryUserAccessBusinessExportReq, reply *apis.LogQueryUserAccessBusinessExportReply, noShowMap map[int64]bool, timeoutInfo map[string]int, countMap map[string]gd_management.UserMerchantCountCode) error {
  165. // 查询
  166. where, val := getBusinessWhereExport(req)
  167. sqlStr := getBusinessExportSql(req, where)
  168. o := orm.NewOrm()
  169. _, err := o.Raw(sqlStr, val).QueryRows(&reply.LogQueryUserAcessBusiness)
  170. if err != nil && err != orm.ErrNoRows {
  171. return errors.DataBaseError
  172. }
  173. // 计算指标
  174. for index, info := range reply.LogQueryUserAcessBusiness {
  175. // 无效中的重复调用
  176. reply.LogQueryUserAcessBusiness[index].UnvalidRedundant = info.Unvalid - info.UnvalidUnredundant
  177. // 去重调用
  178. reply.LogQueryUserAcessBusiness[index].DistinctCount = info.Success + reply.LogQueryUserAcessBusiness[index].FailedUnredundant
  179. // 有效调用
  180. reply.LogQueryUserAcessBusiness[index].Valid = reply.LogQueryUserAcessBusiness[index].Success + info.NorecordUnredundant
  181. // 有效率
  182. reply.LogQueryUserAcessBusiness[index].ValidRate = computeBusinessPercent(float64(reply.LogQueryUserAcessBusiness[index].Valid), float64(info.Total))
  183. computeBusinessCharge(req, &reply.LogQueryUserAcessBusiness[index], countMap)
  184. computeBusinessTimeout(&reply.LogQueryUserAcessBusiness[index], timeoutInfo, req.TabName)
  185. }
  186. countMap = nil
  187. noShowMap = nil
  188. timeoutInfo = nil
  189. return nil
  190. }
  191. // LogQueryUserAccessBusinessExport 商务报表统计
  192. func LogQueryUserAccessBusinessExport(req *apis.LogQueryUserAccessBusinessExportReq, reply *apis.LogQueryUserAccessBusinessExportReply) error {
  193. setBusinessSearchTimestamp(req)
  194. showInfo,err := getNotShow()
  195. if err != nil {
  196. return err
  197. }
  198. timeoutInfo,err := getTimeoutInfo()
  199. if err != nil {
  200. return err
  201. }
  202. countCodeInfo, _, err := getBusinessCountCodeInfo(req)
  203. if err != nil {
  204. return err
  205. }
  206. if req.TabName == "t_gd_access_log_day" {
  207. return logQueryUserAccessBusinessExport(req, reply, showInfo, timeoutInfo, countCodeInfo)
  208. }
  209. exportTimes := getExportTimes(req.StartTimestamp, req.EndTimestamp)
  210. for _, v := range exportTimes {
  211. req.StartTimestamp = v.start
  212. req.EndTimestamp = v.end
  213. req.TabName = getMonthTab("t_gd_access_log_month", req.StartTimestamp)
  214. subReply := &apis.LogQueryUserAccessBusinessExportReply{}
  215. err := logQueryUserAccessBusinessExport(req, subReply, showInfo, timeoutInfo, countCodeInfo)
  216. if err != nil {
  217. return err
  218. }
  219. reply.LogQueryUserAcessBusiness = append(reply.LogQueryUserAcessBusiness, subReply.LogQueryUserAcessBusiness...)
  220. }
  221. return nil
  222. }