2
# -*- coding: utf-8 -*-
4
# $Id: __init__.py 1525 2012-08-16 16:32:03Z g.rodola $
6
# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
7
# Use of this source code is governed by a BSD-style license that can be
8
# found in the LICENSE file.
10
"""psutil is a module providing convenience functions for managing
11
processes and gather system information in a portable way by using
15
from __future__ import division
18
version_info = tuple([int(num) for num in __version__.split('.')])
22
"Error", "NoSuchProcess", "AccessDenied", "TimeoutExpired",
24
"NUM_CPUS", "TOTAL_PHYMEM", "BOOT_TIME",
25
"version_info", "__version__",
26
"STATUS_RUNNING", "STATUS_IDLE", "STATUS_SLEEPING", "STATUS_DISK_SLEEP",
27
"STATUS_STOPPED", "STATUS_TRACING_STOP", "STATUS_ZOMBIE", "STATUS_DEAD",
28
"STATUS_WAKING", "STATUS_LOCKED",
32
"test", "pid_exists", "get_pid_list", "process_iter", "get_process_list",
33
"virtual_memory", "swap_memory",
34
"cpu_times", "cpu_percent", "per_cpu_percent",
35
"network_io_counters", "disk_io_counters",
50
from psutil.error import Error, NoSuchProcess, AccessDenied, TimeoutExpired
51
from psutil._compat import property, callable, defaultdict
52
from psutil._common import cached_property
53
from psutil._common import (deprecated as _deprecated,
54
nt_disk_iostat as _nt_disk_iostat,
55
nt_net_iostat as _nt_net_iostat,
56
nt_sysmeminfo as _nt_sysmeminfo,
57
isfile_strict as _isfile_strict)
58
from psutil._common import (STATUS_RUNNING, STATUS_IDLE, STATUS_SLEEPING,
59
STATUS_DISK_SLEEP, STATUS_STOPPED,
60
STATUS_TRACING_STOP, STATUS_ZOMBIE, STATUS_DEAD,
61
STATUS_WAKING, STATUS_LOCKED)
63
# import the appropriate module for our platform only
64
if sys.platform.startswith("linux"):
65
import psutil._pslinux as _psplatform
66
from psutil._pslinux import (phymem_buffers,
72
phymem_buffers = _psplatform.phymem_buffers
73
cached_phymem = _psplatform.cached_phymem
75
elif sys.platform.startswith("win32"):
76
import psutil._psmswindows as _psplatform
77
from psutil._psmswindows import (ABOVE_NORMAL_PRIORITY_CLASS,
78
BELOW_NORMAL_PRIORITY_CLASS,
81
NORMAL_PRIORITY_CLASS,
82
REALTIME_PRIORITY_CLASS)
84
elif sys.platform.startswith("darwin"):
85
import psutil._psosx as _psplatform
87
elif sys.platform.startswith("freebsd"):
88
import psutil._psbsd as _psplatform
91
raise NotImplementedError('platform %s is not supported' % sys.platform)
93
__all__.extend(_psplatform.__extra__all__)
95
NUM_CPUS = _psplatform.NUM_CPUS
96
BOOT_TIME = _psplatform.BOOT_TIME
97
TOTAL_PHYMEM = _psplatform.TOTAL_PHYMEM
100
class Process(object):
101
"""Represents an OS process."""
103
def __init__(self, pid):
104
"""Create a new Process object for the given pid.
105
Raises NoSuchProcess if pid does not exist.
109
# platform-specific modules define an _psplatform.Process
110
# implementation class
111
self._platform_impl = _psplatform.Process(pid)
112
self._last_sys_cpu_times = None
113
self._last_proc_cpu_times = None
114
# cache creation time for later use in is_running() method
119
except NoSuchProcess:
120
raise NoSuchProcess(pid, None, 'no process found with pid %s' % pid)
125
name = repr(self.name)
126
except NoSuchProcess:
127
details = "(pid=%s (terminated))" % self.pid
129
details = "(pid=%s)" % (self.pid)
131
details = "(pid=%s, name=%s)" % (pid, name)
132
return "%s.%s%s" % (self.__class__.__module__,
133
self.__class__.__name__, details)
136
return "<%s at %s>" % (self.__str__(), id(self))
138
def as_dict(self, attrs=[], ad_value=None):
139
"""Utility method returning process information as a hashable
142
If 'attrs' is specified it must be a list of strings reflecting
143
available Process class's attribute names (e.g. ['get_cpu_times',
144
'name']) else all public (read only) attributes are assumed.
146
'ad_value' is the value which gets assigned to a dict key in case
147
AccessDenied exception is raised when retrieving that particular
150
excluded_names = set(['send_signal', 'suspend', 'resume', 'terminate',
151
'kill', 'wait', 'is_running', 'as_dict', 'parent',
152
'get_children', 'nice'])
154
for name in set(attrs or dir(self)):
155
if name.startswith('_'):
157
if name.startswith('set_'):
159
if name in excluded_names:
162
attr = getattr(self, name)
164
if name == 'get_cpu_percent':
165
ret = attr(interval=0)
172
except NotImplementedError:
173
# in case of not implemented functionality (may happen
174
# on old or exotic systems) we want to crash only if
175
# the user explicitly asked for that particular attr
179
if name.startswith('get'):
182
elif name == 'getcwd':
189
"""The process pid."""
194
"""The process parent pid."""
195
return self._platform_impl.get_process_ppid()
199
"""Return the parent process as a Process object. If no parent
200
pid is known return None.
206
except NoSuchProcess:
211
"""The process name."""
212
name = self._platform_impl.get_process_name()
213
if os.name == 'posix':
214
# On UNIX the name gets truncated to the first 15 characters.
215
# If it matches the first part of the cmdline we return that
216
# one instead because it's usually more explicative.
217
# Examples are "gnome-keyring-d" vs. "gnome-keyring-daemon".
219
cmdline = self.cmdline
224
extended_name = os.path.basename(cmdline[0])
225
if extended_name.startswith(name):
227
# XXX - perhaps needs refactoring
228
self._platform_impl._process_name = name
233
"""The process executable path. May also be an empty string."""
234
def guess_it(fallback):
235
# try to guess exe from cmdline[0] in absence of a native
237
cmdline = self.cmdline
238
if cmdline and hasattr(os, 'access') and hasattr(os, 'X_OK'):
239
exe = cmdline[0] # the possible exe
240
rexe = os.path.realpath(exe) # ...in case it's a symlink
241
if os.path.isabs(rexe) and os.path.isfile(rexe) \
242
and os.access(rexe, os.X_OK):
244
if isinstance(fallback, AccessDenied):
249
exe = self._platform_impl.get_process_exe()
251
err = sys.exc_info()[1]
252
return guess_it(fallback=err)
255
# underlying implementation can legitimately return an
256
# empty string; if that's the case we don't want to
257
# raise AD while guessing from the cmdline
259
exe = guess_it(fallback=exe)
266
"""The command line process has been called with."""
267
return self._platform_impl.get_process_cmdline()
271
"""The process current status as a STATUS_* constant."""
272
return self._platform_impl.get_process_status()
274
if os.name == 'posix':
278
"""Return a named tuple denoting the process real,
279
effective, and saved user ids.
281
return self._platform_impl.get_process_uids()
285
"""Return a named tuple denoting the process real,
286
effective, and saved group ids.
288
return self._platform_impl.get_process_gids()
292
"""The terminal associated with this process, if any,
295
return self._platform_impl.get_process_terminal()
299
"""The name of the user that owns the process.
300
On UNIX this is calculated by using *real* process uid.
302
if os.name == 'posix':
304
# might happen if python was installed from sources
305
raise ImportError("requires pwd module shipped with standard python")
306
return pwd.getpwuid(self.uids.real).pw_name
308
return self._platform_impl.get_process_username()
311
def create_time(self):
312
"""The process creation time as a floating point number
313
expressed in seconds since the epoch, in UTC.
315
return self._platform_impl.get_process_create_time()
318
"""Return a string representing the process current working
321
return self._platform_impl.get_process_cwd()
323
# Linux, BSD and Windows only
324
if hasattr(_psplatform.Process, "get_process_io_counters"):
326
def get_io_counters(self):
327
"""Return process I/O statistics as a namedtuple including
328
the number of read/write calls performed and the amount of
329
bytes read and written by the process.
331
return self._platform_impl.get_process_io_counters()
334
"""Get process niceness (priority)."""
335
return self._platform_impl.get_process_nice()
337
def set_nice(self, value):
338
"""Set process niceness (priority)."""
339
return self._platform_impl.set_process_nice(value)
341
# available only on Linux
342
if hasattr(_psplatform.Process, "get_process_ionice"):
344
def get_ionice(self):
345
"""Return process I/O niceness (priority) as a namedtuple."""
346
return self._platform_impl.get_process_ionice()
348
def set_ionice(self, ioclass, value=None):
349
"""Set process I/O niceness (priority).
350
ioclass is one of the IOPRIO_CLASS_* constants.
351
iodata is a number which goes from 0 to 7. The higher the
352
value, the lower the I/O priority of the process.
354
return self._platform_impl.set_process_ionice(ioclass, value)
356
# available on Windows and Linux only
357
if hasattr(_psplatform.Process, "get_process_cpu_affinity"):
359
def get_cpu_affinity(self):
360
"""Get process current CPU affinity."""
361
return self._platform_impl.get_process_cpu_affinity()
363
def set_cpu_affinity(self, cpus):
364
"""Set process current CPU affinity.
365
'cpus' is a list of CPUs for which you want to set the
366
affinity (e.g. [0, 1]).
368
return self._platform_impl.set_process_cpu_affinity(cpus)
372
def get_num_handles(self):
373
"""Return the number of handles opened by this process
376
return self._platform_impl.get_num_handles()
378
if os.name == 'posix':
380
def get_num_fds(self):
381
"""Return the number of file descriptors opened by this
382
process (POSIX only).
384
return self._platform_impl.get_num_fds()
386
def get_num_ctx_switches(self):
387
"""Return the number voluntary and involuntary context switches
388
performed by this process.
390
return self._platform_impl.get_num_ctx_switches()
392
def get_num_threads(self):
393
"""Return the number of threads used by this process."""
394
return self._platform_impl.get_process_num_threads()
396
def get_threads(self):
397
"""Return threads opened by process as a list of namedtuples
398
including thread id and thread CPU times (user/system).
400
return self._platform_impl.get_process_threads()
402
def get_children(self, recursive=False):
403
"""Return the children of this process as a list of Process
405
If recursive is True return all the parent descendants.
407
Example (A == this process):
412
│ └─ X (grandchild) ─┐
413
│ └─ Y (great grandchild)
419
>>> p.get_children(recursive=True)
422
Note that in the example above if process X disappears
423
process Y won't be returned either as the reference to
426
if not self.is_running():
427
name = self._platform_impl._process_name
428
raise NoSuchProcess(self.pid, name)
432
for p in process_iter():
434
if p.ppid == self.pid:
435
# if child happens to be older than its parent
436
# (self) it means child's PID has been reused
437
if self.create_time <= p.create_time:
439
except NoSuchProcess:
442
# construct a dict where 'values' are all the processes
443
# having 'key' as their parent
444
table = defaultdict(list)
445
for p in process_iter():
447
table[p.ppid].append(p)
448
except NoSuchProcess:
450
# At this point we have a mapping table where table[self.pid]
451
# are the current process's children.
452
# Below, we look for all descendants recursively, similarly
453
# to a recursive function call.
454
checkpids = [self.pid]
455
for pid in checkpids:
456
for child in table[pid]:
458
# if child happens to be older than its parent
459
# (self) it means child's PID has been reused
460
intime = self.create_time <= child.create_time
461
except NoSuchProcess:
466
if child.pid not in checkpids:
467
checkpids.append(child.pid)
470
def get_cpu_percent(self, interval=0.1):
471
"""Return a float representing the current process CPU
472
utilization as a percentage.
474
When interval is > 0.0 compares process times to system CPU
475
times elapsed before and after the interval (blocking).
477
When interval is 0.0 or None compares process times to system CPU
478
times elapsed since last call, returning immediately.
479
In this case is recommended for accuracy that this function be
480
called with at least 0.1 seconds between calls.
482
blocking = interval is not None and interval > 0.0
484
st1 = sum(cpu_times())
485
pt1 = self._platform_impl.get_cpu_times()
487
st2 = sum(cpu_times())
488
pt2 = self._platform_impl.get_cpu_times()
490
st1 = self._last_sys_cpu_times
491
pt1 = self._last_proc_cpu_times
492
st2 = sum(cpu_times())
493
pt2 = self._platform_impl.get_cpu_times()
494
if st1 is None or pt1 is None:
495
self._last_sys_cpu_times = st2
496
self._last_proc_cpu_times = pt2
499
delta_proc = (pt2.user - pt1.user) + (pt2.system - pt1.system)
500
delta_time = st2 - st1
501
# reset values for next call in case of interval == None
502
self._last_sys_cpu_times = st2
503
self._last_proc_cpu_times = pt2
506
# the utilization split between all CPUs
507
overall_percent = (delta_proc / delta_time) * 100
508
except ZeroDivisionError:
509
# interval was too low
511
# the utilization of a single CPU
512
single_cpu_percent = overall_percent * NUM_CPUS
513
# on posix a percentage > 100 is legitimate
514
# http://stackoverflow.com/questions/1032357/comprehending-top-cpu-usage
515
# on windows we use this ugly hack to avoid troubles with float
517
if os.name != 'posix':
518
if single_cpu_percent > 100.0:
520
return round(single_cpu_percent, 1)
522
def get_cpu_times(self):
523
"""Return a tuple whose values are process CPU user and system
524
times. The same as os.times() but per-process.
526
return self._platform_impl.get_cpu_times()
528
def get_memory_info(self):
529
"""Return a tuple representing RSS (Resident Set Size) and VMS
530
(Virtual Memory Size) in bytes.
532
On UNIX RSS and VMS are the same values shown by ps.
534
On Windows RSS and VMS refer to "Mem Usage" and "VM Size" columns
537
return self._platform_impl.get_memory_info()
539
def get_ext_memory_info(self):
540
"""Return a namedtuple with variable fields depending on the
541
platform representing extended memory information about
542
the process. All numbers are expressed in bytes.
544
return self._platform_impl.get_ext_memory_info()
546
def get_memory_percent(self):
547
"""Compare physical system memory to process resident memory and
548
calculate process memory utilization as a percentage.
550
rss = self._platform_impl.get_memory_info()[0]
552
return (rss / float(TOTAL_PHYMEM)) * 100
553
except ZeroDivisionError:
556
def get_memory_maps(self, grouped=True):
557
"""Return process's mapped memory regions as a list of nameduples
558
whose fields are variable depending on the platform.
560
If 'grouped' is True the mapped regions with the same 'path'
561
are grouped together and the different memory fields are summed.
563
If 'grouped' is False every mapped region is shown as a single
564
entity and the namedtuple will also include the mapped region's
565
address space ('addr') and permission set ('perms').
567
it = self._platform_impl.get_memory_maps()
574
d[path] = map(lambda x, y: x+y, d[path], nums)
577
nt = self._platform_impl.nt_mmap_grouped
578
return [nt(path, *d[path]) for path in d]
580
nt = self._platform_impl.nt_mmap_ext
581
return [nt(*x) for x in it]
583
def get_open_files(self):
584
"""Return files opened by process as a list of namedtuples
585
including absolute file name and file descriptor number.
587
return self._platform_impl.get_open_files()
589
def get_connections(self, kind='inet'):
590
"""Return connections opened by process as a list of namedtuples.
591
The kind parameter filters for connections that fit the following
594
Kind Value Connections using
604
unix UNIX socket (both UDP and TCP protocols)
605
all the sum of all the possible families and protocols
607
return self._platform_impl.get_connections(kind)
609
def is_running(self):
610
"""Return whether this process is running."""
614
# Checking if pid is alive is not enough as the pid might
615
# have been reused by another process.
616
# pid + creation time, on the other hand, is supposed to
617
# identify a process univocally.
618
return self.create_time == \
619
self._platform_impl.get_process_create_time()
620
except NoSuchProcess:
624
def send_signal(self, sig):
625
"""Send a signal to process (see signal module constants).
626
On Windows only SIGTERM is valid and is treated as an alias
629
# safety measure in case the current process has been killed in
630
# meantime and the kernel reused its PID
631
if not self.is_running():
632
name = self._platform_impl._process_name
633
raise NoSuchProcess(self.pid, name)
634
if os.name == 'posix':
636
os.kill(self.pid, sig)
638
err = sys.exc_info()[1]
639
name = self._platform_impl._process_name
640
if err.errno == errno.ESRCH:
641
raise NoSuchProcess(self.pid, name)
642
if err.errno == errno.EPERM:
643
raise AccessDenied(self.pid, name)
646
if sig == signal.SIGTERM:
647
self._platform_impl.kill_process()
649
raise ValueError("only SIGTERM is supported on Windows")
652
"""Suspend process execution."""
653
# safety measure in case the current process has been killed in
654
# meantime and the kernel reused its PID
655
if not self.is_running():
656
name = self._platform_impl._process_name
657
raise NoSuchProcess(self.pid, name)
659
if hasattr(self._platform_impl, "suspend_process"):
660
self._platform_impl.suspend_process()
663
self.send_signal(signal.SIGSTOP)
666
"""Resume process execution."""
667
# safety measure in case the current process has been killed in
668
# meantime and the kernel reused its PID
669
if not self.is_running():
670
name = self._platform_impl._process_name
671
raise NoSuchProcess(self.pid, name)
673
if hasattr(self._platform_impl, "resume_process"):
674
self._platform_impl.resume_process()
677
self.send_signal(signal.SIGCONT)
680
"""Terminate the process with SIGTERM.
681
On Windows this is an alias for kill().
683
self.send_signal(signal.SIGTERM)
686
"""Kill the current process."""
687
# safety measure in case the current process has been killed in
688
# meantime and the kernel reused its PID
689
if not self.is_running():
690
name = self._platform_impl._process_name
691
raise NoSuchProcess(self.pid, name)
692
if os.name == 'posix':
693
self.send_signal(signal.SIGKILL)
695
self._platform_impl.kill_process()
697
def wait(self, timeout=None):
698
"""Wait for process to terminate and, if process is a children
699
of the current one also return its exit code, else None.
701
if timeout is not None and not timeout >= 0:
702
raise ValueError("timeout must be a positive integer")
703
return self._platform_impl.process_wait(timeout)
709
"""Get or set process niceness (priority).
710
Deprecated, use get_nice() instead.
712
msg = "this property is deprecated; use Process.get_nice() method instead"
713
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
714
return self.get_nice()
717
def nice(self, value):
718
# invoked on "p.nice = num"; change process niceness
719
# deprecated in favor of set_nice()
720
msg = "this property is deprecated; use Process.set_nice() method instead"
721
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
722
return self.set_nice(value)
725
class Popen(Process):
726
"""A more convenient interface to stdlib subprocess module.
727
It starts a sub process and deals with it exactly as when using
728
subprocess.Popen class but in addition also provides all the
729
property and methods of psutil.Process class in a single interface:
732
>>> from subprocess import PIPE
733
>>> p = psutil.Popen(["/usr/bin/python", "-c", "print 'hi'"], stdout=PIPE)
737
user(real=1000, effective=1000, saved=1000)
743
>>> p.wait(timeout=2)
747
For method names common to both classes such as kill(), terminate()
748
and wait(), psutil.Process implementation takes precedence.
750
For a complete documentation refers to:
751
http://docs.python.org/library/subprocess.html
754
def __init__(self, *args, **kwargs):
755
self.__subproc = subprocess.Popen(*args, **kwargs)
756
self._pid = self.__subproc.pid
758
self._platform_impl = _psplatform.Process(self._pid)
759
self._last_sys_cpu_times = None
760
self._last_proc_cpu_times = None
765
except NoSuchProcess:
766
raise NoSuchProcess(self._pid, None,
767
"no process found with pid %s" % pid)
770
return list(set(dir(Popen) + dir(subprocess.Popen)))
772
def __getattribute__(self, name):
774
return object.__getattribute__(self, name)
775
except AttributeError:
777
return object.__getattribute__(self.__subproc, name)
778
except AttributeError:
779
raise AttributeError("%s instance has no attribute '%s'"
780
%(self.__class__.__name__, name))
783
# =====================================================================
784
# --- system processes related functions
785
# =====================================================================
787
get_pid_list = _psplatform.get_pid_list
788
pid_exists = _psplatform.pid_exists
793
"""Return a generator yielding a Process class instance for all
794
running processes on the local machine.
796
Every new Process instance is only created once and then cached
797
into an internal table which is updated every time this is used.
799
The sorting order in which processes are yielded is based on
804
_pmap[proc.pid] = proc
810
a = set(get_pid_list())
811
b = set(_pmap.keys())
815
for pid in gone_pids:
817
for pid, proc in sorted(list(_pmap.items()) + \
818
list(dict.fromkeys(new_pids).items())):
820
if proc is None: # new process
823
# use is_running() to check whether PID has been reused by
824
# another process in which case yield a new Process instance
825
if proc.is_running():
829
except NoSuchProcess:
832
# Process creation time can't be determined hence there's
833
# no way to tell whether the pid of the cached process
834
# has been reused. Just return the cached version.
837
# =====================================================================
838
# --- CPU related functions
839
# =====================================================================
841
def cpu_times(percpu=False):
842
"""Return system-wide CPU times as a namedtuple object.
843
Every CPU time represents the time CPU has spent in the given mode.
844
The attributes availability varies depending on the platform.
845
Here follows a list of all available attributes:
851
- irq (Linux, FreeBSD)
854
When percpu is True return a list of nameduples for each CPU.
855
First element of the list refers to first CPU, second element
856
to second CPU and so on.
857
The order of the list is consistent across calls.
860
return _psplatform.get_system_cpu_times()
862
return _psplatform.get_system_per_cpu_times()
865
_last_cpu_times = cpu_times()
866
_last_per_cpu_times = cpu_times(percpu=True)
868
def cpu_percent(interval=0.1, percpu=False):
869
"""Return a float representing the current system-wide CPU
870
utilization as a percentage.
872
When interval is > 0.0 compares system CPU times elapsed before
873
and after the interval (blocking).
875
When interval is 0.0 or None compares system CPU times elapsed
876
since last call or module import, returning immediately.
877
In this case is recommended for accuracy that this function be
878
called with at least 0.1 seconds between calls.
880
When percpu is True returns a list of floats representing the
881
utilization as a percentage for each CPU.
882
First element of the list refers to first CPU, second element
883
to second CPU and so on.
884
The order of the list is consistent across calls.
886
global _last_cpu_times
887
global _last_per_cpu_times
888
blocking = interval is not None and interval > 0.0
890
def calculate(t1, t2):
892
t1_busy = t1_all - t1.idle
895
t2_busy = t2_all - t2.idle
897
# this usually indicates a float precision issue
898
if t2_busy <= t1_busy:
901
busy_delta = t2_busy - t1_busy
902
all_delta = t2_all - t1_all
903
busy_perc = (busy_delta / all_delta) * 100
904
return round(busy_perc, 1)
913
_last_cpu_times = cpu_times()
914
return calculate(t1, _last_cpu_times)
919
tot1 = cpu_times(percpu=True)
922
tot1 = _last_per_cpu_times
923
_last_per_cpu_times = cpu_times(percpu=True)
924
for t1, t2 in zip(tot1, _last_per_cpu_times):
925
ret.append(calculate(t1, t2))
928
# =====================================================================
929
# --- system memory related functions
930
# =====================================================================
932
def virtual_memory():
933
"""Return statistics about system memory usage as a namedtuple
934
including the following fields, expressed in bytes:
937
total physical memory available.
940
the actual amount of available memory that can be given
941
instantly to processes that request more memory in bytes; this
942
is calculated by summing different memory values depending on
943
the platform (e.g. free + buffers + cached on Linux) and it is
944
supposed to be used to monitor actual memory usage in a cross
948
the percentage usage calculated as (total - available) / total * 100
951
memory used, calculated differently depending on the platform and
952
designed for informational purposes only:
953
OSX: active + inactive + wired
954
BSD: active + wired + cached
958
memory not being used at all (zeroed) that is readily available;
959
note that this doesn't reflect the actual memory available
960
(use 'available' instead)
962
Platform-specific fields:
965
memory currently in use or very recently used, and so it is in RAM.
968
memory that is marked as not used.
970
- buffers (BSD, Linux):
971
cache for things like file system metadata.
974
cache for various things.
977
memory that is marked to always stay in RAM. It is never moved to disk.
980
memory that may be simultaneously accessed by multiple processes.
982
The sum of 'used' and 'available' does not necessarily equal total.
983
On Windows 'available' and 'free' are the same.
985
return _psplatform.virtual_memory()
988
"""Return system swap memory statistics as a namedtuple including
989
the following attributes:
991
- total: total swap memory in bytes
992
- used: used swap memory in bytes
993
- free: free swap memory in bytes
994
- percent: the percentage usage
995
- sin: no. of bytes the system has swapped in from disk (cumulative)
996
- sout: no. of bytes the system has swapped out from disk (cumulative)
998
'sin' and 'sout' on Windows are meaningless and always set to 0.
1000
return _psplatform.swap_memory()
1002
# =====================================================================
1003
# --- disks/paritions related functions
1004
# =====================================================================
1006
def disk_usage(path):
1007
"""Return disk usage statistics about the given path as a namedtuple
1008
including total, used and free space expressed in bytes plus the
1011
return _psplatform.get_disk_usage(path)
1013
def disk_partitions(all=False):
1014
"""Return mounted partitions as a list of namedtuples including
1015
device, mount point, filesystem type and mount options (a raw
1016
string separated by commas which may vary depending on the platform).
1018
If "all" parameter is False return physical devices only and ignore
1021
return _psplatform.disk_partitions(all)
1023
def disk_io_counters(perdisk=False):
1024
"""Return system disk I/O statistics as a namedtuple including
1025
the following attributes:
1027
- read_count: number of reads
1028
- write_count: number of writes
1029
- read_bytes: number of bytes read
1030
- write_bytes: number of bytes written
1031
- read_time: time spent reading from disk (in milliseconds)
1032
- write_time: time spent writing to disk (in milliseconds)
1034
If perdisk is True return the same information for every
1035
physical disk installed on the system as a dictionary
1036
with partition names as the keys and the namedutuple
1037
described above as the values.
1039
rawdict = _psplatform.disk_io_counters()
1041
raise RuntimeError("couldn't find any physical disk")
1043
for disk, fields in rawdict.items():
1044
rawdict[disk] = _nt_disk_iostat(*fields)
1047
return _nt_disk_iostat(*[sum(x) for x in zip(*rawdict.values())])
1049
# =====================================================================
1050
# --- network related functions
1051
# =====================================================================
1053
def network_io_counters(pernic=False):
1054
"""Return network I/O statistics as a namedtuple including
1055
the following attributes:
1057
- bytes_sent: number of bytes sent
1058
- bytes_recv: number of bytes received
1059
- packets_sent: number of packets sent
1060
- packets_recv: number of packets received
1061
- errin: total number of errors while receiving
1062
- errout: total number of errors while sending
1063
- dropin: total number of incoming packets which were dropped
1064
- dropout: total number of outgoing packets which were dropped
1065
(always 0 on OSX and BSD)
1067
If pernic is True return the same information for every
1068
network interface installed on the system as a dictionary
1069
with network interface names as the keys and the namedtuple
1070
described above as the values.
1072
rawdict = _psplatform.network_io_counters()
1074
raise RuntimeError("couldn't find any network interface")
1076
for nic, fields in rawdict.items():
1077
rawdict[nic] = _nt_net_iostat(*fields)
1080
return _nt_net_iostat(*[sum(x) for x in zip(*rawdict.values())])
1082
# =====================================================================
1083
# --- other system related functions
1084
# =====================================================================
1087
"""Return users currently connected on the system as a list of
1088
namedtuples including the following attributes.
1090
- user: the name of the user
1091
- terminal: the tty or pseudo-tty associated with the user, if any.
1092
- host: the host name associated with the entry, if any.
1093
- started: the creation time as a floating point number expressed in
1094
seconds since the epoch.
1096
return _psplatform.get_system_users()
1098
# =====================================================================
1099
# --- deprecated functions
1100
# =====================================================================
1103
def get_process_list():
1104
"""Return a list of Process class instances for all running
1105
processes on the local machine (deprecated).
1107
return list(process_iter())
1111
"""Return the amount of total, used and free physical memory
1112
on the system in bytes plus the percentage usage.
1113
Deprecated by psutil.virtual_memory().
1115
mem = virtual_memory()
1116
return _nt_sysmeminfo(mem.total, mem.used, mem.free, mem.percent)
1118
@_deprecated("psutil.swap_memory()")
1119
def virtmem_usage():
1120
return swap_memory()
1122
@_deprecated("psutil.phymem_usage().free")
1124
return phymem_usage().free
1126
@_deprecated("psutil.phymem_usage().used")
1128
return phymem_usage().used
1130
@_deprecated("psutil.virtmem_usage().total")
1131
def total_virtmem():
1132
return virtmem_usage().total
1134
@_deprecated("psutil.virtmem_usage().used")
1136
return virtmem_usage().used
1138
@_deprecated("psutil.virtmem_usage().free")
1139
def avail_virtmem():
1140
return virtmem_usage().free
1143
"""List info of all currently running processes emulating ps aux
1147
from psutil._compat import print_
1149
today_day = datetime.date.today()
1150
templ = "%-10s %5s %4s %4s %7s %7s %-13s %5s %7s %s"
1151
attrs = ['pid', 'username', 'get_cpu_percent', 'get_memory_percent', 'name',
1152
'get_cpu_times', 'create_time', 'get_memory_info']
1153
if os.name == 'posix':
1154
attrs.append('terminal')
1155
print_(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY", "START",
1157
for p in sorted(process_iter(), key=lambda p: p.pid):
1159
pinfo = p.as_dict(attrs, ad_value='')
1160
except NoSuchProcess:
1163
if pinfo['create_time']:
1164
ctime = datetime.datetime.fromtimestamp(pinfo['create_time'])
1165
if ctime.date() == today_day:
1166
ctime = ctime.strftime("%H:%M")
1168
ctime = ctime.strftime("%b%d")
1169
cputime = time.strftime("%M:%S", time.localtime(sum(pinfo['cpu_times'])))
1170
user = pinfo['username']
1171
if os.name == 'nt' and '\\' in user:
1172
user = user.split('\\')[1]
1173
vms = pinfo['memory_info'] and \
1174
int(pinfo['memory_info'].vms / 1024) or '?'
1175
rss = pinfo['memory_info'] and \
1176
int(pinfo['memory_info'].rss / 1024) or '?'
1177
memp = pinfo['memory_percent'] and \
1178
round(pinfo['memory_percent'], 1) or '?'
1179
print_(templ % (user[:10],
1181
pinfo['cpu_percent'],
1185
pinfo.get('terminal', '') or '?',
1188
pinfo['name'].strip() or '?'))
1190
if __name__ == "__main__":
1193
del property, cached_property, division
1194
if sys.version_info < (3, 0):