[golang]-golang获取服务器上使用gpu的进程id及对应的k8s容器名

导语:通过golang执行shell获取服务器上正在使用GPU的pid进程,及其对应的k8s pod名称以及对应的open pai平台的job和用户名。

现在执行会页面返回有点慢。还需要优化,只实现了功能。

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os/exec"
	"sort"
	"strconv"
	"strings"
)

// Strval 获取变量的字符串值
// 浮点型 3.0将会转换成字符串3, "3"
// 非数值或字符类型的变量将会被转换成JSON格式字符串
// 把空接口类型转换成string 方便后面输出在界面上。
func Strval(value interface{
    
    }) string {
    
    
	var key string
	if value == nil {
    
    
		return key
	}

	switch value.(type) {
    
    
	case float64:
		ft := value.(float64)
		key = strconv.FormatFloat(ft, 'f', -1, 64)
	case float32:
		ft := value.(float32)
		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
	case int:
		it := value.(int)
		key = strconv.Itoa(it)
	case uint:
		it := value.(uint)
		key = strconv.Itoa(int(it))
	case int8:
		it := value.(int8)
		key = strconv.Itoa(int(it))
	case uint8:
		it := value.(uint8)
		key = strconv.Itoa(int(it))
	case int16:
		it := value.(int16)
		key = strconv.Itoa(int(it))
	case uint16:
		it := value.(uint16)
		key = strconv.Itoa(int(it))
	case int32:
		it := value.(int32)
		key = strconv.Itoa(int(it))
	case uint32:
		it := value.(uint32)
		key = strconv.Itoa(int(it))
	case int64:
		it := value.(int64)
		key = strconv.FormatInt(it, 10)
	case uint64:
		it := value.(uint64)
		key = strconv.FormatUint(it, 10)
	case string:
		key = value.(string)
	case []byte:
		key = string(value.([]byte))
	default:
		newValue, _ := json.Marshal(value)
		key = string(newValue)
	}

	return key
}

// 处理主页请求
func pid(w http.ResponseWriter, r *http.Request) {
    
    
	// m := make(map[string]container)

	// 向客户端写入内容
	fmt.Fprintf(w, "start -----!\n")
	s := []map[string]interface{
    
    }{
    
    }
	// 初始命令获取占用显卡的进程
	cmd1 := exec.Command("sh", "-c", " fuser -v /dev/nvidia*  |   grep '[0-9]*[1-9][0-9]' ")
	stdout1 := &bytes.Buffer{
    
    }
	cmd1.Stdout = stdout1
	cmd1.Run()
	s1 := stdout1.String()
	str_arr1 := strings.Split(s1, " ")
	// fmt.Printf("type:%T\n", str_arr1)
	// 输出 字符串数组 中的 字符串
	for _, str1 := range str_arr1 {
    
    
		if str1 != "" {
    
    
			// println("pid:", str1)
			// 去除字符串中的空格
			str1 = strings.Replace(str1, " ", "", -1)
			// 去除字符串中的换行符
			str1 = strings.Replace(str1, "\n", "", -1)
			cmd_line2 := fmt.Sprintf("%s%s%s", "cat /proc/", str1, "/cgroup | awk -F '/' '{print $5}' | head -n 1")
			cmd2 := exec.Command("sh", "-c", string(cmd_line2))
			stdout2 := &bytes.Buffer{
    
    }
			cmd2.Stdout = stdout2
			cmd2.Run()
			s2 := stdout2.String()
			s2 = strings.Replace(s2, " ", "", -1)
			s2 = strings.Replace(s2, "\n", "", -1)
			if s2 != "" {
    
    
				// pai用户名
				// docker inspect    5364294ae1d3164819323dac7763b375c07e46c30930b9a71bf74514ac10dc15 |grep PAI_USER_NAME
				// k8s pod名
				// docker inspect  --format '{
    
    {.Name}}'    8a1f437dedf0b8cae0002212555cd0eb1e6901b08d3033f8610db32bd21f6507  |sed 's/^\/k8s_app_//' |sed 's/_default.*//'
				// job名
				// docker inspect  --format '{
    
    {.Name}}'    8a1f437dedf0b8cae0002212555cd0eb1e6901b08d3033f8610db32bd21f6507  |sed 's/^\/k8s_app_.*default_//'
				cmd_line3 := fmt.Sprintf("%s%s%s", "docker inspect ", s2, " |grep PAI_USER_NAME")

				// fmt.Println(string(cmd_line3))
				cmd3 := exec.Command("sh", "-c", string(cmd_line3))
				stdout3 := &bytes.Buffer{
    
    }
				cmd3.Stdout = stdout3
				cmd3.Run()
				s3 := stdout3.String()

				if s3 != "" {
    
    
					s3 = strings.Replace(s3, ",", "", -1)
					s3 = strings.Replace(s3, "\n", "", -1)
					s3 = strings.Replace(s3, " ", "", -1)
					// fmt.Println("paisuer", s3)
					// k8s pod name
					cmd_line4 := fmt.Sprintf("%s%s%s", "docker inspect  --format '{
    
    {.Name}}'  ", s2, " |sed 's/^\\/k8s_app_//' |sed 's/_default.*//'")
					// fmt.Println(string(cmd_line4))
					cmd4 := exec.Command("sh", "-c", string(cmd_line4))
					stdout4 := &bytes.Buffer{
    
    }
					cmd4.Stdout = stdout4
					cmd4.Run()
					s4 := stdout4.String()
					// fmt.Println("k8s pod name:", s4)
					// pai job name    需要多加一个  |sed 's/_0//'
					cmd_line5 := fmt.Sprintf("%s%s%s", "docker inspect  --format '{
    
    {.Name}}'  ", s2, "  |sed 's/^\\/k8s_app_.*default_//'")
					// fmt.Println(string(cmd_line5))
					cmd5 := exec.Command("sh", "-c", string(cmd_line5))
					stdout5 := &bytes.Buffer{
    
    }
					cmd5.Stdout = stdout5
					cmd5.Run()
					s5 := stdout5.String()
					// fmt.Println("pai job name:", s5)
					s = append(s, map[string]interface{
    
    }{
    
    "pid": "PID=" + str1, "paiuser": strings.Replace(s3, "\\", "", -1), "k8s_pod_name": "K8S_POD_NAME=" + strings.Replace(s4, "\n", "", -1), "pai_job_name": "PAI_JOB_NAME" + strings.Replace(s5, "\n", "", -1)})
				} else {
    
    
					continue
				}

				//
			} else {
    
    
				continue
			}

		} else {
    
    
			continue
		}

	}

	for _, value := range s {
    
    
		// fmt.Println(value)

		var keys []string
		for k := range value {
    
    
			keys = append(keys, k)
		}

		// 对字符串切片排序
		sort.Strings(keys)
		fmt.Println(keys)

		// 打印key, val
		for _, k := range keys {
    
    
			fmt.Printf("key: %v  val:%v \n", k, value[k])
			strval1 := Strval(value[k])
			fmt.Fprintf(w, "key: "+k+"value: "+strval1+"\n")
			// output, _ := fmt.Printf("key: %v  val:%v \n", k, value[k])
			// fmt.Fprintf(w, string(output)+"\n")
		}
		// b, _ := json.Marshal(v)
		// fmt.Fprintf(w, string(b)+"\n")
		// fmt.Fprintf(w, "------"+"\n")
	}

	// b, err := json.Marshal(s)
	// if err != nil {
    
    
	// 	fmt.Println("json.Marshal failed:", err)
	// 	return
	// }

	// fmt.Fprintf(w, string(b))
	fmt.Fprintf(w, "end -----!\n")

}

func main() {
    
    
	http.HandleFunc("/", pid)                //设置访问的路由
	err := http.ListenAndServe(":9090", nil) //设置监听的端口
	if err != nil {
    
    
		log.Fatal("ListenAndServe: ", err)
	}
}

效果

后面再根据传入参数,根据不同的显卡id获取对应显卡上的相关信息。

猜你喜欢

转载自blog.csdn.net/xujiamin0022016/article/details/124461488
今日推荐