代码拉取完成,页面将自动刷新
package exec_config
import (
"context"
"encoding/json"
"github.com/google/uuid"
"io/ioutil"
"os"
"sync"
"time"
"gitee.com/liucxer/ceph-tools/pkg/ceph"
"gitee.com/liucxer/ceph-tools/pkg/ceph_cluster"
"gitee.com/liucxer/ceph-tools/pkg/csv"
"gitee.com/liucxer/ceph-tools/pkg/fio"
"github.com/sirupsen/logrus"
)
type ResultItem struct {
Cost float64 `json:"cost"`
Count int64 `json:"count"`
Sum float64 `json:"sum"`
Avg float64 `json:"avg"`
Lats []int64 `json:"lats"`
}
type ExecResult struct {
fio.FioResult
ResultMap map[string]map[float64]ResultItem `json:"resultMap"`
}
func NewExecConfig(configPath string) (*ExecConfig, error) {
execConfig := ExecConfig{}
err := execConfig.ReadConfig(configPath)
if err != nil {
return &execConfig, nil
}
execConfig.CephCluster, err = ceph_cluster.NewCluster(execConfig.IpAddr)
if err != nil {
return &execConfig, nil
}
execConfig.CephConf, err = ceph.NewCephConf(execConfig.Master, execConfig.OsdNum)
if err != nil {
return &execConfig, nil
}
resultDir := "output_" + uuid.New().String()
err = os.Mkdir(resultDir, os.ModePerm)
if err != nil {
return &execConfig, err
}
execConfig.ResultDir = resultDir
logrus.Debugf("NewExecConfig. execConfig:%+v", execConfig)
return &execConfig, nil
}
type ExecConfig struct {
*ceph_cluster.CephCluster
*ceph.CephConf
WithJobCost bool `json:"withJobCost"`
OsdNum []int64 `json:"osdNum"`
DiskType string `json:"diskType"`
IpAddr string `json:"ipAddr"`
Runtime int64 `json:"runtime"`
DataPool string `json:"dataPool"`
DataVolume string `json:"dataVolume"`
OpType []string `json:"opType"`
ResultDir string `json:"resultDir"`
}
func (execConfig *ExecConfig) ReadConfig(configFilePath string) error {
bts, err := ioutil.ReadFile(configFilePath)
if err != nil {
logrus.Errorf("ioutil.ReadFile err:%v", err)
return err
}
err = json.Unmarshal(bts, execConfig)
if err != nil {
logrus.Errorf("json.Unmarshal err:%v", err)
return err
}
return err
}
func (execConfig *ExecConfig) Run(opType string) (ExecResult, error) {
var (
err error
res ExecResult
)
res.ResultMap = map[string]map[float64]ResultItem{}
res.ResultMap[opType] = map[float64]ResultItem{}
ctx, cancelFn := context.WithCancel(context.Background())
var jobCostList ceph.JobCostList
var jobCostListMutex sync.Mutex
if execConfig.WithJobCost {
for _, osdNum := range execConfig.OsdNum {
itemOsdNum := osdNum
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
itemJobCostList, err := ceph.GetJobCostList(execConfig.Master, itemOsdNum)
if err != nil {
return
}
jobCostListMutex.Lock()
jobCostList = append(jobCostList, itemJobCostList...)
jobCostListMutex.Unlock()
time.Sleep(10 * time.Second)
}
}
}(ctx)
}
}
fioObject := fio.Fio{
OpType: opType,
Runtime: execConfig.Runtime,
BSRange: "1k-4M",
IoDepth: 1,
Pool: execConfig.DataPool,
RbdName: execConfig.DataVolume,
}
fioResult, err := fioObject.Exec(execConfig.Master)
cancelFn()
if err != nil {
return res, err
}
res.FioResult = *fioResult
name, value, err := csv.ObjectToCsv(res)
if err != nil {
return res, err
}
logrus.Infof("RunOneJob res:%+v", res)
logrus.Infof("RunOneJob name:%s", name)
logrus.Infof("RunOneJob value:%s", value)
resultItem := map[float64]ResultItem{}
jobCostListMutex.Lock()
for _, jobCost := range jobCostList {
if jobCost.Type != opType {
continue
}
if value, ok := resultItem[jobCost.ExpectCost]; ok {
value.Count++
value.Sum += jobCost.ActualCost
value.Avg = value.Sum / float64(value.Count)
if jobCost.ActualCost < 300 {
value.Lats[int(jobCost.ActualCost/10)]++
}
resultItem[jobCost.ExpectCost] = value
} else {
item := ResultItem{
Count: 1,
Cost: jobCost.ExpectCost,
Sum: jobCost.ActualCost,
Avg: jobCost.ActualCost,
}
item.Lats = make([]int64, 30)
if jobCost.ActualCost < 300 {
item.Lats[int(jobCost.ActualCost/10)] = 1
}
resultItem[jobCost.ExpectCost] = item
}
}
res.ResultMap[opType] = resultItem
jobCostListMutex.Unlock()
return res, err
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。