...

Source file src/github.com/prometheus/procfs/proc_limits.go

Documentation: github.com/prometheus/procfs

     1  // Copyright 2018 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package procfs
    15  
    16  import (
    17  	"bufio"
    18  	"fmt"
    19  	"os"
    20  	"regexp"
    21  	"strconv"
    22  )
    23  
    24  // ProcLimits represents the soft limits for each of the process's resource
    25  // limits. For more information see getrlimit(2):
    26  // http://man7.org/linux/man-pages/man2/getrlimit.2.html.
    27  type ProcLimits struct {
    28  	// CPU time limit in seconds.
    29  	CPUTime uint64
    30  	// Maximum size of files that the process may create.
    31  	FileSize uint64
    32  	// Maximum size of the process's data segment (initialized data,
    33  	// uninitialized data, and heap).
    34  	DataSize uint64
    35  	// Maximum size of the process stack in bytes.
    36  	StackSize uint64
    37  	// Maximum size of a core file.
    38  	CoreFileSize uint64
    39  	// Limit of the process's resident set in pages.
    40  	ResidentSet uint64
    41  	// Maximum number of processes that can be created for the real user ID of
    42  	// the calling process.
    43  	Processes uint64
    44  	// Value one greater than the maximum file descriptor number that can be
    45  	// opened by this process.
    46  	OpenFiles uint64
    47  	// Maximum number of bytes of memory that may be locked into RAM.
    48  	LockedMemory uint64
    49  	// Maximum size of the process's virtual memory address space in bytes.
    50  	AddressSpace uint64
    51  	// Limit on the combined number of flock(2) locks and fcntl(2) leases that
    52  	// this process may establish.
    53  	FileLocks uint64
    54  	// Limit of signals that may be queued for the real user ID of the calling
    55  	// process.
    56  	PendingSignals uint64
    57  	// Limit on the number of bytes that can be allocated for POSIX message
    58  	// queues for the real user ID of the calling process.
    59  	MsqqueueSize uint64
    60  	// Limit of the nice priority set using setpriority(2) or nice(2).
    61  	NicePriority uint64
    62  	// Limit of the real-time priority set using sched_setscheduler(2) or
    63  	// sched_setparam(2).
    64  	RealtimePriority uint64
    65  	// Limit (in microseconds) on the amount of CPU time that a process
    66  	// scheduled under a real-time scheduling policy may consume without making
    67  	// a blocking system call.
    68  	RealtimeTimeout uint64
    69  }
    70  
    71  const (
    72  	limitsFields    = 4
    73  	limitsUnlimited = "unlimited"
    74  )
    75  
    76  var (
    77  	limitsMatch = regexp.MustCompile(`(Max \w+\s{0,1}?\w*\s{0,1}\w*)\s{2,}(\w+)\s+(\w+)`)
    78  )
    79  
    80  // NewLimits returns the current soft limits of the process.
    81  //
    82  // Deprecated: Use p.Limits() instead.
    83  func (p Proc) NewLimits() (ProcLimits, error) {
    84  	return p.Limits()
    85  }
    86  
    87  // Limits returns the current soft limits of the process.
    88  func (p Proc) Limits() (ProcLimits, error) {
    89  	f, err := os.Open(p.path("limits"))
    90  	if err != nil {
    91  		return ProcLimits{}, err
    92  	}
    93  	defer f.Close()
    94  
    95  	var (
    96  		l = ProcLimits{}
    97  		s = bufio.NewScanner(f)
    98  	)
    99  
   100  	s.Scan() // Skip limits header
   101  
   102  	for s.Scan() {
   103  		//fields := limitsMatch.Split(s.Text(), limitsFields)
   104  		fields := limitsMatch.FindStringSubmatch(s.Text())
   105  		if len(fields) != limitsFields {
   106  			return ProcLimits{}, fmt.Errorf("%w: couldn't parse %q line %q", ErrFileParse, f.Name(), s.Text())
   107  		}
   108  
   109  		switch fields[1] {
   110  		case "Max cpu time":
   111  			l.CPUTime, err = parseUint(fields[2])
   112  		case "Max file size":
   113  			l.FileSize, err = parseUint(fields[2])
   114  		case "Max data size":
   115  			l.DataSize, err = parseUint(fields[2])
   116  		case "Max stack size":
   117  			l.StackSize, err = parseUint(fields[2])
   118  		case "Max core file size":
   119  			l.CoreFileSize, err = parseUint(fields[2])
   120  		case "Max resident set":
   121  			l.ResidentSet, err = parseUint(fields[2])
   122  		case "Max processes":
   123  			l.Processes, err = parseUint(fields[2])
   124  		case "Max open files":
   125  			l.OpenFiles, err = parseUint(fields[2])
   126  		case "Max locked memory":
   127  			l.LockedMemory, err = parseUint(fields[2])
   128  		case "Max address space":
   129  			l.AddressSpace, err = parseUint(fields[2])
   130  		case "Max file locks":
   131  			l.FileLocks, err = parseUint(fields[2])
   132  		case "Max pending signals":
   133  			l.PendingSignals, err = parseUint(fields[2])
   134  		case "Max msgqueue size":
   135  			l.MsqqueueSize, err = parseUint(fields[2])
   136  		case "Max nice priority":
   137  			l.NicePriority, err = parseUint(fields[2])
   138  		case "Max realtime priority":
   139  			l.RealtimePriority, err = parseUint(fields[2])
   140  		case "Max realtime timeout":
   141  			l.RealtimeTimeout, err = parseUint(fields[2])
   142  		}
   143  		if err != nil {
   144  			return ProcLimits{}, err
   145  		}
   146  	}
   147  
   148  	return l, s.Err()
   149  }
   150  
   151  func parseUint(s string) (uint64, error) {
   152  	if s == limitsUnlimited {
   153  		return 18446744073709551615, nil
   154  	}
   155  	i, err := strconv.ParseUint(s, 10, 64)
   156  	if err != nil {
   157  		return 0, fmt.Errorf("%s: couldn't parse value %q: %w", ErrFileParse, s, err)
   158  	}
   159  	return i, nil
   160  }
   161  

View as plain text