def update_gauges(metrics): metric_dict = {} for (name_list, label_dict, value) in metrics: metric_name = format_metric_name(name_list) if metric_name not in metric_dict: metric_dict[metric_name] = (tuple(label_dict.keys()), {}) label_keys = metric_dict[metric_name][0] label_values = tuple([ format_label_value(label_dict[key]) for key in label_keys ]) metric_dict[metric_name][1][label_values] = value for metric_name, (label_keys, value_dict) in metric_dict.items(): if metric_name in gauges: (old_label_values_set, gauge) = gauges[metric_name] else: old_label_values_set = set() gauge = Gauge(metric_name, '', label_keys) new_label_values_set = set(value_dict.keys()) for label_values in old_label_values_set - new_label_values_set: gauge.remove(*label_values) for label_values, value in value_dict.items(): if label_values: gauge.labels(*label_values).set(value) else: gauge.set(value) gauges[metric_name] = (new_label_values_set, gauge)
def collect_snmp(config, host, port=161): """Scrape a host and return prometheus text format for it""" start = time.time() metrics = {} for metric in config['metrics']: metrics[metric['name']] = Metric(metric['name'], 'SNMP OID {0}'.format(metric['oid']), 'untyped') values = walk_oids(host, port, config['walk']) oids = {} for oid, value in values: oids[tuple(oid)] = value for oid, value in oids.items(): for metric in config['metrics']: prefix = oid_to_tuple(metric['oid']) if oid[:len(prefix)] == prefix: value = float(value) indexes = oid[len(prefix):] labels = parse_indexes(indexes, metric.get('indexes', {}), metric.get('lookups', {}), oids) metrics[metric['name']].add_sample(metric['name'], value=value, labels=labels) class Collector(): def collect(self): return metrics.values() registry = CollectorRegistry() registry.register(Collector()) duration = Gauge('snmp_scrape_duration_seconds', 'Time this SNMP scrape took, in seconds', registry=registry) duration.set(time.time() - start) walked = Gauge('snmp_oids_walked', 'Number of oids walked in this scrape', registry=registry) walked.set(len(oids)) return generate_latest(registry)
def collect_snmp(config, host, port=161): """Scrape a host and return prometheus text format for it""" start = time.time() metrics = {} for metric in config['metrics']: metrics[metric['name']] = Metric(metric['name'], 'SNMP OID {0}'.format(metric['oid']), 'untyped') do_bulkget = 'bulkget' not in config or config['bulkget'] values = walk_oids(host, port, config['walk'], config.get('community', 'public'), do_bulkget) oids = {} for oid, value in values: oids[oid_to_tuple(oid)] = value # Netsnmp doesn't tell us if an error has occured, so # try to spot it by no results. if not oids: raise Exception("No OIDs returned, device not responding?") # Build a tree from the rules based on oid for faster lookup. metric_tree = {} for metric in config['metrics']: prefix = oid_to_tuple(metric['oid']) head = metric_tree for i in prefix: head.setdefault('children', {}) head['children'].setdefault(i, {}) head = head['children'][i] head['entry'] = metric for oid, value in oids.items(): head = metric_tree for i in oid: head = head.get('children', {}).get(i) if not head: break if 'entry' in head: metric = head['entry'] prefix = oid_to_tuple(metric['oid']) value = float(value) indexes = oid[len(prefix):] labels = parse_indexes(indexes, metric.get('indexes', {}), metric.get('lookups', {}), oids) metrics[metric['name']].add_sample(metric['name'], value=value, labels=labels) break class Collector(): def collect(self): return metrics.values() registry = CollectorRegistry() registry.register(Collector()) duration = Gauge('snmp_scrape_duration_seconds', 'Time this SNMP scrape took, in seconds', registry=registry) duration.set(time.time() - start) walked = Gauge('snmp_oids_walked', 'Number of oids walked in this scrape', registry=registry) walked.set(len(oids)) return generate_latest(registry)
class TestGauge(unittest.TestCase): def setUp(self): self.registry = CollectorRegistry() self.gauge = Gauge('g', 'help', registry=self.registry) def test_gauge(self): self.assertEqual(0, self.registry.get_sample_value('g')) self.gauge.inc() self.assertEqual(1, self.registry.get_sample_value('g')) self.gauge.dec(3) self.assertEqual(-2, self.registry.get_sample_value('g')) self.gauge.set(9) self.assertEqual(9, self.registry.get_sample_value('g')) def test_function_decorator(self): self.assertEqual(0, self.registry.get_sample_value('g')) @self.gauge.track_inprogress() def f(): self.assertEqual(1, self.registry.get_sample_value('g')) f() self.assertEqual(0, self.registry.get_sample_value('g')) def test_block_decorator(self): self.assertEqual(0, self.registry.get_sample_value('g')) with self.gauge.track_inprogress(): self.assertEqual(1, self.registry.get_sample_value('g')) self.assertEqual(0, self.registry.get_sample_value('g')) def test_gauge_function(self): x = {} self.gauge.set_function(lambda: len(x)) self.assertEqual(0, self.registry.get_sample_value('g')) self.gauge.inc() self.assertEqual(0, self.registry.get_sample_value('g')) x['a'] = None self.assertEqual(1, self.registry.get_sample_value('g')) def test_function_decorator(self): self.assertEqual(0, self.registry.get_sample_value('g')) @self.gauge.time() def f(): time.sleep(.001) f() self.assertNotEqual(0, self.registry.get_sample_value('g')) def test_block_decorator(self): self.assertEqual(0, self.registry.get_sample_value('g')) with self.gauge.time(): time.sleep(.001) self.assertNotEqual(0, self.registry.get_sample_value('g'))
class CounterRoller(RollerBase): """Accepts a Counter object and creates a gauge tracking its value over a given time period. """ def __init__(self, counter, options=None, registry=REGISTRY, roller_registry=ROLLER_REGISTRY): self.counter = counter if self.counter._type != 'counter': raise ValueError('Only a Counter object should be passed to CounterRoller') options = options or {} self.extract_options(options) self.past_values = deque() full_name, _, _ = self.get_sample() self.configure_with_full_name(full_name) self.gauge = Gauge( self.name, self.documentation, registry=registry ) roller_registry[self.name] = self def get_sample(self): """Returns (full_name, labels, value) """ return self.counter.collect()[0].samples[0] def collect(self): """Update tracked counter values and current gauge value """ now = datetime.datetime.now() # Fetch value from counter _, _, value = self.get_sample() # Add value self.past_values.append((now, value)) # Drop old values remove_old_values(self.past_values, now - self.retention_td) # Calculate and record new rolled value v = self.reducer(values_to_deltas(self.past_values), **self.reducer_kwargs) self.gauge.set(v)
def collect_snmp(config, host, port=161): """Scrape a host and return prometheus text format for it""" start = time.time() metrics = {} for metric in config['metrics']: prom_type = metric['metric_type'] if 'metric_type' in metric else 'gauge' prom_help = metric['metric_help'] if 'metric_help' in metric else 'SNMP OID {0}'.format( metric['oid'] if 'oid' in metric else "NaN" ) metrics[metric['name']] = Metric(metric['name'], prom_help, prom_type) values = walk_oids(host, port, config['walk'], config.get('community', 'public'), config.get('timeout', 5), config.get('retries', 3)) oids = {} for oid, value in values: if oid_to_tuple(oid) in oids: if (((not oids[oid_to_tuple(oid)]) or oids[oid_to_tuple(oid)] == None) and value): oids[oid_to_tuple(oid)] = value else: oids[oid_to_tuple(oid)] = value for oid, value in oids.items(): for metric in config['metrics']: prefix = oid_to_tuple(metric['oid']) if oid[:len(prefix)] == prefix: try: value = float(value) except ValueError as e: print(e) value = 0.0 indexes = oid[len(prefix):] labels = parse_indexes(indexes, metric.get('indexes', {}), metric.get('lookups', {}), oids) metrics[metric['name']].add_sample(metric['name'], value=value, labels=labels) class Collector(): def collect(self): return metrics.values() registry = CollectorRegistry() registry.register(Collector()) duration = Gauge('snmp_scrape_duration_seconds', 'Time this SNMP scrape took, in seconds', registry=registry) duration.set(time.time() - start) walked = Gauge('snmp_oids_walked', 'Number of oids walked in this scrape', registry=registry) walked.set(len(oids)) return generate_latest(registry)
def notify_success(self, source, hostname, filename, stats): registry = CollectorRegistry() s = Summary('backup_size', 'Size of backup file in bytes', registry=registry) s.observe(stats.size) s = Summary('backup_dumptime', 'Time taken to dump and compress/encrypt backup in seconds', registry=registry) s.observe(stats.dumptime) s = Summary('backup_uploadtime', 'Time taken to upload backup in seconds', registry=registry) s.observe(stats.uploadtime) if stats.retained_copies is not None: g = Gauge('backup_retained_copies', 'Number of retained backups found on destination', registry=registry) g.set(stats.retained_copies) g = Gauge('backup_timestamp', 'Time backup completed as seconds-since-the-epoch', registry=registry) g.set_to_current_time() def auth_handler(url, method, timeout, headers, data): return basic_auth_handler(url, method, timeout, headers, data, self.username, self.password) push_to_gateway(self.url, job=source.id, registry=registry, handler=auth_handler) logging.info("Pushed metrics for job '%s' to gateway (%s)" % (source.id, self.url))
def notify_success(self, source, hostname, filename, stats): registry = CollectorRegistry() g = Gauge('backup_size', 'Size of backup file in bytes', registry=registry) g.set(stats.size) g = Gauge('backup_dumptime', 'Time taken to dump and compress/encrypt backup in seconds', registry=registry) g.set(stats.dumptime) g = Gauge('backup_uploadtime', 'Time taken to upload backup in seconds', registry=registry) g.set(stats.uploadtime) g = Gauge('backup_retained_copies', 'Number of retained backups found on destination', registry=registry) g.set(stats.retained_copies) g = Gauge('backup_timestamp', 'Time backup completed as seconds-since-the-epoch', registry=registry) g.set_to_current_time() push_to_gateway(self.url, job=source.id, registry=registry, handler=http_basic_auth_handler, handler_args=self.auth_args) logging.info("Pushed metrics for job '%s' to gateway (%s)" % (source.id, self.url))
humidity_gauge = Gauge('home_humidity', 'Humidity at home') target_temperature_f_gauge = Gauge('home_target_temperature_f', 'Target Temperature at home') ambient_temperature_f_gauge = Gauge('home_ambient_temperature_f', 'Ambient Temperature at home') client = pymongo.MongoClient("mongodb://localhost:27017") nest_database = client.get_database("nest") thermostat_log = nest_database.get_collection("thermostat_log") if __name__ == '__main__': # Start up the server to expose the metrics. start_http_server(HTTP_PORT) # Generate some requests. import time while True: result = thermostat_log.find().sort([('_id', -1)]).limit(1)[0] last_connection = result.get('last_connection') print("last_connection: %s" % last_connection) humidity = result.get('humidity') print("humidity: %s" % humidity) humidity_gauge.set(humidity) target_temperature_f = result.get('target_temperature_f') print("target_temperature_f: %s" % target_temperature_f) target_temperature_f_gauge.set(target_temperature_f) ambient_temperature_f = result.get('ambient_temperature_f') print("ambient_temperature_f: %s" % ambient_temperature_f) ambient_temperature_f_gauge.set(ambient_temperature_f) print("sleeping %s seconds" % SLEEP_DURATION) time.sleep(SLEEP_DURATION)
# If you want to test against a specific server # servers = [1234] s = speedtest.Speedtest() #results_dict = s.results.dict() #print results_dict g_speed = Gauge('speedtest_bits_per_second', 'Speedtest speed in bits per second.', ['direction']) g_ping = Gauge('speedtest_latency_ms', 'Speedtest latency in ms.') # Initialize with 0 g_speed.labels('downstream').set(0.0) g_speed.labels('upstream').set(0.0) g_ping.set(0.0) def process_request(t): s.get_servers(servers) s.get_best_server() s.download() s.upload() results_dict = s.results.dict() g_speed.labels('downstream').set(results_dict["download"]) g_speed.labels('upstream').set(results_dict["upload"]) g_ping.set(results_dict["ping"]) print results_dict["ping"] print results_dict["upload"] print results_dict["download"] time.sleep(t)
# Generate random gauge value number = scaled_random(500) coin_toss = random.random() if coin_toss >= 0.5: gauge.inc(number) # Increment by given value else: gauge.dec(number) # Decrement by given value # Generate random counter value number = scaled_random(5) counter.inc(number) # Increment by Random Value def process_request(t): """A dummy function that takes some time.""" time.sleep(t) if __name__ == '__main__': # Start up the server to expose the metrics. start_http_server(8000) # Set default metrics gauge.set(25000) # Set to a default value # Generate some requests and random metrics. while True: generate_random_metrics(histogram, gauge, counter) process_request(random.random())
from prometheus_client import Gauge, write_to_textfile, REGISTRY import RPi.GPIO as GPIO import dht11 import time TMP_PATH = '/textfile/dht11.prom' GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.cleanup() module = dht11.DHT11(pin=24) g1 = Gauge('temperature', 'Gauge') g2 = Gauge('humidity', 'Gauge') while True: result = module.read() if result.is_valid(): g1.set(result.temperature) g2.set(result.humidity) write_to_textfile(TMP_PATH, REGISTRY) time.sleep(1)
def monitor_host_metrics(): # cpu process_cpu_usage_percents = Gauge('process_cpu_usage_percents', 'CPU Usage in percents') process_cpu_usage_percents.set_function(lambda: psutil.cpu_percent()) process_cpu_time_user_mode = Gauge('process_cpu_time_user_mode', '') process_cpu_time_user_mode.set_function(lambda: psutil.cpu_times().user) process_cpu_time_system_mode = Gauge('process_cpu_time_system_mode', '') process_cpu_time_system_mode.set_function(lambda: psutil.cpu_times().system) process_cpu_time_idle_mode = Gauge('process_cpu_time_idle_mode', '') process_cpu_time_idle_mode.set_function(lambda: psutil.cpu_times().idle) # mem MEMORY_TOTAL = Gauge('host_memory_total_bytes', '') if ("MEMORY_LIMIT" in os.environ): mem_limit_str = os.environ["MEMORY_LIMIT"] MEMORY_TOTAL.set(mem_limit_str[:len(mem_limit_str) - 1]) else: MEMORY_TOTAL.set_function(lambda: virtual_memory().total) MEMORY_CACHED = Gauge('host_memory_cached_bytes', '') MEMORY_CACHED.set_function(lambda: virtual_memory().cached) MEMORY_INACTIVE = Gauge('host_memory_inactive_bytes', '') MEMORY_INACTIVE.set_function(lambda: virtual_memory().inactive) MEMORY_ACTIVE = Gauge('host_memory_active_bytes', '') MEMORY_ACTIVE.set_function(lambda: virtual_memory().active) MEMORY_BUFFERS = Gauge('host_memory_buffers_bytes', '') MEMORY_BUFFERS.set_function(lambda: virtual_memory().buffers) MEMORY_FREE = Gauge('host_memory_free_bytes', '') MEMORY_FREE.set_function(lambda: virtual_memory().free) host_memory_used_bytes = Gauge('host_memory_used_bytes', '') host_memory_used_bytes.set_function(lambda: virtual_memory().used) MEMORY_PERCENT = Gauge('host_memory_percents', '') MEMORY_PERCENT.set_function(lambda: virtual_memory().percent) SWAP_MEMORY_PERCENT = Gauge('host_swap_memory_percent', '') SWAP_MEMORY_PERCENT.set_function(lambda: psutil.swap_memory().percent) SWAP_MEMORY_USED = Gauge('host_swap_memory_used_bytes', '') SWAP_MEMORY_USED.set_function(lambda: psutil.swap_memory().used) SWAP_MEMORY_FREE = Gauge('host_swap_memory_free_bytes', '') SWAP_MEMORY_FREE.set_function(lambda: psutil.swap_memory().free) # network network_bytes_sent_int = Gauge('network_bytes_sent_int', '', ["interface"]) network_bytes_recv_int = Gauge('network_bytes_recv_int', 'Total bytes received via current interface', ["interface"]) for interface in netifaces.interfaces(): network_bytes_sent_int.labels(interface).set_function(lambda: net_stat.rx_tx_bytes(interface)[0]) network_bytes_recv_int.labels(interface).set_function(lambda: net_stat.rx_tx_bytes(interface)[1]) # //per second can be calculate from total network_bytes_sent = Gauge('host_net_tx_bytes', '') network_bytes_sent.set_function(lambda: psutil.net_io_counters().bytes_sent) network_bytes_recv = Gauge('network_bytes_recv', 'Total bytes received') network_bytes_recv.set_function(lambda: psutil.net_io_counters().bytes_recv) network_packets_sent = Gauge('network_packets_sent', '') network_packets_sent.set_function(lambda: psutil.net_io_counters().packets_sent) network_packets_recv = Gauge('network_packets_recv', '') network_packets_recv.set_function(lambda: psutil.net_io_counters().packets_recv) network_errin = Gauge('network_errin', '') network_errin.set_function(lambda: psutil.net_io_counters().errin) network_errout = Gauge('network_errout', '') network_errout.set_function(lambda: psutil.net_io_counters().errout) network_dropin = Gauge('network_dropin', '') network_dropin.set_function(lambda: psutil.net_io_counters().dropin) network_dropout = Gauge('network_dropout', '') network_dropout.set_function(lambda: psutil.net_io_counters().dropout) # disk IO DISK_READ = Gauge('host_disk_reads', 'Total reads for all disks') DISK_READ.set_function(lambda: disk_stat.disk_reads_persec()) DISK_WRITE = Gauge('host_disk_writes', 'Total writes for all disks') DISK_WRITE.set_function(lambda: disk_stat.disk_writes_persec()) host_disk_total = Gauge('host_disk_total', '') host_disk_total.set_function(lambda: psutil.disk_usage("/").total) host_disk_free = Gauge('host_disk_free', '') host_disk_free.set_function(lambda: psutil.disk_usage("/").free) host_disk_used = Gauge('host_disk_used', '') host_disk_used.set_function(lambda: psutil.disk_usage("/").used) host_disk_percent = Gauge('host_disk_percent', '') host_disk_percent.set_function(lambda: psutil.disk_usage("/").percent)
class nanoProm: def __init__(self, config, registry): self.config = config self.ActiveDifficulty = Gauge('nano_active_difficulty', 'Active Difficulty Multiplier', registry=registry) self.NetworkReceiveCurrent = Gauge('nano_active_difficulty_receive', 'current receive multiplier', registry=registry) self.threads = Gauge('nano_node_threads', 'Thread %', ['pid', 'tid'], registry=registry) self.BlockCount = Gauge('nano_block_count', 'Block Count Statistics', ['type'], registry=registry) self.ConfirmationHistory = Gauge('nano_confirmation_history', 'Block Confirmation Average', ['count'], registry=registry) self.PeersCount = Gauge('nano_node_peer_count', 'Peer Cout', registry=registry) self.StatsCounters = Gauge('nano_stats_counters', 'Stats Counters', ['type', 'detail', 'dir'], registry=registry) self.StatsObjectsCount = Gauge('nano_stats_objects_count', 'Objects from nano_stats by count', ['l1', 'l2', 'l3'], registry=registry) self.StatsObjectsSize = Gauge('nano_stats_objects_size', 'Objects from nano_stats by size', ['l1', 'l2', 'l3'], registry=registry) self.Uptime = Gauge('nano_uptime', 'Uptime Counter in seconds', registry=registry) self.Version = Info('nano_version', 'Nano Version details', registry=registry) self.rss = Gauge('nano_node_memory_rss', 'nano_node process memory', ['pid'], registry=registry) self.vms = Gauge('nano_node_memory_vms', 'nano_node process memory', ['pid'], registry=registry) self.pp = Gauge('nano_node_memory_paged_pool', 'nano_node process memory', ['pid'], registry=registry) self.cpu = Gauge('nano_node_cpu_usage', 'nano_node cpu usage', ['pid'], registry=registry) self.databaseSize = Gauge('nano_node_database', 'nano_node data', ['type'], registry=registry) self.databaseVolumeFree = Gauge('nano_node_volume_free', 'data volume stats', registry=registry) self.databaseVolumeUsed = Gauge('nano_node_volume_used', 'data volume stats', registry=registry) self.databaseVolumeTotal = Gauge('nano_node_volume_total', 'data volume stats', registry=registry) self.Frontiers = Gauge('nano_node_frontier_count', 'local node frontier count', registry=registry) self.QuorumDelta = Gauge('nano_node_quorum_delta', 'Quorum Delta from Confirmation Quorum RPC', registry=registry) self.OnlineStake = Gauge('nano_node_online_stake_total', 'Online Stake Total', registry=registry) self.PeersStake = Gauge('nano_node_peers_stake_total', 'Peers Stake Total', registry=registry) self.TrendedStake = Gauge('nano_node_trended_stake_total', 'Trended Stake Total', registry=registry) self.telemetry_raw_blocks = Gauge( 'telemetry_raw_blocks', 'Raw Telemetry block count by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_cemented = Gauge( 'telemetry_raw_cemented', 'Raw Telemetry cemented count by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_unchecked = Gauge( 'telemetry_raw_unchecked', 'Raw Telemetry unchecked count by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_accounts = Gauge( 'telemetry_raw_accounts', 'Raw Telemetry accounts count by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_bandwidth = Gauge( 'telemetry_raw_bandwidth', 'Raw Telemetry bandwidth cap by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_peers = Gauge( 'telemetry_raw_peer', 'Raw Telemetry peer count by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_protocol = Gauge( 'telemetry_raw_protocol', 'Raw Telemetry protocol version by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_major = Gauge( 'telemetry_raw_major', 'Raw Telemetry major version by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_minor = Gauge( 'telemetry_raw_minor', 'Raw Telemetry minor version by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_patch = Gauge( 'telemetry_raw_patch', 'Raw Telemetry patch version by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_pre = Gauge( 'telemetry_raw_pre', 'Raw Telemetry pre-release version by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_uptime = Gauge( 'telemetry_raw_uptime', 'Raw Telemetry uptime counter by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_maker = Gauge('telemetry_raw_maker', 'Raw Telemetry maker by endpoint', ['endpoint'], registry=registry) self.telemetry_raw_timestamp = Gauge( 'telemetry_raw_timestamp', 'Raw Telemetry updated timestamp by endpoint', ['endpoint'], registry=registry) self.network_raw_tx = Gauge('network_raw_tx', 'Raw tx from psutil', registry=registry) self.network_raw_rx = Gauge('network_raw_rx', 'Raw rx from psutil', registry=registry) def update(self, stats): try: self.ActiveDifficulty.set(stats.ActiveDifficulty) self.NetworkReceiveCurrent.set(stats.NetworkReceiveCurrent) self.Uptime.set(stats.Uptime) self.Frontiers.set(stats.Frontiers) if os.path.exists(self.config.node_data_path + "data.ldb"): self.databaseSize.labels("lmdb").set( os.path.getsize(self.config.node_data_path + "data.ldb")) self.databaseVolumeFree.set( psutil.disk_usage(self.config.node_data_path).free) self.databaseVolumeTotal.set( psutil.disk_usage(self.config.node_data_path).total) self.databaseVolumeUsed.set( psutil.disk_usage(self.config.node_data_path).used) self.QuorumDelta.set(stats.QuorumDelta) self.OnlineStake.set(stats.OnlineStake) self.PeersStake.set(stats.PeersStake) self.TrendedStake.set(stats.TrendedStake) for a in stats.BlockCount: self.BlockCount.labels(a).set(stats.BlockCount[a]) self.PeersCount.set(len(stats.Peers['peers'])) for a in (stats.TelemetryRaw + [stats.Telemetry]): endpoint = telemetry_raw(a) self.telemetry_raw_blocks.labels( endpoint=endpoint.endpoint).set(endpoint.block_count) self.telemetry_raw_cemented.labels( endpoint=endpoint.endpoint).set(endpoint.cemented_count) self.telemetry_raw_unchecked.labels( endpoint=endpoint.endpoint).set(endpoint.unchecked_count) self.telemetry_raw_accounts.labels( endpoint=endpoint.endpoint).set(endpoint.account_count) self.telemetry_raw_bandwidth.labels( endpoint=endpoint.endpoint).set(endpoint.bandwidth_cap) self.telemetry_raw_peers.labels( endpoint=endpoint.endpoint).set(endpoint.peer_count) self.telemetry_raw_protocol.labels( endpoint=endpoint.endpoint).set(endpoint.protocol) self.telemetry_raw_major.labels( endpoint=endpoint.endpoint).set(endpoint.major) self.telemetry_raw_minor.labels( endpoint=endpoint.endpoint).set(endpoint.minor) self.telemetry_raw_patch.labels( endpoint=endpoint.endpoint).set(endpoint.patch) self.telemetry_raw_pre.labels(endpoint=endpoint.endpoint).set( endpoint.pre_release) self.telemetry_raw_uptime.labels( endpoint=endpoint.endpoint).set(endpoint.uptime) self.telemetry_raw_maker.labels( endpoint=endpoint.endpoint).set(endpoint.maker) self.telemetry_raw_timestamp.labels( endpoint=endpoint.endpoint).set(endpoint.timestamp) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) try: self.ConfirmationHistory.labels( stats.ConfirmationHistory['confirmation_stats']['count']).set( stats.ConfirmationHistory['confirmation_stats']['average']) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) try: for entry in stats.StatsCounters['entries']: self.StatsCounters.labels(entry['type'], entry['detail'], entry['dir']).set(entry['value']) self.Version.info({ 'rpc_version': stats.Version['rpc_version'], 'store_version': stats.Version['store_version'], 'protocol_version': stats.Version['protocol_version'], 'node_vendor': stats.Version['node_vendor'], 'store_vendor': stats.Version['store_vendor'], 'network': stats.Version['network'], 'network_identifier': stats.Version['network_identifier'], 'build_info': stats.Version['build_info'] }) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) try: for l1 in stats.StatsObjects: for l2 in stats.StatsObjects[l1]: if 'size' in stats.StatsObjects[l1][l2]: self.StatsObjectsSize.labels(l1, l2, "none").set( stats.StatsObjects[l1][l2]['size']) self.StatsObjectsCount.labels(l1, l2, "none").set( stats.StatsObjects[l1][l2]['count']) if os.getenv("NANO_PROM_DEBUG"): print("l2", l1, l2, stats.StatsObjects[l1][l2]['size'], stats.StatsObjects[l1][l2]['count']) else: for l3 in stats.StatsObjects[l1][l2]: if 'size' in stats.StatsObjects[l1][l2][l3]: self.StatsObjectsSize.labels(l1, l2, l3).set( stats.StatsObjects[l1][l2][l3]['size']) self.StatsObjectsCount.labels(l1, l2, l3).set( stats.StatsObjects[l1][l2][l3]['count']) if os.getenv("NANO_PROM_DEBUG"): print( "l3", l1, l2, l3, stats.StatsObjects[l1][l2][l3]['size'], stats.StatsObjects[l1][l2][l3] ['count']) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) @staticmethod def auth_handler(url, method, timeout, headers, data, creds): return basic_auth_handler(url, method, timeout, headers, data, creds['username'], creds['password']) def pushStats(self, registry): for gateway, creds in self.config.push_gateway.items(): try: if creds['username'] != "": def handle(url, method, timeout, headers, data): return self.auth_handler(url, method, timeout, headers, data, creds) push_to_gateway(gateway, job=self.config.hostname, registry=registry, handler=handle) else: push_to_gateway(gateway, job=self.config.hostname, registry=registry) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e)
class PrometheusGaugeMetric(object): def __init__(self, name, desc, labels, value, value_converter, logger=None): ''' name -- metric name (e.g. node_network_status) desc -- metric description labels -- indexes (tuple of strings) in metric_data taken as labels value -- index in metric_data (dict) taken as value for metric value_converter -- sometime value may came in mixed format like - 5s, 3GB. We need to convert this value to numeric. Pass a function reference to this converter, can be lambda as well. logger -- instance of logging.Logger class ''' self.gauge = Gauge(name, desc, list(labels)) self.name = name self.labels = labels self.value = value self.value_converter = value_converter self.logger = logger def populate(self, metric_data): ''' populate labels and value with data metric_data -- dict object return -- metric_labels - dict with label=value, metric_value - converted value ''' try: converter = getattr(self, self.value_converter) except Exception: converter = self.value_converter metric_value = converter(metric_data[self.value]) metric_labels = {} for label in self.labels: metric_labels[label] = metric_data[label] return metric_labels, metric_value def print_metric(self, metric_labels, metric_value): ''' build and print metric metric_labels -- labels to print metric_value -- value to print ''' if metric_labels: label_value = [] for label, value in metric_labels.iteritems(): label_value.append('{l}={v}'.format(l=label, v=value)) # show labels in a log text = '{n}{{{lv}}} {v}'.format(n=self.name, lv=', '.join(label_value), v=metric_value) else: # there are no labels to show text = '{n} {v}'.format(n=self.name, v=metric_value) if self.logger: self.logger.info(text) else: print '[INFO]: {t}'.format(t=text) def update(self, metric_data, print_metric=False): ''' update metric with newer data metric_data -- dict with indexes insterested to print_metric -- print metric to stdout (good for dev stage) ''' metric_labels, metric_value = self.populate(metric_data) if print_metric: self.print_metric(metric_labels, metric_value) if self.labels: self.gauge.labels(**metric_labels).set(metric_value) else: self.gauge.set(metric_value)
return 'news_' + term.replace(' ', '_') + "_hits" search_terms = [ 'new zealand', 'brexit', 'london', 'impeachment', 'openbet', 'sg digital', 'scientific games' ] i_search_terms_checked = 0 r = CollectorRegistry() for term in search_terms: count, words = countNews(term) g = Gauge(gaugeName(term), \ 'Hits on search for news about ' + term, \ registry = r) g.set(count) writeTermsDetail(term, words) i_search_terms_checked += 1 time.sleep(1) #--------------------- Start Instrumentation ------------------------------ i_term_count = Gauge('news_script_searchterms_checked_count', \ 'Number of search terms checked by script in one run', \ registry = r) i_term_count.set(i_search_terms_checked) i_exec_time = Gauge('news_script_exec_duration_milliseconds', \ 'Total time for one run of news collection script', \ registry = r)
def prom_time(sec): registry = CollectorRegistry() g = Gauge(TIME_METRIC, "iBBQ monitoring uptime", registry=registry) g.set(sec) return registry
def prom_battery(pct): registry = CollectorRegistry() g = Gauge(BATTERY_METRIC, "Battery from iBBQ probe", registry=registry) g.set(pct) return registry
def createCatervaMetrics(catchedLines): registry = CollectorRegistry() gaugeScriptError = Gauge("caterva_scriptError", "Script Error", ["errorMsg"], registry=registry) gaugeScriptVersion = Gauge("caterva_version", "Script Version", ["version"], registry=registry) gaugeScriptVersion.labels(version=catchedLines["scriptVersion"]).set(1) if "scriptError" in catchedLines and catchedLines["scriptError"] != "": gaugeScriptError.labels(errorMsg=catchedLines["scriptError"]).set(1) else: gaugeSoc = Gauge("caterva_soc", "SoC in Prozent", ["sn"], registry=registry) gaugeGen = Gauge("caterva_gen", "Generation der Caterva", ["gen"], registry=registry) gaugeBatType = Gauge( "caterva_batteryType", "Typ des Batteriemanagementmoduls", ["type"], registry=registry, ) gaugeFlags = Gauge( "caterva_flags", "Meldungen der Caterva", ["register", "flag"], registry=registry, ) gaugeUptime = Gauge("caterva_uptime", "Uptime in Minuten", ["sn"], registry=registry) gaugeInitSTVAL = Gauge("caterva_initSTVAL", "Initvektor", ["initval"], registry=registry) gaugeBatteryWatt = Gauge("caterva_batteryWatt", "Einspeichern", registry=registry) gaugeNegInverterACPower = Gauge("caterva_negInverterACPower", "Ausspeichern", registry=registry) gaugeRechargeByPowerWatt = Gauge("caterva_rechargeByPowerWatt", "Zwangsnachladung", registry=registry) gaugePvPowerProvision = Gauge("caterva_pvPowerProvision", "PV-Leistung", registry=registry) gaugeAvgLoad = Gauge("caterva_avgLoad", "Systemlast", registry=registry) gaugeCSSteuerung = Gauge( "caterva_cssteuerung", "CS-Steuerung", [ "socMax", "socCharge", "startEinspeichern", "starteAusspeichern", "autoBalancing", "status", ], registry=registry, ) gaugeBO = Gauge( "caterva_bo", "Business Optium", [ "p_in_W_chargeStandbyThreshold", "p_in_W_chargeStandbyThreshold_hyst", "p_in_W_dischargeStandbyThreshold", "p_in_W_dischargeStandbyThreshold_delay", "p_in_W_dischargeStandbyThreshold_hyst", "soc_max", "soc_charge", "soc_discharge", "soc_min", "soc_err", "counter_discharge_to_standby_max", "counter_charge_to_standby_max", "counter_standby_to_discharge_max", "loop_delay", "system_initialization", "ecs3_Configuration", "businessOptimum_BOS", "status", ], registry=registry, ) gaugeBMU = Gauge( "caterva_bmu", "Wertetabelle BMU (nur GEN2)", ["type", "number"], registry=registry, ) gaugeSoc.labels(sn=catchedLines["snValue"]).set( catchedLines["socProzent"]) gaugeUptime.labels(sn=catchedLines["snValue"]).set( catchedLines["uptime"]) gaugeGen.labels(gen=catchedLines["gen"]).set(1) gaugeBatType.labels(type=catchedLines["batteryType"]).set(1) gaugeInitSTVAL.labels(initval=catchedLines["InitSTVAl"]).set(1) gaugeBatteryWatt.set(catchedLines["batteryWatt"]) gaugeNegInverterACPower.set(catchedLines["negInverterACPower"]) gaugeRechargeByPowerWatt.set(catchedLines["rechargeByPowerWatt"]) gaugePvPowerProvision.set(catchedLines["pvPowerProvision"]) gaugeAvgLoad.set(catchedLines["avgLoad"]) gaugeCSSteuerung.labels( socMax=catchedLines["cs_steuerung_cfg"][0], socCharge=catchedLines["cs_steuerung_cfg"][1], startEinspeichern=catchedLines["cs_steuerung_cfg"][2], starteAusspeichern=catchedLines["cs_steuerung_cfg"][3], autoBalancing=catchedLines["cs_steuerung_cfg"][4], status=catchedLines["cs_steuerung_log"], ).set(catchedLines["cs_steuerung_pid"]) gaugeBO.labels( p_in_W_chargeStandbyThreshold=catchedLines["bo_cfg"][0], p_in_W_chargeStandbyThreshold_hyst=catchedLines["bo_cfg"][1], p_in_W_dischargeStandbyThreshold=catchedLines["bo_cfg"][2], p_in_W_dischargeStandbyThreshold_delay=catchedLines["bo_cfg"][3], p_in_W_dischargeStandbyThreshold_hyst=catchedLines["bo_cfg"][4], soc_max=catchedLines["bo_cfg"][5], soc_charge=catchedLines["bo_cfg"][6], soc_discharge=catchedLines["bo_cfg"][7], soc_min=catchedLines["bo_cfg"][8], soc_err=catchedLines["bo_cfg"][9], counter_discharge_to_standby_max=catchedLines["bo_cfg"][10], counter_charge_to_standby_max=catchedLines["bo_cfg"][11], counter_standby_to_discharge_max=catchedLines["bo_cfg"][12], loop_delay=catchedLines["bo_cfg"][13], system_initialization=catchedLines["bo_cfg"][14], ecs3_Configuration=catchedLines["bo_cfg"][15], businessOptimum_BOS=catchedLines["bo_cfg"][16], status=catchedLines["bo_log"], ).set(catchedLines["bo_pid"]) # bmu for type in catchedLines["reg_mod"]: for index, number in enumerate(catchedLines["reg_mod"][type]): numberValue = index if index == 0: numberValue = "BMU" gaugeBMU.labels(type=type, number=numberValue).set(number) # StatusFlags for register in catchedLines["statusFlags"]: for flag in catchedLines["statusFlags"][register]: gaugeFlags.labels(register=register, flag=flag).set(1) return registry
registry = CollectorRegistry() gbch = Gauge('pijuice_battery_charge', 'Percentage of PiJuice battery left', registry=registry) gbcu = Gauge('pijuice_battery_current', 'Percentage of PiJuice battery left', registry=registry) giocu = Gauge('pijuice_io_current', 'Percentage of PiJuice battery left', registry=registry) pijuice = PiJuice(1, 0x14) print('Sleeping 10 seconds before taking reading.') time.sleep(10) charge = pijuice.status.GetChargeLevel() batt_current = pijuice.status.GetBatteryCurrent() current = pijuice.status.GetIoCurrent() print('Charge Level: {}'.format(charge['data'])) gbch.set(charge['data']) print('IO Current: {}'.format(current['data'])) giocu.set(current['data']) print('Battery Current: {}'.format(batt_current['data'])) gbcu.set(batt_current['data']) push_to_gateway('localhost:9091', job='pijuice', registry=registry)
SERVER_SPAWN_DURATION_SECONDS = Histogram( 'server_spawn_duration_seconds', 'time taken for server spawning operation', ['status'], # Use custom bucket sizes, since the default bucket ranges # are meant for quick running processes. Spawns can take a while! buckets=[0.5, 1, 2.5, 5, 10, 15, 30, 60, 120, float("inf")] ) RUNNING_SERVERS = Gauge( 'running_servers', 'the number of user servers currently running' ) RUNNING_SERVERS.set(0) TOTAL_USERS = Gauge( 'total_users', 'toal number of users' ) TOTAL_USERS.set(0) CHECK_ROUTES_DURATION_SECONDS = Histogram( 'check_routes_duration_seconds', 'Time taken to validate all routes in proxy' ) class ServerSpawnStatus(Enum): """
except ImportError: from BaseHTTPServer import HTTPServer from SocketServer import ThreadingMixIn from prometheus_client import MetricsHandler from prometheus_client import Histogram, Summary, Counter, Gauge # metrics app_info = Gauge('domain_automation_app_info', 'Application info', labelnames=('version', )) app_info.labels(os.environ.get('GIT_COMMIT') or 'unknown').set(1) app_built_at = Gauge('domain_automation_app_built_at', 'Application build timestamp') app_built_at.set(float(os.environ.get('BUILD_TIMESTAMP') or '0')) class _HttpServer(ThreadingMixIn, HTTPServer): pass class MetricsServer(object): def __init__(self, port, host='0.0.0.0'): self.port = port self.host = host self._httpd = None def start(self): self._httpd = _HttpServer((self.host, self.port), MetricsHandler)
class StorageInfoCollector(Collector): def __init__(self, artifactory): super().__init__(artifactory) self.name = "storage_collector" self.binaries_count = Gauge("artifactory_storage_binaries_count", "Number of binaries") self.binaries_size = Gauge("artifactory_storage_binaries_size_megabytes", "Total size of binaries (MB)") self.artifacts_size = Gauge("artifactory_storage_artifacts_size_megabytes", "Total size of artifacts (MB)") self.artifacts_count = Gauge("artifactory_storage_artifacts_count", "The total number of artifacts pointing to " "the physical binaries stored on the system") self.item_count = Gauge("artifactory_storage_item_count", "The total number of items (both files and folders) in the system") self.total = Gauge("artifactory_total_storage_megabytes", "Total storage of the system (MB)") self.used = Gauge("artifactory_used_storage_megabytes", "Total storage of the system (MB)") self.free = Gauge("artifactory_free_storage_megabytes", "Total storage of the system (MB)") self.repo_used_space = Gauge("artifactory_repo_used_space_megabytes", "Used space of the repo in MB", ["repoKey", "repoType", "packageType"]) self.repo_file = Gauge("artifactory_repo_files", "Number of files in the repo", ["repoKey", "repoType", "packageType"]) self.repo_item = Gauge("artifactory_repo_items", "Number of items in the repo", ["repoKey", "repoType", "packageType"]) def run(self): logging.debug("Starting collect storage info...") result = [] data = self._artifactory.get_storage_info() binaries_summary = data["binariesSummary"] self.binaries_count.set(int(binaries_summary["binariesCount"].replace(",", ""))) result.extend(self.binaries_count.collect()) self.binaries_size.set(str_to_megabytes(binaries_summary["binariesSize"])) result.extend(self.binaries_size.collect()) self.artifacts_size.set(str_to_megabytes(binaries_summary['artifactsSize'])) result.extend((self.artifacts_size.collect())) self.artifacts_count.set(str_to_int(binaries_summary['artifactsCount'])) result.extend(self.artifacts_count.collect()) self.item_count.set(str_to_int(binaries_summary['itemsCount'])) result.extend(self.item_count.collect()) file_store_summary = data["fileStoreSummary"] self.total.set(str_to_megabytes(file_store_summary["totalSpace"])) result.extend(self.total.collect()[:]) self.used.set(str_to_megabytes("%s %s" % (file_store_summary["usedSpace"].split(" ")[0], file_store_summary["usedSpace"].split(" ")[1]))) result.extend(self.used.collect()[:]) self.free.set(str_to_megabytes("%s %s" % (file_store_summary["freeSpace"].split(" ")[0], file_store_summary["freeSpace"].split(" ")[1]))) result.extend(self.free.collect()) for repo in data["repositoriesSummaryList"]: repo_key = repo["repoKey"] repo_type = repo["repoType"] package_type = "NA" if repo_key != "TOTAL": package_type = repo["packageType"] self.repo_used_space.labels(repo_key, repo_type, package_type).set(str_to_megabytes(repo["usedSpace"])) self.repo_file.labels(repo_key, repo_type, package_type).set(repo["filesCount"]) self.repo_item.labels(repo_key, repo_type, package_type).set(repo["itemsCount"]) result.extend(self.repo_used_space.collect()) result.extend(self.repo_file.collect()) result.extend(self.repo_item.collect()) logging.debug("Storage info collected") return result
import sys import requests import json from prometheus_client import CollectorRegistry, Gauge, push_to_gateway nifi_api_url = sys.argv[1] prometheus_pushgateway_url = sys.argv[2] artifact_id = sys.argv[3] flow_file_loc = nifi_api_url + '/flow/templates' alert_name = artifact_id + 'CheckTemplate' def flow_files_queue(): r = requests.get(flow_file_loc, allow_redirects=True) a = (json.dumps(r.json(), indent=2)) resp = json.loads(a) try: return resp['templates'][0]['template']['encoding-version'] except: return 99999 registry = CollectorRegistry() g = Gauge(alert_name, 'Last Unix time when change was pushed', registry=registry) g.set_to_current_time() g.set(flow_files_queue()) push_to_gateway(prometheus_pushgateway_url, job=alert_name, registry=registry)
class Protector(object): """ The main protector class which checks for malicious queries """ db = None ttl = 0 def __init__(self, rules, blockedlist=[], allowedlist=[], db_config={}, safe_mode=False): """ :param rules: A list of rules to evaluate :param blockedlist: A list of blocked metric names :param allowedlist: A list of allowed metric names :param safe_mode: If set to True, allow the query in case it can not be parsed :return: """ self.guard = Guard(rules) self.blockedlist = blockedlist self.allowedlist = allowedlist self.safe_mode = safe_mode if db_config.get('expire', 0) > 0: self.ttl = db_config['expire'] self.db = redis.Redis(host=db_config['redis']['host'], port=db_config['redis']['port'], password=db_config['redis']['password']) self.REQUESTS_COUNT = Counter('requests_total', 'Total number of requests', ['method', 'path', 'return_code']) self.REQUESTS_BLOCKED = Counter( 'requests_blocked', 'Total number of blocked requests. Tags: safe mode, matched rule', ['safe_mode', 'rule']) self.REQUESTS_ALLOWEDLIST_MATCHED = Counter( 'requests_allowedlist_matched', 'Total number of allowedlist matched requests') self.SAFE_MODE_STATUS = Gauge('safe_mode', 'Safe Mode Status') self.SAFE_MODE_STATUS.set(int(self.safe_mode)) self.DATAPOINTS_SERVED_COUNT = Counter('datapoints_served_count', 'datapoints served count') self.TSDB_REQUEST_LATENCY = Histogram( 'tsdb_request_latency_seconds', 'OpenTSDB Requests latency histogram', ['http_code']) def check(self, query): logging.debug("Checking OpenTSDBQuery: {}".format(query.get_id())) if query: qs_names = query.get_metric_names() if self.blockedlist: for pattern in self.blockedlist: for qn in qs_names: match = re.match(pattern, qn) if match: return Err({ "msg": "Metric name: {} is blocked".format(qn), "rule": "blockedlist" }) if self.allowedlist: all_match = True for pattern in self.allowedlist: for qn in qs_names: match = re.match(pattern, qn) all_match = all_match and bool(match) if match: logging.info( "Allowedlist metric matched: {}".format(qn)) if all_match: self.REQUESTS_ALLOWEDLIST_MATCHED.inc() return Ok(True) self.load_stats(query) return self.guard.is_allowed(query) else: error_msg = "Empty OpenTSDBQuery provided!" logging.info(error_msg) return Err({"msg": error_msg}) def set_top_duration(self, key_prefix, interval, duration): # Get current day of the month and hour of the day d = dt.datetime.now() hour = d.hour day = d.day # Top durations top_duration_key = "top_duration_{}_{}".format(day, hour) zkey = "{}_{}".format(key_prefix, interval) sc = self.db.zscore(top_duration_key, zkey) if not sc: self.db.zadd(top_duration_key, {zkey: duration}) if self.ttl: self.db.expire(top_duration_key, self.ttl) else: if float(duration) > float(sc): self.db.zadd(top_duration_key, {zkey: duration}) ### def set_top_dps(self, key_prefix, interval, sum_dp): # Get current day of the month and hour of the day d = dt.datetime.now() hour = d.hour day = d.day # Top datapoints top_dps_key = "top_dps_{}_{}".format(day, hour) zkey = "{}_{}".format(key_prefix, interval) sc = self.db.zscore(top_dps_key, zkey) if not sc: self.db.zadd(top_dps_key, {zkey: sum_dp}) if self.ttl: self.db.expire(top_dps_key, self.ttl) else: if int(sum_dp) > int(sc): self.db.zadd(top_dps_key, {zkey: sum_dp}) ### def save_stats(self, query, response, duration): try: self.db.ping() except Exception as e: logging.error("Redis server connection issue: {}".format(e)) return time_raw = time.time() current_time = int(round(time_raw)) current_time_milli = int(round(time_raw * 1000)) end_time = query.get_end_timestamp() interval = int((end_time - query.get_start_timestamp()) / 60) logging.info("[{}] start: {}, end: {}, interval: {} minutes".format( query.get_id(), int(query.get_start_timestamp()), end_time, interval)) stats = response.get_stats() key_prefix = query.get_id() if not self.db.exists("{}_{}".format(key_prefix, 'query')): self.db.set("{}_{}".format(key_prefix, 'query'), json.dumps(query.q), ex=(self.ttl or None)) sum_dp = 0 for item in stats: item.update({ 'timestamp': current_time, 'start': query.get_start_timestamp(), 'end': query.get_end() }) self.db.rpush("{}_{}".format(key_prefix, 'stats'), json.dumps(item)) sum_dp += item['emittedDPs'] # Set TTL if supplied if self.ttl: if self.db.ttl("{}_{}".format(key_prefix, 'stats')) == -1: self.db.expire("{}_{}".format(key_prefix, 'stats'), self.ttl) self.DATAPOINTS_SERVED_COUNT.inc(sum_dp) global_stats = { 'emittedDPs': sum_dp, 'duration': duration, 'timestamp': current_time } if not self.db.hexists("{}_{}".format(key_prefix, interval), 'first_occurrence'): global_stats['first_occurrence'] = current_time self.db.hmset("{}_{}".format(key_prefix, interval), global_stats) # Set TTL if supplied if self.ttl: if self.db.ttl("{}_{}".format(key_prefix, interval)) == -1: self.db.expire("{}_{}".format(key_prefix, interval), self.ttl) logging.info("[{}] emittedDPs: {}".format(query.get_id(), sum_dp)) logging.info("[{}] duration: {}".format(query.get_id(), duration)) # Save duration stats self.set_top_duration(key_prefix, interval, duration) # Save dps stats self.set_top_dps(key_prefix, interval, sum_dp) logging.info("[{}] stats saved".format(query.get_id())) now_time = int(round(time.time() * 1000)) logging.debug( "Time spent in save_stats: {} ms".format(now_time - current_time_milli)) def save_stats_timeout(self, query, duration): try: self.db.ping() except Exception as e: logging.error("Redis server connection issue: {}".format(e)) return current_time = int(round(time.time())) end_time = query.get_end_timestamp() interval = int((end_time - query.get_start_timestamp()) / 60) logging.info("[{}] start: {}, end: {}, interval: {} minutes".format( query.get_id(), int(query.get_start_timestamp()), end_time, interval)) key = "{}_{}".format(query.get_id(), interval) stats = {'duration': duration, 'timestamp': current_time} self.db.hmset(key, stats) # Set TTL if supplied if self.ttl: if self.db.ttl(key) == -1: self.db.expire(key, self.ttl) logging.info("[{}] duration: {}".format(query.get_id(), duration)) logging.info("[{}] stats saved".format(query.get_id())) # Save duration stats self.set_top_duration(query.get_id(), interval, duration) def load_stats(self, query): try: self.db.ping() except Exception as e: logging.error("Redis server connection issue: {}".format(e)) return end_time = query.get_end_timestamp() interval = int((end_time - query.get_start_timestamp()) / 60) key = "{}_{}".format(query.get_id(), interval) if self.db.exists(key): logging.info( "[{}] Found previous stats for this interval: {} minutes". format(query.get_id(), interval)) query.set_stats(self.db.hgetall(key)) def get_top(self, toptype="duration"): if (toptype != "duration" and toptype != "dps"): logging.error("Unsupported toptype: {}".format(toptype)) return try: self.db.ping() except Exception as e: logging.error("Redis server connection issue: {}".format(e)) return # Get current day of the month and hour of the day d = dt.datetime.now() hour = d.hour day = d.day data = {} # Dump all hourly tops for today while hour >= 0: # Top top_key = "top_{}_{}_{}".format(toptype, day, hour) sc = self.db.zrange(top_key, 0, -1, True, True) data[hour] = sc hour = hour - 1 return json.dumps(data)
def test_gauge(self): g = Gauge("gg", "A gauge", registry=self.registry) g.set(17) self.assertEqual(b"# HELP gg A gauge\n# TYPE gg gauge\ngg 17.0\n", generate_latest(self.registry))
for denom in active: last_price.update({denom: 0.0}) last_salt.update({denom: ""}) for denom in active: last_price[denom] = this_price[denom] last_salt[denom] = this_salt[denom] last_active.append(denom) last_hash.append(this_hash[denom]) last_swap_price = [] for item in swap_price: last_swap_price.append(item) # Get last amount of misses, if this increased message telegram currentmisses, currentheight = get_current_misses() METRIC_HEIGHT.set(currentheight) METRIC_MISSES.set(currentmisses) if currentheight > 0: misspercentage = round( float(currentmisses) / float(currentheight) * 100, 2) logger.info("Current miss percentage: {}%".format(misspercentage)) if misses == 0: misses = currentmisses if currentmisses > misses: # we have new misses, alert telegram alarm_content = "Terra Oracle misses went from {} to {} ({}%)".format( misses, currentmisses, misspercentage) logger.error(alarm_content)
g_is_holiday = Gauge('is_holiday', 'Boolean value if today is a statutory holiday', ['country', 'state', 'province']) g_is_dst = Gauge('is_daylight_saving_time', 'Boolean value if today is local daylight saving time') try: start_http_server(port=config['main']['port'], addr='0.0.0.0') except OSError as e: print('Error starting server: %s' % e) sys.exit(200) while True: now = datetime.now() g_is_dst.set(int(time.localtime().tm_isdst)) if 'custom_holidays' in config: is_holiday = 0 for custom_holiday in config['custom_holidays']: isodate = custom_holiday['date'].upper().format(YYYY=now.year, MM='%02d' % now.month) if date.fromisoformat(isodate) == date.today(): is_holiday = 1 break g_is_holiday.labels(country='Custom', state='Custom', province='Custom').set(is_holiday) for c in config['holidays']: country = c['country']
for vm in inactive_vms: del vm_epochs[vm] for vm in active_vms: cn = (vm.split('.')[0]).replace('-', '_') svm.labels(cn, 'uptime').set(t0 - vm_epochs[vm]) # Calculate uptime of an active vm # By doing a t0 - vm_epochs[vm] """ DataStore metrics """ for x in datastores: cn = (x['name']).replace('-', '_') sdatastore.labels(cn, 'size').set(x['size'] / BtoGB) t1 = time.time() delta.set((t1 - t0)) while ((t1 - t0) < mintervall): time.sleep(1.0) t1 = time.time() except KeyError: log = logopen(path + lfile) logwriter(log, "KeyError") logwriter(log, str(e.expression)) logwriter(log, str(e.status)) logwriter(log, str(e.message)) logclose(log) except SvtError as e: if e.status == 401: try: log = logopen(path + lfile) logwriter(log, "Open Connection to SimpliVity")
class nanoProm: def __init__(self, config, registry): self.config = config self.ActiveDifficulty = Gauge('nano_active_difficulty', 'Active Difficulty Multiplier', registry=registry) self.threads = Gauge('nano_node_threads', 'Thread %', ['pid', 'tid'], registry=registry) self.BlockCount = Gauge('nano_block_count', 'Block Count Statistics', ['type'], registry=registry) self.ConfirmationHistory = Gauge('nano_confirmation_history', 'Block Confirmation Average', ['count'], registry=registry) self.Peers = Gauge('nano_peers', 'Peer Statistics', ['endpoint', 'protocol_version'], registry=registry) self.PeersCount = Gauge('nano_node_peer_count', 'Peer Cout', registry=registry) self.StatsCounters = Gauge('nano_stats_counters', 'Stats Counters', ['type', 'detail', 'dir'], registry=registry) self.StatsObjectsCount = Gauge('nano_stats_objects_count', 'Objects from nano_stats by count', ['l1', 'l2', 'l3'], registry=registry) self.StatsObjectsSize = Gauge('nano_stats_objects_size', 'Objects from nano_stats by size', ['l1', 'l2', 'l3'], registry=registry) self.Uptime = Gauge('nano_uptime', 'Uptime Counter in seconds', registry=registry) self.Version = Info('nano_version', 'Nano Version details', registry=registry) self.rss = Gauge('nano_node_memory_rss', 'nano_node process memory', ['pid'], registry=registry) self.vms = Gauge('nano_node_memory_vms', 'nano_node process memory', ['pid'], registry=registry) self.pp = Gauge('nano_node_memory_paged_pool', 'nano_node process memory', ['pid'], registry=registry) self.cpu = Gauge('nano_node_cpu_usage', 'nano_node cpu usage', ['pid'], registry=registry) self.databaseSize = Gauge('nano_node_database', 'nano_node data', ['type'], registry=registry) self.databaseVolumeFree = Gauge('nano_node_volume_free', 'data volume stats', registry=registry) self.databaseVolumeUsed = Gauge('nano_node_volume_used', 'data volume stats', registry=registry) self.databaseVolumeTotal = Gauge('nano_node_volume_total', 'data volume stats', registry=registry) self.Frontiers = Gauge('nano_node_frontier_count', 'local node frontier count', registry=registry) self.OnlineStake = Gauge('nano_node_online_stake_total', 'Online Stake Total', registry=registry) self.PeersStake = Gauge('nano_node_peers_stake_total', 'Peers Stake Total', registry=registry) def update(self, stats): try: self.ActiveDifficulty.set(stats.ActiveDifficulty) self.Uptime.set(stats.Uptime) self.Frontiers.set(stats.Frontiers) if os.path.exists(self.config.nodeDataPath + "data.ldb"): self.databaseSize.labels("lmdb").set( os.path.getsize(self.config.nodeDataPath + "data.ldb")) self.databaseVolumeFree.set( psutil.disk_usage(self.config.nodeDataPath).free) self.databaseVolumeTotal.set( psutil.disk_usage(self.config.nodeDataPath).total) self.databaseVolumeUsed.set( psutil.disk_usage(self.config.nodeDataPath).used) self.OnlineStake.set(stats.OnlineStake) self.PeersStake.set(stats.PeersStake) for a in stats.BlockCount: self.BlockCount.labels(a).set(stats.BlockCount[a]) for a in stats.Peers['peers']: self.Peers.labels(a, stats.Peers['peers'][a]) self.PeersCount.set(len(stats.Peers['peers'])) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) else: pass try: self.ConfirmationHistory.labels( stats.ConfirmationHistory['confirmation_stats']['count']).set( stats.ConfirmationHistory['confirmation_stats']['average']) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) else: pass try: for entry in stats.StatsCounters['entries']: self.StatsCounters.labels(entry['type'], entry['detail'], entry['dir']).set(entry['value']) self.Version.info({ 'rpc_version': stats.Version['rpc_version'], 'store_version': stats.Version['store_version'], 'protocol_version': stats.Version['protocol_version'], 'node_vendor': stats.Version['node_vendor'], 'store_vendor': stats.Version['store_vendor'], 'network': stats.Version['network'], 'network_identifier': stats.Version['network_identifier'], 'build_info': stats.Version['build_info'] }) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) else: pass try: for l1 in stats.StatsObjects: for l2 in stats.StatsObjects[l1]: if 'size' in stats.StatsObjects[l1][l2]: self.StatsObjectsSize.labels(l1, l2, "none").set( stats.StatsObjects[l1][l2]['size']) self.StatsObjectsCount.labels(l1, l2, "none").set( stats.StatsObjects[l1][l2]['count']) if os.getenv("NANO_PROM_DEBUG"): print("l2", l1, l2, stats.StatsObjects[l1][l2]['size'], stats.StatsObjects[l1][l2]['count']) else: for l3 in stats.StatsObjects[l1][l2]: if 'size' in stats.StatsObjects[l1][l2][l3]: self.StatsObjectsSize.labels(l1, l2, l3).set( stats.StatsObjects[l1][l2][l3]['size']) self.StatsObjectsCount.labels(l1, l2, l3).set( stats.StatsObjects[l1][l2][l3]['count']) if os.getenv("NANO_PROM_DEBUG"): print( "l3", l1, l2, l3, stats.StatsObjects[l1][l2][l3]['size'], stats.StatsObjects[l1][l2][l3] ['count']) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) else: pass @staticmethod def auth_handler(url, method, timeout, headers, data, creds): return basic_auth_handler(url, method, timeout, headers, data, creds['username'], creds['password']) def pushStats(self, registry): for gateway, creds in self.config.pushGateway.items(): try: if creds['username'] != "": handle = lambda url, method, timeout, headers, data: self.auth_handler( url, method, timeout, headers, data, creds) push_to_gateway(gateway, job=self.config.hostname, registry=registry, handler=handle) else: push_to_gateway(gateway, job=self.config.hostname, registry=registry) except Exception as e: if os.getenv("NANO_PROM_DEBUG"): print(e) else: pass
class ESGaugeMetric(object): def __init__(self, name, desc, labels, value, value_converter, url, query, logger=None): ''' name -- metric name (e.g. node_network_status) desc -- metric description labels -- indexes (tuple of strings) in metric_data taken as labels value -- index in metric_data (dict) taken as value for metric value_converter -- sometime value may came in mixed format like - 5s, 3GB. we need to convert this value to numeric. pass a function reference to this converter, can be lambda as well. url -- elasticsearch url to index or GET query query -- elasticsearch query data for POST request logger -- instance of logging.Logger class ''' self.gauge = Gauge(name, desc, list(labels)) self.name = name self.labels = labels self.value = value self.value_converter = value_converter self.url = url self.query = query self.logger = logger def path_converter(self, path): ''' convert path from indexA.indexB to ['indexA']['indexB'] path -- path in dot notaion return -- path in bracket notaion ''' elems = [] for elem in path.split('.'): bracket = "['{0}']".format(elem) elems.append(bracket) return ''.join(elems) def es_query(self, url, data): ''' query Elasticsearch cluster and return raw requests.Response object url -- url to elastic search e.g. - http://localhost:9200/bank/_search data -- query in json format - more info reffer to Elasticsearch documentation return -- raw requests.Response object ''' headers = {'Content-Type': 'application/json'} resp = requests.post(url, headers=headers, data=data) return resp def populate(self, metric_data): ''' populate labels and value with data metric_data -- dict object return -- metric_labels - dict with label=value, metric_value - converted value ''' try: converter = getattr(self, self.value_converter) except Exception: converter = self.value_converter value_path = self.path_converter(self.value) value_var = 'metric_data{0}'.format(value_path) metric_value = converter(eval(value_var)) metric_labels = {} for label_name, label_path in self.labels.iteritems(): label_path = self.path_converter(label_path) label_var = 'metric_data{0}'.format(label_path) metric_labels[label_name] = eval(label_var) return metric_labels, metric_value def print_metric(self, metric_labels, metric_value): ''' build and print metric metric_labels -- labels to print metric_value -- value to print ''' if metric_labels: label_value = [] for label, value in metric_labels.iteritems(): label_value.append('{l}={v}'.format(l=label, v=value)) # show labels in a log text = '{n}{{{lv}}} {v}'.format(n=self.name, lv=', '.join(label_value), v=metric_value) else: # there are no labels to show text = '{n} {v}'.format(n=self.name, v=metric_value) if self.logger: self.logger.info(text) else: print '[INFO]: {t}'.format(t=text) def update(self, print_metric=False): ''' query ES and update metric with newer value print_metric -- print metric to stdout (good for dev stage) ''' resp = self.es_query(self.url, data=self.query) metric_data = json.loads(resp.text) metric_labels, metric_value = self.populate(metric_data) if print_metric: self.print_metric(metric_labels, metric_value) if self.labels: self.gauge.labels(**metric_labels).set(metric_value) else: self.gauge.set(metric_value)
""" from pykafka import KafkaClient from prometheus_client import start_http_server, Gauge import json if __name__ == '__main__': # start up the metric API server start_http_server(8000) # define a Gauge to send to export into the metrics API g = Gauge('my_kafka_metric', 'Sample Kafka metric') # create a Kafka connectio to a particular topic client = KafkaClient("localhost:9092") topic = client.topics["test"] consumer = topic.get_simple_consumer(consumer_group=b"offset", auto_commit_enable=True) # keep looping through the Kafka messages and as long as we find a valid # JSON containing the fields 'name' and 'value', set the defined Gauge # to whatever value we get from Kafka while True: for msg in consumer: try: metric = json.loads(msg.value) if 'name' in metric and 'value' in metric: g.set(metric['value']) except ValueError as e: # pass if we haven't found a valid JSON metric pass
SENSOR = Adafruit_DHT.AM2302 PIN = "4" METRICS_PORT = 8000 INTERVAL = 30 print("Starting probe on port " + str(METRICS_PORT)) start_http_server(METRICS_PORT) g_temp = Gauge("sensor_temperature_celcius", "Temperature sensor measurements") g_humid = Gauge("sensor_humidity_percentage", "Humidity sensor measurements") while True: try: humidity, temperature = Adafruit_DHT.read_retry(SENSOR, PIN) # print('Temp={0:0.1f}C Humidity={1:0.1f}%'.format(temperature, humidity)) if temperature is not None: g_temp.set(temperature) else: print("ERROR temperature was None") if humidity is not None: g_humid.set(humidity) else: print("ERROR humidity was None") except Exception as e: print("ERROR Unexpected exception during read_retry: " + str(e)) time.sleep(INTERVAL)
def test_gauge(self): g = Gauge('gg', 'A gauge', registry=self.registry) g.set(17) self.assertEqual(b'# HELP gg A gauge\n# TYPE gg gauge\ngg 17.0\n', generate_latest(self.registry))
import time import random from prometheus_client import start_http_server from prometheus_client import Counter, Gauge, Histogram, Summary from prometheus_client import Info, Enum cc = Counter('cc', 'A counter') gg = Gauge('gg', 'A gauge') hh = Histogram('hh', 'A histogram', buckets=(-5, 0, 5), labelnames=['a', 'b']) ss = Summary('ss', 'A summary', labelnames=['a', 'b']) i = Info('my_build_version', 'Description of info') e = Enum('my_task_state', 'Description of enum', states=['starting', 'running', 'stopped']) i.info({'version': '1.2.3', 'buildhost': 'foo@bar'}) if __name__ == '__main__': start_http_server(8000) while True: cc.inc() gg.set(random.random()) hh.labels('c', 'd').observe(random.randint(-10, 10)) ss.labels(a='c', b='d').observe(17) e.state('running') time.sleep(2)
record['Contacts_LeadType_S_Data_Status1'] = 'CAMPAIGN DETAIL ERROR' else: record['Contacts_LeadType_MostRecent_Offer_PrimarySol1'] = thisCampaign['Solution_Code_Family__c'] record['Contacts_LeadType_MostRecent_Offer_ProductSer1'] = thisCampaign['Solution_Code__c'] record['Contacts_LeadType_S_Data_Status1'] = 'CAMPAIGN DETAILS RETREIVED' if (thisCampaign['Solution_Code_Family__c']==None): nullCount += 1 logging.info("Records with no Primary Solution: " + str(nullCount)) importDefName = 'Contacts.LeadType - Get Campaign Details ' + str(datetime.now()) cdoInDef = elq.CreateDef(defType='imports', entity='customObjects', cdoID=1269, fields=myFields, defName=importDefName, identifierFieldName='Email_Address1') logging.info("import definition created: " + cdoInDef['uri']) postInData = elq.PostSyncData(data = dataOut, defObject=cdoInDef, maxPost=20000) logging.info("Data successfully imported, job finished: " + str(datetime.now())) else: logging.info("No records, job finished") ### Logging for Prometheus registry = CollectorRegistry() g = Gauge('job_last_success_unixtime', 'Last time a batch job successfully finished', registry=registry) g.set_to_current_time() h = Gauge('job_total_records_success', 'Total number of records successfully processed in last batch', registry=registry) h.set(len(data)) push_to_gateway(os.environ['PUSHGATEWAY'], job='Contacts.LeadType_getOfferDetails', registry=registry)
def create_gauges(actor_ids): """ Creates a Prometheus gauge for each actor id. The gauge is used to track the number of pending messages in the actor's queue. :param actor_ids: list of actors that should be processed. Does not include stateful actors or actors in a shutting down state. :return: """ logger.debug("top of create_gauges; actor_ids: {}".format(actor_ids)) # dictionary mapping actor_ids to their message queue lengths inbox_lengths = {} for actor_id in actor_ids: logger.debug("top of for loop for actor_id: {}".format(actor_id)) # first, make sure the actor still exists in the actor store try: actor = actors_store[actor_id] except KeyError: logger.error( f"actor {actor_id} does not exist in store; continuing to next actor." ) continue # If the actor doesn't have a gauge, add one if actor_id not in message_gauges.keys(): try: g = Gauge( 'message_count_for_actor_{}'.format( actor_id.replace('-', '_')), 'Number of messages for actor {}'.format( actor_id.replace('-', '_'))) message_gauges.update({actor_id: g}) logger.debug('Created gauge {}'.format(g)) except Exception as e: logger.error( "got exception trying to create/instantiate the gauge; " "actor {}; exception: {}".format(actor_id, e)) g = None else: # Otherwise, get this actor's existing gauge try: g = message_gauges[actor_id] except Exception as e: logger.info( "got exception trying to instantiate an existing gauge; " "actor: {}: exception:{}".format(actor_id, e)) g = None # Update this actor's gauge to its current # of messages try: ch = ActorMsgChannel(actor_id=actor_id) msg_length = len(ch._queue._queue) except Exception as e: logger.error( "Exception connecting to ActorMsgChannel: {}".format(e)) raise e ch.close() result = {'messages': msg_length} # add the actor's current message queue length to the inbox_lengths in-memory variable inbox_lengths[actor_id] = msg_length # if we were able to create the gauge, set it to the current message: if g: try: g.set(result['messages']) except Exception as e: logger.error( f"Got exception trying to set the messages on the gauge for actor: {actor_id}; " f"exception: {e}") logger.debug("METRICS: {} messages found for actor: {}.".format( result['messages'], actor_id)) # add a worker gauge for this actor if one does not exist if actor_id not in worker_gaueges.keys(): try: g = Gauge( 'worker_count_for_actor_{}'.format( actor_id.replace('-', '_')), 'Number of workers for actor {}'.format( actor_id.replace('-', '_'))) worker_gaueges.update({actor_id: g}) logger.debug('Created worker gauge {}'.format(g)) except Exception as e: logger.info( "got exception trying to instantiate the Worker Gauge: {}". format(e)) else: # Otherwise, get the worker gauge that already exists g = worker_gaueges[actor_id] # Update this actor's worker IDs workers = Worker.get_workers(actor_id) result = {'workers': len(workers)} try: g.set(result['workers']) except Exception as e: logger.error( f"got exception trying to set the worker gauge for actor {actor_id}; exception: {e}" ) logger.debug( f"METRICS: {result['workers']} workers found for actor: {actor_id}." ) # Update this actor's command channel metric # channel_name = actor.get("queue") # # queues_list = Config.get('spawner', 'host_queues').replace(' ', '') # valid_queues = queues_list.split(',') # # if not channel_name or channel_name not in valid_queues: # channel_name = 'default' # # if not channel_name: # # TODO -- this must be changed. there is no way returning no arguments will result in # # anythng but an exception. The calling function is expecting 3 arguments... # # if we really want to blow up right here we should just raise an appropriate exception. # return # TODO -- this code needs to be fixed. What follows is only a partial fix; what I think we want to do # is set the length of all of the different command channels once at the end of this loop. What was # happening instead was that it was only setting one of the command channel's lengths -- whatever command # channel happened to belong to the last actor in the loop. channel_name = 'default' ch = CommandChannel(name=channel_name) cmd_length = len(ch._queue._queue) command_gauge.labels(channel_name).set(cmd_length) logger.debug( f"METRICS COMMAND CHANNEL {channel_name} size: {command_gauge}") ch.close() # Return actor_ids so we don't have to query for them again later return actor_ids, inbox_lengths, cmd_length
class Printer(object): def __init__(self, xyz_initial): """ Initialize Printer. Parameters ----------- xyz_initial : ndarray <3,> array of the printer's starting location. """ self.current_location = xyz_initial.copy() self.next_location = xyz_initial.copy() self.active = False self.error_rate = 0.2 self.error_std = 0.5 self._gauge_x = Gauge('printer_x', 'Printer x location') self._gauge_y = Gauge('printer_y', 'Printer y location') self._gauge_z = Gauge('printer_z', 'Printer z location') def activate(self): """ Activate the printer. """ self.active = True def deactivate(self): """ Deactivate the printer. """ self.active = False def move(self): """ Move the printer to the next location if it is active. """ if self.active: self.current_location = self.next_location.copy() self._gauge_x.set(self.current_location[0]) self._gauge_y.set(self.current_location[1]) self._gauge_z.set(self.current_location[2]) else: print('Printer not active. Not moving.') def move_by(self, delta_xyz): """ Set the location for the next move. Parameters ----------- delta_xyz : ndarray <3,> array of the offset from the current location to set the next location. """ delta_xyz_ = delta_xyz.copy() index_error = 1 # y axis error if np.random.random() < self.error_rate: delta_xyz_[index_error] += np.random.normal(scale=self.error_std) self.next_location += delta_xyz_
class matching_rw: def __init__(self): self.map = {} self.transaction_count = Counter('transaction_count', 'A transaction counter') self.transaction_processing_seconds = Gauge( 'transaction_processing_seconds', 'transaction processing seconds') self.transaction_reading_seconds = Gauge( 'transaction_reading_seconds', 'transaction reading seconds') self.transaction_writing_seconds = Gauge( 'transaction_writing_seconds', 'transaction writing seconds') start_http_server(8000) # 初步想法就是pid,fd对应一个list,list里面存储的是对应的时间和上一次调用的函数和三次对应的时间[enter_ts,exit_ts,read_flag,ts1,ts2,ts3] # 例如:server里面存的就是read的开始时间和结束时间,如果下次读取到的是read,就将列表里面的exit(也就是第二个元素)时间更改成实参的exit时间 # 如果是读取到的write,就进行相应的输出 # error情况:探针在探入之前就已经建立了连接,此时如果server直接读取的是wirte,而没有对应的链表,这里我们进行丢弃处理,并打印出来错误 def matching_rw(self, pid, fd, enter_ts, exit_ts, is_server, is_read): if is_server == 1: try: if is_read == 1 and self.map[(pid, fd)][2] == -1: # -1,r self.map[(pid, fd)][0] = enter_ts self.map[(pid, fd)][1] = exit_ts self.map[(pid, fd)][2] = is_read return 0 elif self.map[(pid, fd)][2] == -1 and is_read == 0: # -1 w return 0 elif is_read == 1 and self.map[(pid, fd)][2] == 1: # r r self.map[(pid, fd)][1] = exit_ts self.map[(pid, fd)][2] = is_read return 0 elif self.map[(pid, fd)][2] == 1 and is_read == 0: # r w self.map[(pid, fd)][3] = self.map[(pid, fd)][1] - self.map[ (pid, fd)][0] self.map[(pid, fd)][4] = enter_ts - self.map[(pid, fd)][1] self.map[(pid, fd)][0] = enter_ts self.map[(pid, fd)][1] = exit_ts self.map[(pid, fd)][2] = is_read return 0 elif self.map[(pid, fd)][2] == 0 and is_read == 0: # w w self.map[(pid, fd)][1] = exit_ts return 0 elif self.map[(pid, fd)][2] == 0 and is_read == 1: # w r self.map[(pid, fd)][5] = self.map[(pid, fd)][1] - self.map[ (pid, fd)][0] b = b"%-10d %-10d %-9.3f %-9.3f %-9.3f" % ( pid, fd, self.map[(pid, fd)][3], self.map[(pid, fd)][4], self.map[(pid, fd)][5]) self.transaction_count.inc() self.transaction_processing_seconds.set(self.map[(pid, fd)][4]) self.transaction_reading_seconds.set(self.map[(pid, fd)][3]) self.transaction_writing_seconds.set(self.map[(pid, fd)][5]) self.map[(pid, fd)] = [enter_ts, exit_ts, is_read, -1, -1, -1] return b else: # -1 w 出错了 # print("出错了,服务先write了或者客户端先read了") return 0 except KeyError: if is_read == 0: self.map[(pid, fd)] = [enter_ts, exit_ts, -1, -1, -1, -1] else: self.map[(pid, fd)] = [enter_ts, exit_ts, is_read, -1, -1, -1] return 0 else: return self.matching_rw(pid, fd, enter_ts, exit_ts, not is_server, not is_read) def delete(self, pid, fd): try: del self.map[(pid, fd)] except KeyError: # print("此pid fd 不存在") pass