313 lines
10 KiB
Go
313 lines
10 KiB
Go
// +build windows
|
|
|
|
/*
|
|
Copyright 2019 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package winstats
|
|
|
|
import (
|
|
"sync"
|
|
|
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
|
"k8s.io/klog"
|
|
)
|
|
|
|
const (
|
|
packetsReceivedPerSecondQuery = "\\Network Adapter(*)\\Packets Received/sec"
|
|
packetsSentPerSecondQuery = "\\Network Adapter(*)\\Packets Sent/sec"
|
|
bytesReceivedPerSecondQuery = "\\Network Adapter(*)\\Bytes Received/sec"
|
|
bytesSentPerSecondQuery = "\\Network Adapter(*)\\Bytes Sent/sec"
|
|
packetsReceivedDiscardedQuery = "\\Network Adapter(*)\\Packets Received Discarded"
|
|
packetsReceivedErrorsQuery = "\\Network Adapter(*)\\Packets Received Errors"
|
|
packetsOutboundDiscardedQuery = "\\Network Adapter(*)\\Packets Outbound Discarded"
|
|
packetsOutboundErrorsQuery = "\\Network Adapter(*)\\Packets Outbound Errors"
|
|
)
|
|
|
|
// networkCounter contains the counters for network adapters.
|
|
type networkCounter struct {
|
|
packetsReceivedPerSecondCounter *perfCounter
|
|
packetsSentPerSecondCounter *perfCounter
|
|
bytesReceivedPerSecondCounter *perfCounter
|
|
bytesSentPerSecondCounter *perfCounter
|
|
packetsReceivedDiscardedCounter *perfCounter
|
|
packetsReceivedErrorsCounter *perfCounter
|
|
packetsOutboundDiscardedCounter *perfCounter
|
|
packetsOutboundErrorsCounter *perfCounter
|
|
|
|
mu sync.RWMutex
|
|
adapterStats map[string]cadvisorapi.InterfaceStats
|
|
}
|
|
|
|
func newNetworkCounters() (*networkCounter, error) {
|
|
packetsReceivedPerSecondCounter, err := newPerfCounter(packetsReceivedPerSecondQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
packetsSentPerSecondCounter, err := newPerfCounter(packetsSentPerSecondQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bytesReceivedPerSecondCounter, err := newPerfCounter(bytesReceivedPerSecondQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bytesSentPerSecondCounter, err := newPerfCounter(bytesSentPerSecondQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
packetsReceivedDiscardedCounter, err := newPerfCounter(packetsReceivedDiscardedQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
packetsReceivedErrorsCounter, err := newPerfCounter(packetsReceivedErrorsQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
packetsOutboundDiscardedCounter, err := newPerfCounter(packetsOutboundDiscardedQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
packetsOutboundErrorsCounter, err := newPerfCounter(packetsOutboundErrorsQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &networkCounter{
|
|
packetsReceivedPerSecondCounter: packetsReceivedPerSecondCounter,
|
|
packetsSentPerSecondCounter: packetsSentPerSecondCounter,
|
|
bytesReceivedPerSecondCounter: bytesReceivedPerSecondCounter,
|
|
bytesSentPerSecondCounter: bytesSentPerSecondCounter,
|
|
packetsReceivedDiscardedCounter: packetsReceivedDiscardedCounter,
|
|
packetsReceivedErrorsCounter: packetsReceivedErrorsCounter,
|
|
packetsOutboundDiscardedCounter: packetsOutboundDiscardedCounter,
|
|
packetsOutboundErrorsCounter: packetsOutboundErrorsCounter,
|
|
adapterStats: map[string]cadvisorapi.InterfaceStats{},
|
|
}, nil
|
|
}
|
|
|
|
func (n *networkCounter) getData() ([]cadvisorapi.InterfaceStats, error) {
|
|
packetsReceivedPerSecondData, err := n.packetsReceivedPerSecondCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get packetsReceivedPerSecond perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
packetsSentPerSecondData, err := n.packetsSentPerSecondCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get packetsSentPerSecond perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
bytesReceivedPerSecondData, err := n.bytesReceivedPerSecondCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get bytesReceivedPerSecond perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
bytesSentPerSecondData, err := n.bytesSentPerSecondCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get bytesSentPerSecond perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
packetsReceivedDiscardedData, err := n.packetsReceivedDiscardedCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get packetsReceivedDiscarded perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
packetsReceivedErrorsData, err := n.packetsReceivedErrorsCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get packetsReceivedErrors perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
packetsOutboundDiscardedData, err := n.packetsOutboundDiscardedCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get packetsOutboundDiscarded perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
packetsOutboundErrorsData, err := n.packetsOutboundErrorsCounter.getDataList()
|
|
if err != nil {
|
|
klog.Errorf("Unable to get packetsOutboundErrors perf counter data; err: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
n.mu.Lock()
|
|
defer n.mu.Unlock()
|
|
n.mergeCollectedData(
|
|
packetsReceivedPerSecondData,
|
|
packetsSentPerSecondData,
|
|
bytesReceivedPerSecondData,
|
|
bytesSentPerSecondData,
|
|
packetsReceivedDiscardedData,
|
|
packetsReceivedErrorsData,
|
|
packetsOutboundDiscardedData,
|
|
packetsOutboundErrorsData,
|
|
)
|
|
return n.listInterfaceStats(), nil
|
|
}
|
|
|
|
// mergeCollectedData merges the collected data into cache. It should be invoked under lock protected.
|
|
func (n *networkCounter) mergeCollectedData(packetsReceivedPerSecondData,
|
|
packetsSentPerSecondData,
|
|
bytesReceivedPerSecondData,
|
|
bytesSentPerSecondData,
|
|
packetsReceivedDiscardedData,
|
|
packetsReceivedErrorsData,
|
|
packetsOutboundDiscardedData,
|
|
packetsOutboundErrorsData map[string]uint64) {
|
|
adapters := sets.NewString()
|
|
|
|
// merge the collected data and list of adapters.
|
|
adapters.Insert(n.mergePacketsReceivedPerSecondData(packetsReceivedPerSecondData)...)
|
|
adapters.Insert(n.mergePacketsSentPerSecondData(packetsSentPerSecondData)...)
|
|
adapters.Insert(n.mergeBytesReceivedPerSecondData(bytesReceivedPerSecondData)...)
|
|
adapters.Insert(n.mergeBytesSentPerSecondData(bytesSentPerSecondData)...)
|
|
adapters.Insert(n.mergePacketsReceivedDiscardedData(packetsReceivedDiscardedData)...)
|
|
adapters.Insert(n.mergePacketsReceivedErrorsData(packetsReceivedErrorsData)...)
|
|
adapters.Insert(n.mergePacketsOutboundDiscardedData(packetsOutboundDiscardedData)...)
|
|
adapters.Insert(n.mergePacketsOutboundErrorsData(packetsOutboundErrorsData)...)
|
|
|
|
// delete the cache for non-existing adapters.
|
|
for adapter := range n.adapterStats {
|
|
if !adapters.Has(adapter) {
|
|
delete(n.adapterStats, adapter)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (n *networkCounter) mergePacketsReceivedPerSecondData(packetsReceivedPerSecondData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range packetsReceivedPerSecondData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.RxPackets = newStat.RxPackets + value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergePacketsSentPerSecondData(packetsSentPerSecondData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range packetsSentPerSecondData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.TxPackets = newStat.TxPackets + value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergeBytesReceivedPerSecondData(bytesReceivedPerSecondData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range bytesReceivedPerSecondData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.RxBytes = newStat.RxBytes + value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergeBytesSentPerSecondData(bytesSentPerSecondData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range bytesSentPerSecondData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.TxBytes = newStat.TxBytes + value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergePacketsReceivedDiscardedData(packetsReceivedDiscardedData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range packetsReceivedDiscardedData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.RxDropped = value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergePacketsReceivedErrorsData(packetsReceivedErrorsData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range packetsReceivedErrorsData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.RxErrors = value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergePacketsOutboundDiscardedData(packetsOutboundDiscardedData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range packetsOutboundDiscardedData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.TxDropped = value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) mergePacketsOutboundErrorsData(packetsOutboundErrorsData map[string]uint64) []string {
|
|
var adapters []string
|
|
for adapterName, value := range packetsOutboundErrorsData {
|
|
adapters = append(adapters, adapterName)
|
|
newStat := n.adapterStats[adapterName]
|
|
newStat.Name = adapterName
|
|
newStat.TxErrors = value
|
|
n.adapterStats[adapterName] = newStat
|
|
}
|
|
|
|
return adapters
|
|
}
|
|
|
|
func (n *networkCounter) listInterfaceStats() []cadvisorapi.InterfaceStats {
|
|
stats := make([]cadvisorapi.InterfaceStats, 0, len(n.adapterStats))
|
|
for _, stat := range n.adapterStats {
|
|
stats = append(stats, stat)
|
|
}
|
|
return stats
|
|
}
|