96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
import time
|
|
import psutil
|
|
import sys
|
|
|
|
from amplify.agent.common.util import subp
|
|
|
|
|
|
__author__ = "Mike Belov"
|
|
__copyright__ = "Copyright (C) Nginx, Inc. All rights reserved."
|
|
__license__ = ""
|
|
__maintainer__ = "Mike Belov"
|
|
__email__ = "dedm@nginx.com"
|
|
|
|
|
|
class Process(psutil.Process):
|
|
def cpu_percent(self, interval=None):
|
|
"""
|
|
Rewrites original method to return two values (system and user) instead of one (overall)
|
|
|
|
Return a float representing the current process CPU
|
|
utilization as a percentage.
|
|
|
|
When interval is 0.0 or None (default) compares process times
|
|
to system CPU times elapsed since last call, returning
|
|
immediately (non-blocking). That means that the first time
|
|
this is called it will return a meaningful 0.0 value.
|
|
|
|
When interval is > 0.0 compares process times to system CPU
|
|
times elapsed before and after the interval (blocking).
|
|
|
|
In this case is recommended for accuracy that this function
|
|
be called with at least 0.1 seconds between calls.
|
|
"""
|
|
blocking = interval is not None and interval > 0.0
|
|
num_cpus = psutil.cpu_count()
|
|
|
|
if psutil.POSIX:
|
|
def timer():
|
|
return psutil._timer() * num_cpus
|
|
else:
|
|
def timer():
|
|
return sum(psutil.cpu_times())
|
|
if blocking:
|
|
st1 = timer()
|
|
pt1 = self._proc.cpu_times()
|
|
time.sleep(interval)
|
|
st2 = timer()
|
|
pt2 = self._proc.cpu_times()
|
|
else:
|
|
st1 = self._last_sys_cpu_times
|
|
pt1 = self._last_proc_cpu_times
|
|
st2 = timer()
|
|
pt2 = self._proc.cpu_times()
|
|
if st1 is None or pt1 is None:
|
|
self._last_sys_cpu_times = st2
|
|
self._last_proc_cpu_times = pt2
|
|
return 0.0, 0.0
|
|
|
|
delta_user = pt2.user - pt1.user
|
|
delta_system = pt2.system - pt1.system
|
|
delta_time = st2 - st1
|
|
# reset values for next call in case of interval == None
|
|
self._last_sys_cpu_times = st2
|
|
self._last_proc_cpu_times = pt2
|
|
|
|
try:
|
|
# The utilization split between all CPUs.
|
|
# Note: a percentage > 100 is legitimate as it can result
|
|
# from a process with multiple threads running on different
|
|
# CPU cores, see:
|
|
# http://stackoverflow.com/questions/1032357
|
|
# https://github.com/giampaolo/psutil/issues/474
|
|
user_percent = ((delta_user / delta_time) * 100) * num_cpus
|
|
system_percent = ((delta_system / delta_time) * 100) * num_cpus
|
|
except ZeroDivisionError:
|
|
# interval was too low
|
|
return 0.0, 0.0
|
|
else:
|
|
return user_percent, system_percent
|
|
|
|
def rlimit_nofile(self):
|
|
if hasattr(self, 'rlimit'):
|
|
return self.rlimit(psutil.RLIMIT_NOFILE)[1]
|
|
|
|
elif sys.platform.startswith('freebsd'):
|
|
procstat_out, _ = subp.call("procstat -l %s | grep 'openfiles' | awk '{print $5}'" % self.pid, check=False)
|
|
if procstat_out:
|
|
return int(procstat_out[0])
|
|
|
|
else:
|
|
# fallback for old systems without rlimit
|
|
cat_limits, _ = subp.call("cat /proc/%s/limits | grep 'Max open files' | awk '{print $5}'" % self.pid, check=False)
|
|
if cat_limits:
|
|
return int(cat_limits[0])
|