chrismiles / psi (http://pypi.python.org/pypi/PSI)
PSI is a Python package providing real-time access to processes and other miscellaneous system information such as architecture, boottime and filesystems. It has a pythonic API which is consistent accross all supported platforms but also exposes platform-specific details where desirable.
| commit 521: | d58144bcce28 |
| parent 515: | 9f3299e624b1 |
| parent 520: | 158df70b9984 |
| branch: | hostmodule |
Merge tip from default branch
Changed (Δ2.6 KB):
raw changeset »
README (16 lines added, 51 lines removed)
setup.py (25 lines added, 7 lines removed)
2 |
2 |
PSI - Python System Information |
3 |
3 |
=============================== |
4 |
4 |
|
5 |
Overview |
|
6 |
======== |
|
7 |
5 |
|
8 |
PSI is a Python module providing direct access to real-time system and |
|
9 |
process information. It is made up of several sub-modules. |
|
10 |
||
11 |
The ``arch`` module gives some information about the system such as the |
|
12 |
system name and version, the machine architecture etc. It has a class |
|
13 |
representing each system and a factory function that will return an |
|
14 |
instance of the class which psi is running on currently. |
|
15 |
||
16 |
The ``process`` module provides an interface to information about |
|
17 |
processes currently running on the system. Each process is |
|
18 |
represented as an instance of the Process class and additionally there |
|
19 |
is a ProcessTable class which is a dictionary of all running |
|
20 |
processes. To know exactly what attributes are available and what |
|
21 |
they mean you should look at the docstrings and examples below but |
|
22 |
important to note is that all the information is collected at |
|
23 |
instantiation time. So the contents of ProcessTable and Process |
|
24 |
instances are really snapshots and will still contain all information |
|
25 |
even after the actual process has gone. |
|
26 |
||
27 |
Lastly there are some general functions available directly under the |
|
28 |
``psi`` namespace such as ``loadavg()``, ``getzoneid()`` etc. Once |
|
29 |
more see the docstrings for detailed information. |
|
30 |
||
31 |
Some information may not be available on all platforms, rather then |
|
32 |
trying to emulate this information these parts of the API just don't |
|
33 |
exists on those platforms. Examples of these are: |
|
34 |
``psi.process.Process.pcpu`` which is not available on Linux, |
|
35 |
``psi.getzoneid()`` which is only available on SunOS 10 and above etc. |
|
36 |
If not all information can be found some attribute descriptors of |
|
37 |
objects might return subclasses of AttributeError, allowing you to use |
|
38 |
generic ``getattr()`` semantics as well as more specifically detect why |
|
39 |
an attribute is not available (insufficient privileges, not |
|
40 |
implemented, ...). |
|
6 |
PSI is a Python package providing real-time access to processes and |
|
7 |
other miscellaneous system information such as architecture, boottime |
|
8 |
and filesystems. It has a pythonic API which is consistent accross all |
|
9 |
supported platforms but also exposes platform-specific details where |
|
10 |
desirable. |
|
41 |
11 |
|
42 |
12 |
|
43 |
13 |
Install |
| … | … | @@ -49,13 +19,13 @@ docstring of setup.py for the exact supp |
49 |
19 |
You will also need a working C compiler and the python development |
50 |
20 |
files. If a system is not supported yet the build will fail. After |
51 |
21 |
building it is best to run the test suite, on some platforms not all |
52 |
tests will pass yet and you would rather know of these problems before |
|
53 |
starting to use PSI. |
|
22 |
tests might pass yet and you would rather know of these problems |
|
23 |
before starting to use PSI. |
|
54 |
24 |
|
55 |
25 |
So to fully install PSI from source:: |
56 |
26 |
|
57 |
27 |
$ python setup.py build |
58 |
$ python setup.py test |
|
28 |
$ python setup.py test |
|
59 |
29 |
$ python setup.py install [<your options>] |
60 |
30 |
|
61 |
31 |
See the Python documentation on installing Python module for more |
| … | … | @@ -91,13 +61,10 @@ Limitations |
91 |
61 |
Solaris |
92 |
62 |
------- |
93 |
63 |
|
94 |
If the module is compiled as 32-bit (which is what will usually happen |
|
95 |
since that tends to be how python is compiled) it will use the ILP32 |
|
96 |
model and will not be able to read the address space of 64-bit |
|
97 |
processes as they use the LP64 model. This means that the full |
|
98 |
argument list and the environment dictionary will not be available. |
|
99 |
The partial argument list can still be retrieved from the |
|
100 |
``psi.process.Process.command`` attribute. |
|
64 |
The argv array is read from the process memory on Solaris. If you do |
|
65 |
not have permissions to do this only the ``command`` and ``argc`` |
|
66 |
attributes of ``psi.process.Process`` will be available and using the |
|
67 |
``args`` attribute will return the appropriate ``AttributeError``. |
|
101 |
68 |
|
102 |
69 |
|
103 |
70 |
Unit Tests |
| … | … | @@ -105,13 +72,11 @@ Unit Tests |
105 |
72 |
|
106 |
73 |
To run the unit tests:: |
107 |
74 |
|
108 |
$ python setup.py test |
|
75 |
$ python setup.py test |
|
109 |
76 |
|
110 |
The --all option will run tests that require superuser privileges, |
|
111 |
this is required to run some test applications under specific |
|
112 |
schedulers and priorities to test if psi does detect these correctly. |
|
113 |
To acquire superuser privileges sudo is used when available, falling |
|
114 |
back to "su -c". |
|
77 |
Some tests require superuser privileges and will be silently skipped |
|
78 |
when not running as root. This is required to run test applications |
|
79 |
with specific schedulers and priorities. |
|
115 |
80 |
|
116 |
81 |
If any tests fail, please copy & paste the output and send operating |
117 |
82 |
system version, python version, python executable format (32/64-bit) |
| … | … | @@ -62,9 +62,14 @@ more see the docstrings for detailed inf |
62 |
62 |
|
63 |
63 |
Some information may not be available on all platforms, rather then |
64 |
64 |
trying to emulate this information these parts of the API just don't |
65 |
exist |
|
65 |
exists on those platforms. Examples of these are: |
|
66 |
66 |
``psi.process.Process.pcpu`` which is not available on Linux, |
67 |
67 |
``psi.getzoneid()`` which is only available on SunOS 10 and above etc. |
68 |
If not all information can be found some attribute descriptors of |
|
69 |
objects might return subclasses of AttributeError, allowing you to use |
|
70 |
generic ``getattr()`` semantics as well as more specifically detect why |
|
71 |
an attribute is not available (insufficient privileges, not |
|
72 |
implemented, ...). |
|
68 |
73 |
|
69 |
74 |
|
70 |
75 |
Supported Platforms |
| … | … | @@ -402,7 +407,9 @@ class TestCommand(Command): |
402 |
407 |
sysconfig.customize_compiler(self.cc) |
403 |
408 |
self.compile_ctests() |
404 |
409 |
if os.uname()[0] == 'AIX': |
405 |
self.compile_aix_ctest |
|
410 |
self.compile_aix_ctestx() |
|
411 |
if os.uname()[0] == 'Linux': |
|
412 |
self.compile_linux_ctests() |
|
406 |
413 |
sys.path.insert(0, self.build_purelib) |
407 |
414 |
sys.path.insert(0, self.build_platlib) |
408 |
415 |
tdir = os.path.join(self._dir, 'tests') |
| … | … | @@ -463,7 +470,7 @@ class TestCommand(Command): |
463 |
470 |
except LinkError: |
464 |
471 |
distutils.log.warn('app64 not built, some tests will be skipped') |
465 |
472 |
|
466 |
def compile_aix_ctest |
|
473 |
def compile_aix_ctests(self): |
|
467 |
474 |
"""Compile AIX specific helper executables from C""" |
468 |
475 |
if not distutils.dep_util.newer('tests/aixapp.c', 'tests/aixapp'): |
469 |
476 |
distutils.log.info('AIX helper app is up-to-date') |
| … | … | @@ -471,6 +478,16 @@ class TestCommand(Command): |
471 |
478 |
distutils.log.info('compiling AIX helper app for tests') |
472 |
479 |
self.cc.link_executable(['tests/aixapp.c'], 'tests/aixapp') |
473 |
480 |
|
481 |
def compile_linux_ctests(self): |
|
482 |
"""Compile Linux specific helper executables from C""" |
|
483 |
if not distutils.dep_util.newer('tests/linux_argvapp.c', |
|
484 |
'tests/linux_argvapp'): |
|
485 |
distutils.log.info('Linux helper app is up-to-data') |
|
486 |
return |
|
487 |
distutils.log.info('compiling Linux helper app for tests') |
|
488 |
self.cc.link_executable(['tests/linux_argvapp.c'], |
|
489 |
'tests/linux_argvapp') |
|
490 |
||
474 |
491 |
|
475 |
492 |
class ValgrindCommand(Command): |
476 |
493 |
description = "runs valgrind on test suite using /opt/pydebug/bin/python" |
| … | … | @@ -514,10 +531,11 @@ class CleanCommand(clean): |
514 |
531 |
for f in files: |
515 |
532 |
if f.endswith('.pyc'): |
516 |
533 |
self._clean_me.append(os.path.join(root, f)) |
517 |
if os.path.exists(os.path.join('tests', 'app32')): |
|
518 |
self._clean_me.append(os.path.join('tests', 'app32')) |
|
519 |
if os.path.exists(os.path.join('tests', 'app64')): |
|
520 |
self._clean_me.append(os.path.join('tests', 'app64')) |
|
534 |
f = lambda x: os.path.join('tests', x) |
|
535 |
helper_apps = map(f, ('app32', 'app64', 'aixapp', 'linux_argvapp')) |
|
536 |
for app in helper_apps: |
|
537 |
if os.path.exists(app): |
|
538 |
self._clean_me.append(app) |
|
521 |
539 |
clean.finalize_options(self) |
522 |
540 |
|
523 |
541 |
def run(self): |
