123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- // Copyright 2019 getensh.com. All rights reserved.
- // Use of this source code is governed by getensh.com.
- package access_log
- import (
- "context"
- "gd_statistics/apis"
- "gd_statistics/errors"
- "fmt"
- "strconv"
- "github.com/astaxie/beego/orm"
- )
- type ProviderCodeInfoReq struct {
- Start int64
- End int64
- MerchantId int64
- ProviderApiId int64
- OnlyFail bool
- GroupByApi bool
- }
- func getProviderCodeInfoFromHour(o orm.Ormer, req *ProviderCodeInfoReq) ([]TGdProviderCodeHour, error) {
- if req.End <= req.Start {
- return nil, nil
- }
- 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)
- if req.GroupByApi {
- 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)
- }
- if req.ProviderApiId > 0 {
- sql = fmt.Sprintf("%s and provider_api_id=%d", sql, req.ProviderApiId)
- }
- if req.OnlyFail == true {
- sql = fmt.Sprintf("%s and state = 0", sql)
- }
- if req.GroupByApi {
- sql = fmt.Sprintf("%s group by code, msg, provider_api_id", sql)
- } else {
- sql = fmt.Sprintf("%s group by code, msg", sql)
- }
- tabs := []TGdProviderCodeHour{}
- _, err := o.Raw(sql).QueryRows(&tabs)
- if err != nil && err != orm.ErrNoRows {
- return nil, errors.DataBaseError
- }
- return tabs, nil
- }
- func getProviderCodeInfoFromToday(o orm.Ormer, req *ProviderCodeInfoReq) ([]TGdProviderCodeHour, error) {
- 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)
- if req.GroupByApi {
- 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)
- }
- if req.ProviderApiId > 0 {
- sql = fmt.Sprintf("%s and provider_api_id=%d", sql, req.ProviderApiId)
- }
- if req.OnlyFail == true {
- sql = fmt.Sprintf("%s and state = 0", sql)
- }
- if req.GroupByApi {
- sql = fmt.Sprintf("%s group by code, msg, provider_api_id", sql)
- } else {
- sql = fmt.Sprintf("%s group by code, msg", sql)
- }
- tabs := []TGdProviderCodeHour{}
- _, err := o.Raw(sql).QueryRows(&tabs)
- if err != nil && err != orm.ErrNoRows {
- return nil, errors.DataBaseError
- }
- return tabs, nil
- }
- func sumProviderCode(old []TGdProviderCodeHour, today []TGdProviderCodeHour, groupByApi bool) (ret []TGdProviderCodeHour) {
- m := map[string]*TGdProviderCodeHour{}
- for i, v := range old {
- key := fmt.Sprintf("%s-%s", v.Code, v.Msg)
- if groupByApi {
- key = fmt.Sprintf("%s-%s-%d", v.Code, v.Msg, v.ProviderApiId)
- }
- m[key] = &old[i]
- }
- for i, v := range today {
- key := fmt.Sprintf("%s-%s", v.Code, v.Msg)
- if groupByApi {
- key = fmt.Sprintf("%s-%s-%d", v.Code, v.Msg, v.ProviderApiId)
- }
- if _, ok := m[key]; ok == false {
- m[key] = &today[i]
- continue
- }
- m[key].Count += v.Count
- }
- ret = make([]TGdProviderCodeHour, len(m))
- i := 0
- for _, v := range m {
- ret[i] = *v
- i++
- }
- return ret
- }
- func getProviderCodeInfo(req *ProviderCodeInfoReq) ([]TGdProviderCodeHour, error) {
- o := orm.NewOrm()
- maxHour := int64(0)
- err := o.Raw("select max(hour) as max_hour from t_gd_provider_code_hour").QueryRow(&maxHour)
- if err != nil && err != orm.ErrNoRows {
- return nil, errors.DataBaseError
- }
- todayInfos := []TGdProviderCodeHour{}
- if maxHour+3600 < req.End {
- /*
- mreq := *req
- mreq.Start = maxHour + 3600
- todayInfos, err = getProviderCodeInfoFromToday(o, &mreq)
- if err != nil {
- return nil, err
- }
- */
- }
- mreq := *req
- mreq.End = maxHour + 3600
- oldInfos, err := getProviderCodeInfoFromHour(o, &mreq)
- if err != nil {
- return nil, err
- }
- if len(todayInfos) == 0 {
- return oldInfos, nil
- }
- if len(oldInfos) == 0 {
- return todayInfos, nil
- }
- return sumProviderCode(oldInfos, todayInfos, req.GroupByApi), nil
- }
- func getProviderServiceFailInfo(start, end int64) ([]apis.ProviderServiceFailInfo, error) {
- mreq := ProviderCodeInfoReq{}
- mreq.GroupByApi = true
- mreq.Start = start
- mreq.End = end
- mreq.OnlyFail = true
- codeInfos, err := getProviderCodeInfo(&mreq)
- if err != nil {
- return nil, err
- }
- m := map[int64][]*TGdProviderCodeHour{}
- for i, v := range codeInfos {
- m[v.ProviderApiId] = append(m[v.ProviderApiId], &codeInfos[i])
- }
- ret := []apis.ProviderServiceFailInfo{}
- for _, v := range m {
- item := apis.ProviderServiceFailInfo{}
- for _, sub := range v {
- failItem := apis.ProviderServiceFailDetail{}
- item.ProviderApiName = sub.ProviderApiName
- item.ProviderName = sub.ProviderName
- item.Fail += sub.Count
- failItem.Fail = sub.Count
- failItem.Msg = sub.Msg
- failItem.Code = sub.Code
- item.Detail = append(item.Detail, failItem)
- }
- for i, d := range item.Detail {
- if item.Fail == 0 {
- item.Detail[i].Rate = "0%"
- } else {
- item.Detail[i].Rate = strconv.FormatFloat(float64(100*d.Fail/item.Fail), 'f', 2, 64) + "%"
- }
- }
- ret = append(ret, item)
- }
- return ret, nil
- }
- func sortProviderFailDetailInfo(array []apis.ProviderServiceFailDetail) []apis.ProviderServiceFailDetail {
- length := len(array)
- for i := 0; i < length; i++ {
- for j := i + 1; j < length; j++ {
- if array[i].Fail < array[j].Fail {
- tmp := array[i]
- array[i] = array[j]
- array[j] = tmp
- }
- }
- }
- return array
- }
- func sortProviderFailInfo(array []apis.ProviderServiceFailInfo) []apis.ProviderServiceFailInfo {
- length := len(array)
- for i := 0; i < length; i++ {
- for j := i + 1; j < length; j++ {
- if array[i].Fail < array[j].Fail {
- tmp := array[i]
- array[i] = array[j]
- array[j] = tmp
- }
- }
- }
- for i, v := range array {
- array[i].Detail = sortProviderFailDetailInfo(v.Detail)
- }
- return array
- }
- func BiGetProviderServiceFailInfo(ctx context.Context, req *apis.BiGetProviderServiceFailInfoReq, reply *apis.BiGetProviderServiceFailInfoReply) (err error) {
- // 参数预处理
- if req.PageNumber <= 0 {
- req.PageNumber = 1
- }
- if req.PageSize <= 0 {
- req.PageSize = pageSize
- }
- reply.PageNumber = req.PageNumber
- reply.PageSize = req.PageSize
- offset := (req.PageNumber - 1) * req.PageSize
- limit := req.PageSize
- start := int64(0)
- end := int64(0)
- // 今日,昨日,本周,本月
- switch req.TimeType {
- case 0:
- start, end = getTodayTimestamp()
- case 1:
- start, end = getYesterdayTimestamp()
- case 2:
- start, end = getWeekTimestamp()
- case 3:
- start, end = getMonthTimestamp()
- default:
- return errors.ArgsError
- }
- if req.TodayEndTimestamp < end && req.TodayEndTimestamp > 0 {
- end = req.TodayEndTimestamp
- }
- infos, err := getProviderServiceFailInfo(start, end)
- if err != nil {
- return err
- }
- reply.Total = int64(len(infos))
- infos = sortProviderFailInfo(infos)
- reply.Infos = infos
- // 分页
- switch {
- case reply.Total-int64(offset) <= 0:
- reply.Infos = []apis.ProviderServiceFailInfo{}
- case reply.Total-int64(offset) <= int64(limit):
- reply.Infos = reply.Infos[offset:]
- case reply.Total-int64(offset) > int64(limit):
- reply.Infos = reply.Infos[offset : offset+limit]
- }
- return nil
- }
|