commit
cec96eb68b
@ -56,7 +56,7 @@ func RegisterHandlers(mux httpmux.Mux, m manager.Manager) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Captures the API version, requestType [optional], and remaining request [optional].
|
// Captures the API version, requestType [optional], and remaining request [optional].
|
||||||
var apiRegexp = regexp.MustCompile("/api/([^/]+)/?([^/]+)?(.*)")
|
var apiRegexp = regexp.MustCompile(`/api/([^/]+)/?([^/]+)?(.*)`)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
apiVersion = iota + 1
|
apiVersion = iota + 1
|
||||||
|
@ -172,9 +172,12 @@ func (self *dockerFactory) DebugInfo() map[string][]string {
|
|||||||
return map[string][]string{}
|
return map[string][]string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
version_regexp_string = `(\d+)\.(\d+)\.(\d+)`
|
||||||
|
version_re = regexp.MustCompile(version_regexp_string)
|
||||||
|
)
|
||||||
|
|
||||||
func parseDockerVersion(full_version_string string) ([]int, error) {
|
func parseDockerVersion(full_version_string string) ([]int, error) {
|
||||||
version_regexp_string := "(\\d+)\\.(\\d+)\\.(\\d+)"
|
|
||||||
version_re := regexp.MustCompile(version_regexp_string)
|
|
||||||
matches := version_re.FindAllStringSubmatch(full_version_string, -1)
|
matches := version_re.FindAllStringSubmatch(full_version_string, -1)
|
||||||
if len(matches) != 1 {
|
if len(matches) != 1 {
|
||||||
return nil, fmt.Errorf("version string \"%v\" doesn't match expected regular expression: \"%v\"", full_version_string, version_regexp_string)
|
return nil, fmt.Errorf("version string \"%v\" doesn't match expected regular expression: \"%v\"", full_version_string, version_regexp_string)
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -202,8 +201,6 @@ func scanTcpStats(tcpStatsFile string) (info.TcpStat, error) {
|
|||||||
return stats, fmt.Errorf("failure opening %s: %v", tcpStatsFile, err)
|
return stats, fmt.Errorf("failure opening %s: %v", tcpStatsFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tcpStatLineRE, _ := regexp.Compile("[0-9:].*")
|
|
||||||
|
|
||||||
tcpStateMap := map[string]uint64{
|
tcpStateMap := map[string]uint64{
|
||||||
"01": 0, //ESTABLISHED
|
"01": 0, //ESTABLISHED
|
||||||
"02": 0, //SYN_SENT
|
"02": 0, //SYN_SENT
|
||||||
@ -223,18 +220,24 @@ func scanTcpStats(tcpStatsFile string) (info.TcpStat, error) {
|
|||||||
|
|
||||||
scanner.Split(bufio.ScanLines)
|
scanner.Split(bufio.ScanLines)
|
||||||
|
|
||||||
|
// Discard header line
|
||||||
|
b := scanner.Scan()
|
||||||
|
if !b {
|
||||||
|
return stats, scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
|
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
//skip header
|
|
||||||
matched := tcpStatLineRE.MatchString(line)
|
|
||||||
|
|
||||||
if matched {
|
state := strings.Fields(line)
|
||||||
state := strings.Fields(line)
|
// TCP state is the 4th field.
|
||||||
//#file header tcp state is the 4 filed:
|
// Format: sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
|
||||||
//sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
|
tcpState := state[3]
|
||||||
tcpStateMap[state[3]]++
|
_, ok := tcpStateMap[tcpState]
|
||||||
|
if !ok {
|
||||||
|
return stats, fmt.Errorf("invalid TCP stats line: %v", line)
|
||||||
}
|
}
|
||||||
|
tcpStateMap[tcpState]++
|
||||||
}
|
}
|
||||||
|
|
||||||
stats = info.TcpStat{
|
stats = info.TcpStat{
|
||||||
|
4
fs/fs.go
4
fs/fs.go
@ -34,8 +34,6 @@ import (
|
|||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
var partitionRegex = regexp.MustCompile("^(:?(:?s|xv)d[a-z]+\\d*|dm-\\d+)$")
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LabelSystemRoot = "root"
|
LabelSystemRoot = "root"
|
||||||
LabelDockerImages = "docker-images"
|
LabelDockerImages = "docker-images"
|
||||||
@ -223,6 +221,8 @@ func (self *RealFsInfo) GetFsInfoForPath(mountSet map[string]struct{}) ([]Fs, er
|
|||||||
return filesystems, nil
|
return filesystems, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var partitionRegex = regexp.MustCompile(`^(?:(?:s|xv)d[a-z]+\d*|dm-\d+)$`)
|
||||||
|
|
||||||
func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {
|
func getDiskStatsMap(diskStatsFile string) (map[string]DiskStats, error) {
|
||||||
diskStatsMap := make(map[string]DiskStats)
|
diskStatsMap := make(map[string]DiskStats)
|
||||||
file, err := os.Open(diskStatsFile)
|
file, err := os.Open(diskStatsFile)
|
||||||
|
@ -26,8 +26,8 @@ import (
|
|||||||
var zone = flag.String("zone", "us-central1-f", "Zone the instances are running in")
|
var zone = flag.String("zone", "us-central1-f", "Zone the instances are running in")
|
||||||
var project = flag.String("project", "", "Project the instances are running in")
|
var project = flag.String("project", "", "Project the instances are running in")
|
||||||
|
|
||||||
var gceInternalIpRegexp = regexp.MustCompile(" +networkIP: +([0-9.:]+)\n")
|
var gceInternalIpRegexp = regexp.MustCompile(`\s+networkIP:\s+([0-9.:]+)\n`)
|
||||||
var gceExternalIpRegexp = regexp.MustCompile(" +natIP: +([0-9.:]+)\n")
|
var gceExternalIpRegexp = regexp.MustCompile(`\s+natIP:\s+([0-9.:]+)\n`)
|
||||||
|
|
||||||
// Gets the IP of the specified GCE instance.
|
// Gets the IP of the specified GCE instance.
|
||||||
func GetGceIp(hostname string) (string, error) {
|
func GetGceIp(hostname string) (string, error) {
|
||||||
|
@ -42,7 +42,7 @@ import (
|
|||||||
// Housekeeping interval.
|
// Housekeeping interval.
|
||||||
var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings")
|
var HousekeepingInterval = flag.Duration("housekeeping_interval", 1*time.Second, "Interval between container housekeepings")
|
||||||
|
|
||||||
var cgroupPathRegExp = regexp.MustCompile(".*devices.*:(.*?)[,;$].*")
|
var cgroupPathRegExp = regexp.MustCompile(`.*devices.*:(.*?)[,;$].*`)
|
||||||
|
|
||||||
// Decay value used for load average smoothing. Interval length of 10 seconds is used.
|
// Decay value used for load average smoothing. Interval length of 10 seconds is used.
|
||||||
var loadDecay = math.Exp(float64(-1 * (*HousekeepingInterval).Seconds() / 10))
|
var loadDecay = math.Exp(float64(-1 * (*HousekeepingInterval).Seconds() / 10))
|
||||||
|
@ -152,6 +152,11 @@ func (p testSubcontainersInfoProvider) SubcontainersInfo(string, *info.Container
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
includeRe = regexp.MustCompile(`^(?:(?:# HELP |# TYPE)container_|cadvisor_version_info\{)`)
|
||||||
|
ignoreRe = regexp.MustCompile(`^container_last_seen\{`)
|
||||||
|
)
|
||||||
|
|
||||||
func TestPrometheusCollector(t *testing.T) {
|
func TestPrometheusCollector(t *testing.T) {
|
||||||
prometheus.MustRegister(NewPrometheusCollector(testSubcontainersInfoProvider{}, nil))
|
prometheus.MustRegister(NewPrometheusCollector(testSubcontainersInfoProvider{}, nil))
|
||||||
|
|
||||||
@ -171,8 +176,6 @@ func TestPrometheusCollector(t *testing.T) {
|
|||||||
// (https://github.com/prometheus/client_golang/issues/58), we simply compare
|
// (https://github.com/prometheus/client_golang/issues/58), we simply compare
|
||||||
// verbatim text-format metrics outputs, but ignore certain metric lines
|
// verbatim text-format metrics outputs, but ignore certain metric lines
|
||||||
// whose value depends on the current time or local circumstances.
|
// whose value depends on the current time or local circumstances.
|
||||||
includeRe := regexp.MustCompile("^(?:(?:# HELP |# TYPE)container_|cadvisor_version_info{)")
|
|
||||||
ignoreRe := regexp.MustCompile("^container_last_seen{")
|
|
||||||
for i, want := range wantLines {
|
for i, want := range wantLines {
|
||||||
if !includeRe.MatchString(want) || ignoreRe.MatchString(want) {
|
if !includeRe.MatchString(want) || ignoreRe.MatchString(want) {
|
||||||
continue
|
continue
|
||||||
|
@ -34,12 +34,17 @@ import (
|
|||||||
|
|
||||||
// The utils/machine package contains functions that extract machine-level specs.
|
// The utils/machine package contains functions that extract machine-level specs.
|
||||||
|
|
||||||
var cpuRegExp = regexp.MustCompile("processor\\t*: +([0-9]+)")
|
var (
|
||||||
var coreRegExp = regexp.MustCompile("core id\\t*: +([0-9]+)")
|
cpuRegExp = regexp.MustCompile(`^processor\s*:\s*([0-9]+)$`)
|
||||||
var nodeRegExp = regexp.MustCompile("physical id\\t*: +([0-9]+)")
|
coreRegExp = regexp.MustCompile(`^core id\s*:\s*([0-9]+)$`)
|
||||||
var CpuClockSpeedMHz = regexp.MustCompile("cpu MHz\\t*: +([0-9]+.[0-9]+)")
|
nodeRegExp = regexp.MustCompile(`^physical id\s*:\s*([0-9]+)$`)
|
||||||
var memoryCapacityRegexp = regexp.MustCompile("MemTotal: *([0-9]+) kB")
|
// Power systems have a different format so cater for both
|
||||||
var swapCapacityRegexp = regexp.MustCompile("SwapTotal: *([0-9]+) kB")
|
cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`)
|
||||||
|
memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`)
|
||||||
|
swapCapacityRegexp = regexp.MustCompile(`SwapTotal:\s*([0-9]+) kB`)
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"
|
||||||
|
|
||||||
// GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file.
|
// GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file.
|
||||||
func GetClockSpeed(procInfo []byte) (uint64, error) {
|
func GetClockSpeed(procInfo []byte) (uint64, error) {
|
||||||
@ -49,7 +54,6 @@ func GetClockSpeed(procInfo []byte) (uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// First look through sys to find a max supported cpu frequency.
|
// First look through sys to find a max supported cpu frequency.
|
||||||
const maxFreqFile = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"
|
|
||||||
if utils.FileExists(maxFreqFile) {
|
if utils.FileExists(maxFreqFile) {
|
||||||
val, err := ioutil.ReadFile(maxFreqFile)
|
val, err := ioutil.ReadFile(maxFreqFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -63,15 +67,11 @@ func GetClockSpeed(procInfo []byte) (uint64, error) {
|
|||||||
return maxFreq, nil
|
return maxFreq, nil
|
||||||
}
|
}
|
||||||
// Fall back to /proc/cpuinfo
|
// Fall back to /proc/cpuinfo
|
||||||
matches := CpuClockSpeedMHz.FindSubmatch(procInfo)
|
matches := cpuClockSpeedMHz.FindSubmatch(procInfo)
|
||||||
if len(matches) != 2 {
|
if len(matches) != 2 {
|
||||||
//Check if we are running on Power systems which have a different format
|
return 0, fmt.Errorf("could not detect clock speed from output: %q", string(procInfo))
|
||||||
CpuClockSpeedMHz, _ = regexp.Compile("clock\\t*: +([0-9]+.[0-9]+)MHz")
|
|
||||||
matches = CpuClockSpeedMHz.FindSubmatch(procInfo)
|
|
||||||
if len(matches) != 2 {
|
|
||||||
return 0, fmt.Errorf("could not detect clock speed from output: %q", string(procInfo))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
speed, err := strconv.ParseFloat(string(matches[1]), 64)
|
speed, err := strconv.ParseFloat(string(matches[1]), 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -139,6 +139,9 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
|
|||||||
lastCore := -1
|
lastCore := -1
|
||||||
lastNode := -1
|
lastNode := -1
|
||||||
for _, line := range strings.Split(cpuinfo, "\n") {
|
for _, line := range strings.Split(cpuinfo, "\n") {
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
ok, val, err := extractValue(line, cpuRegExp)
|
ok, val, err := extractValue(line, cpuRegExp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, -1, fmt.Errorf("could not parse cpu info from %q: %v", line, err)
|
return nil, -1, fmt.Errorf("could not parse cpu info from %q: %v", line, err)
|
||||||
@ -157,6 +160,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
|
|||||||
lastNode = -1
|
lastNode = -1
|
||||||
}
|
}
|
||||||
lastThread = thread
|
lastThread = thread
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
ok, val, err = extractValue(line, coreRegExp)
|
ok, val, err = extractValue(line, coreRegExp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -164,6 +168,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
|
|||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
lastCore = val
|
lastCore = val
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
ok, val, err = extractValue(line, nodeRegExp)
|
ok, val, err = extractValue(line, nodeRegExp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -171,6 +176,7 @@ func GetTopology(sysFs sysfs.SysFs, cpuinfo string) ([]info.Node, int, error) {
|
|||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
lastNode = val
|
lastNode = val
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodeIdx, err := addNode(&nodes, lastNode)
|
nodeIdx, err := addNode(&nodes, lastNode)
|
||||||
@ -213,7 +219,7 @@ func extractValue(s string, r *regexp.Regexp) (bool, int, error) {
|
|||||||
if len(matches) == 2 {
|
if len(matches) == 2 {
|
||||||
val, err := strconv.ParseInt(string(matches[1]), 10, 32)
|
val, err := strconv.ParseInt(string(matches[1]), 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, -1, err
|
return false, -1, err
|
||||||
}
|
}
|
||||||
return true, int(val), nil
|
return true, int(val), nil
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func TestTopology(t *testing.T) {
|
|||||||
sysFs.SetCacheInfo(c)
|
sysFs.SetCacheInfo(c)
|
||||||
topology, numCores, err := GetTopology(sysFs, string(testcpuinfo))
|
topology, numCores, err := GetTopology(sysFs, string(testcpuinfo))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to get topology for sample cpuinfo %s", string(testcpuinfo))
|
t.Errorf("failed to get topology for sample cpuinfo %s: %v", string(testcpuinfo), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if numCores != 12 {
|
if numCores != 12 {
|
||||||
|
@ -29,12 +29,11 @@ import (
|
|||||||
"github.com/google/cadvisor/utils"
|
"github.com/google/cadvisor/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var containerRegexp *regexp.Regexp = regexp.MustCompile(
|
var (
|
||||||
`Task in (.*) killed as a result of limit of (.*)`)
|
containerRegexp = regexp.MustCompile(`Task in (.*) killed as a result of limit of (.*)`)
|
||||||
var lastLineRegexp *regexp.Regexp = regexp.MustCompile(
|
lastLineRegexp = regexp.MustCompile(`(^[A-Z][a-z]{2} .*[0-9]{1,2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}) .* Killed process ([0-9]+) \(([\w]+)\)`)
|
||||||
`(^[A-Z]{1}[a-z]{2} .*[0-9]{1,2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}) .* Killed process ([0-9]+) \(([0-9A-Za-z_]+)\)`)
|
firstLineRegexp = regexp.MustCompile(`invoked oom-killer:`)
|
||||||
var firstLineRegexp *regexp.Regexp = regexp.MustCompile(
|
)
|
||||||
`invoked oom-killer:`)
|
|
||||||
|
|
||||||
// struct to hold file from which we obtain OomInstances
|
// struct to hold file from which we obtain OomInstances
|
||||||
type OomParser struct {
|
type OomParser struct {
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/google/cadvisor/utils/sysfs"
|
"github.com/google/cadvisor/utils/sysfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var schedulerRegExp = regexp.MustCompile(".*\\[(.*)\\].*")
|
var schedulerRegExp = regexp.MustCompile(`.*\[(.*)\].*`)
|
||||||
|
|
||||||
// Get information about block devices present on the system.
|
// Get information about block devices present on the system.
|
||||||
// Uses the passed in system interface to retrieve the low level OS information.
|
// Uses the passed in system interface to retrieve the low level OS information.
|
||||||
@ -65,18 +65,14 @@ func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {
|
|||||||
// size is in 512 bytes blocks.
|
// size is in 512 bytes blocks.
|
||||||
disk_info.Size = size * 512
|
disk_info.Size = size * 512
|
||||||
|
|
||||||
sched, err := sysfs.GetBlockDeviceScheduler(name)
|
disk_info.Scheduler = "none"
|
||||||
if err != nil {
|
blkSched, err := sysfs.GetBlockDeviceScheduler(name)
|
||||||
sched = "none"
|
if err == nil {
|
||||||
} else {
|
matches := schedulerRegExp.FindSubmatch([]byte(blkSched))
|
||||||
matches := schedulerRegExp.FindSubmatch([]byte(sched))
|
if len(matches) >= 2 {
|
||||||
if len(matches) < 2 {
|
disk_info.Scheduler = string(matches[1])
|
||||||
sched = "none"
|
|
||||||
} else {
|
|
||||||
sched = string(matches[1])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
disk_info.Scheduler = sched
|
|
||||||
device := fmt.Sprintf("%d:%d", disk_info.Major, disk_info.Minor)
|
device := fmt.Sprintf("%d:%d", disk_info.Major, disk_info.Minor)
|
||||||
diskMap[device] = disk_info
|
diskMap[device] = disk_info
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user