Commit 1220025e authored by Pengfei Ni's avatar Pengfei Ni

Add network stats for node interfaces

parent 84a7f48c
......@@ -101,8 +101,13 @@ func (p *perfCounterNodeStatsClient) startMonitoring() error {
return err
}
networkAdapterCounter, err := newNetworkCounters()
if err != nil {
return err
}
go wait.Forever(func() {
p.collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter)
p.collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter, networkAdapterCounter)
}, perfCounterUpdatePeriod)
return nil
......@@ -138,7 +143,7 @@ func (p *perfCounterNodeStatsClient) getNodeInfo() nodeInfo {
return p.nodeInfo
}
func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter *perfCounter) {
func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter *perfCounter, networkAdapterCounter *networkCounter) {
cpuValue, err := cpuCounter.getData()
if err != nil {
klog.Errorf("Unable to get cpu perf counter data; err: %v", err)
......@@ -157,12 +162,19 @@ func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSe
return
}
networkAdapterStats, err := networkAdapterCounter.getData()
if err != nil {
klog.Errorf("Unable to get network adapter perf counter data; err: %v", err)
return
}
p.mu.Lock()
defer p.mu.Unlock()
p.nodeMetrics = nodeMetrics{
cpuUsageCoreNanoSeconds: p.convertCPUValue(cpuValue),
memoryPrivWorkingSetBytes: memWorkingSetValue,
memoryCommittedBytes: memCommittedBytesValue,
interfaceStats: networkAdapterStats,
timeStamp: time.Now(),
}
}
......
......@@ -71,6 +71,7 @@ func newPerfCounter(counter string) (*perfCounter, error) {
}, nil
}
// getData is used for getting data without * in counter name.
func (p *perfCounter) getData() (uint64, error) {
ret := win_pdh.PdhCollectQueryData(p.queryHandle)
if ret != win_pdh.ERROR_SUCCESS {
......@@ -100,3 +101,36 @@ func (p *perfCounter) getData() (uint64, error) {
return data, nil
}
// getData is used for getting data with * in counter name.
func (p *perfCounter) getDataList() (map[string]uint64, error) {
ret := win_pdh.PdhCollectQueryData(p.queryHandle)
if ret != win_pdh.ERROR_SUCCESS {
return nil, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
var bufSize, bufCount uint32
var size = uint32(unsafe.Sizeof(win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{}))
var emptyBuf [1]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr.
data := map[string]uint64{}
ret = win_pdh.PdhGetFormattedCounterArrayDouble(p.counterHandle, &bufSize, &bufCount, &emptyBuf[0])
if ret != win_pdh.PDH_MORE_DATA {
return nil, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
filledBuf := make([]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size)
ret = win_pdh.PdhGetFormattedCounterArrayDouble(p.counterHandle, &bufSize, &bufCount, &filledBuf[0])
if ret != win_pdh.ERROR_SUCCESS {
return nil, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
for i := 0; i < int(bufCount); i++ {
c := filledBuf[i]
value := uint64(c.FmtValue.DoubleValue)
name := win_pdh.UTF16PtrToString(c.SzName)
data[name] = value
}
return data, nil
}
......@@ -58,6 +58,7 @@ type nodeMetrics struct {
memoryPrivWorkingSetBytes uint64
memoryCommittedBytes uint64
timeStamp time.Time
interfaceStats []cadvisorapi.InterfaceStats
}
type nodeInfo struct {
......@@ -109,12 +110,11 @@ func (c *StatsClient) WinVersionInfo() (*cadvisorapi.VersionInfo, error) {
func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, error) {
nodeMetrics, err := c.client.getNodeMetrics()
if err != nil {
return nil, err
}
var stats []*cadvisorapiv2.ContainerStats
var stats []*cadvisorapiv2.ContainerStats
stats = append(stats, &cadvisorapiv2.ContainerStats{
Timestamp: nodeMetrics.timeStamp,
Cpu: &cadvisorapi.CpuStats{
......@@ -126,6 +126,9 @@ func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, e
WorkingSet: nodeMetrics.memoryPrivWorkingSetBytes,
Usage: nodeMetrics.memoryCommittedBytes,
},
Network: &cadvisorapiv2.NetworkStats{
Interfaces: nodeMetrics.interfaceStats,
},
})
nodeInfo := c.client.getNodeInfo()
......@@ -134,6 +137,7 @@ func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, e
CreationTime: nodeInfo.startTime,
HasCpu: true,
HasMemory: true,
HasNetwork: true,
Memory: cadvisorapiv2.MemorySpec{
Limit: nodeInfo.memoryPhysicalCapacityBytes,
},
......
......@@ -86,8 +86,9 @@ func TestWinContainerInfos(t *testing.T) {
infos := make(map[string]cadvisorapiv2.ContainerInfo)
infos["/"] = cadvisorapiv2.ContainerInfo{
Spec: cadvisorapiv2.ContainerSpec{
HasCpu: true,
HasMemory: true,
HasCpu: true,
HasMemory: true,
HasNetwork: true,
Memory: cadvisorapiv2.MemorySpec{
Limit: 1.6e+10,
},
......@@ -95,7 +96,11 @@ func TestWinContainerInfos(t *testing.T) {
Stats: stats,
}
assert.Equal(t, actualRootInfos, infos)
assert.Equal(t, len(actualRootInfos), len(infos))
assert.Equal(t, actualRootInfos["/"].Spec, infos["/"].Spec)
assert.Equal(t, len(actualRootInfos["/"].Stats), len(infos["/"].Stats))
assert.Equal(t, actualRootInfos["/"].Stats[0].Cpu, infos["/"].Stats[0].Cpu)
assert.Equal(t, actualRootInfos["/"].Stats[0].Memory, infos["/"].Stats[0].Memory)
}
func TestWinMachineInfo(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment