December 15, 2008

Python - Get Remote Windows Metrics Script

In a recent blog post, I introduced a script for remotely monitoring Windows machines. It is used to retrieve performance/health metrics. It uses WMI (Windows Management Instrumentation) to interact with the Windows machine and its Win32 classes.

Now I will show how you an example of using the module (which I named "machine_stats.py"). I call it from a multithreaded controller to poll multiple machines in parallel.

The script below reads a list of Host Names (or IP's) from a file named "machines.txt". It then spawns a thread for each machine to be monitored and grabs each health metric. Results are printed to STDOUT so you can pipe it to a file (it is in csv format) to analyze. You can call this script at regular intervals to continuously monitor a set of machines.

#!/usr/bin/env python
# (c) Corey Goldberg (corey@goldb.org) 2008


import time
import threading
import pythoncom
import machine_stats



# set these to the Windows login name with admin privileges
user_name = 'corey'
pwd = 'secret'
        
        
        
def main():           
    host_names = [line.strip() for line in open('machines.txt', 'r').readlines()]
    metric_store = MetricStore()
               
    # gather metrics in threads
    for host in host_names:
        mp = MetricsProbe(host, metric_store)
        mp.start()
    while len(threading.enumerate()) > 1:  # wait for threads to finish
        time.sleep(.25)
    
        

class MetricsProbe(threading.Thread):
    def __init__(self, host, metric_store):
        threading.Thread.__init__(self)
        self.host = host
        self.metric_store = metric_store
        
    def run(self):
        pythoncom.CoInitialize()  # need this for multithreading COM/WMI
        try:
            uptime = machine_stats.get_uptime(self.host, user_name, pwd)
            cpu = machine_stats.get_cpu(self.host, user_name, pwd)
            mem_mbyte = machine_stats.get_mem_mbytes(self.host, user_name, pwd)
            mem_pct = machine_stats.get_mem_pct(self.host, user_name, pwd)            
        except:
            uptime = 0
            cpu = 0
            mem_mbyte = 0
            mem_pct = 0
            print 'error getting stats from host: ' + self.host
        self.metric_store.uptimes[self.host] = uptime
        self.metric_store.cpus[self.host] = cpu
        self.metric_store.mem_mbytes[self.host] = mem_mbyte
        self.metric_store.mem_pcts[self.host] = mem_pct
        print '%s,uptime:%d,cpu:%d,mem_mbyte:%d,mem_pct:%d' \
            % (self.host, uptime, cpu, mem_mbyte, mem_pct)
                


class MetricStore(object):
    def __init__(self):
        self.uptimes = {}
        self.cpus = {}
        self.mem_mbytes = {}
        self.mem_pcts = {}
            


if __name__ == '__main__':
    main()

Output is a single line like this:

12/15/08 08:10:33,server2,uptime:158,cpu:5,mem_mbyte:1125,mem_pct:29

Usage Instructions:

  • Download the Code from here: monitor_win_machines.zip
  • Edit "machines.txt" and add your own Hosts/IPs
  • Edit the username/password in "monitor_machines.py"
  • Run the "monitor_machines.py" script from the command line.

You could continuously pipe the output to text file like this to build your results file:

$> python monitor_machines.py >> output.txt

4 comments:

Unknown said...

I've had very good luck with the Python WMI library. I've used it quite extensively with good results to do all sorts of WMI-related things with some reasonable abstraction.

Unknown said...

Never mind, I saw you used it already!

Anonymous said...

Corey i am using pylot for my performance testing, Can u tell me how can i know the CPU utilization of remote LINUX machines? ie.. i want to run a test with n agents and check CPU utilization of the server which is a LINUX machine..

Advance thx,
Murali.

Corey Goldberg said...

on *nix I mostly use system tools, and do remote collection over ssh if I need to.