Beispiel #1
0
func ListContainers() ([]string, error) {
	out, err := linux.Exec("docker ps -q --no-trunc")
	if err != nil {
		return nil, err
	}

	return strings.Fields(out), nil
}
Beispiel #2
0
func GetNetInUsage(cont string) (int64, error) {
	cmd := fmt.Sprintf("docker exec %s cat /sys/devices/virtual/net/eth0/statistics/rx_bytes", cont)
	out, err := linux.Exec(cmd)
	if err != nil {
		return 0, err
	}

	net, err := strconv.ParseInt(strings.TrimSpace(out), 10, 64)
	if err != nil {
		return 0, err
	}

	return net, nil
}
Beispiel #3
0
func GetMemUsage(cont string) (int64, error) {
	cmd := fmt.Sprintf("head -2 /sys/fs/cgroup/memory/system.slice/docker-%s.scope/memory.stat", cont)
	out, err := linux.Exec(cmd)
	if err != nil {
		return 0, err
	}

	mem, err := strconv.ParseInt(strings.Fields(out)[3], 10, 64)
	if err != nil {
		return 0, err
	}

	return mem, nil
}
Beispiel #4
0
func main() {
	// read arguments
	if len(os.Args) < 3 {
		fmt.Println("[ERROR] incomplete command!")
		fmt.Printf("Usage: %s <cont-name> <freq>\n", os.Args[0])
		os.Exit(1)
	}
	cont_name := os.Args[1]
	freq, err := strconv.ParseInt(os.Args[2], 10, 32)
	if err != nil {
		fmt.Println("[ERROR] unknown frequency argument!")
		os.Exit(1)
	}

	// get container id
	out, err := linux.Exec(fmt.Sprintf("docker inspect --format='{{.Id}}' %s", cont_name))
	if err != nil {
		fmt.Printf("[ERROR] unable to run cmd, output: (%s)\n", out)
		panic(err)
	}
	cont_id := strings.TrimSpace(string(out))

	// check if feedgnuplot exists
	command := exec.Command("which", "feedgnuplot")
	empty, err := command.CombinedOutput()
	if err != nil || string(empty) == "" {
		panic("[ERROR] feedgnuplot doesn't exists!")
	}

	// CTRL+C signal handler
	sigs := make(chan os.Signal, 1)
	done := true
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		_ = <-sigs
		done = false
	}()

	// init feedgnuplot
	command = exec.Command("feedgnuplot", "--lines --stream --title 'cpu-usage' --ylabel 'cpu (100% = 1core)' --xlabel 'time ticks'")
	reader, writer := io.Pipe()
	command.Stdin = reader
	command.Stdout = os.Stdout
	command.Stderr = os.Stderr
	err = command.Start()
	if err != nil {
		fmt.Println("[ERROR] error while starting feedgnuplot!")
		panic(err)
	}

	// init readings
	cur_time := time.Now().UnixNano()
	cur_cpu, err := docker.GetCPUUsage(cont_id)
	if err != nil {
		fmt.Println("[WARN] unable to get container CPU usage!")
		cur_cpu = 0
	}

	// infinite loop for plotting data
	for done {
		new_cpu, err := docker.GetCPUUsage(cont_id)
		if err != nil {
			fmt.Println("[WARN] unable to get container CPU usage!")
			new_cpu = 0
		}

		new_time := time.Now().UnixNano()
		avg_cpu := float64(new_cpu-cur_cpu) / float64(new_time-cur_time) * 1000000000.0
		cur_time = new_time
		cur_cpu = new_cpu

		_, err = io.WriteString(writer, fmt.Sprintf("%.6f\n", avg_cpu))
		if err != nil {
			panic("[ERROR] unable to write to feedgnuplot-stdin!")
		}

		time.Sleep(time.Duration(freq) * time.Millisecond)
	}

	_, err = io.WriteString(writer, "exit\n")
	if err != nil {
		panic("[ERROR] unable to write to feedgnuplot-stdin!")
	}

	command.Wait()
	return
}
Beispiel #5
0
func sendNetUsage(interval time.Duration) {
	out, err := linux.Exec("ifconfig -s")
	now := time.Now()
	if err != nil {
		log.Printf("[WARN] unable to get system net usage: ", err.Error())
	} else {
		reader := csv.NewReader(strings.NewReader(out))
		reader.Comma = ' '
		reader.TrimLeadingSpace = true
		net_data, err := reader.ReadAll()
		if err != nil {
			log.Println("[WARN] unable to get system net usage: ", err.Error())
		} else {
			for index, row := range net_data {
				if index == 0 {
					continue
				}

				net, err := strconv.ParseInt(row[3], 10, 64)
				if err != nil {
					log.Println("[WARN] error in converting to integer: ", err.Error())
				} else {
					ntup, ok := rxdata[row[0]]
					if ok {
						avg := float64(net-ntup.net) * 1000000000 / float64(now.Sub(ntup.time))
						ntup.time = now
						ntup.net = net
						dispatch(row[0], now, avg, "rx")
					} else {
						rxdata[row[0]] = &ntuple{time: now, net: net}
					}
				}

				net, err = strconv.ParseInt(row[7], 10, 64)
				if err != nil {
					log.Println("[WARN] error in converting to integer: ", err.Error())
				} else {
					ntup, ok := txdata[row[0]]
					if ok {
						avg := float64(net-ntup.net) * 1000000000 / float64(now.Sub(ntup.time))
						ntup.time = now
						ntup.net = net
						dispatch(row[0], now, avg, "tx")
					} else {
						txdata[row[0]] = &ntuple{time: now, net: net}
					}
				}
			}
		}
	}

	conts, err := docker.ListContainers()
	if err != nil {
		log.Fatalln("[WARN] unable to get list of containers: ", err.Error())
	}
	for _, cont := range conts {
		net, err := docker.GetNetInUsage(cont)
		now = time.Now()
		if err != nil {
			log.Printf("[WARN] unable to get rx net usage for %s: %s\n", cont, err.Error())
		} else {
			ntup, ok := rxdata[cont]
			if ok {
				avg := float64(net-ntup.net) * 1000000000 / float64(now.Sub(ntup.time))
				ntup.time = now
				ntup.net = net
				dispatch(cont, now, avg, "rx")
			} else {
				rxdata[cont] = &ntuple{time: now, net: net}
			}
		}

		net, err = docker.GetNetOutUsage(cont)
		now = time.Now()
		if err != nil {
			log.Printf("[WARN] unable to get tx net usage for %s: %s\n", cont, err.Error())
		} else {
			ntup, ok := txdata[cont]
			if ok {
				avg := float64(net-ntup.net) * 1000000000 / float64(now.Sub(ntup.time))
				ntup.time = now
				ntup.net = net
				dispatch(cont, now, avg, "tx")
			} else {
				txdata[cont] = &ntuple{time: now, net: net}
			}
		}
	}

	for _, client := range clients {
		client.Flush()
	}
}