def get_traffic_for(interfaces): """Get traffic average for the given interfaces using one request :param QueryDict interfaces: interfaces to fetch data for :returns: A dict of {interface: { suffix: value, suffix: value}} """ metric_mapping = {} # Store metric_name -> interface targets = [] traffic = defaultdict(dict) for interface in interfaces: metrics = [ m for m in interface.get_port_metrics() if m['suffix'] in [INOCTETS, OUTOCTETS] ] for metric in metrics: target = get_metric_meta(metric['id'])['target'] metric_mapping[target] = interface targets.append(target) data = get_metric_average(sorted(targets), start=TRAFFIC_TIMEPERIOD) for metric, value in iteritems(data): interface = metric_mapping[metric] if INOCTETS in metric: traffic[interface].update({INOCTETS: value}) elif OUTOCTETS: traffic[interface].update({OUTOCTETS: value}) return traffic
def _get_target(direction): assert direction.lower() in ('in', 'out') path = metric_path_for_interface( interface.netbox.sysname, interface.ifname, 'if{0}{1}'.format(direction.capitalize(), kind)) meta = get_metric_meta(path) return meta['target'], meta.get('unit', None)
def get_link_load(sysname, ifname, time_interval): """Gets the link load of the interface, averaged over a time interval. :param sysname: The sysname of the device we're measuring from. :param ifname: An interface name. :param time_interval: A dict(start=..., end=...) describing the desired time interval in terms valid to Graphite web. :returns: An (avg_in_Mbps, avg_out_Mbps) tuple. """ in_bps = out_bps = float('nan') if sysname and ifname: targets = [metric_path_for_interface(sysname, ifname, counter) for counter in ('ifInOctets', 'ifOutOctets')] targets = [get_metric_meta(t)['target'] for t in targets] try: data = get_metric_average(targets, start=time_interval['start'], end=time_interval['end']) except GraphiteUnreachableError: _logger.error("graphite unreachable on load query for %s:%s (%r)", sysname, ifname, time_interval) return in_bps, out_bps for key, value in data.iteritems(): if 'ifInOctets' in key: in_bps = value / MEGABIT elif 'ifOutOctets' in key: out_bps = value / MEGABIT return in_bps, out_bps
def _get_target(direction): assert direction.lower() in ('in', 'out') path = metric_path_for_interface( interface.netbox.sysname, interface.ifname, 'if{0}{1}'.format(direction.capitalize(), kind) ) meta = get_metric_meta(path) return meta['target'], meta.get('unit', None)
def get_interface_data(interface): """Get ifin/outoctets for an interface using a single request""" in_bps = out_bps = None targets = [metric_path_for_interface(interface.netbox.sysname, interface.ifname, counter) for counter in (INOCTETS, OUTOCTETS)] targets = [get_metric_meta(t)['target'] for t in targets] data = get_metric_average(targets, start=TRAFFIC_TIMEPERIOD) for key, value in iteritems(data): if 'ifInOctets' in key: in_bps = value elif 'ifOutOctets' in key: out_bps = value return in_bps, out_bps
def __init__(self, target, period=DEFAULT_INTERVAL, raw=False): """ :param target: A graphite target/seriesList to look at. :param period: How far back in historic data to look. :type period: datetime.timedelta :param raw: If True, the target is fed raw to Graphite, otherwise it is evaluated and possibly transformed by NAV's rules first. """ self.target = self.orig_target = target self.period = period self.raw = raw self.result = {} if not raw: meta = get_metric_meta(target) if meta: self.target = meta['target']
def get_multiple_link_load(items, time_interval): """ Gets the link load of the interfaces, averaged over a time interval, and adds to the load properties of the items. :param items: A dictionary of {(sysname, ifname): properties lazy_dict, ...} :param time_interval: A dict(start=..., end=...) describing the desired time interval in terms valid to Graphite web. """ target_map = {} for (sysname, ifname), properties in items.items(): if not (sysname and ifname): continue targets = [ metric_path_for_interface(sysname, ifname, counter) for counter in ('ifInOctets', 'ifOutOctets') ] targets = [get_metric_meta(t)['target'] for t in targets] target_map.update({t: properties for t in targets}) _logger.debug( "getting %s graphite traffic targets in chunks", len(target_map.keys()) ) data = {} for chunk in chunks(target_map.keys(), METRIC_CHUNK_SIZE): data.update(_get_metric_average(chunk, time_interval)) for key, value in data.items(): properties = target_map.get(key, None) if properties: if value: bps = value / MEGABIT if 'ifInOctets' in key: properties['load_in'] = bps elif 'ifOutOctets' in key: properties['load_out'] = bps else: _logger.error( "no match for key %r (%r) in data returned from graphite", key, value ) missing = set(target_map).difference(data) if missing: _logger.debug("missed %d targets in graphite response", len(missing))
def _fetch_data(interface): in_bps = out_bps = speed = None if isinstance(interface, Interface): speed = interface.speed targets = [metric_path_for_interface(interface.netbox.sysname, interface.ifname, counter) for counter in ('ifInOctets', 'ifOutOctets')] targets = [get_metric_meta(t)['target'] for t in targets] data = get_metric_average(targets, start=TRAFFIC_TIMEPERIOD) for key, value in data.iteritems(): if 'ifInOctets' in key: in_bps = value elif 'ifOutOctets' in key: out_bps = value return InterfaceLoad(in_bps, out_bps, speed)
def get_traffic_for(interfaces): """Get traffic average for the given interfaces using one request :param QueryDict interfaces: interfaces to fetch data for :returns: A dict of {interface: { suffix: value, suffix: value}} """ metric_mapping = {} # Store metric_name -> interface metrics = [] traffic = defaultdict(dict) _logger.debug("preparing to get traffic data for %d interfaces", len(interfaces)) # assume transform is the same for all octet counters transform = get_metric_meta("." + INOCTETS)["transform"] for interface in interfaces: # what we need ifc_metrics = _get_traffic_counter_metrics_for(interface) metrics.extend(ifc_metrics) # what to look for in the response transformed = [transform.format(id=m) for m in ifc_metrics] metric_mapping.update({target: interface for target in transformed}) targets = [transform.format(id=m) for m in _merge_metrics(sorted(metrics))] _logger.debug( "getting data for %d targets in chunks of %d", len(targets), MAX_TARGETS_PER_REQUEST, ) data = {} for request in chunks(targets, MAX_TARGETS_PER_REQUEST): data.update(get_metric_average(request, start=TRAFFIC_TIMEPERIOD)) _logger.debug("received %d metrics in response", len(data)) for metric, value in data.items(): interface = metric_mapping[metric] if INOCTETS in metric: traffic[interface].update({INOCTETS: value}) elif OUTOCTETS in metric: traffic[interface].update({OUTOCTETS: value}) return traffic
def _fetch_data(interface): in_bps = out_bps = speed = None if isinstance(interface, Interface): speed = interface.speed targets = [ metric_path_for_interface(interface.netbox.sysname, interface.ifname, counter) for counter in ('ifInOctets', 'ifOutOctets') ] targets = [get_metric_meta(t)['target'] for t in targets] data = get_metric_average(targets, start=TRAFFIC_TIMEPERIOD) for key, value in data.iteritems(): if 'ifInOctets' in key: in_bps = value elif 'ifOutOctets' in key: out_bps = value return InterfaceLoad(in_bps, out_bps, speed)