...

Source file src/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go

Documentation: k8s.io/kubernetes/pkg/kubelet/winstats

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2017 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  // Package winstats provides a client to get node and pod level stats on windows
    21  package winstats
    22  
    23  import (
    24  	"syscall"
    25  	"time"
    26  	"unsafe"
    27  
    28  	cadvisorapi "github.com/google/cadvisor/info/v1"
    29  	cadvisorapiv2 "github.com/google/cadvisor/info/v2"
    30  )
    31  
    32  var (
    33  	procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW")
    34  )
    35  
    36  // Client is an interface that is used to get stats information.
    37  type Client interface {
    38  	WinContainerInfos() (map[string]cadvisorapiv2.ContainerInfo, error)
    39  	WinMachineInfo() (*cadvisorapi.MachineInfo, error)
    40  	WinVersionInfo() (*cadvisorapi.VersionInfo, error)
    41  	GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error)
    42  }
    43  
    44  // StatsClient is a client that implements the Client interface
    45  type StatsClient struct {
    46  	client winNodeStatsClient
    47  }
    48  
    49  type winNodeStatsClient interface {
    50  	startMonitoring() error
    51  	getNodeMetrics() (nodeMetrics, error)
    52  	getNodeInfo() nodeInfo
    53  	getMachineInfo() (*cadvisorapi.MachineInfo, error)
    54  	getVersionInfo() (*cadvisorapi.VersionInfo, error)
    55  }
    56  
    57  type nodeMetrics struct {
    58  	cpuUsageCoreNanoSeconds   uint64
    59  	cpuUsageNanoCores         uint64
    60  	memoryPrivWorkingSetBytes uint64
    61  	memoryCommittedBytes      uint64
    62  	timeStamp                 time.Time
    63  	interfaceStats            []cadvisorapi.InterfaceStats
    64  }
    65  
    66  type nodeInfo struct {
    67  	memoryPhysicalCapacityBytes uint64
    68  	kernelVersion               string
    69  	osImageVersion              string
    70  	// startTime is the time when the node was started
    71  	startTime time.Time
    72  }
    73  
    74  type cpuUsageCoreNanoSecondsCache struct {
    75  	latestValue   uint64
    76  	previousValue uint64
    77  }
    78  
    79  // newClient constructs a Client.
    80  func newClient(statsNodeClient winNodeStatsClient) (Client, error) {
    81  	statsClient := new(StatsClient)
    82  	statsClient.client = statsNodeClient
    83  
    84  	err := statsClient.client.startMonitoring()
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	return statsClient, nil
    90  }
    91  
    92  // WinContainerInfos returns a map of container infos. The map contains node and
    93  // pod level stats. Analogous to cadvisor GetContainerInfoV2 method.
    94  func (c *StatsClient) WinContainerInfos() (map[string]cadvisorapiv2.ContainerInfo, error) {
    95  	infos := make(map[string]cadvisorapiv2.ContainerInfo)
    96  	rootContainerInfo, err := c.createRootContainerInfo()
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	infos["/"] = *rootContainerInfo
   102  
   103  	return infos, nil
   104  }
   105  
   106  // WinMachineInfo returns a cadvisorapi.MachineInfo with details about the
   107  // node machine. Analogous to cadvisor MachineInfo method.
   108  func (c *StatsClient) WinMachineInfo() (*cadvisorapi.MachineInfo, error) {
   109  	return c.client.getMachineInfo()
   110  }
   111  
   112  // WinVersionInfo returns a  cadvisorapi.VersionInfo with version info of
   113  // the kernel and docker runtime. Analogous to cadvisor VersionInfo method.
   114  func (c *StatsClient) WinVersionInfo() (*cadvisorapi.VersionInfo, error) {
   115  	return c.client.getVersionInfo()
   116  }
   117  
   118  func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, error) {
   119  	nodeMetrics, err := c.client.getNodeMetrics()
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	var stats []*cadvisorapiv2.ContainerStats
   125  	stats = append(stats, &cadvisorapiv2.ContainerStats{
   126  		Timestamp: nodeMetrics.timeStamp,
   127  		Cpu: &cadvisorapi.CpuStats{
   128  			Usage: cadvisorapi.CpuUsage{
   129  				Total: nodeMetrics.cpuUsageCoreNanoSeconds,
   130  			},
   131  		},
   132  		CpuInst: &cadvisorapiv2.CpuInstStats{
   133  			Usage: cadvisorapiv2.CpuInstUsage{
   134  				Total: nodeMetrics.cpuUsageNanoCores,
   135  			},
   136  		},
   137  		Memory: &cadvisorapi.MemoryStats{
   138  			WorkingSet: nodeMetrics.memoryPrivWorkingSetBytes,
   139  			Usage:      nodeMetrics.memoryCommittedBytes,
   140  		},
   141  		Network: &cadvisorapiv2.NetworkStats{
   142  			Interfaces: nodeMetrics.interfaceStats,
   143  		},
   144  	})
   145  
   146  	nodeInfo := c.client.getNodeInfo()
   147  	rootInfo := cadvisorapiv2.ContainerInfo{
   148  		Spec: cadvisorapiv2.ContainerSpec{
   149  			CreationTime: nodeInfo.startTime,
   150  			HasCpu:       true,
   151  			HasMemory:    true,
   152  			HasNetwork:   true,
   153  			Memory: cadvisorapiv2.MemorySpec{
   154  				Limit: nodeInfo.memoryPhysicalCapacityBytes,
   155  			},
   156  		},
   157  		Stats: stats,
   158  	}
   159  
   160  	return &rootInfo, nil
   161  }
   162  
   163  // GetDirFsInfo returns filesystem capacity and usage information.
   164  func (c *StatsClient) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) {
   165  	var freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes int64
   166  	var err error
   167  
   168  	ret, _, err := syscall.Syscall6(
   169  		procGetDiskFreeSpaceEx.Addr(),
   170  		4,
   171  		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
   172  		uintptr(unsafe.Pointer(&freeBytesAvailable)),
   173  		uintptr(unsafe.Pointer(&totalNumberOfBytes)),
   174  		uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)),
   175  		0,
   176  		0,
   177  	)
   178  	if ret == 0 {
   179  		return cadvisorapiv2.FsInfo{}, err
   180  	}
   181  
   182  	return cadvisorapiv2.FsInfo{
   183  		Timestamp: time.Now(),
   184  		Capacity:  uint64(totalNumberOfBytes),
   185  		Available: uint64(freeBytesAvailable),
   186  		Usage:     uint64(totalNumberOfBytes - freeBytesAvailable),
   187  	}, nil
   188  }
   189  

View as plain text