def get_counter_val(counter_path, *args, **kwargs): try: sleep = float(kwargs['sleep'][0]) except (KeyError, TypeError, IndexError): sleep = 0 try: factor = int(kwargs['factor'][0]) except (KeyError, TypeError, IndexError): factor = 0 # Allow using PDH_FMT_LONG for certain counter types if it is required fmt = win32pdh.PDH_FMT_DOUBLE try: fmt = int(kwargs['format'][0]) if fmt == 1: fmt = win32pdh.PDH_FMT_LONG except (KeyError, TypeError, IndexError): pass query = win32pdh.OpenQuery() try: counter = win32pdh.AddEnglishCounter(query, counter_path) try: if factor != 0: # Multiply results by 10^(factor) to get around limitations on threshold types win32pdh.SetCounterScaleFactor(counter, factor) win32pdh.CollectQueryData(query) if sleep != 0: time.sleep(sleep) win32pdh.CollectQueryData(query) _, _, _, _, _, _, _, info, _ = win32pdh.GetCounterInfo( counter, False) _, value = win32pdh.GetFormattedCounterValue(counter, fmt) finally: win32pdh.RemoveCounter(counter) finally: win32pdh.CloseQuery(query) unit = info[-1] if not isinstance(value, (int, long)): value = round(value, 2) return [value, unit]
def get_all_values(self): ret = {} # self will retrieve the list of all object names in the class (i.e. all the network interface # names in the class "network interface" win32pdh.CollectQueryData(self.hq) for inst, counter_handle in self.counterdict.iteritems(): try: t, val = win32pdh.GetFormattedCounterValue(counter_handle, self._precision) ret[inst] = val except Exception as e: # exception usually means self type needs two data points to calculate. Wait # a bit and try again time.sleep(DATA_POINT_INTERVAL) win32pdh.CollectQueryData(self.hq) # if we get exception self time, just return it up try: t, val = win32pdh.GetFormattedCounterValue(counter_handle, self._precision) ret[inst] = val except Exception as e: raise e return ret
def getcpuload(): """ Returns total CPU usage as fraction (0..1). Warning: side-effect: sleeps for 0.1 second to do diff """ # mempath = win32pdh.MakeCounterPath((None, "Memory", None, None, -1, "Available MBytes")) cpupath = win32pdh.MakeCounterPath((None, "Processor", "_Total", None, -1, "% Processor Time")) query = win32pdh.OpenQuery(None, 0) counter = win32pdh.AddCounter(query, cpupath, 0) win32pdh.CollectQueryData(query) # Collect must be called twice for CPU, see http://support.microsoft.com/kb/262938 time.sleep(0.1) win32pdh.CollectQueryData(query) status, value = win32pdh.GetFormattedCounterValue(counter, win32pdh.PDH_FMT_LONG) return float(value) / 100.0
def __win32getProfileAttribute(self, object, instance, inum, counter): # make the path, open and collect the query path = win32pdh.MakeCounterPath((None, object, instance, None, inum, counter)) query = win32pdh.OpenQuery() hcounter = win32pdh.AddCounter(query, path) win32pdh.CollectQueryData(query) # format the counter value value = None try: value = win32pdh.GetFormattedCounterValue(hcounter, win32pdh.PDH_FMT_LONG)[1] except Exception: pass # tidy up and return the value win32pdh.RemoveCounter(hcounter) win32pdh.CloseQuery(query) return value
def GetCounterValue(hq, hc): """Returns the current value of the given counter Args: hq: Handle of the query for the counter hc: Handle of the counter Returns: The current value of the counter """ try: win32pdh.CollectQueryData(hq) type, val = win32pdh.GetFormattedCounterValue(hc, win32pdh.PDH_FMT_LONG) return val except: return None
def getProcessIdByName(self, procName): _object = "Process" instances = self.objlist() val = None vals = [] if procName in instances : hq = win32pdh.OpenQuery() hcs = [] item = "ID Process" path = win32pdh.MakeCounterPath( (None,_object,procName, None, 0, item) ) hcs.append(win32pdh.AddCounter(hq, path)) win32pdh.CollectQueryData(hq) time.sleep(0.01) win32pdh.CollectQueryData(hq) for hc in hcs: t, val = win32pdh.GetFormattedCounterValue(hc,win32pdh.PDH_FMT_LONG) vals.append(val) win32pdh.RemoveCounter(hc) win32pdh.CloseQuery(hq) return vals
def GetProcessID(name): object = "Process" items, instances = win32pdh.EnumObjectItems(None, None, object, win32pdh.PERF_DETAIL_WIZARD) val = None if name in instances: hq = win32pdh.OpenQuery() hcs = [] item = "ID Process" path = win32pdh.MakeCounterPath((None, object, name, None, 0, item)) hcs.append(win32pdh.AddCounter(hq, path)) win32pdh.CollectQueryData(hq) time.sleep(0.01) win32pdh.CollectQueryData(hq) for hc in hcs: type, val = win32pdh.GetFormattedCounterValue( hc, win32pdh.PDH_FMT_LONG) win32pdh.RemoveCounter(hc) win32pdh.CloseQuery(hq) return val
def get_process_ids(self): # Credit: http://code.activestate.com/recipes/303339-getting-process-information-on-windows/ import win32pdh _, instances = win32pdh.EnumObjectItems(None, None, 'process', win32pdh.PERF_DETAIL_WIZARD) instance_count = instances.count(self.process_name) if instance_count == 0: return None pids = [] for inum in range(instance_count): hq = win32pdh.OpenQuery() path = win32pdh.MakeCounterPath( (None, 'process', self.process_name, None, inum, 'ID Process')) counter_handle = win32pdh.AddCounter(hq, path) win32pdh.CollectQueryData(hq) _, pid = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG) win32pdh.CloseQuery(hq) pids.append(pid) return pids
def list(): #each instance is a process, you can have multiple processes w/same name junk, instances = win32pdh.EnumObjectItems(None,None,'process', win32pdh.PERF_DETAIL_WIZARD) procs=[] proc_dict={} for instance in instances: proc_dict[instance]=0 for instance, max_instances in proc_dict.items(): try: for inum in range(max_instances+1): hq = win32pdh.OpenQuery() # initializes the query handle path = win32pdh.MakeCounterPath( (None,'process',instance, None, inum,'ID Process') ) counter_handle=win32pdh.AddCounter(hq, path) win32pdh.CollectQueryData(hq) #collects data for the counter type, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG) procs.append({'name': instance, 'pid': val}) win32pdh.CloseQuery(hq) except pywintypes.error as e: print(e) #TODO: use logger instead return procs
def getprocesses(self): junk, instances = win32pdh.EnumObjectItems(None,None,"process", win32pdh.PERF_DETAIL_WIZARD) proc_ids=[] proc_dict={} for instance in instances: if proc_dict.has_key(instance): proc_dict[instance] = proc_dict[instance] + 1 else: proc_dict[instance]=0 for instance, max_instances in proc_dict.items(): for inum in xrange(max_instances+1): hq = win32pdh.OpenQuery() # initializes the query handle path = win32pdh.MakeCounterPath( (None,"process",instance, None, inum, "% Processor Time") ) counter_handle=win32pdh.AddCounter(hq, path) #convert counter path to counter handle win32pdh.CollectQueryData(hq) #collects data for the counter win32pdh.CollectQueryData(hq) #collects data for the counter type, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_DOUBLE) proc_ids.append(instance+'\t'+str(val)) win32pdh.CloseQuery(hq) proc_ids.sort()
def __init__(self): self.base = win32pdh.OpenQuery() # for memory self.counter_mem = win32pdh.AddCounter(self.base, MEMORY_PERCENT) # for cpu self.counter_cpu = win32pdh.AddCounter(self.base, PROCESS_USAGE) # for nic bandwidth try: nic_bandwidth = r'\Network Interface(' + NIC_CHK + r')\Current Bandwidth' self.counter_nic_bandwidth = win32pdh.AddCounter(self.base, nic_bandwidth) nic_recv_rate = r'\Network Interface(' + NIC_CHK + r')\Bytes Received/sec' self.counter_nic_recv_rate = win32pdh.AddCounter(self.base, nic_recv_rate) nic_send_rate = r'\Network Interface(' + NIC_CHK + r')\Bytes Sent/sec' self.counter_nic_send_rate = win32pdh.AddCounter(self.base, nic_send_rate) nic_bandwidth = win32pdh.GetFormattedCounterValue(self.counter_nic_bandwidth, win32pdh.PDH_FMT_LONG)[1] except: str = '嗯,你需要从“设备管理器”中找到网卡的名字,并修改这个脚本的第 13 行的内容' print str.decode('utf-8').encode('gbk') exit() self.reset()
def procids(): # each instance is a process, you can have multiple processes w/same name junk, instances = win32pdh.EnumObjectItems(None, None, 'process', win32pdh.PERF_DETAIL_WIZARD) proc_ids = [] proc_dict = {} for instance in instances: if instance in proc_dict: proc_dict[instance] = proc_dict[instance] + 1 else: proc_dict[instance] = 0 for instance, max_instances in proc_dict.items(): for inum in xrange(max_instances + 1): hq = win32pdh.OpenQuery() # initializes the query handle path = win32pdh.MakeCounterPath((None, 'process', instance, None, inum, 'ID Process')) counter_handle = win32pdh.AddCounter(hq, path) win32pdh.CollectQueryData(hq) # collects data for the counter type, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG) proc_ids.append((instance, str(val))) win32pdh.CloseQuery(hq) proc_ids.sort() return proc_ids
def get_counter_val(counter_path, *args, **kwargs): try: sleep = float(kwargs['sleep'][0]) except (KeyError, TypeError, IndexError): sleep = 0 query = win32pdh.OpenQuery() counter = win32pdh.AddCounter(query, counter_path) win32pdh.CollectQueryData(query) time.sleep(sleep) win32pdh.CollectQueryData(query) _, _, _, _, _, _, _, info, _ = win32pdh.GetCounterInfo(counter, False) _, value = win32pdh.GetFormattedCounterValue(counter, win32pdh.PDH_FMT_DOUBLE) win32pdh.CloseQuery(query) unit = info[-1] if not isinstance(value, (int, long)): value = round(value, 2) return [value, unit]
def collectdataslave(self,format = win32pdh.PDH_FMT_LONG): ''' ### Not a public method Called only when the Query is known to be open, runs over the whole set of counters, appending results to the temp, returns the values as a list. ''' try: win32pdh.CollectQueryData(self._base) temp = [] for counter in self.counters: ok = 0 try: if counter: temp.append(win32pdh.GetFormattedCounterValue(counter, format)[1]) ok = 1 except win32api.error: pass if not ok: temp.append(-1) # a better way to signal failure??? return temp except win32api.error: # will happen if, for instance, no counters are part of the query and we attempt to collect data for it. return [-1] * len(self.counters)
def _getCpuUsage(self): if os.name == 'nt': #Collect the percent idle time win32pdh.CollectQueryData(self.mPdhQuery) format = win32pdh.PDH_FMT_LONG | win32pdh.PDH_FMT_NOSCALE idleTime = win32pdh.GetFormattedCounterValue(self.mProcCounter,format)[1] return idleTime else: statFile = file("/proc/stat", "r") for line in statFile.readlines(): m = PAT_STAT_CPU.match(line) if m: current_time = map(long, m.groups()) diff_time = [0,0,0,0] for i in xrange(4): diff_time[i] = current_time[i] - self.mLastCPUTime[i] self.mLastCPUTime = current_time (tuser, tnice, tsys, tidle) = diff_time #print "User [%s] nice [%s] sys [%s] idle [%s]" % (tuser, tnice, tsys, tidle) cpu_usage = 100.00 - 100.00 * (float(diff_time[3]) / sum(diff_time)) return cpu_usage else: return 0.0
def GetPerformanceAttributes(object, counter, instance=None, inum=-1, format=win32pdh.PDH_FMT_LONG, machine=None): # NOTE: Many counters require 2 samples to give accurate results, # including "% Processor Time" (as by definition, at any instant, a # thread's CPU usage is either 0 or 100). To read counters like this, # you should copy this function, but keep the counter open, and call # CollectQueryData() each time you need to know. # See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262938 # and http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp # My older explanation for this was that the "AddCounter" process forced # the CPU to 100%, but the above makes more sense :) path = win32pdh.MakeCounterPath((machine, object, instance, None, inum, counter)) hq = win32pdh.OpenQuery() try: hc = win32pdh.AddCounter(hq, path) try: win32pdh.CollectQueryData(hq) type, val = win32pdh.GetFormattedCounterValue(hc, format) return val finally: win32pdh.RemoveCounter(hc) finally: win32pdh.CloseQuery(hq)
def mem_used(): counter=r'\Memory\Committed Bytes' machine, object, instance, parentInstance, index, counter = win32pdh.ParseCounterPath(counter) instance = None inum=-1 format = win32pdh.PDH_FMT_DOUBLE machine=None path = win32pdh.MakeCounterPath( (machine,object, instance, None, inum,counter) ) hq = win32pdh.OpenQuery() try: hc = win32pdh.AddCounter(hq, path) try: win32pdh.CollectQueryData(hq) type, val = win32pdh.GetFormattedCounterValue(hc, format) return int(val / 1024) except pywintypes.error: return 0 finally: win32pdh.RemoveCounter(hc) finally: win32pdh.CloseQuery(hq)
def get_processes(): win32pdh.EnumObjects(None, None, win32pdh.PERF_DETAIL_WIZARD) junk, instances = win32pdh.EnumObjectItems(None, None, 'Process', win32pdh.PERF_DETAIL_WIZARD) proc_dict = {} for instance in instances: if proc_dict.has_key(instance): proc_dict[instance] = proc_dict[instance] + 1 else: proc_dict[instance] = 0 proc_ids = [] for instance, max_instances in proc_dict.items(): for inum in xrange(max_instances + 1): hq = win32pdh.OpenQuery() # initializes the query handle try: path = win32pdh.MakeCounterPath( (None, 'Process', instance, None, inum, 'ID Process')) counter_handle = win32pdh.AddCounter( hq, path) #convert counter path to counter handle try: win32pdh.CollectQueryData( hq) #collects data for the counter type, val = win32pdh.GetFormattedCounterValue( counter_handle, win32pdh.PDH_FMT_LONG) proc_ids.append((instance, val)) except win32pdh.error, e: #print e pass win32pdh.RemoveCounter(counter_handle) except win32pdh.error, e: #print e pass win32pdh.CloseQuery(hq)
def GetPerformanceAttributes(object, counter, instance=None, inum=-1, format=None, machine=None): # NOTE: Many counters require 2 samples to give accurate results, # including "% Processor Time" (as by definition, at any instant, a # thread's CPU usage is either 0 or 100). To read counters like this, # you should copy this function, but keep the counter open, and call # CollectQueryData() each time you need to know. # See http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp # My older explanation for this was that the "AddCounter" process forced # the CPU to 100%, but the above makes more sense :) import win32pdh if format is None: format = win32pdh.PDH_FMT_LONG path = win32pdh.MakeCounterPath( (machine, object, instance, None, inum, counter)) hq = win32pdh.OpenQuery() try: hc = win32pdh.AddCounter(hq, path) try: win32pdh.CollectQueryData(hq) type, val = win32pdh.GetFormattedCounterValue(hc, format) return val finally: win32pdh.RemoveCounter(hc) finally: win32pdh.CloseQuery(hq) def memusage(processName="python", instance=0): # from win32pdhutil, part of the win32all package import win32pdh return GetPerformanceAttributes("Process", "Virtual Bytes", processName, instance, win32pdh.PDH_FMT_LONG, None)
def getProcessCpuTimeWindows(self, process): ''' Get the current CPU processor time as a double based on a process instance (chrome#10). ''' try: if process == None: return None if self.cpu_path == None: self.cpu_path = win32pdh.MakeCounterPath( (None, 'Process', process, None, 0, '% Processor Time')) if self.cpu_hq == None: self.cpu_hq = win32pdh.OpenQuery() if self.cpu_counter_handle == None: self.cpu_counter_handle = win32pdh.AddCounter( self.cpu_hq, self.cpu_path) #convert counter path to counter handle win32pdh.CollectQueryData( self.cpu_hq) #collects data for the counter time.sleep(0.25) win32pdh.CollectQueryData( self.cpu_hq) #collects data for the counter (v, cpu) = win32pdh.GetFormattedCounterValue( self.cpu_counter_handle, win32pdh.PDH_FMT_DOUBLE) return cpu except: print sys.exc_info() return None
def ShowAllProcesses(): object = find_pdh_counter_localized_name("Process") items, instances = win32pdh.EnumObjectItems(None, None, object, win32pdh.PERF_DETAIL_WIZARD) # Need to track multiple instances of the same name. instance_dict = {} for instance in instances: try: instance_dict[instance] = instance_dict[instance] + 1 except KeyError: instance_dict[instance] = 0 # Bit of a hack to get useful info. items = [find_pdh_counter_localized_name("ID Process")] + items[:5] print("Process Name", ",".join(items)) for instance, max_instances in instance_dict.items(): for inum in range(max_instances + 1): hq = win32pdh.OpenQuery() hcs = [] for item in items: path = win32pdh.MakeCounterPath( (None, object, instance, None, inum, item)) hcs.append(win32pdh.AddCounter(hq, path)) win32pdh.CollectQueryData(hq) # as per http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262938, some "%" based # counters need two collections time.sleep(0.01) win32pdh.CollectQueryData(hq) print("%-15s\t" % (instance[:15]), end=" ") for hc in hcs: type, val = win32pdh.GetFormattedCounterValue( hc, win32pdh.PDH_FMT_LONG) print("%5d" % (val), end=" ") win32pdh.RemoveCounter(hc) print() win32pdh.CloseQuery(hq)
def GetCounterValue(hq, hc): win32pdh.CollectQueryData(hq) format = win32pdh.PDH_FMT_LONG type, val = win32pdh.GetFormattedCounterValue(hc, format) return val
def _getSettings(self): settings = {} # Windows. if os.name == 'nt': comp = self.mWMIConnection.Win32_ComputerSystem()[0] settings['Caption'] = comp.Caption settings['Description'] = comp.Description settings['Domain'] = comp.Domain settings['Manufacturer'] = comp.Manufacturer settings['Model'] = comp.Model settings['Name'] = comp.Name settings['Number of Processors'] = comp.NumberOfProcessors settings['Primary Owner'] = comp.PrimaryOwnerName settings['Status'] = comp.Status settings['System Type'] = comp.SystemType settings['Total Physical Memory'] = comp.TotalPhysicalMemory settings['User Name'] = comp.UserName settings['Workgroup'] = comp.Workgroup # The following is based on a comment posted in response to the # following ASPN Python Cookbook recipe: # # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496815 path = win32pdh.MakeCounterPath( (None, 'System', None, None, 0, 'System Up Time')) query = win32pdh.OpenQuery() handle = win32pdh.AddCounter(query, path) win32pdh.CollectQueryData(query) uptime = \ win32pdh.GetFormattedCounterValue( handle, win32pdh.PDH_FMT_LONG | win32pdh.PDH_FMT_NOSCALE ) settings['Up Time'] = u"%d days, %d:%02d:%02d" % \ self._convertUpTime(uptime[1]) for k in settings.keys(): if settings[k] is None: settings[k] = u'' # Linux. elif sys.platform.startswith('linux'): lines = [] # Read the contents of these files into lines in the order that they # are listed here. files = ['/proc/cpuinfo', '/proc/meminfo', '/proc/version'] for f in files: file = open(f, 'r') lines.extend(file.readlines()) file.close() # We assume that the machine has at least one processor. :) proc_num = 0 # Loop through lines and build up settings based on what we find. for l in lines: match = self.proc_num_re.match(l) if match is not None: proc_num = int(match.group(1)) continue if self._addInfo(self.cpu_vendor_re, l, 'CPU %d Vendor' % proc_num, settings): pass elif self._addInfo(self.cpu_model_re, l, 'CPU %d Model' % proc_num, settings): pass elif self._addInfo(self.cpu_speed_re, l, 'CPU %d Speed' % proc_num, settings): token = 'CPU %d Speed' % proc_num settings[token] = settings[token] + ' MHz' elif self._addInfo(self.mem_total_re, l, 'Total Physical Memory', settings): pass elif self._addInfo(self.swap_total_re, l, 'Total Swap', settings): pass elif self._addInfo(self.kernel_ver_re, l, 'Kernel Version', settings): pass # At this point, proc_num will hold the value of the last processor # information block read from /proc/cpuinfo. Incrementing that value # by one gives us the total number of processors. settings['Number of Processors'] = str(proc_num + 1) file = open('/proc/uptime', 'r') line = file.readline() file.close() settings['Up Time'] = "%d days, %d:%02d:%02d" % \ self._convertUpTime(line.split()[0]) settings['Name'] = socket.gethostname() return settings
def getCounterValue(self, counter): hc = self.counters[counter] return win32pdh.GetFormattedCounterValue(hc, win32pdh.PDH_FMT_DOUBLE)[1]
def _get_stats(self): win32pdh.CollectQueryData(self.hq) type, val = win32pdh.GetFormattedCounterValue(self.hc, self.format) val = val / 100.0 return val
def run(self): # noqa """Collect the data.""" nexttime = time.time() interval = 5 qhandles = {} query = win32pdh.OpenQuery() for key in self.fields: qhandles[key] = win32pdh.AddCounter(query, self.fields[key]) win32pdh.CollectQueryData(query) cores = multiprocessing.cpu_count() time.sleep(1) loadFromPercent = 0 while not self.halt: curtime = time.time() self.lock.acquire() state = copy.copy(self.state) self.lock.release() win32pdh.CollectQueryData(query) for key in self.fields: chandle = qhandles[key] if '%' in self.fields[key]: try: (ctype, value) = win32pdh.GetFormattedCounterValue( chandle, win32pdh.PDH_FMT_DOUBLE) except Exception: value = 0 else: (ctype, value) = win32pdh.GetFormattedCounterValue( chandle, win32pdh.PDH_FMT_LONG) state[key] = value loadFromPercent += state["percent"] * 0.01 * cores if loadFromPercent >= 1: state["load"] += int(loadFromPercent) loadFromPercent -= int(loadFromPercent) state["residual"] = loadFromPercent for key in ("load", "diskload"): value = state[key] for avg in avgWeights: akey = key + "_" + str(avg) cur = state.get(akey, 0) bits = avgWeights[avg]["bits"] w = avgWeights[avg]["w"] new = (cur * w + ((1 << bits) - w) * (value << bits)) >> bits state[akey] = new state["time"] = curtime self.lock.acquire() for key in state: self.state[key] = state[key] if key not in self.history: self.history[key] = [] self.history[key] = self.history[key][-self.maxhistory:] self.history[key].append(state[key]) self.lock.release() if self.verbose >= 2: print "%5.3f %s" % (curtime, self.format(state, "load")) if self.verbose >= 3: print " %s" % self.format(state, "proc") print " %s" % self.format(state, "disk") if self.verbose >= 4: pprint.pprint(state) nexttime += interval delay = nexttime - time.time() if delay > 0: time.sleep(delay) else: state["missed"] = state.get("missed", 0) + 1 state["last_miss"] = -delay state["total_miss"] = state.get("total_miss", 0) - delay win32pdh.CloseQuery(query)
def get_processes_dict(self): """ returns a dictionary that contains all the processes PIDs as keys and names as values. :return: processes dictionary as described above. """ try: # Getting all processes name z, proc_name = win32pdh.EnumObjectItems( None, None, self.process_obj, win32pdh.PERF_DETAIL_WIZARD) # PERF_DETAIL_WIZARD = 400 instances = {} for instance in proc_name: if instance in instances: instances[instance] += 1 else: instances[instance] = 1 proc_pid_name = {} for instance, max_instances in instances.items(): for inum in xrange(max_instances + 1): try: hq = win32pdh.OpenQuery( ) # initializes the query handle path = win32pdh.MakeCounterPath( (None, self.process_obj, instance, None, inum, self.item)) counter_handle = win32pdh.AddCounter( hq, path) # convert counter path to counter handle win32pdh.CollectQueryData( hq) # collects data for the counter type, val = win32pdh.GetFormattedCounterValue( counter_handle, win32pdh.PDH_FMT_LONG) proc_pid_name[val] = [instance] win32pdh.CloseQuery(hq) except: raise OSError("Problem getting process id") return proc_pid_name except: try: from win32com.client import GetObject WMI = GetObject('winmgmts:') # COM object proc_instances = WMI.InstancesOf( 'Win32_Process') # WMI instanse proc_name = [ process.Properties_('Name').Value for process in proc_instances ] # Get the processess names proc_id = [ process.Properties_('ProcessId').Value for process in proc_instances ] # Get the processess names proc_pid_name = {} proc_id_counter = 0 for instance in range(len(proc_name)): proc_pid_name[proc_id[instance]] = [(proc_name[instance])] proc_id_counter += 1 return proc_pid_name except: raise OSError('Counldnt get the process list')
def get_perfmon_counters(metrics_json) -> List[Metric]: collected_metrics: List[Metric] = [] with query_perfmon() as perfmon_conn: # A cache so we don't need to ask windows for the list of the instances multiple times instance_cache: Dict[str, List[str]] = {} perfmon_metrics = [metric for metric in metrics_json if "source" in metric] for metric_json in perfmon_metrics: result_type = "absolute" if "type" in metric_json["source"]: result_type = metric_json["source"]["type"] # This class will hold a list of it's instances metric = Metric( metric_json["timeseries"]["key"], metric_json["source"]["object"], metric_json["source"]["counter"], result_type, metric_json["source"]["process_name"], ) if metric.obj not in instance_cache: _, instances = win32pdh.EnumObjectItems( None, None, metric.obj, win32pdh.PERF_DETAIL_WIZARD ) else: instances = instance_cache[metric.obj] if instances: for instance in instances: try: # Add the query to perfmon, this does not do any metric collection path = win32pdh.MakeCounterPath( (None, metric.obj, instance, None, -1, metric.counter) ) metric.instances.append( Instance(instance, win32pdh.AddCounter(perfmon_conn, path)) ) except Exception as e: logger.exception( f"Could not add the counter {metric.obj} - {metric.counter}: {e}" ) else: path = win32pdh.MakeCounterPath( (None, metric.obj, None, None, -1, metric.counter) ) metric.instances.append( Instance("Null", win32pdh.AddCounter(perfmon_conn, path)) ) collected_metrics.append(metric) # We do this because of % and rate metrics need to be collected twice # This needs to be reviewed, we cannot collect a subset of datapoints for a 60 second interval # We cannot also keep the perfmon connection opened across multiple runs (maybe we can?) try: win32pdh.CollectQueryData(perfmon_conn) time.sleep(1) win32pdh.CollectQueryData(perfmon_conn) except Exception as e: logger.exception(f"Failed to collect query data: {e}") for metric in collected_metrics: for instance in metric.instances: _, value = win32pdh.GetFormattedCounterValue(instance.counter_query, win32pdh.PDH_FMT_DOUBLE) instance.value = value return collected_metrics
def get_counter_value(counter_handle): # https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetformattedcountervalue # https://mhammond.github.io/pywin32/win32pdh__GetFormattedCounterValue_meth.html return win32pdh.GetFormattedCounterValue(counter_handle, COUNTER_VALUE_FORMAT)[1]
def extract(self): def getQueryValue(data,key): if key in data: return data[key] else: return None paths = [ ('cpu-total','Processor','_Total','% Processor Time'), ('cpu-us','Processor','_Total','% User Time'), ('cpu-sy','Processor','_Total','% Privileged Time'), ('cpu-r','System',None,'Processor Queue Length'), ('mem-free','Memory',None,'Available Mbytes'), ('mem-pages-ps','Memory',None,'Pages/sec'), ('disk-readtime','PhysicalDisk','_Total','% Disk Read Time'), ('disk-writetime','PhysicalDisk','_Total','% Disk Write Time'), ('disk-queue','PhysicalDisk','_Total','Current Disk Queue Length'), ('disk-rbps','PhysicalDisk','_Total','Disk Read Bytes/sec'), ('disk-wbps','PhysicalDisk','_Total','Disk Write Bytes/sec'), ('disk-rps','PhysicalDisk','_Total','Disk Reads/sec'), ('disk-wps','PhysicalDisk','_Total','Disk Writes/sec'), ('sql-qps','SQLServer:SQL Statistics',None,'Batch Requests/sec'), ('sql-tps','SQLServer:Databases','_Total','Transactions/sec'), ('sql-connections','SQLServer:General Statistics',None,'User Connections'), ('sql-fullscans','SQLServer:Access Methods',None,'Full Scans/sec'), ('sql-targetmemory','SQLServer:Memory Manager',None,'Target Server Memory (KB)'), ('sql-totalmemory','SQLServer:Memory Manager',None,'Total Server Memory (KB)'), ('sql-dataspace','SQLServer:Databases','_Total','Data File(s) Size (KB)'), ('sql-logspace','SQLServer:Databases','_Total','Log File(s) Size (KB)'), ('sql-cachehitratio','SQLServer:Buffer Manager',None,'Buffer cache hit ratio'), ('ws-bps','Web Service','_Total','Bytes Total/sec'), ('ws-rps','Web Service','_Total','Total Method Requests/sec'), ('ws-connections','Web Service','_Total','Current Connections') #('ni-bps','Network Interface','_Total','Bytes Total/sec') ] counters, instances = win32pdh.EnumObjectItems(None, None, 'Network Interface', win32pdh.PERF_DETAIL_WIZARD) #print instances for i, n in enumerate(instances): paths.append( ('ni-bps' + str(i),'Network Interface',n,'Bytes Total/sec') ) #print paths counters = {} base = win32pdh.OpenQuery() #print base for path in paths: counterPath = win32pdh.MakeCounterPath( (None,path[1],path[2], None, -1, path[3]) ) if win32pdh.ValidatePath(counterPath) == 0: #print path counter = win32pdh.AddCounter(base, counterPath) #print counter counters[path[0]] = counter #else: #print path[0], '------path is not valid' # collect the data for the query object. We need to collect the query data # twice to be able to calculate the % Processor Time win32pdh.CollectQueryData(base) set1 = self.getProcess() time.sleep(1) win32pdh.CollectQueryData(base) queryData = {} nibps = 0 # Get the formatted value of the counter for key in counters.keys(): if key.find('ni-bps') == 0: nibps += win32pdh.GetFormattedCounterValue(counters[key],win32pdh.PDH_FMT_LONG)[1] else: queryData[key] = win32pdh.GetFormattedCounterValue(counters[key],win32pdh.PDH_FMT_LONG)[1] queryData['ni-bps'] = nibps win32pdh.CloseQuery(base) info = {} cpu = {} cpu["us"] = getQueryValue(queryData,"cpu-us") cpu["sy"] = getQueryValue(queryData,"cpu-sy") cpu["id"] = 100 - float(getQueryValue(queryData,"cpu-total")) cpu["r"] = getQueryValue(queryData,"cpu-r") memory = {} memory["free"] = getQueryValue(queryData,"mem-free") memory["pages-ps"] = getQueryValue(queryData,"mem-pages-ps") disk = {} disk["readtime"] = getQueryValue(queryData,"disk-readtime") disk["writetime"] = getQueryValue(queryData,"disk-writetime") disk["queue"] = getQueryValue(queryData,"disk-queue") disk["rbps"] = getQueryValue(queryData,"disk-rbps") disk["wbps"] = getQueryValue(queryData,"disk-wbps") disk["bps"] = disk["rbps"] + disk["wbps"] disk["rps"] = getQueryValue(queryData,"disk-rps") disk["wps"] = getQueryValue(queryData,"disk-wps") disk["iops"] = disk["rps"] + disk["wps"] freespace,disksize = self.getDiskSize() #print freespace,disksize if(disksize > 0): disk["size"] = disksize/(1024*1024) disk["used"] = (disksize - freespace) / (1024*1024) disk["use"] = disk["used"] * 100 / disk["size"] if("sql-qps" in queryData): database = {} sqlserver = {} sqlserver["qps"] = getQueryValue(queryData,"sql-qps") sqlserver["tps"] = getQueryValue(queryData,"sql-tps") sqlserver["connections"] = getQueryValue(queryData,"sql-connections") sqlserver["fullscans"] = getQueryValue(queryData,"sql-fullscans") sqlserver["targetmemory"] = getQueryValue(queryData,"sql-targetmemory") sqlserver["totalmemory"] = getQueryValue(queryData,"sql-totalmemory") sqlserver["dataspace"] = getQueryValue(queryData,"sql-dataspace") sqlserver["logspace"] = getQueryValue(queryData,"sql-logspace") sqlserver["cachehitratio"] = getQueryValue(queryData,"sql-cachehitratio") database["sqlserver"] = sqlserver info["database"] = database webserver = {} iis = {} if("ws-bps" in queryData): iis["bps"] = getQueryValue(queryData,"ws-bps") iis["rps"] = getQueryValue(queryData,"ws-rps") iis["connections"] = getQueryValue(queryData,"ws-connections") #iis["requestqueued"] = float(result[col+3]) #+ float(result[col+4]) webserver['iis'] = iis info["webserver"] = webserver network = {} network["bps"] = getQueryValue(queryData,"ni-bps") process = [] set2 = self.getProcess() #self.logger.debug(set1) #self.logger.debug(set2) totaltime = set2['total'] - set1['total'] for s in set1: if s == 'total' : continue if(set2.has_key(s)): proc = {} proc["pid"] = s if totaltime > 0: proc["cpu"] = (sum(set2[s][0:2]) - sum(set1[s][0:2]) )* 100 / totaltime else: proc["cpu"] = 0 proc["mem"] = set2[s][2] proc["mem2"] = set2[s][3] proc["name"] = set2[s][4] proc["command"] = set2[s][5] process.append(proc) process = sorted(process, key=lambda d: d["cpu"]) if len(process) > 10: process = process[-11:] info["infoid"] = str(uuid.uuid1()) info["machineid"] = str(uuid.getnode()) info["timestamp"] = time.strftime("%Y%m%d%H%M%S", time.localtime()) info["os"] = "windows" info["appkey"] = self.AppKey info["cpu"] = cpu info["memory"] = memory info["disk"] = disk info["network"] = network info["process"] = process self.val["info"] = info #pythoncom.CoUninitialize() return self.val