123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- package service
- import (
- "context"
- "encoding/json"
- "math"
- "sort"
- "strconv"
- "strings"
- "time"
- "go-common/app/admin/ep/melloi/conf"
- "go-common/app/admin/ep/melloi/model"
- "go-common/library/log"
- )
- // QueryReportSummarys query report summary
- func (s *Service) QueryReportSummarys(c context.Context, sessionID string, qrsr *model.QueryReportSuRequest) (qrs *model.QueryReportSuResponse, err error) {
- // 获取服务树节点
- var treeNodes, treeNodesd []string
- if treeNodesd, err = s.QueryUserRoleNode(c, sessionID); err != nil {
- log.Error("QueryUserRoleNode (%v): ", err)
- return
- }
- treeNodes = append(treeNodesd, "")
- if ExistsInSlice(qrsr.Executor, conf.Conf.Melloi.Executor) {
- if qrs, err = s.dao.QueryReportSummarysWhiteName(&qrsr.ReportSummary, qrsr.SearchAll, qrsr.PageNum, qrsr.PageSize); err != nil {
- return
- }
- } else {
- if qrs, err = s.dao.QueryReportSummarys(&qrsr.ReportSummary, qrsr.SearchAll, qrsr.PageNum, qrsr.PageSize, treeNodes); err != nil {
- return
- }
- }
- // 获取label
- for _, report := range qrs.ReportSummarys {
- lr := model.LabelRelation{Type: model.ReportType, TargetID: int64(report.ID)}
- if report.Labels, err = s.dao.QueryLabelRelation(&lr); err != nil {
- return
- }
- }
- return
- }
- // QueryReportByID Query Report By ID
- func (s *Service) QueryReportByID(id int) (summary *model.ReportSummary, err error) {
- return s.dao.QueryReportSuryByID(id)
- }
- // CountQueryReportSummarys count query report summarys
- func (s *Service) CountQueryReportSummarys(reportSummary *model.ReportSummary) (int, error) {
- return s.dao.CountQueryReportSummarys(reportSummary)
- }
- // UpdateReportSummary update report summary
- func (s *Service) UpdateReportSummary(reportSummary *model.ReportSummary) (status string, err error) {
- if err = s.dao.UpdateReportSummary(reportSummary); err != nil {
- status = "update fail"
- return
- }
- status = "success"
- return
- }
- // UpdateReportStatus update report summary status
- func (s *Service) UpdateReportStatus(status int) error {
- return s.dao.UpdateReportStatus(status)
- }
- // AddReSummaryByPtest Add ReSummary By Ptest
- func (s *Service) AddReSummaryByPtest(ptestParam model.DoPtestParam, jobName, executeID string, testNameNicks []string, snapID, Debug int) (reportSuID int, err error) {
- reportSummary := model.ReportSummary{
- JobName: jobName,
- TestStatus: 2,
- UserName: ptestParam.UserName,
- ResJtl: ptestParam.ResJtl,
- JmeterLog: ptestParam.JmeterLog,
- Department: ptestParam.Department,
- Project: ptestParam.Project,
- APP: ptestParam.APP,
- ScriptID: ptestParam.ScriptID,
- DockerSum: 1,
- Active: 1,
- Debug: Debug,
- ScriptSnapID: snapID,
- ExecuteID: executeID,
- SceneID: ptestParam.SceneID,
- Type: ptestParam.Type,
- LoadTime: ptestParam.LoadTime,
- }
- //Upload==true,这里表示从前端上传的脚本,testNames 和 testNameNicks 长度可能大于1,需要遍历,写入 reportSummary
- if ptestParam.Upload {
- reportSummary.TestNameNick = SliceToString(testNameNicks, ",")
- reportSummary.TestName = ptestParam.ProjectName
- reportSummary.Type = model.PROTOCOL_SCENE
- }
- // 从页面上直接输入参数生成的单场景脚本,testNames 和 testNameNicks 长度都是 1
- // 生成的场景脚本,ptestParam.TestNameNick 不为空
- if !ptestParam.Upload {
- for _, testName := range ptestParam.TestNames {
- reportSummary.TestNameNick = QueryTestNameNick(testName, testNameNicks)
- reportSummary.TestName = testName
- }
- //场景脚本的 reportSummary 逻辑
- if ptestParam.Type == model.PROTOCOL_SCENE && ptestParam.TestNameNick != "" {
- reportSummary.TestNameNick = ptestParam.TestNameNick
- reportSummary.TestName = ptestParam.SceneName
- }
- }
- if reportSuID, err = s.dao.AddReportSummary(&reportSummary); err != nil {
- log.Error("s.dao.AddReportSummary err :(%v)", err)
- return
- }
- return
- }
- // AddReportSummary add report summary
- func (s *Service) AddReportSummary(reportSummary *model.ReportSummary) (status string, reportSuID int, err error) {
- var total int
- if total, err = s.dao.CountQueryReportSummarys(reportSummary); err != nil {
- log.Error("CountQueryReportSummarys error:(%v)", err)
- status = "fail"
- return
- }
- if (total == 1) || (reportSummary.TestName == "") {
- status = "数据已存在或者无接口名"
- } else {
- if reportSuID, err = s.dao.AddReportSummary(reportSummary); err != nil {
- status = "fail"
- return
- }
- status = "success"
- }
- return
- }
- // QueryReGraph query reGraph
- func (s *Service) QueryReGraph(testNameNicks []string) (reportGraphssd [][]model.ReportGraph, err error) {
- var (
- TestNames []string
- reportGraphss []model.ReportGraph
- reportGraphs []model.ReportGraph
- )
- if reportGraphs, err = s.dao.QueryReportGraph(testNameNicks); err != nil {
- log.Error("dao.QueryReportGraph error:(%v)", err)
- return
- }
- if len(reportGraphs) > 0 {
- for _, reportGraph := range reportGraphs {
- TestNames = append(TestNames, reportGraph.TestName)
- }
- TestNamesd := RemoveRepByMap(TestNames)
- for _, testName := range TestNamesd {
- for _, reportGraph := range reportGraphs {
- if reportGraph.TestName == testName {
- reportGraphss = append(reportGraphss, reportGraph)
- }
- }
- reportGraphssd = append(reportGraphssd, reportGraphss)
- reportGraphss = []model.ReportGraph{}
- }
- }
- return
- }
- // QueryClientMoni query client moni
- func (s *Service) QueryClientMoni(cli *model.ClientMoni) (clientMonisd [][]*model.ClientMoni, err error) {
- var (
- jobNames []string
- clientMoniss []*model.ClientMoni
- clientMonis []*model.ClientMoni
- )
- if clientMonis, err = s.dao.QueryClientMoni(cli); err != nil {
- log.Error("dao.QueryClientMoni error:(%v)", err)
- return
- }
- if len(clientMonis) > 0 {
- for _, clientMoni := range clientMonis {
- jobNames = append(jobNames, clientMoni.JobName)
- }
- jobNamesd := RemoveRepByMap(jobNames)
- for _, jobNamed := range jobNamesd {
- for _, clientMoni := range clientMonis {
- if clientMoni.JobName == jobNamed {
- clientMoniss = append(clientMoniss, clientMoni)
- }
- }
- clientMonisd = append(clientMonisd, clientMoniss)
- clientMoniss = []*model.ClientMoni{}
- }
- }
- return
- }
- //QueryReGraphAvg query reGraph
- func (s *Service) QueryReGraphAvg(testNameNicks []string) (reportGraphAvgs []model.ReportGraph, err error) {
- var reportGraphssd [][]model.ReportGraph
- if reportGraphssd, err = s.QueryReGraph(testNameNicks); err != nil {
- log.Error("QueryReGraph error :(%s)", err)
- return
- }
- for _, reportGraphsd := range reportGraphssd {
- reportGraph := ReportGraphAvg(reportGraphsd)
- reportGraphAvgs = append(reportGraphAvgs, reportGraph)
- }
- return
- }
- //ReportGraphAvg report graph avg
- func ReportGraphAvg(reportGraphs []model.ReportGraph) (reportGraph model.ReportGraph) {
- var sumTime, sumQPS, sumNetIo, min, max, sumCount, sumError, sumCodeEll, sumCodeWll, sumCodeWly, sumCodeWle, sumCodeWls,
- sumCodeSll, sumCodeSly, sumCodeSls, sumCodeKong, sumCodeNonHTTP, sumCodeOthers, fiftyTime, ninetyTime, ninetyFiveTime,
- ninetyNineTime, sumCode301, sumCode302, timeCount, sumQPSRecent, QPSRecent int
- var mins, maxs []int
- if len(reportGraphs) > 0 {
- for _, reportGraph := range reportGraphs {
- mins = append(mins, reportGraph.Min)
- maxs = append(maxs, reportGraph.Max)
- sumCount = sumCount + reportGraph.Count
- timeCount = reportGraph.Count * reportGraph.AvgTime
- sumTime = sumTime + timeCount
- sumError = sumError + reportGraph.Error
- sumQPS = sumQPS + reportGraph.QPS
- sumNetIo = sumNetIo + reportGraph.NetIo
- sumCodeEll = sumCodeEll + reportGraph.CodeEll
- sumCodeWll = sumCodeWll + reportGraph.CodeWll
- sumCodeWly = sumCodeWly + reportGraph.CodeWly
- sumCodeWle = sumCodeWle + reportGraph.CodeWle
- sumCodeWls = sumCodeWls + reportGraph.CodeWls
- sumCodeSll = sumCodeSll + reportGraph.CodeSll
- sumCodeSly = sumCodeSly + reportGraph.CodeSly
- sumCodeSls = sumCodeSls + reportGraph.CodeSls
- sumCodeKong = sumCodeKong + reportGraph.CodeKong
- sumCode301 = sumCode301 + reportGraph.Code301
- sumCode302 = sumCode302 + reportGraph.Code302
- sumCodeNonHTTP = sumCodeNonHTTP + reportGraph.CodeNonHTTP
- sumCodeOthers = sumCodeOthers + reportGraph.CodeOthers
- fiftyTime = fiftyTime + reportGraph.FiftyTime
- ninetyTime = ninetyTime + reportGraph.NinetyTime
- ninetyFiveTime = ninetyFiveTime + reportGraph.NinetyFiveTime
- ninetyNineTime = ninetyNineTime + reportGraph.NinetyNineTime
- }
- // 取最后 recent次统计的平均 qps,作为最近一段时间的qps
- recent := conf.Conf.Melloi.Recent
- if len(reportGraphs) > recent {
- for i := 1; i <= recent; i++ {
- sumQPSRecent += reportGraphs[len(reportGraphs)-i].QPS
- QPSRecent = sumQPSRecent / recent
- }
- } else {
- QPSRecent = sumQPS / len(reportGraphs)
- }
- if len(mins) != 0 {
- sort.Ints(mins)
- min = mins[0]
- sort.Ints(maxs)
- max = maxs[len(maxs)-1]
- }
- failPercentd := float64(sumError) * 100 / float64(sumCount)
- n10 := math.Pow10(3)
- fail := math.Trunc((failPercentd+0.5/n10)*n10) / n10
- failStr := strconv.FormatFloat(fail, 'f', -1, 64)
- failPercent := failStr + "%"
- num := len(reportGraphs)
- reportGraph = model.ReportGraph{
- TestName: reportGraphs[0].TestName, TestNameNick: reportGraphs[0].TestNameNick, Max: max, Min: min, Count: sumCount, Error: sumError,
- NetIo: sumNetIo / num, QPS: sumQPS / num, AvgTime: sumTime / sumCount, Ctime: reportGraphs[len(reportGraphs)-1].Ctime,
- CodeEll: sumCodeEll, CodeSll: sumCodeSll, CodeSly: sumCodeSly, CodeSls: sumCodeSls, CodeWll: sumCodeWll, CodeWly: sumCodeWly,
- CodeWle: sumCodeWle, CodeWls: sumCodeWls, CodeNonHTTP: sumCodeNonHTTP, CodeKong: sumCodeKong, CodeOthers: sumCodeOthers,
- FailPercent: failPercent, FiftyTime: fiftyTime / num, NinetyTime: ninetyTime / num, NinetyFiveTime: ninetyFiveTime / num,
- NinetyNineTime: ninetyNineTime / num, Code301: sumCode301, Code302: sumCode302, BeginTime: reportGraphs[0].Ctime, QpsRecent: QPSRecent,
- }
- }
- return
- }
- //addReGraphTimer add regraph timer
- func (s *Service) addReGraphTimer(c context.Context, addReGrapht model.AddReGraphTimer, res chan interface{}, timeout <-chan time.Time) {
- var (
- status = 1
- reportSummary model.ReportSummary
- testNamesd []string
- podNames []string
- beginTimed string
- afterTimed string
- beginTime = addReGrapht.BeginTime
- testNames = addReGrapht.TestNames
- jobName = addReGrapht.JobName
- token = addReGrapht.Token
- testNameNicks = addReGrapht.TestNameNicks
- RetMap *model.PaasJobQueryStatus
- scriptID = addReGrapht.ScriptID
- reportSuID = addReGrapht.ReportSuID
- ptestJobs []*model.PtestJob
- err error
- btm time.Time
- firstRetMap *model.PaasJobQueryStatus
- reportGraphs []model.ReportGraph
- JSON []byte
- fusingList = addReGrapht.FusingList
- useBusiStopList = addReGrapht.UseBusiStopList
- busiStopPercentList = addReGrapht.BusiStopPercentList
- )
- timer := time.NewTicker(5 * time.Second)
- done := make(chan bool, 1)
- num := 1
- go func() {
- defer close(res)
- a := 1
- for {
- if btm, err = time.Parse("2006-01-02 15:04:05", beginTime); err != nil {
- timeout = time.After(time.Until(time.Now().Add(1 * time.Second)))
- return
- }
- select {
- case <-timer.C:
- elapsedTime := (num - 1) * 5
- //实时当前任务的所有容器
- if ptestJobs, err = s.QueryOrStopAllPtestByJobName(context.TODO(), reportSuID, false, 3); err != nil {
- log.Error("get all Job err (%v)", err)
- }
- //遍历容器,并查询每个容器的cpu
- if len(ptestJobs) > 0 {
- for _, ptestJob := range ptestJobs {
- if RetMap, err = s.dao.Job(c, token, ptestJob.JobName); err != nil {
- log.Error("get job info err (%v)", err)
- }
- if RetMap != nil && len(RetMap.Data.Pods) > 0 {
- for _, pod := range RetMap.Data.Pods {
- podNames = append(podNames, pod.Name)
- log.Info("containerID :(%s)", pod.ContainerID)
- go s.addJobCPU(context.TODO(), pod, scriptID, reportSuID, elapsedTime, ptestJob.JobName)
- }
- }
- }
- }
- log.Info("podName :(%s)", podNames)
- if firstRetMap, err = s.dao.Job(c, token, jobName); err != nil {
- log.Error("查询容器状态 error-------(%v)", err)
- //接口报错,则删除所有压测容器
- timeout = time.After(time.Until(time.Now().Add(1 * time.Second)))
- return
- }
- if JSON, err = json.Marshal(firstRetMap); err != nil {
- timeout = time.After(time.Until(time.Now().Add(1 * time.Second)))
- }
- result := string(JSON)
- log.Info("查询容器状态:(%s)", result)
- if firstRetMap.Status == 400 {
- status = 3
- timeout = time.After(time.Until(time.Now().Add(1 * time.Second)))
- }
- if firstRetMap.Status == 200 && firstRetMap.Data.ActiveNum == 1 {
- log.Info("第(%d)次同步数据", a)
- if num == 1 {
- log.Info("job 执行参数 testName:(%s), beginTime :(%s),elapsedTime :(%d), num: (%d)", testNames, beginTime, elapsedTime, num)
- for index, testName := range testNames {
- testNameNick := QueryTestNameNick(testName, testNameNicks)
- reportGraphAdd := model.ReportGraphAdd{
- JobName: jobName,
- TestName: testName,
- BeginTime: beginTime,
- AfterTime: beginTime,
- TestNameNick: testNameNick,
- PodNames: podNames,
- ElapsedTime: elapsedTime,
- ReportSuID: reportSuID,
- UseBusinessStop: addReGrapht.UseBusinessStop,
- BusinessStopPercent: addReGrapht.BusinessStopPercent,
- }
- if addReGrapht.TestType == model.PROTOCOL_SCENE {
- reportGraphAdd.Fusing = fusingList[index]
- reportGraphAdd.UseBusinessStop = useBusiStopList[index]
- reportGraphAdd.BusinessStopPercent = busiStopPercentList[index]
- } else {
- reportGraphAdd.Fusing = addReGrapht.Fusing
- }
- go s.addReportGraph(context.TODO(), reportGraphAdd)
- }
- } else {
- for i := 1; i <= num-1; i++ {
- btm = btm.Add(time.Second * 5)
- aft := btm.Add(time.Second * 2)
- beginTimed = btm.Format("2006-01-02 15:04:05")
- afterTimed = aft.Format("2006-01-02 15:04:05")
- }
- log.Info("job 执行参数 testName:(%s),beginTime :(%s),elapsedTime :(%d)", testNames, beginTimed, elapsedTime)
- for index, testName := range testNames {
- testNameNick := QueryTestNameNick(testName, testNameNicks)
- reportGraphAdd := model.ReportGraphAdd{
- JobName: jobName,
- TestName: testName,
- BeginTime: beginTimed,
- AfterTime: afterTimed,
- TestNameNick: testNameNick,
- PodNames: podNames,
- ElapsedTime: elapsedTime,
- ReportSuID: reportSuID,
- UseBusinessStop: addReGrapht.UseBusinessStop,
- BusinessStopPercent: addReGrapht.BusinessStopPercent,
- }
- if addReGrapht.TestType == model.PROTOCOL_SCENE {
- reportGraphAdd.Fusing = fusingList[index]
- reportGraphAdd.UseBusinessStop = useBusiStopList[index]
- reportGraphAdd.BusinessStopPercent = busiStopPercentList[index]
- } else {
- reportGraphAdd.Fusing = addReGrapht.Fusing
- }
- go s.addReportGraph(context.TODO(), reportGraphAdd)
- }
- }
- }
- podNames = []string{}
- if firstRetMap.Status == 200 && firstRetMap.Data.ActiveNum == 0 {
- timeout = time.After(time.Until(time.Now().Add(1 * time.Second)))
- }
- num++
- res <- a
- a++
- case <-timeout:
- close(done)
- log.Info("real stop time (%s)", time.Now().Format("2006-01-02 15:04:05"))
- // 关闭所有压测该项目或者接口的容器
- go s.QueryOrStopAllPtestByJobName(context.TODO(), reportSuID, true, status)
- if reportGraphs, err = s.dao.QueryReportGraph(testNameNicks); err != nil {
- log.Error("query reportGraphs error :(%v) ", err)
- return
- }
- for _, reportGraph := range reportGraphs {
- testNamesd = append(testNames, reportGraph.TestName)
- }
- // 如果reportGraphs 的成员都是同一个testName ,则执行如下代码,表示进行结果合并,生成 reportSummary
- if IsUniqObject(testNamesd) {
- if len(reportGraphs) > 0 {
- reportGraph := ReportGraphAvg(reportGraphs)
- reportSummary = model.ReportSummary{
- ID: reportSuID,
- TestName: reportGraph.TestName,
- TestNameNick: reportGraph.TestNameNick,
- Count: reportGraph.Count,
- Error: reportGraph.Error,
- QPS: reportGraph.QPS,
- AvgTime: reportGraph.AvgTime,
- NetIo: reportGraph.NetIo,
- Min: reportGraph.Min,
- Max: reportGraph.Max,
- }
- reportSummary.TestStatus = status
- } else {
- log.Info("sorry,your test duration is too short ..... ")
- reportSummary = model.ReportSummary{ID: reportSuID, TestStatus: 3}
- }
- s.dao.UpdateReportSummary(&reportSummary)
- }
- //场景压测、多个接口走该逻辑
- if !IsUniqObject(testNamesd) && len(testNameNicks) > 0 {
- if len(reportGraphs) > 0 {
- reportSummary = model.ReportSummary{ID: reportSuID, TestStatus: status}
- } else {
- reportSummary = model.ReportSummary{ID: reportSuID, TestStatus: 3}
- }
- }
- s.dao.UpdateReportSummary(&reportSummary)
- return
- }
- }
- }()
- <-done
- }
- //addPtestJobHostIp add regraph timer
- func (s *Service) addPtestJobHostIp(c context.Context, addReGrapht model.AddReGraphTimer, res chan interface{}, timeout <-chan time.Time) {
- var (
- RetMap *model.PaasJobQueryStatus
- token = addReGrapht.Token
- err error
- ptestJobs []*model.PtestJob
- ptestJobsd []*model.PtestJob
- firstRetMap *model.PaasJobQueryStatus
- )
- timer := time.NewTicker(10 * time.Second)
- done := make(chan bool, 1)
- go func() {
- defer close(res)
- a := 1
- for {
- select {
- case <-timer.C:
- if firstRetMap, err = s.dao.Job(c, token, addReGrapht.JobName); err != nil {
- log.Error("查询容器状态 error-------(%v)", err)
- //接口报错,则删除所有压测容器
- return
- }
- if firstRetMap == nil || firstRetMap.Status == 400 || (firstRetMap.Status == 200 && firstRetMap.Data.ActiveNum == 0) {
- return
- }
- ptestJob := model.PtestJob{ReportSuID: addReGrapht.ReportSuID, Active: 1}
- if ptestJobs, err = s.dao.QueryPtestJob(&ptestJob); err != nil {
- return
- }
- for _, job := range ptestJobs {
- if job.HostIP == "" || job.JobIP == "" || job.JobID == "" {
- ptestJobsd = append(ptestJobsd, job)
- }
- }
- if len(ptestJobsd) > 0 {
- for _, ptestJob := range ptestJobsd {
- //查询容器状态
- if RetMap, err = s.dao.Job(c, token, ptestJob.JobName); err != nil {
- log.Error("get job info err (%v)", err)
- }
- if RetMap != nil && len(RetMap.Data.Pods) > 0 {
- for _, pod := range RetMap.Data.Pods {
- ptestjo := model.PtestJob{ID: ptestJob.ID, HostIP: pod.HostIP, JobID: pod.ContainerID, JobIP: pod.IP}
- //更新容器hostIp
- s.dao.UpdatePtestJob(ptestjo)
- }
- }
- }
- }
- res <- a
- a++
- case <-timeout:
- close(done)
- return
- }
- }
- }()
- <-done
- }
- //addJobCPU job cpu
- func (s *Service) addJobCPU(c context.Context, pod model.PodInfo, scriptID, reportSuID, elapsedTime int, jobName string) (err error) {
- var (
- clientMoni = model.ClientMoni{
- ScriptID: scriptID,
- ReportSuID: reportSuID,
- JobName: jobName,
- JobNameAll: pod.Name,
- ElapsdTime: elapsedTime,
- }
- dockerStats *model.DockerStats
- CPUResult *model.PaasQueryJobCPUResult
- )
- //首先查我们自己的容器cpu 获取服务
- if pod.ContainerID != "" {
- if dockerStats, err = s.QueryJobCPUByEP(context.TODO(), pod.ContainerID, pod.HostIP); err != nil {
- log.Error("query CPU err ...(%s)", err)
- }
- if dockerStats != nil && dockerStats.CPU != "" {
- cpu := strings.Replace(dockerStats.CPU, "%", "", 1)
- cpufloat, _ := strconv.ParseFloat(cpu, 32)
- cpuFinal := cpufloat
- cpuString := strconv.FormatFloat(cpuFinal, 'f', -1, 32)
- clientMoni.CPUUsed = cpuString
- }
- if dockerStats == nil || dockerStats.CPU == "" {
- //如果我们的服务挂了,就查 moni
- if CPUResult, err = s.QueryJobCPU(context.TODO(), pod.Name); err != nil {
- log.Error("query client cpu err(%v)", err)
- return
- }
- if len(CPUResult.Data) > 0 {
- for _, data := range CPUResult.Data {
- if len(data.Value) > 1 {
- clientMoni.CPUUsed = data.Value[1].(string)
- }
- }
- }
- }
- }
- //cpu 信息记录到数据库
- if _, err = s.AddClientMoni(&clientMoni); err != nil {
- log.Error("add ClientMoni err(%v)", err)
- return
- }
- return
- }
- //addReportGraph add reportGraph
- func (s *Service) addReportGraph(c context.Context, reportGraphAdd model.ReportGraphAdd) {
- var (
- sumTime, sumQPS, sumNetIo, sumCodeEll, sumCodeWll, sumCodeWly, sumCodeWle, sumCodeWls, sumCodeSll, sumCodeSly, sumCodeSls,
- sumCodeKong, sumCodeNonHTTP, sumCodeOthers, sumCount, sumError, sumThreads, fiftyTime, ninetyTime, ninetyFiveTime,
- timeCount, ninetyNineTime, sumCode301, sumCode302 int
- mins, maxs []int
- reportTimelys []*model.ReportTimely
- err error
- )
- busiStopPerc := reportGraphAdd.BusinessStopPercent
- if reportTimelys, err = s.dao.QueryReTimely(reportGraphAdd.TestName, reportGraphAdd.BeginTime, reportGraphAdd.AfterTime, reportGraphAdd.PodNames); err != nil {
- return
- }
- log.Info("------reportTimelys:(%v)", reportTimelys)
- if len(reportTimelys) > 0 {
- for _, reportTimely := range reportTimelys {
- mins = append(mins, reportTimely.Min)
- maxs = append(maxs, reportTimely.Max)
- sumCount = sumCount + reportTimely.Count
- //计算一个容器的接口响应总时间
- timeCount = reportTimely.Count * reportTimely.AvgTime
- //计算所有容器的接口响应时间
- sumTime = sumTime + timeCount
- sumQPS = sumQPS + reportTimely.QPS
- sumError = sumError + reportTimely.Error
- sumNetIo = sumNetIo + reportTimely.NetIo
- sumCodeEll = sumCodeEll + reportTimely.CodeEll
- sumCodeWll = sumCodeWll + reportTimely.CodeWll
- sumCodeWly = sumCodeWly + reportTimely.CodeWly
- sumCodeWle = sumCodeWle + reportTimely.CodeWle
- sumCodeWls = sumCodeWls + reportTimely.CodeWls
- sumCodeSll = sumCodeSll + reportTimely.CodeSll
- sumCodeSly = sumCodeSly + reportTimely.CodeSly
- sumCodeSls = sumCodeSls + reportTimely.CodeSls
- sumCodeKong = sumCodeKong + reportTimely.CodeKong
- sumCodeNonHTTP = sumCodeNonHTTP + reportTimely.CodeNonHTTP
- sumCodeOthers = sumCodeOthers + reportTimely.CodeOthers
- sumCode301 = sumCode301 + reportTimely.Code301
- sumCode302 = sumCode302 + reportTimely.Code302
- sumThreads = sumThreads + reportTimely.ThreadsSum
- fiftyTime = fiftyTime + reportTimely.FiftyTime
- ninetyTime = ninetyTime + reportTimely.NinetyTime
- ninetyFiveTime = ninetyFiveTime + reportTimely.NinetyFiveTime
- ninetyNineTime = ninetyNineTime + reportTimely.NinetyNineTime
- }
- sort.Ints(mins)
- min := mins[0]
- sort.Ints(maxs)
- max := maxs[len(maxs)-1]
- log.Info("test_nick_name ----- :(%s)", reportGraphAdd.TestNameNick)
- reportGraph := model.ReportGraph{
- TestName: reportGraphAdd.TestName, TestNameNick: reportGraphAdd.TestNameNick,
- Count: sumCount,
- QPS: sumQPS,
- Error: sumError,
- AvgTime: sumTime / sumCount,
- NetIo: sumNetIo,
- Min: min,
- Max: max,
- ElapsdTime: reportGraphAdd.ElapsedTime,
- CodeEll: sumCodeEll,
- CodeWll: sumCodeWll,
- CodeWly: sumCodeWly,
- CodeWle: sumCodeWle,
- CodeWls: sumCodeWls,
- CodeSll: sumCodeSll,
- CodeSly: sumCodeSly,
- CodeSls: sumCodeSls,
- CodeKong: sumCodeKong,
- CodeNonHTTP: sumCodeNonHTTP,
- CodeOthers: sumCodeOthers,
- ThreadsSum: sumThreads,
- FiftyTime: fiftyTime / len(reportTimelys),
- NinetyTime: ninetyTime / len(reportTimelys),
- NinetyFiveTime: ninetyFiveTime / len(reportTimelys),
- NinetyNineTime: ninetyNineTime / len(reportTimelys),
- Code301: sumCode301,
- Code302: sumCode302,
- }
- suCodeRate, suBusinessRate := CalcuSuccess(reportGraph)
- if reportGraphAdd.Fusing == 0 {
- reportGraphAdd.Fusing = conf.Conf.Melloi.DefaultFusing
- }
- //压测熔断
- //使用业务熔断,只要http code 和 业务断言错误满足一条阈值,则熔断
- if reportGraphAdd.UseBusinessStop {
- if busiStopPerc == 0 {
- busiStopPerc = conf.Conf.Melloi.DefaultBusinessRate
- }
- if suCodeRate < reportGraphAdd.Fusing || suBusinessRate < busiStopPerc {
- log.Info("接口失败率超过设置阈值,执行自动熔断,jobName :(%s)", reportGraphAdd.JobName)
- if _, err = s.DeleteJob(c, reportGraphAdd.JobName); err != nil {
- return
- }
- reportsu := model.ReportSummary{ID: reportGraphAdd.ReportSuID, IsFusing: true, BusinessValue: busiStopPerc, UseBusinessStop: reportGraphAdd.UseBusinessStop,
- FusingTestName: reportGraphAdd.TestName, SuccessCodeRate: suCodeRate, SuccessBusinessRate: suBusinessRate, FusingValue: reportGraphAdd.Fusing}
- s.dao.UpdateReportSummary(&reportsu)
- }
- } else { //不使用业务熔断
- if suCodeRate < reportGraphAdd.Fusing {
- log.Info("接口失败率超过设置阈值,执行自动熔断,jobName :(%s)", reportGraphAdd.JobName)
- if _, err = s.DeleteJob(c, reportGraphAdd.JobName); err != nil {
- return
- }
- reportsu := model.ReportSummary{ID: reportGraphAdd.ReportSuID, IsFusing: true, BusinessValue: busiStopPerc,
- FusingTestName: reportGraphAdd.TestName, SuccessCodeRate: suCodeRate, SuccessBusinessRate: suBusinessRate, FusingValue: reportGraphAdd.Fusing}
- s.dao.UpdateReportSummary(&reportsu)
- }
- }
- s.dao.AddReportGraph(&reportGraph)
- return
- }
- }
- //CalcuSuccess calcu success
- func CalcuSuccess(reportGraph model.ReportGraph) (successCodeRate, successBusinessRate int) {
- success := reportGraph.CodeEll + reportGraph.CodeKong + reportGraph.Code301 + reportGraph.Code302
- successCodeRate = success * 100 / reportGraph.Count
- successBusinessRate = (reportGraph.Count - reportGraph.Error) * 100 / reportGraph.Count
- return
- }
- // DelReportSummary delete report summary
- func (s *Service) DelReportSummary(id int) error {
- return s.dao.DelReportSummary(id)
- }
|