Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Per core cpu utilization from to heasper MetrciSet #5

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions metrics/sinks/poseidon/poseidon_sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"k8s.io/heapster/metrics/core"
"k8s.io/heapster/metrics/sinks/poseidon/stats"
"net/url"
"strconv"
"sync"
"time"
)
Expand Down Expand Up @@ -37,16 +38,17 @@ func (sink *PoseidonSink) Stop() {
func (sink *PoseidonSink) ProcessNodeStats(nodeMetrics *core.MetricSet) {
glog.V(2).Infoln("ProcessNodeStats called...")
nodeStats := &stats.NodeStats{
Hostname: nodeMetrics.Labels[core.LabelHostname.Key],
Timestamp: uint64(nodeMetrics.ScrapeTime.UnixNano()) / uint64(time.Microsecond),
CpuAllocatable: int64(getMetricValue(nodeMetrics, core.MetricNodeCpuAllocatable).FloatValue),
CpuCapacity: int64(getMetricValue(nodeMetrics, core.MetricNodeCpuCapacity).FloatValue),
CpuReservation: float64(getMetricValue(nodeMetrics, core.MetricNodeCpuReservation).FloatValue),
CpuUtilization: float64(getMetricValue(nodeMetrics, core.MetricNodeCpuUtilization).FloatValue),
MemAllocatable: int64(getMetricValue(nodeMetrics, core.MetricNodeMemoryAllocatable).FloatValue / KILOBYTE),
MemCapacity: int64(getMetricValue(nodeMetrics, core.MetricNodeMemoryCapacity).FloatValue / KILOBYTE),
MemReservation: float64(getMetricValue(nodeMetrics, core.MetricNodeMemoryReservation).FloatValue),
MemUtilization: float64(getMetricValue(nodeMetrics, core.MetricNodeMemoryUtilization).FloatValue),
Hostname: nodeMetrics.Labels[core.LabelHostname.Key],
Timestamp: uint64(nodeMetrics.ScrapeTime.UnixNano()) / uint64(time.Microsecond),
CpuAllocatable: int64(getMetricValue(nodeMetrics, core.MetricNodeCpuAllocatable).FloatValue),
CpuCapacity: int64(getMetricValue(nodeMetrics, core.MetricNodeCpuCapacity).FloatValue),
CpuReservation: float64(getMetricValue(nodeMetrics, core.MetricNodeCpuReservation).FloatValue),
CpuUtilization: float64(getMetricValue(nodeMetrics, core.MetricNodeCpuUtilization).FloatValue),
MemAllocatable: int64(getMetricValue(nodeMetrics, core.MetricNodeMemoryAllocatable).FloatValue / KILOBYTE),
MemCapacity: int64(getMetricValue(nodeMetrics, core.MetricNodeMemoryCapacity).FloatValue / KILOBYTE),
MemReservation: float64(getMetricValue(nodeMetrics, core.MetricNodeMemoryReservation).FloatValue),
MemUtilization: float64(getMetricValue(nodeMetrics, core.MetricNodeMemoryUtilization).FloatValue),
CpuCoreUtilization: getCoreValues(nodeMetrics),
}
glog.V(2).Infoln("Sending nodeStat to nodeStatChan", nodeStats)
sink.nodeStatChan <- nodeStats
Expand Down Expand Up @@ -171,6 +173,19 @@ func (sink *PoseidonSink) ExportData(dataBatch *core.DataBatch) {
}
}

func getCoreValues(metricSet *core.MetricSet) []int64 {
//TODO:(shiv) Assuming 128 core to be the max core per node
var coreUsage []int64
for i := 0; i < 128; i++ {
if value, ok := metricSet.MetricValues["cpucore/core_"+strconv.Itoa(i)]; ok {
coreUsage = append(coreUsage, value.IntValue)
} else {
break
}
}
return coreUsage
}

func getMetricValue(metricSet *core.MetricSet, metric core.Metric) core.MetricValue {
return metricSet.MetricValues[metric.MetricDescriptor.Name]
}
Expand Down
111 changes: 60 additions & 51 deletions metrics/sinks/poseidon/stats/poseidonstats.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion metrics/sinks/poseidon/stats/poseidonstats.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ message NodeStats {
// Memory stats (fraction of total).
double mem_reservation = 9;
double mem_utilization = 10;
// per core utilization
repeated int64 cpu_core_utilization = 11;
}

enum NodeStatsResponseType {
Expand Down Expand Up @@ -91,4 +93,4 @@ message PodStatsResponse {
PodStatsResponseType type = 1;
string name = 2;
string namespace = 3;
}
}
25 changes: 24 additions & 1 deletion metrics/sources/kubelet/kubelet_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ func (self *KubeletClient) GetSummary(host Host) (*stats.Summary, error) {
if self.config != nil && self.config.EnableHttps {
url.Scheme = "https"
}

req, err := http.NewRequest("GET", url.String(), nil)
if err != nil {
return nil, err
Expand All @@ -156,6 +155,30 @@ func (self *KubeletClient) GetSummary(host Host) (*stats.Summary, error) {
client = http.DefaultClient
}
err = self.postRequestAndGetValue(client, req, summary)
self.GetCPUCoreStats(host, summary)
return summary, err
}

func (self *KubeletClient) GetCPUCoreStats(host Host, summary *stats.Summary) (*stats.Summary, error) {
url := url.URL{
Scheme: "http",
Host: fmt.Sprintf("%s:%d", host.IP, host.Port),
Path: "/stats",
}
if self.config != nil && self.config.EnableHttps {
url.Scheme = "https"
}
req, err := http.NewRequest("GET", url.String(), nil)
if err != nil {
return nil, err
}
cpuCoreStats := &cadvisor.ContainerInfo{}
client := self.client
if client == nil {
client = http.DefaultClient
}
err = self.postRequestAndGetValue(client, req, cpuCoreStats)
summary.Node.CPUPerCore = &cpuCoreStats.Stats[len(cpuCoreStats.Stats)-1].Cpu
return summary, err
}

Expand Down
22 changes: 22 additions & 0 deletions metrics/sources/summary/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ package summary
import (
"fmt"
"net/url"
"strconv"
"time"

. "k8s.io/heapster/metrics/core"
"k8s.io/heapster/metrics/sources/kubelet"

"github.com/golang/glog"
cadvisor "github.com/google/cadvisor/info/v1"
"github.com/prometheus/client_golang/prometheus"
"k8s.io/apimachinery/pkg/labels"
kube_client "k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -157,6 +159,7 @@ func (this *summaryMetricsSource) decodeNodeStats(metrics map[string]*MetricSet,

this.decodeUptime(nodeMetrics, node.StartTime.Time)
this.decodeCPUStats(nodeMetrics, node.CPU)
this.decodeCpuCoreStats(nodeMetrics, node.CPUPerCore)
this.decodeMemoryStats(nodeMetrics, node.Memory)
this.decodeNetworkStats(nodeMetrics, node.Network)
this.decodeFsStats(nodeMetrics, RootFsKey, node.Fs)
Expand Down Expand Up @@ -241,6 +244,25 @@ func (this *summaryMetricsSource) decodeCPUStats(metrics *MetricSet, cpu *stats.
this.addIntMetric(metrics, &MetricCpuUsage, cpu.UsageCoreNanoSeconds)
}

func (this *summaryMetricsSource) decodeCpuCoreStats(metrics *MetricSet, coreStats *cadvisor.CpuStats) {
if coreStats == nil {
glog.V(9).Infof("missing cpu core usage metric!")
return
}
for index, value := range coreStats.Usage.PerCpu {
MetricCpuCoreUsage := Metric{
MetricDescriptor: MetricDescriptor{
Name: "cpucore/core_" + strconv.Itoa(index),
Description: "CPU core usage in nanocores.",
Type: MetricGauge,
ValueType: ValueInt64,
Units: UnitsCount,
},
}
this.addIntMetric(metrics, &MetricCpuCoreUsage, &value)
}
}

func (this *summaryMetricsSource) decodeMemoryStats(metrics *MetricSet, memory *stats.MemoryStats) {
if memory == nil {
glog.V(9).Infof("missing memory metrics!")
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.