81 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // +build linux
 | |
| 
 | |
| /*
 | |
|    Copyright The containerd 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 sys
 | |
| 
 | |
| import (
 | |
| 	"bufio"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/opencontainers/runc/libcontainer/system"
 | |
| )
 | |
| 
 | |
| const nanoSecondsPerSecond = 1e9
 | |
| 
 | |
| var clockTicksPerSecond = uint64(system.GetClockTicks())
 | |
| 
 | |
| // GetSystemCPUUsage returns the host system's cpu usage in
 | |
| // nanoseconds. An error is returned if the format of the underlying
 | |
| // file does not match.
 | |
| //
 | |
| // Uses /proc/stat defined by POSIX. Looks for the cpu
 | |
| // statistics line and then sums up the first seven fields
 | |
| // provided. See `man 5 proc` for details on specific field
 | |
| // information.
 | |
| func GetSystemCPUUsage() (uint64, error) {
 | |
| 	var line string
 | |
| 	f, err := os.Open("/proc/stat")
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 	bufReader := bufio.NewReaderSize(nil, 128)
 | |
| 	defer func() {
 | |
| 		bufReader.Reset(nil)
 | |
| 		f.Close()
 | |
| 	}()
 | |
| 	bufReader.Reset(f)
 | |
| 	err = nil
 | |
| 	for err == nil {
 | |
| 		line, err = bufReader.ReadString('\n')
 | |
| 		if err != nil {
 | |
| 			break
 | |
| 		}
 | |
| 		parts := strings.Fields(line)
 | |
| 		switch parts[0] {
 | |
| 		case "cpu":
 | |
| 			if len(parts) < 8 {
 | |
| 				return 0, fmt.Errorf("bad format of cpu stats")
 | |
| 			}
 | |
| 			var totalClockTicks uint64
 | |
| 			for _, i := range parts[1:8] {
 | |
| 				v, err := strconv.ParseUint(i, 10, 64)
 | |
| 				if err != nil {
 | |
| 					return 0, fmt.Errorf("error parsing cpu stats")
 | |
| 				}
 | |
| 				totalClockTicks += v
 | |
| 			}
 | |
| 			return (totalClockTicks * nanoSecondsPerSecond) /
 | |
| 				clockTicksPerSecond, nil
 | |
| 		}
 | |
| 	}
 | |
| 	return 0, fmt.Errorf("bad stats format")
 | |
| }
 | 
