def test_wmi_provider_architecture(self): """ Validate and set a WMI Provider Architecture. """ # No provider given, default wmi_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"]) self.assertEquals(wmi_sampler.provider, ProviderArchitecture.DEFAULT) # Invalid provider, default wmi_sampler1 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], provider="foo") wmi_sampler2 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], provider=123) self.assertEquals(wmi_sampler1.provider, ProviderArchitecture.DEFAULT) self.assertEquals(wmi_sampler2.provider, ProviderArchitecture.DEFAULT) # Valid providers wmi_sampler32 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], provider=32) wmi_sampler64 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], provider="64") self.assertEquals(wmi_sampler32.provider, ProviderArchitecture._32BIT) self.assertEquals(wmi_sampler64.provider, ProviderArchitecture._64BIT)
def test_one_wmi_connection_at_a_time(self): """ Only use one WMI connection at a time. """ wmi_sampler = WMISampler( "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost", namespace="some/namespace", username="******", password="******" ) # Create a new connection and release it with wmi_sampler.get_connection(): pass self.assertWMIConn(wmi_sampler, count=1) # Refetch the existing connection with wmi_sampler.get_connection(): # No connection is available, create a new one self.assertWMIConn(wmi_sampler, count=0) with wmi_sampler.get_connection(): pass # Two connections are now available self.assertWMIConn(wmi_sampler, count=2)
def _get_tag_query_tag(self, sampler, wmi_obj, tag_query): """ Design a query based on the given WMIObject to extract a tag. Returns: tag or TagQueryUniquenessFailure exception. """ self.log.debug( u"`tag_queries` parameter found." " wmi_object={wmi_obj} - query={tag_query}".format(wmi_obj=wmi_obj, tag_query=tag_query) ) # Extract query information target_class, target_property, filters = self._format_tag_query(sampler, wmi_obj, tag_query) # Create a specific sampler tag_query_sampler = WMISampler(self.log, target_class, [target_property], filters=filters, **sampler.connection) tag_query_sampler.sample() # Extract tag self._raise_on_invalid_tag_query_result(tag_query_sampler, wmi_obj, tag_query) link_value = str(tag_query_sampler[0][target_property]).lower() tag = "{tag_name}:{tag_value}".format(tag_name=target_property.lower(), tag_value="_".join(link_value.split())) self.log.debug(u"Extracted `tag_queries` tag: '{tag}'".format(tag=tag)) return tag
def test_one_wmi_connection_at_a_time(self): """ Only use one WMI connection at a time. """ wmi_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost", namespace="some/namespace", username="******", password="******") # Create a new connection and release it with wmi_sampler.get_connection(): pass self.assertWMIConn(wmi_sampler, count=1) # Refetch the existing connection with wmi_sampler.get_connection(): # No connection is available, create a new one self.assertWMIConn(wmi_sampler, count=0) with wmi_sampler.get_connection(): pass # Two connections are now available self.assertWMIConn(wmi_sampler, count=2)
class Cpu(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler(logger, "Win32_PerfRawData_PerfOS_Processor", ["Name", "PercentInterruptTime"]) self.counter("system.cpu.user") self.counter("system.cpu.idle") self.gauge("system.cpu.interrupt") self.counter("system.cpu.system") def check(self, agentConfig): try: self.wmi_sampler.sample() except TimeoutException: self.logger.warning( u"Timeout while querying Win32_PerfRawData_PerfOS_Processor WMI class." u" CPU metrics will be returned at next iteration." ) return [] if not (len(self.wmi_sampler)): self.logger.warning( "Missing Win32_PerfRawData_PerfOS_Processor WMI class." " No CPU metrics will be returned" ) return [] cpu_interrupt = self._average_metric(self.wmi_sampler, "PercentInterruptTime") if cpu_interrupt is not None: self.save_sample("system.cpu.interrupt", cpu_interrupt) cpu_percent = psutil.cpu_times() self.save_sample("system.cpu.user", 100 * cpu_percent.user / psutil.cpu_count()) self.save_sample("system.cpu.idle", 100 * cpu_percent.idle / psutil.cpu_count()) self.save_sample("system.cpu.system", 100 * cpu_percent.system / psutil.cpu_count()) return self.get_metrics() def _average_metric(self, sampler, wmi_prop): """ Sum all of the values of a metric from a WMI class object, excluding the value for "_Total" """ val = 0 counter = 0 for wmi_object in sampler: if wmi_object["Name"] == "_Total": # Skip the _Total value continue wmi_prop_value = wmi_object.get(wmi_prop) if wmi_prop_value is not None: counter += 1 val += float(wmi_prop_value) if counter > 0: return val / counter return val
def test_wmi_sampler_timeout(self): """ Gracefully handle WMI query timeouts. """ from checks.libs.wmi.sampler import WMISampler logger = Mock() # Create a sampler that timeouts wmi_sampler = WMISampler( logger, "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"], timeout_duration=0.5) SWbemServices._exec_query_run_time = 0.5 # `TimeoutException` exception is raised, DEBUG message logged self.assertRaises(TimeoutException, wmi_sampler.sample) self.assertTrue(wmi_sampler._sampling) self.assertTrue(logger.debug.called) # Cannot iterate on data self.assertRaises(TypeError, lambda: len(wmi_sampler)) self.assertRaises(TypeError, lambda: sum(1 for _ in wmi_sampler)) # Recover from timeout at next iteration wmi_sampler.sample() self.assertFalse(wmi_sampler._sampling) # The existing query was retrieved self.assertEquals(SWbemServices.ExecQuery.call_count, 1, SWbemServices.ExecQuery.call_count) # Data is populated self.assertEquals(len(wmi_sampler), 2) self.assertEquals(sum(1 for _ in wmi_sampler), 2)
def test_raw_properties_formatting(self): """ WMI Object's RAW data are returned formatted. """ wmi_raw_sampler = WMISampler( "Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa wmi_raw_sampler.sample() self.assertEquals(len(wmi_raw_sampler), 2) # Using an iterator for wmi_obj in wmi_raw_sampler: self.assertWMIObject(wmi_obj, [ "CounterRawCount", "CounterCounter", "Timestamp_Sys100NS", "Frequency_Sys100NS", "name" ]) # noqa self.assertEquals(wmi_obj['CounterRawCount'], 500) self.assertEquals(wmi_obj['CounterCounter'], 50) # Using an accessor for index in xrange(0, 2): self.assertWMIObject(wmi_raw_sampler[index], [ "CounterRawCount", "CounterCounter", "Timestamp_Sys100NS", "Frequency_Sys100NS", "name" ]) # noqa self.assertEquals(wmi_raw_sampler[index]['CounterRawCount'], 500) self.assertEquals(wmi_raw_sampler[index]['CounterCounter'], 50)
class Processes(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength", "Processes"] ) self.gauge('system.proc.queue_length') self.gauge('system.proc.count') def check(self, agentConfig): self.wmi_sampler.sample() if not (len(self.wmi_sampler)): self.logger.info('Missing Win32_PerfRawData_PerfOS_System WMI class.' ' No process metrics will be returned.') return os = self.wmi_sampler[0] processor_queue_length = os.get('ProcessorQueueLength') processes = os.get('Processes') if processor_queue_length is not None: self.save_sample('system.proc.queue_length', processor_queue_length) if processes is not None: self.save_sample('system.proc.count', processes) return self.get_metrics()
def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.os_wmi_sampler = WMISampler( logger, "Win32_OperatingSystem", ["TotalVisibleMemorySize", "FreePhysicalMemory"] ) self.mem_wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfOS_Memory", ["CacheBytes", "CommittedBytes", "PoolPagedBytes", "PoolNonpagedBytes"]) self.gauge('system.mem.free') self.gauge('system.mem.used') self.gauge('system.mem.total') # area of physical memory that stores recently used pages of data # for applications self.gauge('system.mem.cached') # Committed memory is physical memory for which space has been # reserved on the disk paging file in case it must be written # back to disk self.gauge('system.mem.committed') # physical memory used by the operating system, for objects # that can be written to disk when they are not being used self.gauge('system.mem.paged') # physical memory used by the operating system for objects that # cannot be written to disk, but must remain in physical memory # as long as they are allocated. self.gauge('system.mem.nonpaged') # usable = free + cached self.gauge('system.mem.usable') self.gauge('system.mem.pct_usable')
def _get_tag_query_tag(self, sampler, wmi_obj, tag_query): self.log.debug(u"`tag_queries` parameter found." " wmi_object={wmi_obj} - query={tag_query}".format( wmi_obj=wmi_obj, tag_query=tag_query, )) target_class, target_property, filters = \ self._format_tag_query(sampler, wmi_obj, tag_query) tag_query_sampler = WMISampler(self.log, target_class, [target_property], filters=filters, **sampler.connection) tag_query_sampler.sample() self._raise_on_invalid_tag_query_result(tag_query_sampler, wmi_obj, tag_query) link_value = str(tag_query_sampler[0][target_property]).lower() tag = "{tag_name}:{tag_value}".format(tag_name=target_property.lower(), tag_value="_".join( link_value.split())) self.log.debug(u"Extracted `tag_queries` tag: '{tag}'".format(tag=tag)) return tag
def test_wmi_sampler_timeout(self): """ Gracefully handle WMI query timeouts. """ from checks.libs.wmi.sampler import WMISampler logger = Mock() # Create a sampler that timeouts wmi_sampler = WMISampler(logger, "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"], timeout_duration=0.1) SWbemServices._exec_query_run_time = 0.11 # `TimeoutException` exception is raised, DEBUG message logged self.assertRaises(TimeoutException, wmi_sampler.sample) self.assertTrue(wmi_sampler._sampling) self.assertTrue(logger.debug.called) # Cannot iterate on data self.assertRaises(TypeError, lambda: len(wmi_sampler)) self.assertRaises(TypeError, lambda: sum(1 for _ in wmi_sampler)) # Recover from timeout at next iteration wmi_sampler.sample() self.assertFalse(wmi_sampler._sampling) # The existing query was retrieved self.assertEquals(SWbemServices.ExecQuery.call_count, 1, SWbemServices.ExecQuery.call_count) # Data is populated self.assertEquals(len(wmi_sampler), 2) self.assertEquals(sum(1 for _ in wmi_sampler), 2)
def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.os_wmi_sampler = WMISampler( logger, "Win32_OperatingSystem", ["TotalVisibleMemorySize", "FreePhysicalMemory"]) self.mem_wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfOS_Memory", [ "CacheBytes", "CommittedBytes", "PoolPagedBytes", "PoolNonpagedBytes" ]) self.gauge('system.mem.free') self.gauge('system.mem.used') self.gauge('system.mem.total') # area of physical memory that stores recently used pages of data # for applications self.gauge('system.mem.cached') # Committed memory is physical memory for which space has been # reserved on the disk paging file in case it must be written # back to disk self.gauge('system.mem.committed') # physical memory used by the operating system, for objects # that can be written to disk when they are not being used self.gauge('system.mem.paged') # physical memory used by the operating system for objects that # cannot be written to disk, but must remain in physical memory # as long as they are allocated. self.gauge('system.mem.nonpaged') # usable = free + cached self.gauge('system.mem.usable') self.gauge('system.mem.pct_usable')
class Network(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_Tcpip_NetworkInterface", ["Name", "BytesReceivedPerSec", "BytesSentPerSec"] ) self.gauge('system.net.bytes_rcvd') self.gauge('system.net.bytes_sent') def check(self, agentConfig): self.wmi_sampler.sample() if not (len(self.wmi_sampler)): self.logger.info('Missing Win32_PerfRawData_Tcpip_NetworkInterface WMI class.' ' No network metrics will be returned') return for iface in self.wmi_sampler: name = iface.get('Name') bytes_received_per_sec = iface.get('BytesReceivedPerSec') bytes_sent_per_sec = iface.get('BytesSentPerSec') name = self.normalize_device_name(name) if bytes_received_per_sec is not None: self.save_sample('system.net.bytes_rcvd', bytes_received_per_sec, device_name=name) if bytes_sent_per_sec is not None: self.save_sample('system.net.bytes_sent', bytes_sent_per_sec, device_name=name) return self.get_metrics()
def __init__(self, logger): Check.__init__(self, logger) self.os_wmi_sampler = WMISampler( logger, "Win32_OperatingSystem", ["TotalVisibleMemorySize", "FreePhysicalMemory"]) self.mem_wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfOS_Memory", [ "CacheBytes", "CommittedBytes", "PoolPagedBytes", "PoolNonpagedBytes" ]) self.gauge('system.mem.free') self.gauge('system.mem.used') self.gauge('system.mem.total') self.gauge('system.mem.cached') self.gauge('system.mem.committed') self.gauge('system.mem.paged') self.gauge('system.mem.nonpaged') self.gauge('system.mem.usable') self.gauge('system.mem.pct_usage')
def test_missing_property(self): """ Do not raise on missing properties but backfill with empty values. """ wmi_raw_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["UnknownCounter", "MissingProperty"]) # noqa wmi_raw_sampler.sample() self.assertWMISampler(wmi_raw_sampler, ["MissingProperty"], count=1)
def __init__(self, logger): Check.__init__(self, logger) self.wmi_sampler = WMISampler(logger, "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength", "Processes"]) self.gauge('system.proc.queue_length') self.gauge('system.proc.count')
def __init__(self, logger): Check.__init__(self, logger) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_Tcpip_NetworkInterface", ["Name", "BytesReceivedPerSec", "BytesSentPerSec"]) self.gauge('system.net.bytes_rcvd') self.gauge('system.net.bytes_sent')
class Cpu(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfOS_Processor", ["Name", "PercentInterruptTime"] ) self.counter('system.cpu.user') self.counter('system.cpu.idle') self.gauge('system.cpu.interrupt') self.counter('system.cpu.system') def check(self, agentConfig): self.wmi_sampler.sample() if not (len(self.wmi_sampler)): self.logger.info('Missing Win32_PerfRawData_PerfOS_Processor WMI class.' ' No CPU metrics will be returned') return cpu_interrupt = self._average_metric(self.wmi_sampler, 'PercentInterruptTime') if cpu_interrupt is not None: self.save_sample('system.cpu.interrupt', cpu_interrupt) cpu_percent = psutil.cpu_times() self.save_sample('system.cpu.user', 100 * cpu_percent.user / psutil.NUM_CPUS) self.save_sample('system.cpu.idle', 100 * cpu_percent.idle / psutil.NUM_CPUS) self.save_sample('system.cpu.system', 100 * cpu_percent.system / psutil.NUM_CPUS) return self.get_metrics() def _average_metric(self, sampler, wmi_prop): ''' Sum all of the values of a metric from a WMI class object, excluding the value for "_Total" ''' val = 0 counter = 0 for wmi_object in sampler: if wmi_object['Name'] == '_Total': # Skip the _Total value continue wmi_prop_value = wmi_object.get(wmi_prop) if wmi_prop_value is not None: counter += 1 val += float(wmi_prop_value) if counter > 0: return val / counter return val
def test_raw_perf_properties(self): """ Extend the list of properties to query for RAW Performance classes. """ # Formatted Performance class wmi_sampler = WMISampler("Win32_PerfFormattedData_PerfOS_System", ["ProcessorQueueLength"]) self.assertEquals(len(wmi_sampler.property_names), 1) # Raw Performance class wmi_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa self.assertEquals(len(wmi_sampler.property_names), 4)
class IO(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfDisk_LogicalDisk", ["Name", "DiskWriteBytesPerSec", "DiskWritesPerSec", "DiskReadBytesPerSec", "DiskReadsPerSec", "CurrentDiskQueueLength"] ) self.gauge('system.io.wkb_s') self.gauge('system.io.w_s') self.gauge('system.io.rkb_s') self.gauge('system.io.r_s') self.gauge('system.io.avg_q_sz') def check(self, agentConfig): self.wmi_sampler.sample() if not (len(self.wmi_sampler)): self.logger.info('Missing Win32_PerfRawData_PerfDisk_LogicalDiskUnable WMI class.' ' No I/O metrics will be returned.') return blacklist_re = agentConfig.get('device_blacklist_re', None) for device in self.wmi_sampler: name = device.get('Name') disk_write_bytes_per_sec = device.get('DiskWriteBytesPerSec') disk_writes_per_sec = device.get('DiskWritesPerSec') disk_read_bytes_per_sec = device.get('DiskReadBytesPerSec') disk_reads_per_sec = device.get('DiskReadsPerSec') current_disk_queue_length = device.get('CurrentDiskQueueLength') name = self.normalize_device_name(name) if should_ignore_disk(name, blacklist_re): continue if disk_write_bytes_per_sec is not None: self.save_sample('system.io.wkb_s', int(disk_write_bytes_per_sec) / B2KB, device_name=name) if disk_writes_per_sec is not None: self.save_sample('system.io.w_s', int(disk_writes_per_sec), device_name=name) if disk_read_bytes_per_sec is not None: self.save_sample('system.io.rkb_s', int(disk_read_bytes_per_sec) / B2KB, device_name=name) if disk_reads_per_sec is not None: self.save_sample('system.io.r_s', int(disk_reads_per_sec), device_name=name) if current_disk_queue_length is not None: self.save_sample('system.io.avg_q_sz', current_disk_queue_length, device_name=name) return self.get_metrics()
def test_missing_property(self): """ Do not raise on missing properties. """ wmi_raw_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["UnknownCounter", "MissingProperty"]) # noqa wmi_raw_sampler.sample() self.assertEquals(len(wmi_raw_sampler), 2) for wmi_obj in wmi_raw_sampler: # Access a non existent property self.assertFalse(wmi_obj['MissingProperty'])
def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler(logger, "Win32_PerfRawData_PerfOS_Processor", ["Name", "PercentInterruptTime"]) self.counter('system.cpu.user') self.counter('system.cpu.idle') self.gauge('system.cpu.interrupt') self.counter('system.cpu.system')
def test_raw_properties_formatting(self): """ WMI Object's RAW data are returned formatted. """ wmi_raw_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa wmi_raw_sampler.sample() self.assertWMISampler( wmi_raw_sampler, [("CounterRawCount", 500), ("CounterCounter", 50), "Timestamp_Sys100NS", "Frequency_Sys100NS", "name"], count=2, )
def test_raw_initial_sampling(self): """ Query for initial sample for RAW Performance classes. """ wmi_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa wmi_sampler.sample() # 2 queries should have been made: one for initialization, one for sampling self.assertEquals(SWbemServices.ExecQuery.call_count, 2, SWbemServices.ExecQuery.call_count) # Repeat wmi_sampler.sample() self.assertEquals(SWbemServices.ExecQuery.call_count, 3, SWbemServices.ExecQuery.call_count)
def test_raw_properties_formatting(self): """ WMI Object's RAW data are returned formatted. """ wmi_raw_sampler = WMISampler( "Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa wmi_raw_sampler.sample() self.assertWMISampler(wmi_raw_sampler, [("CounterRawCount", 500), ("CounterCounter", 50), "Timestamp_Sys100NS", "Frequency_Sys100NS", "name"], count=2)
def __init__(self, logger): Check.__init__(self, logger) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfDisk_LogicalDisk", [ "Name", "DiskWriteBytesPerSec", "DiskWritesPerSec", "DiskReadBytesPerSec", "DiskReadsPerSec", "CurrentDiskQueueLength" ]) self.gauge('system.io.wkb_s') self.gauge('system.io.w_s') self.gauge('system.io.rkb_s') self.gauge('system.io.r_s') self.gauge('system.io.avg_q_sz')
def test_wmi_parser(self): """ Parse WMI objects from WMI query results. """ wmi_sampler = WMISampler( "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"] ) wmi_sampler.sample() # Assert `results` expected_results = [ {"freemegabytes": 19742.0, "name": "C:", "avgdiskbytesperwrite": 1536.0}, {"freemegabytes": 19742.0, "name": "D:", "avgdiskbytesperwrite": 1536.0}, ] self.assertEquals(wmi_sampler, expected_results, wmi_sampler)
def test_wmi_sampler_iterator_getter(self): """ Iterate/Get on the WMISampler object iterates/gets on its current sample. """ wmi_sampler = WMISampler("Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"]) wmi_sampler.sample() self.assertEquals(len(wmi_sampler), 2) # Using an iterator for wmi_obj in wmi_sampler: self.assertWMIObject(wmi_obj, ["AvgDiskBytesPerWrite", "FreeMegabytes", "name"]) # Using an accessor for index in xrange(0, 2): self.assertWMIObject(wmi_sampler[index], ["AvgDiskBytesPerWrite", "FreeMegabytes", "name"])
def test_wmi_connection(self): """ Establish a WMI connection to the specified host/namespace, with the right credentials. """ wmi_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost", namespace="some/namespace", username="******", password="******") # Request a connection but do nothing wmi_sampler.get_connection() # Connection was established with the right parameters self.assertWMIConn(wmi_sampler, param="myhost") self.assertWMIConn(wmi_sampler, param="some/namespace")
def test_raw_cache_qualifiers(self): """ Cache the qualifiers on the first query against RAW Performance classes. """ # Append `flag_use_amended_qualifiers` flag on the first query wmi_raw_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa wmi_raw_sampler._query() self.assertWMIQuery(flags=131120) wmi_raw_sampler._query() self.assertWMIQuery(flags=48) # Qualifiers are cached self.assertTrue(wmi_raw_sampler.property_counter_types) self.assertIn("CounterRawCount", wmi_raw_sampler.property_counter_types) self.assertIn("CounterCounter", wmi_raw_sampler.property_counter_types)
def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler(logger, "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength", "Processes"]) self.gauge("system.proc.queue_length") self.gauge("system.proc.count")
def test_raw_properties_fallback(self): """ Print a warning on RAW Performance classes if the calculator is undefined. Returns the original RAW value. """ from checks.libs.wmi.sampler import WMISampler logger = Mock() wmi_raw_sampler = WMISampler(logger, "Win32_PerfRawData_PerfOS_System", ["UnknownCounter", "MissingProperty"]) # noqa wmi_raw_sampler.sample() self.assertEquals(len(wmi_raw_sampler), 2) for wmi_obj in wmi_raw_sampler: self.assertWMIObject(wmi_obj, ["UnknownCounter", "Timestamp_Sys100NS", "Frequency_Sys100NS", "name"]) # noqa self.assertEquals(wmi_obj['UnknownCounter'], 999) self.assertTrue(logger.warning.called)
def _get_wmi_sampler(self, instance_key, wmi_class, properties, **kwargs): """ Create and cache a WMISampler for the given (class, properties) """ if instance_key not in self.wmi_samplers: wmi_sampler = WMISampler(self.log, wmi_class, properties, **kwargs) self.wmi_samplers[instance_key] = wmi_sampler return self.wmi_samplers[instance_key]
def test_wmi_connection(self): """ Establish a WMI connection to the specified host/namespace, with the right credentials. """ wmi_sampler = WMISampler( "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost", namespace="some/namespace", username="******", password="******", ) # Request a connection but do nothing wmi_sampler.get_connection() # Connection was established with the right parameters self.assertWMIConn(wmi_sampler, param="myhost") self.assertWMIConn(wmi_sampler, param="some/namespace")
def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler(logger, "Win32_PerfRawData_PerfOS_Processor", ["Name", "PercentInterruptTime"]) self.counter("system.cpu.user") self.counter("system.cpu.idle") self.gauge("system.cpu.interrupt") self.counter("system.cpu.system")
def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_Tcpip_NetworkInterface", ["Name", "BytesReceivedPerSec", "BytesSentPerSec"] ) self.gauge("system.net.bytes_rcvd") self.gauge("system.net.bytes_sent")
def test_wmi_connection(self): """ Establish a WMI connection to the specified host/namespace, with the right credentials. """ wmi_sampler = WMISampler( "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost", namespace="some/namespace", username="******", password="******" ) wmi_conn = wmi_sampler._get_connection() # WMI connection is cached self.assertIn('myhost:some/namespace:datadog', wmi_sampler._wmi_connections) # Connection was established with the right parameters self.assertWMIConnWith(wmi_sampler, "myhost") self.assertWMIConnWith(wmi_sampler, "some/namespace")
def test_raw_properties_formatting(self): """ WMI Object's RAW data are returned formatted. """ wmi_raw_sampler = WMISampler("Win32_PerfRawData_PerfOS_System", ["CounterRawCount", "CounterCounter"]) # noqa wmi_raw_sampler.sample() self.assertEquals(len(wmi_raw_sampler), 2) # Using an iterator for wmi_obj in wmi_raw_sampler: self.assertWMIObject(wmi_obj, ["CounterRawCount", "CounterCounter", "Timestamp_Sys100NS", "Frequency_Sys100NS", "name"]) # noqa self.assertEquals(wmi_obj['CounterRawCount'], 500) self.assertEquals(wmi_obj['CounterCounter'], 50) # Using an accessor for index in xrange(0, 2): self.assertWMIObject(wmi_raw_sampler[index], ["CounterRawCount", "CounterCounter", "Timestamp_Sys100NS", "Frequency_Sys100NS", "name"]) # noqa self.assertEquals(wmi_raw_sampler[index]['CounterRawCount'], 500) self.assertEquals(wmi_raw_sampler[index]['CounterCounter'], 50)
class Network(Check): def __init__(self, logger): Check.__init__(self, logger) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_Tcpip_NetworkInterface", ["Name", "BytesReceivedPerSec", "BytesSentPerSec"]) self.gauge('system.net.bytes_rcvd') self.gauge('system.net.bytes_sent') def check(self, agentConfig): try: self.wmi_sampler.sample() except TimeoutException: self.logger.warning( u"Timeout while querying Win32_PerfRawData_Tcpip_NetworkInterface WMI class." u" Network metrics will be returned at next iteration.") return [] if not (len(self.wmi_sampler)): self.logger.warning( 'Missing Win32_PerfRawData_Tcpip_NetworkInterface WMI class.' ' No network metrics will be returned') return [] for iface in self.wmi_sampler: name = iface.get('Name') bytes_received_per_sec = iface.get('BytesReceivedPerSec') bytes_sent_per_sec = iface.get('BytesSentPerSec') name = self.normalize_device_name(name) if bytes_received_per_sec is not None: self.save_sample('system.net.bytes_rcvd', bytes_received_per_sec, device_name=name) if bytes_sent_per_sec is not None: self.save_sample('system.net.bytes_sent', bytes_sent_per_sec, device_name=name) return self.get_metrics()
def test_wmi_parser(self): """ Parse WMI objects from WMI query results. """ wmi_sampler = WMISampler( "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"]) wmi_sampler.sample() # Assert `results` expected_results = [{ 'freemegabytes': 19742.0, 'name': 'C:', 'avgdiskbytesperwrite': 1536.0 }, { 'freemegabytes': 19742.0, 'name': 'D:', 'avgdiskbytesperwrite': 1536.0 }] self.assertEquals(wmi_sampler, expected_results, wmi_sampler)
def test_wmi_sampler_timeout(self): """ Gracefully handle WMI queries' timeouts. """ from checks.libs.wmi.sampler import WMISampler logger = Mock() # Create a sampler that timeouts wmi_sampler = WMISampler(logger, "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"], timeout_duration=0.5) SWbemServices._exec_query_run_time = 0.5 # Gracefully timeout with a warning message but no exception wmi_sampler.sample() self.assertTrue(wmi_sampler._sampling) self.assertTrue(logger.warning.called) # Show no data self.assertEquals(len(wmi_sampler), 0) self.assertEquals(sum(1 for _ in wmi_sampler), 0) # Recover from timeout at next iteration wmi_sampler.sample() self.assertFalse(wmi_sampler._sampling) # The existing query was retrieved self.assertEquals(SWbemServices.ExecQuery.call_count, 1, SWbemServices.ExecQuery.call_count) # Data is populated self.assertEquals(len(wmi_sampler), 2) self.assertEquals(sum(1 for _ in wmi_sampler), 2)
def _get_tag_query_tag(self, sampler, wmi_obj, tag_query): """ Design a query based on the given WMIObject to extract a tag. Returns: tag or TagQueryUniquenessFailure exception. """ self.log.debug( u"`tag_queries` parameter found." " wmi_object={wmi_obj} - query={tag_query}".format( wmi_obj=wmi_obj, tag_query=tag_query, ) ) # Extract query information target_class, target_property, filters = \ self._format_tag_query(sampler, wmi_obj, tag_query) # Create a specific sampler connection = sampler.get_connection() tag_query_sampler = WMISampler( self.log, target_class, [target_property], filters=filters, **connection ) tag_query_sampler.sample() # Extract tag self._raise_on_invalid_tag_query_result(tag_query_sampler, wmi_obj, tag_query) link_value = str(tag_query_sampler[0][target_property]).lower() tag = "{tag_name}:{tag_value}".format( tag_name=target_property.lower(), tag_value="_".join(link_value.split()) ) self.log.debug(u"Extracted `tag_queries` tag: '{tag}'".format(tag=tag)) return tag
def test_wmi_connection_pooling(self): """ Share WMI connections among WMISampler objects. """ from win32com.client import Dispatch wmi_sampler_1 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"]) wmi_sampler_2 = WMISampler("Win32_OperatingSystem", ["TotalVisibleMemorySize"]) wmi_sampler_3 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost") # noqa wmi_sampler_1.sample() wmi_sampler_2.sample() self.assertEquals(Dispatch.ConnectServer.call_count, 1, Dispatch.ConnectServer.call_count) wmi_sampler_3.sample() self.assertEquals(Dispatch.ConnectServer.call_count, 2, Dispatch.ConnectServer.call_count)
class Network(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_Tcpip_NetworkInterface", ["Name", "BytesReceivedPerSec", "BytesSentPerSec"] ) self.gauge("system.net.bytes_rcvd") self.gauge("system.net.bytes_sent") def check(self, agentConfig): try: self.wmi_sampler.sample() except TimeoutException: self.logger.warning( u"Timeout while querying Win32_PerfRawData_Tcpip_NetworkInterface WMI class." u" Network metrics will be returned at next iteration." ) return [] if not (len(self.wmi_sampler)): self.logger.warning( "Missing Win32_PerfRawData_Tcpip_NetworkInterface WMI class." " No network metrics will be returned" ) return [] for iface in self.wmi_sampler: name = iface.get("Name") bytes_received_per_sec = iface.get("BytesReceivedPerSec") bytes_sent_per_sec = iface.get("BytesSentPerSec") name = self.normalize_device_name(name) if bytes_received_per_sec is not None: self.save_sample("system.net.bytes_rcvd", bytes_received_per_sec, device_name=name) if bytes_sent_per_sec is not None: self.save_sample("system.net.bytes_sent", bytes_sent_per_sec, device_name=name) return self.get_metrics()
class Processes(Check): def __init__(self, logger): Check.__init__(self, logger) # Sampler(s) self.wmi_sampler = WMISampler( logger, "Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength", "Processes"] ) self.gauge('system.proc.queue_length') self.gauge('system.proc.count') def check(self, agentConfig): try: self.wmi_sampler.sample() except TimeoutException: self.logger.warning( u"Timeout while querying Win32_PerfRawData_PerfOS_System WMI class." u" Processes metrics will be returned at next iteration." ) return [] if not (len(self.wmi_sampler)): self.logger.warning('Missing Win32_PerfRawData_PerfOS_System WMI class.' ' No process metrics will be returned.') return [] os = self.wmi_sampler[0] processor_queue_length = os.get('ProcessorQueueLength') processes = os.get('Processes') if processor_queue_length is not None: self.save_sample('system.proc.queue_length', processor_queue_length) if processes is not None: self.save_sample('system.proc.count', processes) return self.get_metrics()
def test_wmi_query(self): """ Query WMI using WMI Query Language (WQL). """ # No filters wmi_sampler = WMISampler( "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"] ) wmi_sampler.sample() self.assertWMIQuery( wmi_sampler, "Select AvgDiskBytesPerWrite,FreeMegabytes" " from Win32_PerfFormattedData_PerfDisk_LogicalDisk", ) # Single filter wmi_sampler = WMISampler( "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"], filters=[{"Name": "C:"}], ) wmi_sampler.sample() self.assertWMIQuery( wmi_sampler, "Select AvgDiskBytesPerWrite,FreeMegabytes" " from Win32_PerfFormattedData_PerfDisk_LogicalDisk" " WHERE ( Name = 'C:' )", ) # Multiple filters wmi_sampler = WMISampler( "Win32_PerfFormattedData_PerfDisk_LogicalDisk", ["AvgDiskBytesPerWrite", "FreeMegabytes"], filters=[{"Name": "C:", "Id": "123"}], ) wmi_sampler.sample() self.assertWMIQuery( wmi_sampler, "Select AvgDiskBytesPerWrite,FreeMegabytes" " from Win32_PerfFormattedData_PerfDisk_LogicalDisk" " WHERE ( Name = 'C:' AND Id = '123' )", )
def _get_wmi_sampler(self, instance_key, wmi_class, properties, tag_by="", **kwargs): properties = properties + [tag_by] if tag_by else properties if instance_key not in self.wmi_samplers: wmi_sampler = WMISampler(self.log, wmi_class, properties, **kwargs) self.wmi_samplers[instance_key] = wmi_sampler return self.wmi_samplers[instance_key]
def test_wmi_connection_pooling(self): """ Until caching is enabled WMI connections will not be shared among WMISampler objects. """ from win32com.client import Dispatch wmi_sampler_1 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"]) wmi_sampler_2 = WMISampler("Win32_OperatingSystem", ["TotalVisibleMemorySize"]) wmi_sampler_3 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost") # noqa wmi_sampler_1.sample() wmi_sampler_2.sample() # one connection, two samples self.assertEquals(Dispatch.ConnectServer.call_count, 3, Dispatch.ConnectServer.call_count) wmi_sampler_3.sample() # two connection, three samples self.assertEquals(Dispatch.ConnectServer.call_count, 5, Dispatch.ConnectServer.call_count)
def test_no_wmi_connection_pooling(self): """ WMI connections are not be shared among WMISampler objects. """ from win32com.client import Dispatch wmi_sampler_1 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"]) wmi_sampler_2 = WMISampler("Win32_OperatingSystem", ["TotalVisibleMemorySize"]) wmi_sampler_3 = WMISampler("Win32_PerfRawData_PerfOS_System", ["ProcessorQueueLength"], host="myhost") # noqa wmi_sampler_1.sample() wmi_sampler_2.sample() # 3 conns have been opened, 2 for the raw sampler and 1 for the other sampler self.assertEquals(Dispatch.ConnectServer.call_count, 3, Dispatch.ConnectServer.call_count) wmi_sampler_3.sample() # 5 conns now self.assertEquals(Dispatch.ConnectServer.call_count, 5, Dispatch.ConnectServer.call_count)