3

I have a python script to start a process which I want to monitor using Nagios. When I run that script and perform ps -ef on my ubuntu EC2 instance, it shows process as python <filename>.py --arguments. For Nagios to monitor that process using check_procs, we need to supply process name. Here process name becomes 'python'.

/usr/lib/nagios/plugins/check_procs -C python

It returns the output that one python process is running. This is fine when I'm running one python process. But If I'm running multiple python scripts and monitor only few, then I have to give that particular process name. If in the above command, I give python script name, it throws an error. So I want to mask whole python <filename>.py --arguments to some other name so that while performing check_procs, I can give that new name.

If anyone have any idea, please let me know. I have checked other stackoverflow questions which suggest changing python process name using setproctitle but I want to perform it using shell.

Regards,

Sanket

spazm
  • 4,399
  • 31
  • 30
Sanket Dangi
  • 1,185
  • 9
  • 16
  • You want to use a shell to start a Python script, which in turn will start another process. However, you want the shell to start that original Python process with a different process name and arguments to the ones you're actually providing to the shell. Is that correct? – me_and Jan 25 '12 at 13:05
  • Yes..This is what I exactly want to achieve !! – Sanket Dangi Jan 30 '12 at 08:22
  • check_procs is more clever than just looking at the ps 'command' output. It can already detect the name if you use #! lines in your python and execute them directly. [Totally not documented in the man page :( ]. See my answer: http://stackoverflow.com/a/10232406/117714 – spazm Apr 19 '12 at 16:26

6 Answers6

4

You can use the check_procs command to look at arguments, which includes the module name. The following command will let you know if the python module 'module.py' is running.

/usr/lib/nagios/plugins/check_procs -c 1:1 -a module.py -C python

The -c argument lets you set the critical range. 1:1 will trigger a critical status if there is more or less than 1 process that matches running.

The -a argument will filter based on processes that contain the args 'module.py' (change it to the name of the module you want to monitor)

The -C argument will make sure that the process is a python process

If you need help figuring out how to create the service definition, I had to figure that out too. Just let me know.

REFERENCE: check_procs plugin manpage http://nagiosplugins.org/man/check_procs

tomjkidd
  • 56
  • 1
  • 4
2

You can't change the process name from pure Python, although you can use a wrapper (for example, written in C) to do so.

However, what you should do instead is making your program a daemon, and using a pidfile. Have a look at the python Daemon API and its implementation python-daemon.

phihag
  • 278,196
  • 72
  • 453
  • 469
  • this is a much better way to identify the correct process - if you're not already writing a PID file then this is just one of the many reasons you should be. – jmc Jul 06 '16 at 11:53
1

check_procs already handles this situation.

check_procs can tell the difference between scripts launched as an argument to the interpreter vs jobs run directly a hashbang interpreter. Even though both of these look the same in the ps output!! The latter case will not be listed in check_procs -C python!

If you run your scripts explicitly via python: python <filename.py>, then you can monitor them with the check_procs -C python -a filename.py.

If you put #!/usr/bin/python in your scripts and run them as ./filename.py, then you can monitor with check_procs -C filename.py.

Example command line session showing this behavior:

#make test.py directly executable.  See code below
$ chmod a+x test.py

#launch via python explicitly:
$ /usr/bin/python ./test.py &
[1] 27094
$ check_procs -C python && check_procs -C test.py && check_procs -a test.py
PROCS OK: 1 process with command name 'python'
PROCS OK: 0 processes with command name 'test.py'
PROCS OK: 1 process with args 'test.py'

#launch via python implicitly
$ ./test.py &
[2] 27134
$ check_procs -C python && check_procs -C test.py && check_procs -a test.py
PROCS OK: 1 process with command name 'python'
PROCS OK: 1 process with command name 'test.py'
PROCS OK: 2 processes with args 'test.py'

#PS 'COMMAND' output looks the same
$ ps 27094 27134
  PID TTY      STAT   TIME COMMAND
27094 pts/6    S      0:00 /usr/bin/python ./test.py
27134 pts/6    S      0:00 /usr/bin/python ./test.py

#kill the explicit test
$ kill 27094 
[1]  - terminated  /usr/bin/python ./test.py                                                                           
$ check_procs -C python && check_procs -C test.py && check_procs -a test.py
PROCS OK: 0 processes with command name 'python'
PROCS OK: 1 process with command name 'test.py'
PROCS OK: 1 process with args 'test.py'

#kill the implicit test
$ kill 27134
[2]  + terminated  ./test.py                                                                                           
$ check_procs -C python && check_procs -C test.py && check_procs -a test.py
PROCS OK: 0 processes with command name 'python'
PROCS OK: 0 processes with command name 'test.py'
PROCS OK: 0 processes with args 'test.py'

test.py is a python script that sleeps for 2 minutes. It is chmod +x and has a hashbang #! line invoking /usr/bin/python.

#!/usr/bin/python
import time
time.sleep(120)
spazm
  • 4,399
  • 31
  • 30
0

Create a pid file and use that file for the process lookup with nagios.

Ortwin Angermeier
  • 5,957
  • 2
  • 34
  • 34
0

I'm not saying this is the best solution (it wouldn't scale well at all), but you can create a symbolic link to the python command and execute your script using this link. e.g.

ln -s `which python` ~/mypython
~/mypython myscript.py

Scripts launched using the link should show up as mypython in ps.

kindall
  • 178,883
  • 35
  • 278
  • 309
0

You can use subprocess.Popen to change the executable name, but you'd have to use a wrapper script (or some weird fork magic). The following code causes ps to list the executable as kwyjibo /tmp/test.py instead of /usr/bin/python /tmp/test.py:

import subprocess
p = subprocess.Popen(['kwyjibo', '/tmp/test.py'], executable='/usr/bin/python')
nfirvine
  • 1,479
  • 12
  • 23