ping multiple Ips with python
.d.hos
dhostetler at sopris.net
Mon Jan 6 13:59:13 EST 2003
Gerhard Haering <gerhard.haering at gmx.de> wrote in message news:<mailman.1041650767.29913.python-list at python.org>...
> * darrell <dgallion1 at yahoo.com> [2003-01-04 03:07 +0000]:
> > Multiple ping sounded like fun.
>
> Indeed :)
>
> > So here's a quick mod to some ping code I found.
>
> I'll try to look at it. I've meanwhile come up with this piece of code
> (unfortunately I can't sucessfully kill the pings, the os.kill only kills the
> 'sh' processes from popen2.Popen3:
>
> If nothing else, the original poster might benefit from the example of using
> Queue.Queue with *one* database logger thread.
>
> #v+
> import threading
> import os, popen2, select, signal
> import Queue
> import time
>
> from pyPgSQL import PgSQL
>
> # (PostgreSQL) database schema:
> # CREATE TABLE LOG(ADDRESS INET, UP BOOL);
>
> HOST_UP = 1
> HOST_DOWN = 0
>
> PING_INTERVAL = 5
>
> def log(s):
> print s
>
> class Pinger(threading.Thread):
> def __init__(self, queue, address, *args, **kwargs):
> self.address = address
> self.queue = queue
> threading.Thread.__init__(self, *args, **kwargs)
> self.stop = 0
>
> def run(self):
> child = popen2.Popen3("ping -i %i %s 2>&1" % (PING_INTERVAL, self.address))
> log("started child %i" % child.pid)
> while 1:
> ready_fds = select.select([child.fromchild], [], [])
>
> line = child.fromchild.readline()
> if line.find("Host is down") >= 0:
> log("host %s is down" % self.address)
> self.queue.put((self.address, HOST_DOWN))
> else:
> log("host %s is up" % self.address)
> self.queue.put((self.address, HOST_UP))
>
> if self.stop:
> os.kill(child.pid, signal.SIGTERM)
> log("killed child %i." % child.pid)
> break
>
> class DbLogger(threading.Thread):
> def __init__(self, queue, *args, **kwargs):
> self.stop = 0
> self.queue = queue
> threading.Thread.__init__(self, *args, **kwargs)
>
> def run(self):
> con = PgSQL.connect()
> cursor = con.cursor()
> while 1:
> if self.stop:
> con.close()
> break
>
> item = self.queue.get()
> cursor.execute("INSERT INTO LOG(ADDRESS, UP) VALUES (%s, %s)",
> (item[0], PgSQL.PgBoolean(item[1])))
> con.commit()
> log("committed.")
>
> def main():
> pinglist = ["127.0.0.1", "192.168.0.1", "192.168.2.1", "192.168.2.10", "192.168.2.11"]
> threads = []
> queue = Queue.Queue()
> for adr in pinglist:
> threads.append(Pinger(queue, adr))
>
> threads.append(DbLogger(queue))
>
> for thread in threads:
> thread.start()
>
> try:
> while 1:
> time.sleep(1)
> log("in main loop.")
> except KeyboardInterrupt:
> pass
>
> for thread in threads:
> thread.stop = 1
>
> for thread in threads:
> thread.join(2.0)
>
> # Ok, I've had enough of you stupid threads.
> os._exit(0)
>
> if __name__ == "__main__":
> main()
> #v-
>
> If you try this out and are annoyed by the remaining 'ping' processes, here's a
> quick *cough* solution ;-)
>
> #v+
> import os, signal, commands
>
> s = commands.getoutput("ps aux|grep ping|grep -v grep")
> for line in s.split("\n"):
> pid = int(line.split()[1])
> os.kill(pid, signal.SIGKILL)
> #v-
>
> Gerhard
Thanks to everyone for the code and suggestions,
Gerhard, I'm trying out your code, as mentioned in the inital post -
I'm fairly new to python, so please bear with me :)
Also, this application has to be run from a windows server, and i was
hoping to execute the script as cgi.
if your still interested, I've been going over the code and have
stripped out the db logging in efforts of getting the multi-threading
working. I'll modify the DbLogger() class to insert into msSQL after I
get the forementioned working...
Here's the stripped down version:
=======================================
import threading
import os, popen2, select, signal
import Queue
import time
HOST_UP = 1
HOST_DOWN = 0
PING_INTERVAL = 5
def log(s):
print s
class Pinger(threading.Thread):
def __init__(self, queue, address, *args, **kwargs):
self.address = address
self.queue = queue
threading.Thread.__init__(self, *args, **kwargs)
self.stop = 0
def run(self):
child = popen2.Popen3("ping -i %i %s 2>&1" % (PING_INTERVAL,
self.address))
log("started child %i" % child.pid)
while 1:
ready_fds = select.select([child.fromchild], [], [])
line = child.fromchild.readline()
if line.find("Host is down") >= 0:
log("host %s is down" % self.address)
self.queue.put((self.address, HOST_DOWN))
else:
log("host %s is up" % self.address)
self.queue.put((self.address, HOST_UP))
if self.stop:
os.kill(child.pid, signal.SIGTERM)
log("killed child %i." % child.pid)
break
def main():
pinglist = ["127.0.0.1"]
threads = []
queue = Queue.Queue()
for adr in pinglist:
threads.append(Pinger(queue, adr))
for thread in threads:
thread.start()
try:
while 1:
time.sleep(1)
log("in main loop.")
except KeyboardInterrupt:
pass
for thread in threads:
thread.stop = 1
for thread in threads:
thread.join(2.0)
# Ok, I've had enough of you stupid threads.
os._exit(0)
if __name__ == "__main__":
main()
====================================
when I run the script, I get the following error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "I:\Python22\lib\threading.py", line 408, in __bootstrap
self.run()
File "I:\Python22\multi_ping.py", line 22, in run
child = popen2.Popen3("ping -i %i %s 2>&1" % (PING_INTERVAL,
self.address))
AttributeError: 'module' object has no attribute 'Popen3'
Then the script continues to loop printing out "in main loop". I'm
asssuming that the script is waiting for a response from the Pinger()
class, and continues to loop because Pinger() never finishes
executing?
any ideas?
thanks in advance, .d.hos
More information about the Python-list
mailing list