in metric/system/process/process_linux_common.go [445:484]
func getFDStats(hostfs resolve.Resolver, pid int) (ProcFDInfo, error) {
state := ProcFDInfo{}
path := hostfs.Join("proc", strconv.Itoa(pid), "limits")
data, err := os.ReadFile(path)
if err != nil {
return state, fmt.Errorf("error opening file %s: %w", path, err)
}
for _, line := range strings.Split(string(data), "\n") {
if strings.HasPrefix(line, "Max open files") {
fields := strings.Fields(line)
if len(fields) == 6 {
softLimit, err := strconv.ParseUint(fields[3], 10, 64)
if err != nil {
return state, fmt.Errorf("error parsing limits value %s for pid %d: %w", fields[3], pid, err)
}
state.Limit.Soft = opt.UintWith(softLimit)
hardLimit, err := strconv.ParseUint(fields[4], 10, 64)
if err != nil {
return state, fmt.Errorf("error parsing limits value %s for pid %d: %w", fields[3], pid, err)
}
state.Limit.Hard = opt.UintWith(hardLimit)
}
}
}
pathFD := hostfs.Join("proc", strconv.Itoa(pid), "fd")
fds, err := os.ReadDir(pathFD)
if errors.Is(err, os.ErrPermission) { // ignore permission errors, passthrough other data
return state, nil
} else if err != nil {
return state, fmt.Errorf("error reading FD directory for pid %d: %w", pid, err)
}
state.Open = opt.UintWith(uint64(len(fds)))
return state, nil
}