Introduction: Execute the shell through golang to obtain the pid process using the GPU on the server, its corresponding k8s pod name, and the corresponding open pai platform job and user name.
Now the execution will return a bit slow. Still needs to be optimized, only the function is implemented.
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)
}
}
Effect
Later, according to the incoming parameters, the relevant information on the corresponding graphics card is obtained according to different graphics card IDs.