代码拉取完成,页面将自动刷新
package ceph
import (
"encoding/json"
"errors"
"fmt"
"gitee.com/liucxer/ceph-tools/pkg/interfacer"
"gitee.com/liucxer/ceph-tools/pkg/tools"
"strconv"
"strings"
"sync"
)
func GetOSDIpMap(worker interfacer.Worker, osdNums []int64) (map[int64]string, error) {
var (
err error
res map[int64]string
)
res = map[int64]string{}
var wg sync.WaitGroup
for _, osdNum := range osdNums {
itemOsdNum := osdNum
wg.Add(1)
go func() {
defer func() { wg.Done() }()
ip, err := GetOSDIp(worker, itemOsdNum)
if err != nil {
return
}
res[itemOsdNum] = ip
}()
}
wg.Wait()
return res, err
}
func GetOSDIp(worker interfacer.Worker, osdNum int64) (string, error) {
var (
err error
)
type Resp struct {
BackAddr string `json:"back_addr"`
}
bts, err := worker.ExecCmd("ceph osd metadata " + strconv.Itoa(int(osdNum)))
if err != nil {
return "", err
}
var res Resp
err = json.Unmarshal(bts, &res)
if err != nil {
return "", err
}
tmpList := strings.Split(res.BackAddr, ":")
if len(tmpList) < 2 {
return "", errors.New("res.BackAddr error")
}
return tmpList[1], nil
}
func GetDiskGroupByPoolName(worker interfacer.Worker, poolName string) (string, error) {
var (
err error
)
type Resp struct {
Steps []struct {
Op string `json:"op"`
ItemName string `json:"item_name"`
} `json:"steps"`
}
bts, err := worker.ExecCmd("ceph osd crush rule dump " + poolName + "_ruleset")
if err != nil {
return "", err
}
var res Resp
err = json.Unmarshal(bts, &res)
if err != nil {
return "", err
}
for _, step := range res.Steps {
if step.Op == "take" {
return step.ItemName, nil
}
}
return "", errors.New("not found DiskGroup")
}
type Node struct {
ID int64 `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Children []int64 `json:"children"`
}
func GetOsdIDsByDiskGroupName(worker interfacer.Worker, diskGroupName string) ([]int64, error) {
var (
err error
)
bts, err := worker.ExecCmd("ceph osd crush tree -f json")
if err != nil {
return nil, err
}
type Resp struct {
Nodes []Node `json:"nodes"`
}
var res Resp
err = json.Unmarshal(bts, &res)
if err != nil {
return nil, err
}
nodeIDMap := map[int64]Node{}
nodeNameMap := map[string]Node{}
for _, node := range res.Nodes {
nodeIDMap[node.ID] = node
nodeNameMap[node.Name] = node
}
var diskGroupID int64
if value, ok := nodeNameMap[diskGroupName]; ok {
diskGroupID = value.ID
}
nodeList := GetSub(diskGroupID, nodeIDMap)
nodeIDs := []int64{}
for _, node := range nodeList {
nodeIDs = append(nodeIDs, node.ID)
}
return nodeIDs, nil
}
func GetSub(nodeID int64, nodeIDMap map[int64]Node) []Node {
node := nodeIDMap[nodeID]
if len(node.Children) == 0 {
return []Node{node}
}
var res []Node
for _, itemID := range node.Children {
tmpList := GetSub(itemID, nodeIDMap)
res = append(res, tmpList...)
}
return res
}
// 根据磁盘组找到 osd
type JobCost struct {
ExpectCost float64 `json:"expect_cost"`
ActualCost float64 `json:"actual_cost(ms)"`
Type string `json:"type"`
Bytes int64 `json:"bytes"`
}
type JobCostList []JobCost
func (list JobCostList) BaseLineActualCost() float64 {
if len(list) == 0 {
return 0
}
actualCost := []float64{}
for _, item := range list {
actualCost = append(actualCost, item.ActualCost)
}
return tools.Avg80(actualCost)
}
func (list JobCostList) AvgExpectCost() float64 {
if len(list) == 0 {
return 0
}
sum := float64(0)
for _, item := range list {
sum = sum + item.ExpectCost
}
res, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", sum/float64(len(list))), 64)
return res
}
func blockSizeToBytes(blockSize string) (int64, error) {
if strings.Contains(blockSize, "k") {
resStr := strings.Split(blockSize, "k")[0]
resInt, err := strconv.Atoi(resStr)
return int64(resInt * 1024), err
}
if strings.Contains(blockSize, "M") {
resStr := strings.Split(blockSize, "M")[0]
resInt, err := strconv.Atoi(resStr)
return int64(resInt * 1024 * 1024), err
}
return 0, nil
}
func (list JobCostList) AvgActualCost() float64 {
if len(list) == 0 {
return 0
}
sum := float64(0)
count := 0
for _, item := range list {
sum = sum + item.ActualCost
count++
}
res, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", sum/float64(count)), 64)
return res
}
func (list JobCostList) TotalExpectCost() float64 {
sum := float64(0)
for _, item := range list {
sum = sum + item.ExpectCost
}
return sum
}
func (list JobCostList) TotalActualCost() float64 {
sum := float64(0)
for _, item := range list {
sum = sum + item.ActualCost
}
return sum
}
/* ceph tell osd.0 dump_recent_ops_cost */
func GetJobCostList(worker interfacer.Worker, osdNum int64) (JobCostList, error) {
var (
res JobCostList
err error
)
res = JobCostList{}
bts, err := worker.ExecCmd("ceph tell osd." + strconv.Itoa(int(osdNum)) + " dump_recent_ops_cost")
if err != nil {
return res, err
}
err = json.Unmarshal(bts, &res)
if err != nil {
return res, err
}
return res, nil
}
func GetRecoveryLimit(worker interfacer.Worker, osdNum int64) (float64, error) {
var (
res float64
err error
)
cmdStr := "ceph daemon osd." + strconv.Itoa(int(osdNum)) + " config show |grep 'osd_op_queue_mclock_recov_lim' |awk -F'\"' '{print $4}'"
bts, err := worker.ExecCmd(cmdStr)
if err != nil {
return res, err
}
limitStr := strings.Trim(string(bts), "\n")
res, err = strconv.ParseFloat(limitStr, 64)
if err != nil {
return res, err
}
return res, nil
}
func GetOsdRecoveryMaxActive(worker interfacer.Worker, osdNum int64) (int64, error) {
var (
res int64
err error
)
cmdStr := "ceph daemon osd." + strconv.Itoa(int(osdNum)) + " config show |grep 'osd_recovery_max_active' |awk -F'\"' '{print $4}'"
bts, err := worker.ExecCmd(cmdStr)
if err != nil {
return res, err
}
limitStr := strings.Trim(string(bts), "\n")
resInt, err := strconv.Atoi(limitStr)
if err != nil {
return res, err
}
res = int64(resInt)
return res, nil
}
func GetJobCostListByOsdNums(worker interfacer.Worker, osdNums []int64, threadNum int64) (JobCostList, error) {
var jobCostList JobCostList
var jobCostListMutex sync.Mutex
ch := make(chan int, threadNum)
for _, osdNum := range osdNums {
itemOsdNum := osdNum
ch <- 1
go func() {
defer func() { <-ch }()
itemList, err := GetJobCostList(worker, itemOsdNum)
if err != nil {
return
}
jobCostListMutex.Lock()
jobCostList = append(jobCostList, itemList...)
jobCostListMutex.Unlock()
}()
}
for i := 0; i < int(threadNum); i++ {
ch <- 1
}
return jobCostList, nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。