Unverified Commit 4e3d8d46 authored by Xin.Zh's avatar Xin.Zh Committed by GitHub

Merge pull request #37 from dubbogo/feature/runtime

Add: get host/container cpu/mem info
parents 6acc198d 928960b8
......@@ -16,6 +16,8 @@ github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/pbnjay/memory v0.0.0-20201129165224-b12e5d931931 h1:EeWknjeRU+R3O4ghG7XZCpgSfJNStZyEP8aWyQwJM8s=
github.com/pbnjay/memory v0.0.0-20201129165224-b12e5d931931/go.mod h1:RMU2gJXhratVxBDTFeOdNhd540tG57lt9FIUV0YLvIQ=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
......
......@@ -63,8 +63,8 @@ func (d *Page) HasData() bool {
return d.GetDataSize() > 0
}
// New will create an instance
func New(requestOffset int, pageSize int,
// NewPage will create an instance
func NewPage(requestOffset int, pageSize int,
data []interface{}, totalSize int) *Page {
remain := totalSize % pageSize
......
......@@ -27,7 +27,7 @@ import (
func TestNewDefaultPage(t *testing.T) {
data := make([]interface{}, 10)
page := New(121, 10, data, 499)
page := NewPage(121, 10, data, 499)
assert.Equal(t, 10, page.GetDataSize())
assert.Equal(t, 121, page.GetOffset())
......@@ -37,6 +37,6 @@ func TestNewDefaultPage(t *testing.T) {
assert.True(t, page.HasNext())
assert.True(t, page.HasData())
page = New(492, 10, data, 499)
page = NewPage(492, 10, data, 499)
assert.False(t, page.HasNext())
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 gxfilepath
import (
"fmt"
"os"
)
// Exists returns whether the given file or directory exists
func Exists(path string) (bool, error) {
_, err := os.Lstat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
// FileExists checks whether a file exists in the given path. It also fails if
// the path points to a directory or there is an error when trying to check the file.
func FileExists(path string) (bool, error) {
info, err := os.Lstat(path)
if err != nil {
return false, err
}
if info.IsDir() {
return false, fmt.Errorf("%q is a directory", path)
}
return true, nil
}
// DirExists checks whether a directory exists in the given path. It also fails
// if the path is a file rather a directory or there is an error checking whether it exists.
func DirExists(path string) (bool, error) {
info, err := os.Lstat(path)
if err != nil {
return false, err
}
if !info.IsDir() {
return false, fmt.Errorf("%q is a file", path)
}
return true, nil
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 gxfilepath
import (
"testing"
)
import (
"github.com/stretchr/testify/assert"
)
func TestFileExists(t *testing.T) {
file := "./path_test.go"
ok, err := Exists(file)
assert.True(t, ok)
assert.Nil(t, err)
ok, err = DirExists(file)
assert.False(t, ok)
assert.NotNil(t, err)
ok, err = FileExists(file)
assert.True(t, ok)
assert.Nil(t, err)
file = "./path_test1.go"
ok, err = Exists(file)
assert.False(t, ok)
assert.Nil(t, err)
ok, err = DirExists(file)
assert.False(t, ok)
assert.NotNil(t, err)
ok, err = FileExists(file)
assert.False(t, ok)
assert.NotNil(t, err)
}
func TestDirExists(t *testing.T) {
file := "./"
ok, err := Exists(file)
assert.True(t, ok)
assert.Nil(t, err)
ok, err = DirExists(file)
assert.True(t, ok)
assert.Nil(t, err)
ok, err = FileExists(file)
assert.False(t, ok)
assert.NotNil(t, err)
file = "./go"
ok, err = Exists(file)
assert.False(t, ok)
assert.Nil(t, err)
ok, err = DirExists(file)
assert.False(t, ok)
assert.NotNil(t, err)
ok, err = FileExists(file)
assert.False(t, ok)
assert.NotNil(t, err)
}
......@@ -31,7 +31,7 @@ import (
func TestGoSafe(t *testing.T) {
times := int32(1)
wg := sync.WaitGroup{}
var wg sync.WaitGroup
GoSafely(&wg,
false,
func() {
......@@ -60,7 +60,7 @@ func TestGoSafe(t *testing.T) {
func TestGoUnterminated(t *testing.T) {
times := uint64(1)
wg := sync.WaitGroup{}
var wg sync.WaitGroup
GoUnterminated(
func() {
if atomic.AddUint64(&times, 1) == 2 {
......
......@@ -28,9 +28,14 @@ import (
)
import (
"github.com/shirou/gopsutil/mem"
"github.com/shirou/gopsutil/process"
)
import (
"github.com/dubbogo/gost/path/filepath"
)
var (
CurrentPID = os.Getpid()
)
......@@ -39,6 +44,36 @@ const (
cgroupMemLimitPath = "/sys/fs/cgroup/memory/memory.limit_in_bytes"
)
// GetCPUNum gets current os's cpu number
func GetCPUNum() int {
return runtime.NumCPU()
}
// GetMemoryStat gets current os's memory size in bytes
func GetMemoryStat() (total, used, free uint64, usedPercent float64) {
stat, err := mem.VirtualMemory()
if err != nil {
return 0, 0, 0, 0
}
return stat.Total, stat.Used, stat.Free, stat.UsedPercent
}
// IsCgroup checks whether current os is a container or not
func IsCgroup() bool {
ok, _ := gxfilepath.Exists(cgroupMemLimitPath)
if ok {
return true
}
return false
}
// GetCgroupMemoryLimit returns a container's total memory in bytes
func GetCgroupMemoryLimit() (uint64, error) {
return readUint(cgroupMemLimitPath)
}
// GetThreadNum gets current process's thread number
func GetThreadNum() int {
return pprof.Lookup("threadcreate").Count()
......@@ -124,10 +159,6 @@ func readUint(path string) (uint64, error) {
return parseUint(strings.TrimSpace(string(v)), 10, 64)
}
func GetCgroupMemoryLimit() (uint64, error) {
return readUint(cgroupMemLimitPath)
}
// GetCgroupProcessMemoryPercent gets current process's memory usage percent in cgroup env
func GetCgroupProcessMemoryPercent() (float64, error) {
p, err := process.NewProcess(int32(os.Getpid()))
......
......@@ -22,7 +22,10 @@ import (
"time"
)
func TestProcessSysStat(t *testing.T) {
func TestSysStat(t *testing.T) {
t.Logf("current os cpu number %d", GetCPUNum())
total, used, free, usedPercent := GetMemoryStat()
t.Logf("memory: limit %d bytes, used %d bytes, free %d bytes, usedPercent %f", total, used, free, usedPercent)
t.Logf("current prcess thread number %d", GetThreadNum())
go func() {
time.Sleep(10e9)
......@@ -40,16 +43,18 @@ func TestProcessSysStat(t *testing.T) {
t.Logf("process cpu stat %v", cpu)
size := 100 * 1024 * 1024
bytes := make([]byte, size)
_ = bytes[:size-1]
arr := make([]byte, size)
for idx := range arr {
arr[idx] = byte(idx / 255)
}
memoryStat, err := GetProcessMemoryStat()
if err != nil {
t.Errorf("GetProcessMemoryStat() = error %+v", err)
}
t.Logf("process memory usage stat %v", memoryStat)
//if memoryStat <= uint64(size) {
// t.Errorf("memory usage stat %d < %d", memoryStat, size)
//}
//t.Logf("process memory usage stat %v", memoryStat)
if memoryStat <= uint64(size) {
t.Errorf("memory usage stat %d < %d", memoryStat, size)
}
memoryUsage, err := GetProcessMemoryPercent()
if err != nil {
......@@ -57,4 +62,17 @@ func TestProcessSysStat(t *testing.T) {
}
t.Logf("process memory usage percent %v", memoryUsage)
if IsCgroup() {
memoryLimit, err := GetCgroupMemoryLimit()
if err != nil {
t.Errorf("GetCgroupMemoryLimit() = error %+v", err)
}
t.Logf("CGroupMemoryLimit() = %d", memoryLimit)
memoryPercent, err := GetCgroupProcessMemoryPercent()
if err != nil {
t.Errorf("GetCgroupProcessMemoryPercent(ps:%d) = error %+v", CurrentPID, err)
}
t.Logf("GetCgroupProcessMemoryPercent(ps:%d) = %+v", CurrentPID, memoryPercent)
}
}
......@@ -81,8 +81,9 @@ func TestTaskPoolSimple(t *testing.T) {
}
wg.Wait()
if taskCnt != atomic.LoadInt64(cnt) {
t.Error("want ", taskCnt, " got ", *cnt)
cntValue := atomic.LoadInt64(cnt)
if taskCnt != cntValue {
t.Error("want ", taskCnt, " got ", cntValue)
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment