package robot import ( "fmt" "go_dreamfactory/lego/core" "go_dreamfactory/lego/core/cbase" "os" "sort" "sync" "time" ) /* 统计组件 */ type statisticalComp struct { cbase.ModuleCompBase module *RobotModule succclientNum int32 //链接成功客户端数 failclientNum int32 //链接失败客户端数 robotdata map[string][]*RobotStatistics //机器人统计数据 lock sync.RWMutex start time.Time //开始时间 end time.Time //结束时间 } //组件初始化接口 func (this *statisticalComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.ModuleCompBase.Init(service, module, comp, options) this.module = module.(*RobotModule) this.robotdata = make(map[string][]*RobotStatistics) return } func (this *statisticalComp) Start() (err error) { err = this.ModuleCompBase.Start() this.start = time.Now() go this.run() return } //添加成功客户端数 func (this *statisticalComp) AddSuccClient(robot *Robot) { } //添加失败客户端数 func (this *statisticalComp) AddFailClient(robot *Robot, err error) { this.failclientNum++ } //机器人测试结束 func (this *statisticalComp) RobotFinishedTest(robot *Robot) { this.lock.Lock() this.robotdata[robot.Account()] = robot.statistics this.lock.Unlock() this.succclientNum++ this.end = time.Now() } //输出报表 func (this *statisticalComp) OutReport() { var ( messages map[string][]int64 = make(map[string][]int64) totalmessage int32 ok bool ) this.lock.Lock() for _, datas := range this.robotdata { for _, v := range datas { totalmessage++ if _, ok = messages[v.message]; !ok { messages[v.message] = make([]int64, 0) } messages[v.message] = append(messages[v.message], v.time) } } this.lock.Unlock() file, err := os.OpenFile(this.module.options.OutFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { fmt.Println(err) return } defer file.Close() file.WriteString(fmt.Sprintf("机器人总数: %d\n", this.module.options.RobotTotalNum)) file.WriteString(fmt.Sprintf("成功数量: %d\n", this.succclientNum)) file.WriteString(fmt.Sprintf("失败数量: %d\n", this.failclientNum)) file.WriteString(fmt.Sprintf("压测执行时长: %.2f秒\n", this.end.Sub(this.start).Seconds())) file.WriteString(fmt.Sprintf("消息总请求数: %d\n", totalmessage)) file.WriteString("---消息压测详情----------------------------------------------------------------------------------------------------\n") for message, data := range messages { sort.Slice(data, func(i, j int) bool { return data[i] < data[j] }) max := data[len(data)-1] min := data[0] sum := int64(0) for _, num := range data { sum += num } avg := float64(sum) / float64(len(data)) var median float64 if len(data)%2 == 0 { median = float64(data[len(data)/2-1]+data[len(data)/2]) / 2.0 } else { median = float64(data[len(data)/2]) } file.WriteString(fmt.Sprintf("消息名:%-20s 请求次数:%-5d 耗时最小:%-5dms 耗时最大:%-5dms 平均耗时:%-5.2fms 中位耗时:%-5.2fms \n", message, len(data), min, max, avg, median)) } } func (this *statisticalComp) run() { timer := time.NewTicker(time.Second * 10) for { select { case <-timer.C: this.OutReport() } } }