-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add possibility to get process limits
- Loading branch information
Showing
3 changed files
with
193 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
}) | ||
|
||
} |