Skip to content

Commit 3573b29

Browse files
authored
Merge pull request #21 from infrawatch/proclimits
Add system.GetOpenedFiles
2 parents 995e6ad + dfd6a51 commit 3573b29

2 files changed

Lines changed: 49 additions & 12 deletions

File tree

system/proc.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,22 @@ import (
1111

1212
// Modifiable constants
1313
var (
14-
ProcLimitColumns = 4
15-
ProcLimitPathFmt = "/proc/%d/limits"
16-
splitRex = regexp.MustCompile(" +")
14+
ProcLimitColumns = 4
15+
ProcLimitPathFmt = "/proc/%d/limits"
16+
ProcOpenedFilesFmt = "/proc/%d/fd"
17+
splitRex = regexp.MustCompile(" +")
1718
)
1819

19-
// GetProcLimits returns limits for the given process. Use -1 for actual process.
20-
func GetProcLimits(PID int) (map[string]map[string]interface{}, error) {
20+
func getProcPath(pathFmt string, PID int) string {
2121
if PID == -1 {
2222
PID = os.Getpid()
2323
}
24+
return fmt.Sprintf(pathFmt, PID)
25+
}
2426

25-
data, err := ioutil.ReadFile(fmt.Sprintf(ProcLimitPathFmt, PID))
27+
// GetProcLimits returns limits for the given process. Use -1 for actual process.
28+
func GetProcLimits(PID int) (map[string]map[string]interface{}, error) {
29+
data, err := ioutil.ReadFile(getProcPath(ProcLimitPathFmt, PID))
2630
if err != nil {
2731
return nil, err
2832
}
@@ -56,3 +60,19 @@ func GetProcLimits(PID int) (map[string]map[string]interface{}, error) {
5660

5761
return out, nil
5862
}
63+
64+
// GetOpenedFiles returns count of opened files by the given process. Use -1 for actual process.
65+
func GetOpenedFiles(PID int) (int, error) {
66+
dir, err := os.Open(getProcPath(ProcOpenedFilesFmt, PID))
67+
if err != nil {
68+
return -1, err
69+
}
70+
71+
files, err := dir.Readdir(-1)
72+
dir.Close()
73+
if err != nil {
74+
return -1, err
75+
}
76+
77+
return len(files), nil
78+
}

tests/system_test.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tests
22

33
import (
4+
"fmt"
45
"io/ioutil"
56
"os"
67
"path"
@@ -34,13 +35,13 @@ func TestProcLimits(t *testing.T) {
3435
require.NoError(t, err)
3536
defer os.RemoveAll(tmpdir)
3637

37-
// save test content
38-
file, err := os.Create(path.Join(tmpdir, "0_limits"))
39-
require.NoError(t, err)
40-
file.WriteString(procLimitData)
41-
require.NoError(t, file.Close())
42-
4338
t.Run("Test parsed limit file", func(t *testing.T) {
39+
// save test content
40+
file, err := os.Create(path.Join(tmpdir, "0_limits"))
41+
require.NoError(t, err)
42+
file.WriteString(procLimitData)
43+
require.NoError(t, file.Close())
44+
4445
system.ProcLimitPathFmt = path.Join(tmpdir, "%d_limits")
4546

4647
expected := map[string]map[string]interface{}{
@@ -131,4 +132,20 @@ func TestProcLimits(t *testing.T) {
131132
assert.Equal(t, expected, parsed, "Did not parse correctly")
132133
})
133134

135+
t.Run("Test opened files from process", func(t *testing.T) {
136+
fdir := path.Join(tmpdir, "0")
137+
err := os.Mkdir(fdir, 0755)
138+
require.NoError(t, err)
139+
140+
for i := 0; i < 10; i++ {
141+
file, err := os.Create(path.Join(fdir, fmt.Sprintf("socket%d", i)))
142+
require.NoError(t, err)
143+
require.NoError(t, file.Close())
144+
}
145+
146+
system.ProcOpenedFilesFmt = path.Join(tmpdir, "%d")
147+
fcount, err := system.GetOpenedFiles(0)
148+
require.NoError(t, err)
149+
assert.Equal(t, 10, fcount)
150+
})
134151
}

0 commit comments

Comments
 (0)