cadvisor.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package cadvisor
  15. import (
  16. "flag"
  17. "fmt"
  18. "net/http"
  19. "os"
  20. "path"
  21. "time"
  22. "github.com/google/cadvisor/cache/memory"
  23. cadvisormetrics "github.com/google/cadvisor/container"
  24. "github.com/google/cadvisor/container/containerd"
  25. _ "github.com/google/cadvisor/container/containerd/install"
  26. "github.com/google/cadvisor/events"
  27. cadvisorapi "github.com/google/cadvisor/info/v1"
  28. cadvisorapiv2 "github.com/google/cadvisor/info/v2"
  29. "github.com/google/cadvisor/manager"
  30. "github.com/google/cadvisor/utils/sysfs"
  31. "yunion.io/x/log"
  32. "yunion.io/x/pkg/errors"
  33. )
  34. const (
  35. // The amount of time for which to keep stats in memory.
  36. statsCacheDuration = 2 * time.Minute
  37. maxHousekeepingInterval = 15 * time.Second
  38. defaultHousekeepingInterval = 10 * time.Second
  39. allowDynamicHousekeeping = true
  40. )
  41. func init() {
  42. ep := "/var/run/onecloud/containerd/containerd.sock"
  43. containerd.ArgContainerdEndpoint = &ep
  44. // REF: k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go
  45. // override cadvisor flag defaults.
  46. flagOverrides := map[string]string{
  47. // Override the default cadvisor housekeeping interval.
  48. "housekeeping_interval": defaultHousekeepingInterval.String(),
  49. // Disable event storage by default.
  50. "event_storage_event_limit": "default=0",
  51. "event_storage_age_limit": "default=0",
  52. }
  53. for name, defaultValue := range flagOverrides {
  54. if f := flag.Lookup(name); f != nil {
  55. f.DefValue = defaultValue
  56. f.Value.Set(defaultValue)
  57. } else {
  58. log.Errorf("Expected cAdvisor flag %q not found", name)
  59. }
  60. }
  61. }
  62. type cadvisorClient struct {
  63. manager.Manager
  64. rootPath string
  65. imageFsInfoProvider ImageFsInfoProvider
  66. }
  67. func New(imageFsInfoProvider ImageFsInfoProvider, rootPath string, cgroupRoots []string) (Interface, error) {
  68. includedMetrics := cadvisormetrics.MetricSet{
  69. cadvisormetrics.CpuUsageMetrics: struct{}{},
  70. cadvisormetrics.MemoryUsageMetrics: struct{}{},
  71. cadvisormetrics.CpuLoadMetrics: struct{}{},
  72. cadvisormetrics.DiskIOMetrics: struct{}{},
  73. cadvisormetrics.NetworkUsageMetrics: struct{}{},
  74. cadvisormetrics.AcceleratorUsageMetrics: struct{}{},
  75. cadvisormetrics.AppMetrics: struct{}{},
  76. cadvisormetrics.ProcessMetrics: struct{}{},
  77. cadvisormetrics.DiskUsageMetrics: struct{}{},
  78. }
  79. duration := maxHousekeepingInterval
  80. allowDynamic := allowDynamicHousekeeping
  81. housekeepingConfig := manager.HouskeepingConfig{
  82. Interval: &duration,
  83. AllowDynamic: &allowDynamic,
  84. }
  85. // Create the cAdvisor container manager
  86. sysFs := sysfs.NewRealSysFs()
  87. m, err := manager.New(memory.New(statsCacheDuration, nil), sysFs, housekeepingConfig, includedMetrics, http.DefaultClient, cgroupRoots, nil, "", time.Duration(0))
  88. if err != nil {
  89. return nil, errors.Wrap(err, "new cadvisor manager")
  90. }
  91. if _, err := os.Stat(rootPath); err != nil {
  92. if os.IsNotExist(err) {
  93. if err := os.MkdirAll(path.Clean(rootPath), 0750); err != nil {
  94. return nil, errors.Wrapf(err, "creating root direcotory %q", rootPath)
  95. }
  96. } else {
  97. return nil, errors.Wrapf(err, "failed to stat %q", rootPath)
  98. }
  99. }
  100. return &cadvisorClient{
  101. imageFsInfoProvider: imageFsInfoProvider,
  102. rootPath: rootPath,
  103. Manager: m,
  104. }, nil
  105. }
  106. func (cc *cadvisorClient) Start() error {
  107. return cc.Manager.Start()
  108. }
  109. func (cc *cadvisorClient) ContainerInfo(name string, req *cadvisorapi.ContainerInfoRequest) (*cadvisorapi.ContainerInfo, error) {
  110. return cc.GetContainerInfo(name, req)
  111. }
  112. func (cc *cadvisorClient) ContainerInfoV2(name string, options cadvisorapiv2.RequestOptions) (map[string]cadvisorapiv2.ContainerInfo, error) {
  113. return cc.GetContainerInfoV2(name, options)
  114. }
  115. func (cc *cadvisorClient) VersionInfo() (*cadvisorapi.VersionInfo, error) {
  116. return cc.GetVersionInfo()
  117. }
  118. func (cc *cadvisorClient) SubcontainerInfo(name string, req *cadvisorapi.ContainerInfoRequest) (map[string]*cadvisorapi.ContainerInfo, error) {
  119. infos, err := cc.SubcontainersInfo(name, req)
  120. if err != nil && len(infos) == 0 {
  121. return nil, err
  122. }
  123. result := make(map[string]*cadvisorapi.ContainerInfo, len(infos))
  124. for _, info := range infos {
  125. result[info.Name] = info
  126. }
  127. return result, err
  128. }
  129. func (cc *cadvisorClient) MachineInfo() (*cadvisorapi.MachineInfo, error) {
  130. return cc.GetMachineInfo()
  131. }
  132. func (cc *cadvisorClient) ImagesFsInfo() (cadvisorapiv2.FsInfo, error) {
  133. label, err := cc.imageFsInfoProvider.ImageFsInfoLabel()
  134. if err != nil {
  135. return cadvisorapiv2.FsInfo{}, err
  136. }
  137. return cc.getFsInfo(label)
  138. }
  139. func (cc *cadvisorClient) RootFsInfo() (cadvisorapiv2.FsInfo, error) {
  140. return cc.GetDirFsInfo(cc.rootPath)
  141. }
  142. func (cc *cadvisorClient) getFsInfo(label string) (cadvisorapiv2.FsInfo, error) {
  143. res, err := cc.GetFsInfo(label)
  144. if err != nil {
  145. return cadvisorapiv2.FsInfo{}, err
  146. }
  147. if len(res) == 0 {
  148. return cadvisorapiv2.FsInfo{}, fmt.Errorf("failed to find information for the filesystem labeled %q", label)
  149. }
  150. // TODO(vmarmol): Handle this better when a label has more than one image filesystem.
  151. if len(res) > 1 {
  152. log.Warningf("More than one filesystem labeled %q: %#v. Only using the first one", label, res)
  153. }
  154. return res[0], nil
  155. }
  156. func (cc *cadvisorClient) WatchEvents(request *events.Request) (*events.EventChannel, error) {
  157. return cc.WatchForEvents(request)
  158. }