Skip to content

Commit

Permalink
Move cpu usage to cpu.usage_in_percents to give more flexibility and …
Browse files Browse the repository at this point in the history
…better swap usage
  • Loading branch information
Soulou committed Nov 3, 2015
1 parent 5c82a93 commit 9f6d49d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 45 deletions.
56 changes: 23 additions & 33 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ package client

import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"strconv"

"gopkg.in/errgo.v1"
)

type MemoryUsage struct {
MemoryUsage int64 `json:"memory_usage"`
SwapMemoryUsage int64 `json:"swap_memory_usage"`
MemoryLimit int64 `json:"memory_limit"`
SwapMemoryLimit int64 `json:"swap_memory_limit"`
MaxMemoryUsage int64 `json:"max_memory_usage"`
MaxSwapMemoryUsage int64 `json:"max_swap_memory_usage"`
MemoryUsage int64 `json:"memory_usage"`
SwapUsage int64 `json:"swap_usage"`
MemoryLimit int64 `json:"memory_limit"`
SwapLimit int64 `json:"swap_limit"`
MaxMemoryUsage int64 `json:"max_memory_usage"`
MaxSwapUsage int64 `json:"max_swap_usage"`
}

type CpuUsage struct {
UsageInPercents int `json:"usage_in_percents"`
}

type Client struct {
Expand Down Expand Up @@ -55,42 +57,30 @@ func (c *Client) Memory(dockerId string) (*MemoryUsage, error) {
return mem, nil
}

func (c *Client) CpuUsage(dockerId string) (int64, error) {
func (c *Client) CpuUsage(dockerId string) (*CpuUsage, error) {
req, err := http.NewRequest("GET", c.Endpoint+"/containers/"+dockerId+"/cpu", nil)
if err != nil {
return -1, errgo.Mask(err)
}

cpu, err := c.getInt(req)
if err != nil {
return -1, errgo.Mask(err)
return nil, errgo.Mask(err)
}

return cpu, nil
}

func (c *Client) do(req *http.Request) (*http.Response, error) {
req.Header.Add("Content-Type", "text/plain")
req.Header.Add("User-Agent", "Acadocker Client v1")
return http.DefaultClient.Do(req)
}

func (c *Client) getInt(req *http.Request) (int64, error) {
res, err := c.do(req)
if err != nil {
return -1, errgo.Mask(err)
return nil, errgo.Mask(err)
}

defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
var cpu *CpuUsage
err = json.NewDecoder(res.Body).Decode(&cpu)
if err != nil {
return -1, errgo.Mask(err)
return nil, errgo.Mask(err)
}

i, err := strconv.ParseInt(string(body), 10, 64)
if err != nil {
return -1, errgo.Mask(err)
}
return cpu, nil
}

return i, nil
func (c *Client) do(req *http.Request) (*http.Response, error) {
req.Header.Add("Content-Type", "application/json")
req.Header.Add("User-Agent", "Acadocker Client v1")
return http.DefaultClient.Do(req)
}
14 changes: 10 additions & 4 deletions cpu/cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"sync"
"time"

"github.com/Scalingo/acadock-monitoring/client"
"github.com/Scalingo/acadock-monitoring/config"
"github.com/Scalingo/acadock-monitoring/docker"
)
Expand All @@ -20,6 +21,8 @@ const (
LXC_CPUACCT_USAGE_FILE = "cpuacct.usage"
)

type Usage client.CpuUsage

var (
currentSystemUsage = make(map[string]int64)
previousSystemUsage = make(map[string]int64)
Expand Down Expand Up @@ -89,19 +92,22 @@ func monitorContainer(id string) {
}
}

func GetUsage(id string) (int64, error) {
func GetUsage(id string) (*Usage, error) {
id, err := docker.ExpandId(id)
if err != nil {
log.Println("Error when expanding id:", err)
return -1, err
return nil, err
}
if _, ok := previousCpuUsages[id]; !ok {
return -1, nil
return nil, nil
}
deltaCpuUsage := float64(cpuUsages[id] - previousCpuUsages[id])
deltaSystemCpuUsage := float64(currentSystemUsage[id] - previousSystemUsage[id])

return int64(deltaCpuUsage / deltaSystemCpuUsage * 100 * float64(runtime.NumCPU())), nil
percents := int(deltaCpuUsage / deltaSystemCpuUsage * 100 * float64(runtime.NumCPU()))
return &Usage{
UsageInPercents: percents,
}, nil
}

func systemUsage() (int64, error) {
Expand Down
12 changes: 10 additions & 2 deletions mem/mem.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ const (
LXC_MAX_SWAP_MEM_FILE = "memory.memsw.max_usage_in_bytes"
)

type Usage client.MemoryUsage
type Usage struct {
client.MemoryUsage
SwapMemoryUsage int64 `json:"-"`
SwapMemoryLimit int64 `json:"-"`
MaxSwapMemoryUsage int64 `json:"-"`
}

func GetUsage(id string) (Usage, error) {
usage := Usage{}
Expand All @@ -36,7 +41,7 @@ func GetUsage(id string) (Usage, error) {
go readMemoryCgroupInt64Async(id, LXC_MAX_MEM_FILE, &usage.MaxMemoryUsage, errors, wg)
go readMemoryCgroupInt64Async(id, LXC_MAX_SWAP_MEM_FILE, &usage.MaxSwapMemoryUsage, errors, wg)
go readMemoryCgroupInt64Async(id, LXC_MEM_LIMIT_FILE, &usage.MemoryLimit, errors, wg)
go readMemoryCgroupInt64Async(id, LXC_MEM_USAGE_FILE, &usage.MemoryUsage, errors, wg)
go readMemoryCgroupInt64Async(id, LXC_MEM_USAGE_FILE, &usage.MemoryUsage.MemoryUsage, errors, wg)
go readMemoryCgroupInt64Async(id, LXC_SWAP_MEM_LIMIT_FILE, &usage.SwapMemoryLimit, errors, wg)
go readMemoryCgroupInt64Async(id, LXC_SWAP_MEM_USAGE_FILE, &usage.SwapMemoryUsage, errors, wg)

Expand All @@ -51,6 +56,9 @@ func GetUsage(id string) (Usage, error) {
}
}

usage.SwapUsage = usage.SwapMemoryUsage - usage.MemoryUsage.MemoryUsage
usage.SwapLimit = usage.SwapMemoryLimit - usage.MemoryLimit
usage.MaxSwapUsage = usage.MaxSwapMemoryUsage - usage.MaxMemoryUsage
return usage, nil
}

Expand Down
16 changes: 10 additions & 6 deletions server/acadock_monitoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"flag"
"fmt"
"log"
"strconv"

"net/http"
"net/http/pprof"
Expand Down Expand Up @@ -33,22 +32,27 @@ func containerMemUsageHandler(params martini.Params, res http.ResponseWriter) {
json.NewEncoder(res).Encode(&containerMemoryUsage)
}

func containerCpuUsageHandler(params martini.Params) (int, string) {
func containerCpuUsageHandler(res http.ResponseWriter, req *http.Request, params martini.Params) {
id := params["id"]

containerCpu, err := cpu.GetUsage(id)
containerCpuUsage, err := cpu.GetUsage(id)
if err != nil {
return 200, err.Error()
res.WriteHeader(500)
res.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(res, err.Error())
return
}
containerCpuStr := strconv.FormatInt(containerCpu, 10)
return 200, containerCpuStr
res.WriteHeader(200)
json.NewEncoder(res).Encode(&containerCpuUsage)
}

func containerNetUsageHandler(params martini.Params, res http.ResponseWriter) {
id := params["id"]

containerNet, err := net.GetUsage(id)
if err != nil {
res.WriteHeader(500)
res.Header().Set("Content-Type", "text/plain")
res.Write([]byte(err.Error()))
return
}
Expand Down

0 comments on commit 9f6d49d

Please sign in to comment.