Skip to content

Commit

Permalink
Merge pull request #20 from infrawatch/proclimits
Browse files Browse the repository at this point in the history
Add possibility to get process limits
  • Loading branch information
paramite committed Aug 5, 2021
2 parents 7b12c5e + 4eb8013 commit 995e6ad
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 2 deletions.
58 changes: 58 additions & 0 deletions system/proc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package system

import (
"fmt"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
)

// Modifiable constants
var (
ProcLimitColumns = 4
ProcLimitPathFmt = "/proc/%d/limits"
splitRex = regexp.MustCompile(" +")
)

// GetProcLimits returns limits for the given process. Use -1 for actual process.
func GetProcLimits(PID int) (map[string]map[string]interface{}, error) {
if PID == -1 {
PID = os.Getpid()
}

data, err := ioutil.ReadFile(fmt.Sprintf(ProcLimitPathFmt, PID))
if err != nil {
return nil, err
}

indexes := []string{}
out := make(map[string]map[string]interface{})
for i, line := range strings.Split(string(data), "\n") {
parts := splitRex.Split(line, ProcLimitColumns)
if i == 0 {
indexes = parts
continue
}

value := make(map[string]interface{})
for i, idx := range indexes {
if i == 0 {
continue
}
if len(parts) > i {
if val, err := strconv.Atoi(parts[i]); err == nil {
value[idx] = val
} else {
value[idx] = parts[i]
}
} else {
value[idx] = ""
}
}
out[parts[0]] = value
}

return out, nil
}
3 changes: 1 addition & 2 deletions tests/jsonconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package tests
import (
"fmt"
"io/ioutil"
"log"
"os"
"path"
"testing"
Expand Down Expand Up @@ -66,7 +65,7 @@ func TestJSONConfigValues(t *testing.T) {
// create temporary config file
tmpdir, err := ioutil.TempDir(".", "config_test")
if err != nil {
log.Fatal(err)
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
logpath := path.Join(tmpdir, "test.log")
Expand Down
134 changes: 134 additions & 0 deletions tests/system_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package tests

import (
"io/ioutil"
"os"
"path"
"testing"

"github.com/infrawatch/apputils/system"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const procLimitData = `Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 125751 125751 processes
Max open files 1024 1048576 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 125751 125751 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us`

func TestProcLimits(t *testing.T) {
tmpdir, err := ioutil.TempDir(".", "system_test")
require.NoError(t, err)
defer os.RemoveAll(tmpdir)

// save test content
file, err := os.Create(path.Join(tmpdir, "0_limits"))
require.NoError(t, err)
file.WriteString(procLimitData)
require.NoError(t, file.Close())

t.Run("Test parsed limit file", func(t *testing.T) {
system.ProcLimitPathFmt = path.Join(tmpdir, "%d_limits")

expected := map[string]map[string]interface{}{
"Max cpu time": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "seconds",
},
"Max file size": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "bytes",
},
"Max data size": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "bytes",
},
"Max stack size": {
"Soft Limit": 8388608,
"Hard Limit": "unlimited",
"Units": "bytes",
},
"Max core file size": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "bytes",
},
"Max resident set": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "bytes",
},
"Max processes": {
"Soft Limit": 125751,
"Hard Limit": 125751,
"Units": "processes",
},
"Max open files": {
"Soft Limit": 1024,
"Hard Limit": 1048576,
"Units": "files",
},
"Max locked memory": {
"Soft Limit": 65536,
"Hard Limit": 65536,
"Units": "bytes",
},
"Max address space": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "bytes",
},
"Max file locks": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "locks",
},
"Max pending signals": {
"Soft Limit": 125751,
"Hard Limit": 125751,
"Units": "signals",
},
"Max msgqueue size": {
"Soft Limit": 819200,
"Hard Limit": 819200,
"Units": "bytes",
},
"Max nice priority": {
"Soft Limit": 0,
"Hard Limit": 0,
"Units": "",
},
"Max realtime priority": {
"Soft Limit": 0,
"Hard Limit": 0,
"Units": "",
},
"Max realtime timeout": {
"Soft Limit": "unlimited",
"Hard Limit": "unlimited",
"Units": "us",
},
}

parsed, err := system.GetProcLimits(0)
require.NoError(t, err)
assert.Equal(t, expected, parsed, "Did not parse correctly")
})

}

0 comments on commit 995e6ad

Please sign in to comment.