/Godeps/_workspace/src/github.com/google/cadvisor/utils/sysinfo/sysinfo.go

https://gitlab.com/leetchang/kubernetes · Go · 210 lines · 174 code · 13 blank · 23 comment · 65 complexity · dda3eb5945c0eba345bcd8d9824b640b MD5 · raw file

  1. // Copyright 2014 Google Inc. All Rights Reserved.
  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 sysinfo
  15. import (
  16. "fmt"
  17. "regexp"
  18. "strconv"
  19. "strings"
  20. info "github.com/google/cadvisor/info/v1"
  21. "github.com/google/cadvisor/utils/sysfs"
  22. )
  23. var schedulerRegExp = regexp.MustCompile(".*\\[(.*)\\].*")
  24. // Get information about block devices present on the system.
  25. // Uses the passed in system interface to retrieve the low level OS information.
  26. func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {
  27. disks, err := sysfs.GetBlockDevices()
  28. if err != nil {
  29. return nil, err
  30. }
  31. diskMap := make(map[string]info.DiskInfo)
  32. for _, disk := range disks {
  33. name := disk.Name()
  34. // Ignore non-disk devices.
  35. // TODO(rjnagal): Maybe just match hd, sd, and dm prefixes.
  36. if strings.HasPrefix(name, "loop") || strings.HasPrefix(name, "ram") || strings.HasPrefix(name, "sr") {
  37. continue
  38. }
  39. disk_info := info.DiskInfo{
  40. Name: name,
  41. }
  42. dev, err := sysfs.GetBlockDeviceNumbers(name)
  43. if err != nil {
  44. return nil, err
  45. }
  46. n, err := fmt.Sscanf(dev, "%d:%d", &disk_info.Major, &disk_info.Minor)
  47. if err != nil || n != 2 {
  48. return nil, fmt.Errorf("could not parse device numbers from %s for device %s", dev, name)
  49. }
  50. out, err := sysfs.GetBlockDeviceSize(name)
  51. if err != nil {
  52. return nil, err
  53. }
  54. // Remove trailing newline before conversion.
  55. size, err := strconv.ParseUint(strings.TrimSpace(out), 10, 64)
  56. if err != nil {
  57. return nil, err
  58. }
  59. // size is in 512 bytes blocks.
  60. disk_info.Size = size * 512
  61. sched, err := sysfs.GetBlockDeviceScheduler(name)
  62. if err != nil {
  63. sched = "none"
  64. } else {
  65. matches := schedulerRegExp.FindSubmatch([]byte(sched))
  66. if len(matches) < 2 {
  67. sched = "none"
  68. } else {
  69. sched = string(matches[1])
  70. }
  71. }
  72. disk_info.Scheduler = sched
  73. device := fmt.Sprintf("%d:%d", disk_info.Major, disk_info.Minor)
  74. diskMap[device] = disk_info
  75. }
  76. return diskMap, nil
  77. }
  78. // Get information about network devices present on the system.
  79. func GetNetworkDevices(sysfs sysfs.SysFs) ([]info.NetInfo, error) {
  80. devs, err := sysfs.GetNetworkDevices()
  81. if err != nil {
  82. return nil, err
  83. }
  84. netDevices := []info.NetInfo{}
  85. for _, dev := range devs {
  86. name := dev.Name()
  87. // Ignore docker, loopback, and veth devices.
  88. ignoredDevices := []string{"lo", "veth", "docker"}
  89. ignored := false
  90. for _, prefix := range ignoredDevices {
  91. if strings.HasPrefix(name, prefix) {
  92. ignored = true
  93. break
  94. }
  95. }
  96. if ignored {
  97. continue
  98. }
  99. address, err := sysfs.GetNetworkAddress(name)
  100. if err != nil {
  101. return nil, err
  102. }
  103. mtuStr, err := sysfs.GetNetworkMtu(name)
  104. if err != nil {
  105. return nil, err
  106. }
  107. var mtu int64
  108. n, err := fmt.Sscanf(mtuStr, "%d", &mtu)
  109. if err != nil || n != 1 {
  110. return nil, fmt.Errorf("could not parse mtu from %s for device %s", mtuStr, name)
  111. }
  112. netInfo := info.NetInfo{
  113. Name: name,
  114. MacAddress: strings.TrimSpace(address),
  115. Mtu: mtu,
  116. }
  117. speed, err := sysfs.GetNetworkSpeed(name)
  118. // Some devices don't set speed.
  119. if err == nil {
  120. var s int64
  121. n, err := fmt.Sscanf(speed, "%d", &s)
  122. if err != nil || n != 1 {
  123. return nil, fmt.Errorf("could not parse speed from %s for device %s", speed, name)
  124. }
  125. netInfo.Speed = s
  126. }
  127. netDevices = append(netDevices, netInfo)
  128. }
  129. return netDevices, nil
  130. }
  131. func GetCacheInfo(sysFs sysfs.SysFs, id int) ([]sysfs.CacheInfo, error) {
  132. caches, err := sysFs.GetCaches(id)
  133. if err != nil {
  134. return nil, err
  135. }
  136. info := []sysfs.CacheInfo{}
  137. for _, cache := range caches {
  138. if !strings.HasPrefix(cache.Name(), "index") {
  139. continue
  140. }
  141. cacheInfo, err := sysFs.GetCacheInfo(id, cache.Name())
  142. if err != nil {
  143. return nil, err
  144. }
  145. info = append(info, cacheInfo)
  146. }
  147. return info, nil
  148. }
  149. func GetNetworkStats(name string) (info.InterfaceStats, error) {
  150. // TODO(rjnagal): Take syfs as an argument.
  151. sysFs, err := sysfs.NewRealSysFs()
  152. if err != nil {
  153. return info.InterfaceStats{}, err
  154. }
  155. return getNetworkStats(name, sysFs)
  156. }
  157. func getNetworkStats(name string, sysFs sysfs.SysFs) (info.InterfaceStats, error) {
  158. var stats info.InterfaceStats
  159. var err error
  160. stats.Name = name
  161. stats.RxBytes, err = sysFs.GetNetworkStatValue(name, "rx_bytes")
  162. if err != nil {
  163. return stats, err
  164. }
  165. stats.RxPackets, err = sysFs.GetNetworkStatValue(name, "rx_packets")
  166. if err != nil {
  167. return stats, err
  168. }
  169. stats.RxErrors, err = sysFs.GetNetworkStatValue(name, "rx_errors")
  170. if err != nil {
  171. return stats, err
  172. }
  173. stats.RxDropped, err = sysFs.GetNetworkStatValue(name, "rx_dropped")
  174. if err != nil {
  175. return stats, err
  176. }
  177. stats.TxBytes, err = sysFs.GetNetworkStatValue(name, "tx_bytes")
  178. if err != nil {
  179. return stats, err
  180. }
  181. stats.TxPackets, err = sysFs.GetNetworkStatValue(name, "tx_packets")
  182. if err != nil {
  183. return stats, err
  184. }
  185. stats.TxErrors, err = sysFs.GetNetworkStatValue(name, "tx_errors")
  186. if err != nil {
  187. return stats, err
  188. }
  189. stats.TxDropped, err = sysFs.GetNetworkStatValue(name, "tx_dropped")
  190. if err != nil {
  191. return stats, err
  192. }
  193. return stats, nil
  194. }
  195. func GetSystemUUID(sysFs sysfs.SysFs) (string, error) {
  196. return sysFs.GetSystemUUID()
  197. }