PyXR

c:\python24\lib\site-packages\win32\lib \ win32pdhutil.py



0001 """Utilities for the win32 Performance Data Helper module
0002 
0003 Example:
0004   To get a single bit of data:
0005   >>> import win32pdhutil
0006   >>> win32pdhutil.GetPerformanceAttributes("Memory", "Available Bytes")
0007   6053888
0008   >>> win32pdhutil.FindPerformanceAttributesByName("python", counter="Virtual Bytes")
0009   [22278144]
0010   
0011   First example returns data which is not associated with any specific instance.
0012   
0013   The second example reads data for a specific instance - hence the list return - 
0014   it would return one result for each instance of Python running.
0015 
0016   In general, it can be tricky finding exactly the "name" of the data you wish to query.  
0017   Although you can use <om win32pdh.EnumObjectItems>(None,None,(eg)"Memory", -1) to do this, 
0018   the easiest way is often to simply use PerfMon to find out the names.
0019 """
0020 
0021 import win32pdh, string, time
0022 
0023 error = win32pdh.error
0024 
0025 # Handle some localization issues.
0026 # see http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q287/1/59.asp&NoWebContent=1
0027 # Build a map of english_counter_name: counter_id
0028 counter_english_map = {}
0029 
0030 def find_pdh_counter_localized_name(english_name, machine_name = None):
0031         if not counter_english_map:
0032                 import win32api, win32con
0033                 counter_reg_value = win32api.RegQueryValueEx(win32con.HKEY_PERFORMANCE_DATA, "Counter 009")
0034                 counter_list = counter_reg_value[0]
0035                 for i in range(0, len(counter_list) - 1, 2):
0036                         try:
0037                                 counter_id = int(counter_list[i])
0038                         except ValueError:
0039                                 continue
0040                         counter_english_map[counter_list[i+1].lower()] = counter_id
0041         return win32pdh.LookupPerfNameByIndex(machine_name, counter_english_map[english_name.lower()])
0042 
0043 def GetPerformanceAttributes(object, counter, instance = None, inum=-1, format = win32pdh.PDH_FMT_LONG, machine=None):
0044         # NOTE: Many counters require 2 samples to give accurate results,
0045         # including "% Processor Time" (as by definition, at any instant, a
0046         # thread's CPU usage is either 0 or 100).  To read counters like this,
0047         # you should copy this function, but keep the counter open, and call
0048         # CollectQueryData() each time you need to know.
0049         # See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
0050         # My older explanation for this was that the "AddCounter" process forced
0051         # the CPU to 100%, but the above makes more sense :)
0052         path = win32pdh.MakeCounterPath( (machine,object,instance, None, inum,counter) )
0053         hq = win32pdh.OpenQuery()
0054         try:
0055                 hc = win32pdh.AddCounter(hq, path)
0056                 try:
0057                         win32pdh.CollectQueryData(hq)
0058                         type, val = win32pdh.GetFormattedCounterValue(hc, format)
0059                         return val
0060                 finally:
0061                         win32pdh.RemoveCounter(hc)
0062         finally:
0063                 win32pdh.CloseQuery(hq)
0064 
0065 def FindPerformanceAttributesByName(instanceName, object = None, counter = None, format = win32pdh.PDH_FMT_LONG, machine = None, bRefresh=0):
0066         """Find peformance attributes by (case insensitive) instance name.
0067         
0068         Given a process name, return a list with the requested attributes.
0069         Most useful for returning a tuple of PIDs given a process name.
0070         """
0071         if object is None: object = find_pdh_counter_localized_name("Process", machine)
0072         if counter is None: counter = find_pdh_counter_localized_name("ID Process", machine)
0073         if bRefresh: # PDH docs say this is how you do a refresh.
0074                 win32pdh.EnumObjects(None, machine, 0, 1)
0075         instanceName = string.lower(instanceName)
0076         items, instances = win32pdh.EnumObjectItems(None,None,object, -1)
0077         # Track multiple instances.
0078         instance_dict = {}
0079         for instance in instances:
0080                 try:
0081                         instance_dict[instance] = instance_dict[instance] + 1
0082                 except KeyError:
0083                         instance_dict[instance] = 0
0084                 
0085         ret = []
0086         for instance, max_instances in instance_dict.items():
0087                 for inum in xrange(max_instances+1):
0088                         if string.lower(instance) == instanceName:
0089                                 ret.append(GetPerformanceAttributes(object, counter, instance, inum, format, machine))
0090         return ret
0091 
0092 def ShowAllProcesses():
0093         object = "Process"
0094         items, instances = win32pdh.EnumObjectItems(None,None,object, win32pdh.PERF_DETAIL_WIZARD)
0095         # Need to track multiple instances of the same name.
0096         instance_dict = {}
0097         for instance in instances:
0098                 try:
0099                         instance_dict[instance] = instance_dict[instance] + 1
0100                 except KeyError:
0101                         instance_dict[instance] = 0
0102                 
0103         # Bit of a hack to get useful info.
0104         items = ["ID Process"] + items[:5]
0105         print "Process Name", string.join(items,",")
0106         for instance, max_instances in instance_dict.items():
0107                 for inum in xrange(max_instances+1):
0108                         hq = win32pdh.OpenQuery()
0109                         hcs = []
0110                         for item in items:
0111                                 path = win32pdh.MakeCounterPath( (None,object,instance, None, inum, item) )
0112                                 hcs.append(win32pdh.AddCounter(hq, path))
0113                         win32pdh.CollectQueryData(hq)
0114                         # as per http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262938, some "%" based
0115                         # counters need two collections
0116                         time.sleep(0.01)
0117                         win32pdh.CollectQueryData(hq)
0118                         print "%-15s\t" % (instance[:15]),
0119                         for hc in hcs:
0120                                 type, val = win32pdh.GetFormattedCounterValue(hc, win32pdh.PDH_FMT_LONG)
0121                                 print "%5d" % (val),
0122                                 win32pdh.RemoveCounter(hc)
0123                         print
0124                         win32pdh.CloseQuery(hq)
0125 
0126 def BrowseCallBackDemo(counter):
0127         machine, object, instance, parentInstance, index, counterName = \
0128                 win32pdh.ParseCounterPath(counter)
0129 
0130         result = GetPerformanceAttributes(object, counterName, instance, index, win32pdh.PDH_FMT_DOUBLE, machine)
0131         print "Value of '%s' is" % counter, result
0132         print "Added '%s' on object '%s' (machine %s), instance %s(%d)-parent of %s" % (counterName, object, machine, instance, index, parentInstance)
0133 
0134 def browse( callback = BrowseCallBackDemo, title="Python Browser", level=win32pdh.PERF_DETAIL_WIZARD):
0135         print "Virtual Bytes = ", FindPerformanceAttributesByName("python", counter="Virtual Bytes")         
0136         print "Available Bytes = ", GetPerformanceAttributes("Memory", "Available Bytes")
0137 
0138 if __name__=='__main__':
0139         ShowAllProcesses()
0140         print "Browsing for counters..."
0141         browse()
0142 

Generated by PyXR 0.9.4
SourceForge.net Logo