[golang]-golang获取服务器上使用gpu的进程id及对应的k8s容器名
导语:通过golang执行shell获取服务器上正在使用GPU的pid进程,及其对应的k8s pod名称以及对应的open pai平台的job和用户名。现在执行会页面返回有点慢。还需要优化,只实现了功能。package mainimport ("bytes""encoding/json""fmt""log""net/http""os/exec""sort""strconv""strings")//
·
导语:通过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获取对应显卡上的相关信息。
更多推荐
已为社区贡献84条内容
所有评论(0)