Recipe13.12.Monitoring a Network with HTTP


Recipe 13.12. Monitoring a Network with HTTP

Credit: Magnus Lyckå

Problem

You want to implement special-purpose HTTP servers to enable you to monitor your network.

Solution

The Python Standard Library BaseHTTPServer module makes it easy to implement special-purpose HTTP servers. For example, here is a special-purpose HTTP server program that runs local commands on the server host to get the data for replies to each GET request:

import BaseHTTPServer, shutil, os from cStringIO import StringIO class MyHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):     # HTTP paths we serve, and what commandline-commands we serve them with     cmds = {'/ping': 'ping www.thinkware.se',             '/netstat' : 'netstat -a',             '/tracert': 'tracert www.thinkware.se',             '/srvstats': 'net statistics server',             '/wsstats': 'net statistics workstation',             '/route' : 'route print',             }     def do_GET(self):         """ Serve a GET request. """         f = self.send_head( )         if f:             f = StringIO( )             machine = os.popen('hostname').readlines( )[0]             if self.path == '/':                 heading = "Select a command to run on %s" % (machine)                 body = (self.getMenu( ) +                         "<p>The screen won't update until the selected "                         "command has finished. Please be patient.")             else:                 heading = "Execution of ``%s'' on %s" % (                            self.cmds[self.path], machine)                 cmd = self.cmds[self.path]                 body = '<a href="/">Main Menu&lt;/a&gt;<pre>%s</pre>\n' % \                        os.popen(cmd).read( )                 # Translation CP437 -> Latin 1 needed for Swedish Windows.                 body = body.decode('cp437').encode('latin1')             f.write("<html><head><title>%s</title></head>\n" % heading)             f.write('<body><H1>%s</H1>\n' % (heading))             f.write(body)             f.write('</body></html>\n')             f.seek(0)             self.copyfile(f, self.wfile)             f.close( )         return f     def do_HEAD(self):         """ Serve a HEAD request. """         f = self.send_head( )         if f:             f.close( )     def send_head(self):         path = self.path         if not path in ['/'] + self.cmds.keys( ):             head = 'Command "%s" not found. Try one of these:<ul>' % path             msg = head + self.getMenu( )             self.send_error(404, msg)             return None         self.send_response(200)         self.send_header("Content-type", 'text/html')         self.end_headers( )         f = StringIO( )         f.write("A test %s\n" % self.path)         f.seek(0)         return f     def getMenu(self):         keys = self.cmds.keys( )         keys.sort( )         msg = [  ]         for k in keys:             msg.append('<li><a href="%s">%s => %s&lt;/a&gt;</li>' %(                                      k,  k,    self.cmds[k]))         msg.append('</ul>')         return "\n".join(msg)     def copyfile(self, source, outputfile):         shutil.copyfileobj(source, outputfile) def main(HandlerClass = MyHTTPRequestHandler,          ServerClass = BaseHTTPServer.HTTPServer):     BaseHTTPServer.test(HandlerClass, ServerClass) if _ _name_ _ == '_ _main_ _':     main( )

Discussion

The Python Standard Library module BaseHTTPServer makes it easy to set up custom web servers on an internal network. This way, you can run commands on various machines by just visiting those servers with a browser. The code in this recipe is Windows-specific, indeed specific to the version of Windows normally run in Sweden, because it knows about code page 437 providing the encoding for the various commands' results. The commands themselves are Windows ones, but that's just as easy to customize for your own purposes as the encoding issuefor example, using traceroute (the Unix spelling of the command) instead of tracert (the way Windows spells it).

In this recipe, all substantial work is performed by external commands invoked by os.popen calls. Of course, it would be perfectly feasible to satisfy some or all of the requests by running actual Python code within the same process as the web server. We would normally not worry about concurrency issues for this kind of special-purpose, ad hoc, administrative server (unlike most web servers): the scenario it's intended to cover is one system administrator sitting at her system and visiting, with her browser, various machines on the network being administered/monitoredconcurrency is not really needed. If your scenario is somewhat different so that you do need concurrency, then multithreading and asynchronous operations, shown in several other recipes, are your fundamental options.

See Also

Documentation for the standard library modules BaseHTTPServer, shutil, os, and cStringIO in the Library Reference and Python in a Nutshell.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net