def process_segment(r, segment): # Self alarms if segment.id in aseg: for a in aseg[segment.id]: r["alarms"] += [{ "alarm_id": a.id, "object": a.managed_object, "alarm": a, "severity": a.severity, "timestamp": a.timestamp, "duration": a.display_duration, "escalation_tt": a.escalation_tt or "", "summary": { "subscriber": SummaryItem.items_to_dict(a.direct_subscribers), "service": SummaryItem.items_to_dict(a.direct_services) } }] for ns in NetworkSegment.objects.filter(parent=segment.id): if ns.id not in seen_seg: continue sr = { "segment": ns, "children": [], "alarms": [], "summary": { "subscriber": {}, "service": {} } } process_segment(sr, ns) r["children"] += [sr]
def get_data(self): r = self.object.copy() if r["resolved"]: r["duration"] = r["close_ts"] - r["open_ts"] else: r["duration"] = datetime.datetime.now() - r["open_ts"] r["alarms"] = [] now = datetime.datetime.now() for ac in (ActiveAlarm, ArchivedAlarm): for a in ac.objects.filter(escalation_tt=r["full_id"]): if a.status == "C": duration = a.clear_timestamp - a.timestamp else: duration = now - a.timestamp r["alarms"] += [{ "alarm": a, "id": a.id, "timestamp": a.timestamp, "duration": duration, "subject": a.subject, "summary": { "subscriber": SummaryItem.items_to_dict(a.total_subscribers), "service": SummaryItem.items_to_dict(a.total_services) } }] return r
def get_data(self): # Calculate contained objects summary = { "service": SummaryItem.items_to_dict(self.object.total_services), "subscriber": SummaryItem.items_to_dict(self.object.total_subscribers) } objects = [] for mo in self.object.managed_objects.filter(is_managed=True): ss = ServiceSummary.get_object_summary(mo) objects += [{ "id": mo.id, "name": mo.name, "object": mo, "summary": ss }] # Update object statuses mos = [o["id"] for o in objects] alarms = set(d["managed_object"] for d in ActiveAlarm._get_collection().find({ "managed_object": { "$in": mos } }, {"_id": 0, "managed_object": 1})) o_status = ObjectStatus.get_statuses(mos) for o in objects: if o["id"] in o_status: if o["id"] in alarms: o["status"] = "alarm" else: o["status"] = "up" else: o["status"] = "down" # Calculate children children = [] for ns in NetworkSegment.objects.filter(parent=self.object.id): children += [{ "id": ns.id, "name": ns.name, "object": ns, "summary": { "service": SummaryItem.items_to_dict(ns.total_services), "subscriber": SummaryItem.items_to_dict(ns.total_subscribers), } }] # Calculate VLANs vlans = [] if self.object.vlan_border: vlans = list(VLAN.objects.filter(segment=self.object.id).order_by("vlan")) # return { "object": self.object, "managed_objects": sorted(objects, key=operator.itemgetter("name")), "children": sorted(children, key=operator.itemgetter("name")), "parent": self.object.parent, "summary": summary, "vlans": vlans }
def flatten(ca, r, level): ca._level = level ca.service_summary = { "service": SummaryItem.items_to_dict(ca.direct_services), "subscriber": SummaryItem.items_to_dict(ca.direct_subscribers) } r += [ca] if hasattr(ca, "_children"): for c in sorted(ca._children, key=operator.attrgetter("timestamp")): flatten(c, r, level + 1)
def get_data(self): def update_dict(d1, d2): for k in d2: if k in d1: d1[k] += d2[k] else: d1[k] = d2[k] summary = {"subscriber": {}, "service": {}} if self.current_user.is_superuser: qs = ActiveAlarm.objects.filter(root__exists=False) else: qs = ActiveAlarm.objects.filter( adm_path__in=self.get_user_domains(), root__exists=False) for a in qs.only("total_subscribers", "total_services"): update_dict(summary["subscriber"], SummaryItem.items_to_dict(a.total_subscribers or [])) update_dict(summary["service"], SummaryItem.items_to_dict(a.total_services or [])) return { "summary": summary, "is_clear": not summary["subscriber"] and not summary["service"], }
def update_summary(self): def update_dict(d1, d2): for k in d2: if k in d1: d1[k] += d2[k] else: d1[k] = d2[k] services = SummaryItem.items_to_dict(self.direct_services) subscribers = SummaryItem.items_to_dict(self.direct_subscribers) objects = { self.managed_object.object_profile.id: 1 } for a in ActiveAlarm.objects.filter(root=self.id): a.update_summary() update_dict( objects, SummaryItem.items_to_dict(a.total_objects) ) update_dict( services, SummaryItem.items_to_dict(a.total_services) ) update_dict( subscribers, SummaryItem.items_to_dict(a.total_subscribers) ) obj_list = ObjectSummaryItem.dict_to_items(objects) svc_list = SummaryItem.dict_to_items(services) sub_list = SummaryItem.dict_to_items(subscribers) if svc_list != self.total_services or sub_list != self.total_subscribers or obj_list != self.total_objects: ns = ServiceSummary.get_severity({ "service": services, "subscriber": subscribers, "objects": objects }) self.total_objects = obj_list self.total_services = svc_list self.total_subscribers = sub_list if ns != self.severity: self.change_severity(severity=ns, to_save=False) self.safe_save()
def get_data(self): def get_segment_path(segment): if segment.parent: return segment_path[segment.parent] + [segment] else: return [segment] def update_summary(segment): """ Calculate summary for segment and all nested segments """ services = {} subscribers = {} # Calculate direct segments' coverage for o in segment["objects"].values(): update_dict(services, o["services"]) update_dict(subscribers, o["subscribers"]) # Flatten objects segment["objects"] = sorted(segment["objects"].values(), key=lambda x: -x["weight"]) # Calculate children's coverage for s in segment["segments"].values(): update_summary(s) update_dict(services, s["services"]) update_dict(subscribers, s["subscribers"]) segment["segments"] = sorted(segment["segments"].values(), key=lambda x: -x["weight"]) segment["services"] = services segment["subscribers"] = subscribers segment["summary"] = {"service": services, "subscriber": subscribers} segment["weight"] = ServiceSummary.get_weight(segment["summary"]) def update_dict(d1, d2): for k in d2: if k in d1: d1[k] += d2[k] else: d1[k] = d2[k] segment_path = cachetools.LRUCache(maxsize=10000) segment_path.__missing__ = get_segment_path # Build tree tree = {"segment": None, "segments": {}, "objects": {}, "subscribers": {}, "services": {}} if self.current_user.is_superuser: qs = ActiveAlarm.objects.filter(root__exists=False) else: qs = ActiveAlarm.objects.filter( adm_path__in=self.get_user_domains(), root__exists=False ) now = datetime.datetime.now() for alarm in qs: if not alarm.total_services and not alarm.total_subscribers: continue ct = tree for sp in segment_path[alarm.managed_object.segment]: if sp.id not in ct["segments"]: ct["segments"][sp.id] = { "segment": sp, "segments": {}, "objects": {}, "subscribers": {}, "services": {}, } ct = ct["segments"][sp.id] subscribers = SummaryItem.items_to_dict(alarm.total_subscribers) services = SummaryItem.items_to_dict(alarm.total_services) ct["objects"][alarm.id] = { "object": alarm.managed_object, "alarm": alarm, "severity": alarm.severity, "timestamp": alarm.timestamp, "duration": now - alarm.timestamp, "escalation_tt": alarm.escalation_tt, "subscribers": subscribers, "services": services, "summary": {"subscriber": subscribers, "service": services}, } ct["objects"][alarm.id]["weight"] = ServiceSummary.get_weight( ct["objects"][alarm.id]["summary"] ) # Calculate segment summaries update_summary(tree) # Calculate total summaries services = {} subscribers = {} for s in tree["segments"]: update_dict(services, s["summary"]["service"]) update_dict(subscribers, s["summary"]["subscriber"]) for o in tree["objects"]: update_dict(services, o["summary"]["service"]) update_dict(subscribers, o["summary"]["subscriber"]) tree["summary"] = {"subscriber": subscribers, "service": services} return tree
def instance_to_dict(self, o, fields=None): s = AlarmSeverity.get_severity(o.severity) n_events = (ActiveEvent.objects.filter(alarms=o.id).count() + ArchivedEvent.objects.filter(alarms=o.id).count()) mtc = o.managed_object.id in Maintenance.currently_affected() if o.status == "C": # For archived alarms mtc = Maintenance.objects.filter( start__lte=o.clear_timestamp, stop__lte=o.timestamp, affected_objects__in=[ MaintenanceObject(object=o.managed_object) ]).count() > 0 d = { "id": str(o.id), "status": o.status, "managed_object": o.managed_object.id, "managed_object__label": o.managed_object.name, "administrative_domain": o.managed_object.administrative_domain_id, "administrative_domain__label": o.managed_object.administrative_domain.name, "severity": o.severity, "severity__label": s.name, "alarm_class": str(o.alarm_class.id), "alarm_class__label": o.alarm_class.name, "timestamp": self.to_json(o.timestamp), "subject": o.subject, "events": n_events, "duration": o.duration, "clear_timestamp": self.to_json(o.clear_timestamp) if o.status == "C" else None, "row_class": s.style.css_class_name, "segment__label": o.managed_object.segment.name, "segment": str(o.managed_object.segment.id), "location_1": self.location(o.managed_object.container.id)[0] if o.managed_object.container else "", "location_2": self.location(o.managed_object.container.id)[1] if o.managed_object.container else "", "escalation_tt": o.escalation_tt, "escalation_error": o.escalation_error, "platform": o.managed_object.platform.name if o.managed_object.platform else "", "address": o.managed_object.address, "isInMaintenance": mtc, "summary": self.f_glyph_summary({ "subscriber": SummaryItem.items_to_dict(o.total_subscribers), "service": SummaryItem.items_to_dict(o.total_services) }), "total_objects": sum(x.summary for x in o.total_objects) } if fields: d = dict((k, d[k]) for k in fields) return d
def get_ajax_data(self, **kwargs): def update_dict(d, s): for k in s: if k in d: d[k] += s[k] else: d[k] = s[k] zoom = int(self.handler.get_argument("z")) west = float(self.handler.get_argument("w")) east = float(self.handler.get_argument("e")) north = float(self.handler.get_argument("n")) south = float(self.handler.get_argument("s")) ms = int(self.handler.get_argument("maintenance")) active_layers = [ l for l in self.get_pop_layers() if l.min_zoom <= zoom <= l.max_zoom ] alarms = [] services = {} subscribers = {} t_data = defaultdict(list) if self.current_user.is_superuser: qs = ActiveAlarm.objects.all() else: qs = ActiveAlarm.objects.filter( adm_path__in=self.get_user_domains()) if ms == 0: # Filter out equipment under maintenance qs = qs.filter( managed_object__nin=Maintenance.currently_affected()) for a in qs.only("id", "managed_object", "direct_subscribers", "direct_services"): s_sub, s_service = {}, {} if a.direct_subscribers: s_sub = SummaryItem.items_to_dict(a.direct_subscribers) if a.direct_services: s_service = SummaryItem.items_to_dict(a.direct_services) mo = a.managed_object if not mo: continue if mo.x and mo.y: w = ServiceSummary.get_weight({ "subscriber": s_sub, "service": s_service }) # @todo: Should we add the object's weight to summary? # @todo: Check west/south hemisphere if active_layers and west <= mo.x <= east and south <= mo.y <= north: t_data[mo.x, mo.y] += [(mo, w)] else: w = 0 alarms += [{ "alarm_id": str(a.id), "managed_object": mo.name, "x": mo.x, "y": mo.y, "w": max(w, 1), }] if s_service: update_dict(services, s_service) if s_sub: update_dict(subscribers, s_sub) links = None o_seen = set() points = None o_data = {} if t_data and active_layers: # Create lines bbox = get_bbox(west, east, north, south) lines = [] for d in ObjectConnection._get_collection().find( { "type": "pop_link", "layer": { "$in": [l.id for l in active_layers] }, "line": { "$geoIntersects": { "$geometry": bbox } }, }, { "_id": 0, "connection": 1, "line": 1 }, ): for c in d["line"]["coordinates"]: if tuple(c) in t_data: for c in d["line"]["coordinates"]: tc = tuple(c) o_data[tc] = t_data.get(tc, []) o_seen.add(tuple(c)) lines += [d["line"]] break if lines: links = geojson.FeatureCollection(features=lines) # Create points points = [] for x, y in o_data: mos = {} for mo, w in o_data[x, y]: if mo not in mos: mos[mo] = w mos = sorted(mos, key=lambda z: mos[z], reverse=True)[:self.TOOLTIP_LIMIT] points += [ geojson.Feature( geometry=geojson.Point(coordinates=[x, y]), properties={ "alarms": len(t_data[x, y]), "objects": [{ "id": mo.id, "name": mo.name, "address": mo.address } for mo in mos], }, ) ] points = geojson.FeatureCollection(features=points) return { "alarms": alarms, "summary": self.f_glyph_summary({ "service": services, "subscriber": subscribers }), "links": links, "pops": points, }
def get_data(self): def get_container_path(self): # Get container path if not self.object: return None cp = [] if self.object.container: c = self.object.container.id while c: try: o = Object.objects.get(id=c) # @todo: Address data if o.container: cp.insert(0, {"id": o.id, "name": o.name}) c = o.container.id if o.container else None except DoesNotExist: metrics["error", ("type", "no_such_object")] += 1 break return cp if not self.object: return None # @todo: Stage # @todo: Service range # @todo: Open TT now = datetime.datetime.now() # Get object status and uptime alarms = list( ActiveAlarm.objects.filter(managed_object=self.object.id)) current_start = None duration = None if self.object.is_managed: if self.object.get_status(): if alarms: current_state = "alarm" else: current_state = "up" uptime = Uptime.objects.filter(object=self.object.id, stop=None).first() if uptime: current_start = uptime.start else: current_state = "down" outage = Outage.objects.filter(object=self.object.id, stop=None).first() if outage is not None: current_start = outage.start else: current_state = "unmanaged" if current_start: duration = now - current_start cp = get_container_path(self) # MAC addresses macs = [] o_macs = DiscoveryID.macs_for_object(self.object) if o_macs: for f, l in o_macs: if f == l: macs += [f] else: macs += ["%s - %s" % (f, l)] # Links uplinks = set(self.object.data.uplinks) if len(uplinks) > 1: if self.object.segment.lost_redundancy: redundancy = "L" else: redundancy = "R" else: redundancy = "N" links = [] for l in Link.object_links(self.object): local_interfaces = [] remote_interfaces = [] remote_objects = set() for i in l.interfaces: if i.managed_object.id == self.object.id: local_interfaces += [i] else: remote_interfaces += [i] remote_objects.add(i.managed_object) if len(remote_objects) == 1: ro = remote_objects.pop() if ro.id in uplinks: role = "uplink" else: role = "downlink" links += [{ "id": l.id, "role": role, "local_interface": sorted(local_interfaces, key=lambda x: split_alnum(x.name)), "remote_object": ro, "remote_interface": sorted(remote_interfaces, key=lambda x: split_alnum(x.name)), "remote_status": "up" if ro.get_status() else "down", }] links = sorted( links, key=lambda x: (x["role"] != "uplink", split_alnum(x["local_interface"][0].name)), ) # Build global services summary service_summary = ServiceSummary.get_object_summary(self.object) # Interfaces interfaces = [] metrics_map = [ "Interface | Load | In", "Interface | Load | Out", "Interface | Errors | In", "Interface | Errors | Out", ] mo = ManagedObject.objects.filter(id=self.object.id) ifaces_metrics, last_ts = get_interface_metrics(mo[0]) ifaces_metrics = ifaces_metrics[mo[0]] objects_metrics, last_time = get_objects_metrics(mo[0]) objects_metrics = objects_metrics.get(mo[0]) meta = {} metric_type_name = dict(MetricType.objects.filter().scalar( "name", "measure")) metric_type_field = dict(MetricType.objects.filter().scalar( "field_name", "measure")) if objects_metrics: for path, mres in six.iteritems(objects_metrics): for key in mres: metric_name = "%s | %s" % (key, path) if any( path.split("|")) else key meta[metric_name] = { "type": metric_type_name[key], "value": mres[key] } for i in Interface.objects.filter(managed_object=self.object.id, type="physical"): load_in = "-" load_out = "-" errors_in = "-" errors_out = "-" iface_metrics = ifaces_metrics.get(str(i.name)) if iface_metrics: for key, value in six.iteritems(iface_metrics): if key not in metrics_map: continue metric_type = metric_type_name.get( key) or metric_type_field.get(key) if key == "Interface | Load | In": load_in = ("%s%s" % (self.humanize_speed(value, metric_type), metric_type) if value else "-") if key == "Interface | Load | Out": load_out = ("%s%s" % (self.humanize_speed(value, metric_type), metric_type) if value else "-") if key == "Interface | Errors | In": errors_in = value if value else "-" if key == "Interface | Errors | Out": errors_out = value if value else "-" interfaces += [{ "id": i.id, "name": i.name, "admin_status": i.admin_status, "oper_status": i.oper_status, "mac": i.mac or "", "full_duplex": i.full_duplex, "load_in": load_in, "load_out": load_out, "errors_in": errors_in, "errors_out": errors_out, "speed": max([i.in_speed or 0, i.out_speed or 0]) / 1000, "untagged_vlan": None, "tagged_vlan": None, "profile": i.profile, "service": i.service, "service_summary": service_summary.get("interface").get(i.id, {}), "description": i.description, }] si = list(i.subinterface_set.filter(enabled_afi="BRIDGE")) if len(si) == 1: si = si[0] interfaces[-1]["untagged_vlan"] = si.untagged_vlan interfaces[-1]["tagged_vlans"] = list_to_ranges( si.tagged_vlans).replace(",", ", ") interfaces = sorted(interfaces, key=lambda x: split_alnum(x["name"])) # Resource groups # Service groups (i.e. server) static_services = set(self.object.static_service_groups) service_groups = [] for rg_id in self.object.effective_service_groups: rg = ResourceGroup.get_by_id(rg_id) service_groups += [{ "id": rg_id, "name": rg.name, "technology": rg.technology, "is_static": rg_id in static_services, }] # Client groups (i.e. client) static_clients = set(self.object.static_client_groups) client_groups = [] for rg_id in self.object.effective_client_groups: rg = ResourceGroup.get_by_id(rg_id) client_groups += [{ "id": rg_id, "name": rg.name, "technology": rg.technology, "is_static": rg_id in static_clients, }] # @todo: Administrative domain path # Alarms alarm_list = [] for a in alarms: alarm_list += [{ "id": a.id, "root_id": self.get_root(alarms), "timestamp": a.timestamp, "duration": now - a.timestamp, "subject": a.subject, "managed_object": a.managed_object, "service_summary": { "service": SummaryItem.items_to_dict(a.total_services), "subscriber": SummaryItem.items_to_dict(a.total_subscribers), }, "alarm_class": a.alarm_class, }] alarm_list = sorted(alarm_list, key=operator.itemgetter("timestamp")) # Maintenance maintenance = [] for m in Maintenance.objects.filter( affected_objects__object=self.object.id, is_completed=False, start__lte=now + datetime.timedelta(hours=1), ): maintenance += [{ "maintenance": m, "id": m.id, "subject": m.subject, "start": m.start, "stop": m.stop, "in_progress": m.start <= now, }] # Get Inventory inv = [] for p in self.object.get_inventory(): c = self.get_nested_inventory(p) c["name"] = p.name or self.object.name inv += [c] # Build result if self.object.platform is not None: platform = self.object.platform.name else: platform = "Unknown" if self.object.version is not None: version = self.object.version.version else: version = "" r = { "id": self.object.id, "object": self.object, "name": self.object.name, "address": self.object.address, "platform": platform, # self.object.platform.name if self.object.platform else "Unknown", "version": version, # self.object.version.version if self.object.version else "", "description": self.object.description, "object_profile": self.object.object_profile.id, "object_profile_name": self.object.object_profile.name, "macs": ", ".join(sorted(macs)), "segment": self.object.segment, "firmware_status": FirmwarePolicy.get_status(self.object.platform, self.object.version), "firmware_recommended": FirmwarePolicy.get_recommended_version(self.object.platform), "service_summary": service_summary, "container_path": cp, "current_state": current_state, # Start of uptime/downtime "current_start": current_start, # Current uptime/downtime "current_duration": duration, "service_groups": service_groups, "client_groups": client_groups, "tt": [], "links": links, "alarms": alarm_list, "interfaces": interfaces, "metrics": meta, "maintenance": maintenance, "redundancy": redundancy, "inventory": self.flatten_inventory(inv), "serial_number": self.object.get_attr("Serial Number"), "attributes": list( ManagedObjectAttribute.objects.filter( managed_object=self.object.id)), "confdb": self.object.get_confdb(), } return r
def update_summary(self): """ Update summaries :return: """ def update_dict(d1, d2): for k in d2: if k in d1: d1[k] += d2[k] else: d1[k] = d2[k] objects = dict( (d["object_profile"], d["count"]) for d in self.managed_objects.values( "object_profile" ).annotate( count=Count("id") ).order_by("count")) # Direct services mo_ids = self.managed_objects.values_list("id", flat=True) services, subscribers = ServiceSummary.get_direct_summary(mo_ids) self.direct_services = SummaryItem.dict_to_items(services) self.direct_subscribers = SummaryItem.dict_to_items(subscribers) self.direct_objects = ObjectSummaryItem.dict_to_items(objects) siblings = set() for ns in NetworkSegment.objects.filter(parent=self.id): if ns.id in siblings: continue update_dict(services, SummaryItem.items_to_dict(ns.total_services)) update_dict(subscribers, SummaryItem.items_to_dict(ns.total_subscribers)) update_dict(objects, ObjectSummaryItem.items_to_dict(ns.total_objects)) siblings.add(ns.id) if ns.sibling: siblings.add(ns.sibling.id) self.total_services = SummaryItem.dict_to_items(services) self.total_subscribers = SummaryItem.dict_to_items(subscribers) self.total_objects = ObjectSummaryItem.dict_to_items(objects) self.save() # Update upwards ns = self.parent while ns: services = SummaryItem.items_to_dict(ns.direct_services) subscribers = SummaryItem.items_to_dict(ns.direct_subscribers) objects = ObjectSummaryItem.items_to_dict(ns.direct_objects) for nsc in NetworkSegment.objects.filter(parent=ns.id): update_dict(services, SummaryItem.items_to_dict(nsc.total_services)) update_dict(subscribers, SummaryItem.items_to_dict(nsc.total_subscribers)) update_dict(objects, ObjectSummaryItem.items_to_dict(nsc.total_objects)) ns.total_services = SummaryItem.dict_to_items(services) ns.total_subscribers = SummaryItem.dict_to_items(subscribers) ns.total_objects = ObjectSummaryItem.dict_to_items(objects) ns.save() ns = ns.parent
def raise_alarm(self, r, e): managed_object = self.eval_expression(r.managed_object, event=e) if not managed_object: self.logger.info("Empty managed object, ignoring") return # @todo: Make configurable if not managed_object.is_managed: self.logger.info( "Managed object is not managed. Do not raise alarm") return if e.managed_object.id != managed_object.id: metrics["alarm_change_mo"] += 1 self.logger.info("Changing managed object to %s", managed_object.name) discriminator, vars = r.get_vars(e) if r.unique: assert discriminator is not None a = ActiveAlarm.objects.filter( managed_object=managed_object.id, discriminator=discriminator).first() if not a: # Try to reopen alarm a = ArchivedAlarm.objects.filter( managed_object=managed_object.id, discriminator=discriminator, control_time__gte=e.timestamp).first() if a: # Reopen alarm self.logger.info("[%s|%s|%s] %s reopens alarm %s(%s)", e.id, managed_object.name, managed_object.address, e.event_class.name, a.alarm_class.name, a.id) a = a.reopen("Reopened by disposition rule '%s'" % r.u_name) metrics["alarm_reopen"] += 1 if a: # Active alarm found, refresh self.logger.info( "[%s|%s|%s] Contributing event %s to active alarm %s(%s)", e.id, managed_object.name, managed_object.address, e.event_class.name, a.alarm_class.name, a.id) # Contribute event to alarm e.contribute_to_alarm(a) if e.timestamp < a.timestamp: # Set to earlier date a.timestamp = e.timestamp a.save() elif e.timestamp > a.last_update: # Refresh last update a.last_update = e.timestamp a.save() metrics["alarm_contribute"] += 1 return # Calculate alarm coverage summary = ServiceSummary.get_object_summary(managed_object) summary["object"] = {managed_object.object_profile.id: 1} # severity = max(ServiceSummary.get_severity(summary), 1) self.logger.info("[%s|%s|%s] %s: Calculated alarm severity is: %s", e.id, managed_object.name, managed_object.address, r.u_name, severity) # Create new alarm a = ActiveAlarm( timestamp=e.timestamp, last_update=e.timestamp, managed_object=managed_object.id, alarm_class=r.alarm_class, severity=severity, vars=vars, discriminator=discriminator, direct_services=SummaryItem.dict_to_items(summary["service"]), direct_subscribers=SummaryItem.dict_to_items( summary["subscriber"]), total_objects=ObjectSummaryItem.dict_to_items(summary["object"]), total_services=SummaryItem.dict_to_items(summary["service"]), total_subscribers=SummaryItem.dict_to_items(summary["subscriber"]), log=[ AlarmLog(timestamp=datetime.datetime.now(), from_status="A", to_status="A", message="Alarm risen from event %s(%s) by rule '%s'" % (str(e.id), str(e.event_class.name), r.u_name)) ], opening_event=e.id) a.save() e.contribute_to_alarm(a) self.logger.info("[%s|%s|%s] %s raises alarm %s(%s): %r", e.id, managed_object.name, managed_object.address, e.event_class.name, a.alarm_class.name, a.id, a.vars) metrics["alarm_raise"] += 1 self.correlate(r, a) # Notify about new alarm if not a.root: a.managed_object.event( a.managed_object.EV_ALARM_RISEN, { "alarm": a, "subject": a.subject, "body": a.body, "symptoms": a.alarm_class.symptoms, "recommended_actions": a.alarm_class.recommended_actions, "probable_causes": a.alarm_class.probable_causes }, delay=a.alarm_class.get_notification_delay()) # Gather diagnostics when necessary AlarmDiagnosticConfig.on_raise(a) # Watch for escalations, when necessary if config.correlator.auto_escalation and not a.root: AlarmEscalation.watch_escalations(a)
def get_data(self): if not self.object: return None # Get container path cp = [] if self.object.managed_object.container: c = self.object.managed_object.container.id while c: try: o = Object.objects.get(id=c) # @todo: Address data if o.container: cp.insert(0, {"id": o.id, "name": o.name}) c = o.container.id if o.container else None except DoesNotExist: metrics["error", ("type", "user_not_found")] += 1 break # Build log log = [] if self.object.log: log = [{ "timestamp": l.timestamp, "from_status": l.from_status, "to_status": l.to_status, "message": l.message } for l in self.object.log] # Build alarm tree alarms = self.get_alarms() # Service summary service_summary = { "service": SummaryItem.items_to_dict(self.object.total_services), "subscriber": SummaryItem.items_to_dict(self.object.total_subscribers) } # Maintenance mainteinance = Maintenance.objects.filter( is_completed=False, start__lte=datetime.datetime.now(), affected_objects__in=[ MaintenanceObject(object=self.object.managed_object) ]) mo = self.object.managed_object # Build result r = { "id": self.object.id, "alarm": self.object, "severity": AlarmSeverity.get_severity(self.object.severity), "managed_object": self.object.managed_object, "timestamp": self.object.timestamp, "duration": self.object.display_duration, "subject": self.object.subject, "body": self.object.body, "container_path": cp, "log": log, "service_summary": service_summary, "alarms": alarms, "diagnostic": AlarmDiagnostic.get_diagnostics(self.object), "maintenance": mainteinance, "lon": mo.x, "lat": mo.y, "zoom": mo.default_zoom, "tt_system": self.object.managed_object.tt_system.name if self.object.managed_object.tt_system else None, "tt_system_failed": (self.object.status == "A" and not self.object.escalation_tt and self.object.managed_object.tt_system and self.object.managed_object.tt_system.is_failed()), "escalation_ctx": self.object.escalation_ctx, "escalation_close_ctx": getattr(self.object, "escalation_close_ctx", None) } return r
def instance_to_dict(self, o, fields=None): s = AlarmSeverity.get_severity(o.severity) n_events = (ActiveEvent.objects.filter(alarms=o.id).count() + ArchivedEvent.objects.filter(alarms=o.id).count()) d = { "id": str(o.id), "status": o.status, "managed_object": o.managed_object.id, "managed_object__label": o.managed_object.name, "administrative_domain": o.managed_object.administrative_domain_id, "administrative_domain__label": o.managed_object.administrative_domain.name, "severity": o.severity, "severity__label": s.name, "alarm_class": str(o.alarm_class.id), "alarm_class__label": o.alarm_class.name, "timestamp": self.to_json(o.timestamp), "subject": o.subject, "events": n_events, "duration": o.duration, "clear_timestamp": self.to_json(o.clear_timestamp) if o.status == "C" else None, "row_class": s.style.css_class_name, "segment__label": o.managed_object.segment.name, "segment": str(o.managed_object.segment.id), "location_1": self.location(o.managed_object.container.id)[0] if o.managed_object.container else "", "location_2": self.location(o.managed_object.container.id)[1] if o.managed_object.container else "", "escalation_tt": o.escalation_tt, "escalation_error": o.escalation_error, "platform": o.managed_object.platform.name if o.managed_object.platform else "", "address": o.managed_object.address, "ack_ts": self.to_json(o.ack_ts), "ack_user": o.ack_user, "summary": self.f_glyph_summary({ "subscriber": SummaryItem.items_to_dict(o.total_subscribers), "service": SummaryItem.items_to_dict(o.total_services), }), "total_objects": sum(x.summary for x in o.total_objects), "total_subscribers": self.f_summary( {"subscriber": SummaryItem.items_to_dict(o.total_subscribers)}), "total_services": self.f_summary( {"service": SummaryItem.items_to_dict(o.total_services)}), "logs": [{ "timestamp": self.to_json(ll.timestamp), "user": ll.source or "NOC", "message": ll.message, } for ll in o.log if getattr(ll, "source", None) ][:config.web.api_alarm_comments_limit], } if fields: d = {k: d[k] for k in fields} return d
def get_data(self): intervals = ( ("y", 31557617), # 60 * 60 * 24 * 7 * 52 ("w", 604800), # 60 * 60 * 24 * 7 ("d", 86400), # 60 * 60 * 24 ("h", 3600), # 60 * 60 ("m", 60), ("s", 1), ) def display_time(seconds): result = [] for name, count in intervals: value = seconds // count if value: seconds -= value * count if value == 1: name = name.rstrip("s") result.append("{}{}".format(value, name)) return ", ".join(result[:-1]) def sortdict(dct): kys = sorted(dct.keys()) res = OrderedDict() for x in kys: for k, v in dct.items(): if k == x: res[k] = v return res def get_container_path(self): # Get container path if not self.object: return None cp = [] if self.object.container: c = self.object.container.id while c: try: o = Object.objects.get(id=c) # @todo: Address data if o.container: cp.insert(0, {"id": o.id, "name": o.name}) c = o.container.id if o.container else None except DoesNotExist: metrics["error", ("type", "no_such_object")] += 1 break return cp if not self.object: return None # @todo: Stage # @todo: Service range # @todo: Open TT now = datetime.datetime.now() # Get object status and uptime alarms = list(ActiveAlarm.objects.filter(managed_object=self.object.id)) current_start = None duration = None if self.object.is_managed: if self.object.get_status(): if alarms: current_state = "alarm" else: current_state = "up" uptime = Uptime.objects.filter(object=self.object.id, stop=None).first() if uptime: current_start = uptime.start else: current_state = "down" outage = Outage.objects.filter(object=self.object.id, stop=None).first() if outage is not None: current_start = outage.start else: current_state = "unmanaged" if current_start: duration = now - current_start cp = get_container_path(self) # MAC addresses macs = [] o_macs = DiscoveryID.macs_for_object(self.object) if o_macs: for f, l in o_macs: if f == l: macs += [f] else: macs += ["%s - %s" % (f, l)] # Hostname hostname = "" did = DiscoveryID.objects.filter(object=self.object.id).first() if did and did.hostname: hostname = did.hostname # Links uplinks = set(self.object.data.uplinks) if len(uplinks) > 1: if self.object.segment.lost_redundancy: redundancy = "L" else: redundancy = "R" else: redundancy = "N" links = [] for _link in Link.object_links(self.object): local_interfaces = [] remote_interfaces = [] remote_objects = set() for iface in _link.interfaces: if iface.managed_object.id == self.object.id: local_interfaces += [iface] else: remote_interfaces += [iface] remote_objects.add(iface.managed_object) if len(remote_objects) == 1: ro = remote_objects.pop() if ro.id in uplinks: role = "uplink" else: role = "downlink" links += [ { "id": _link.id, "role": role, "local_interface": sorted( local_interfaces, key=lambda x: alnum_key(x.name) ), "remote_object": ro, "remote_interface": sorted( remote_interfaces, key=lambda x: alnum_key(x.name) ), "remote_status": "up" if ro.get_status() else "down", } ] links = sorted( links, key=lambda x: (x["role"] != "uplink", alnum_key(x["local_interface"][0].name)), ) # Build global services summary service_summary = ServiceSummary.get_object_summary(self.object) # Interfaces interfaces = [] mo = ManagedObject.objects.filter(id=self.object.id) mo = mo[0] ifaces_metrics, last_ts = get_interface_metrics(mo) ifaces_metrics = ifaces_metrics[mo] objects_metrics, last_time = get_objects_metrics(mo) objects_metrics = objects_metrics.get(mo) # Sensors sensors_metrics = None s_metrics = None sensors = {} s_meta = [] STATUS = {0: "OK", 1: "Alarm"} meric_map = {} if mo.get_caps().get("Sensor | Controller"): for mc in MetricType.objects.filter(scope=MetricScope.objects.get(name="Environment")): if meric_map: meric_map["map"].update({mc.field_name: mc.name}) else: meric_map = {"table_name": mc.scope.table_name, "map": {mc.field_name: mc.name}} sensors_metrics, last_ts = get_interface_metrics(mo, meric_map) sensors_metrics = sensors_metrics[mo] m_tp = {} if mo.object_profile.metrics: for mt in mo.object_profile.metrics: if mt.get("threshold_profile"): threshold_profile = ThresholdProfile.get_by_id(mt.get("threshold_profile")) m_tp[MetricType.get_by_id(mt.get("metric_type")).name] = threshold_profile data = {} meta = [] metric_type_name = dict(MetricType.objects.filter().scalar("name", "measure")) metric_type_field = dict(MetricType.objects.filter().scalar("field_name", "measure")) if objects_metrics: for path, mres in objects_metrics.items(): t_v = False for key in mres: m_path = path if any(path.split("|")) else key m_path = " | ".join(kk.strip() for kk in m_path.split("|")) if m_tp.get(key): t_v = self.get_threshold_config(m_tp.get(key), int(mres[key])) val = { "name": m_path, "type": "" if m_path == "Object | SysUptime" else metric_type_name[key], "value": display_time(int(mres[key])) if m_path == "Object | SysUptime" else mres[key], "threshold": t_v, } if data.get(key): data[key] += [val] else: data[key] = [val] data = sortdict(data) for k, d in data.items(): collapsed = False if len(d) == 1: collapsed = True for dd in d: isdanger = False if dd["threshold"]: isdanger = True collapsed = True meta.append({"name": k, "value": d, "collapsed": collapsed, "isdanger": isdanger}) for i in Interface.objects.filter(managed_object=self.object.id, type="physical"): load_in = "-" load_out = "-" errors_in = "-" errors_out = "-" iface_metrics = ifaces_metrics.get(str(i.name)) if iface_metrics: for key, value in iface_metrics.items(): metric_type = metric_type_name.get(key) or metric_type_field.get(key) if key == "Interface | Load | In": load_in = ( "%s%s" % (self.humanize_speed(value, metric_type), metric_type) if value else "-" ) if key == "Interface | Load | Out": load_out = ( "%s%s" % (self.humanize_speed(value, metric_type), metric_type) if value else "-" ) if key == "Interface | Errors | In": errors_in = value if value else "-" if key == "Interface | Errors | Out": errors_out = value if value else "-" interfaces += [ { "id": i.id, "name": i.name, "admin_status": i.admin_status, "oper_status": i.oper_status, "mac": i.mac or "", "full_duplex": i.full_duplex, "load_in": load_in, "load_out": load_out, "errors_in": errors_in, "errors_out": errors_out, "speed": max([i.in_speed or 0, i.out_speed or 0]) / 1000, "untagged_vlan": None, "tagged_vlan": None, "profile": i.profile, "service": i.service, "service_summary": service_summary.get("interface").get(i.id, {}), "description": i.description, } ] if sensors_metrics: s_metrics = sensors_metrics.get(str(i.name)) if s_metrics: sens_metrics = [] for i_metrics in i.profile.metrics: sens_metrics.append(i_metrics.metric_type.name) for key, value in s_metrics.items(): if key not in sens_metrics: continue val = { "name": key, "type": metric_type_name[key], "value": STATUS.get(value) if metric_type_name[key] == " " else value, "threshold": None, } if sensors.get(i.name): sensors[i.name] += [val] else: sensors[i.name] = [val] si = list(i.subinterface_set.filter(enabled_afi="BRIDGE")) if len(si) == 1: si = si[0] interfaces[-1]["untagged_vlan"] = si.untagged_vlan interfaces[-1]["tagged_vlans"] = list_to_ranges(si.tagged_vlans).replace(",", ", ") if sensors: sensors = sortdict(sensors) for k, d in sensors.items(): for dd in d: isdanger = False if dd["threshold"]: isdanger = True s_meta.append({"name": k, "value": d, "isdanger": isdanger}) interfaces = sorted(interfaces, key=lambda x: alnum_key(x["name"])) # Resource groups # Service groups (i.e. server) static_services = set(self.object.static_service_groups) service_groups = [] for rg_id in self.object.effective_service_groups: rg = ResourceGroup.get_by_id(rg_id) service_groups += [ { "id": rg_id, "name": rg.name, "technology": rg.technology, "is_static": rg_id in static_services, } ] # Client groups (i.e. client) static_clients = set(self.object.static_client_groups) client_groups = [] for rg_id in self.object.effective_client_groups: rg = ResourceGroup.get_by_id(rg_id) client_groups += [ { "id": rg_id, "name": rg.name, "technology": rg.technology, "is_static": rg_id in static_clients, } ] # @todo: Administrative domain path # Alarms alarm_list = [] for a in alarms: alarm_list += [ { "id": a.id, "root_id": self.get_root(alarms), "timestamp": a.timestamp, "duration": now - a.timestamp, "subject": a.subject, "managed_object": a.managed_object, "service_summary": { "service": SummaryItem.items_to_dict(a.total_services), "subscriber": SummaryItem.items_to_dict(a.total_subscribers), }, "alarm_class": a.alarm_class, } ] alarm_list = sorted(alarm_list, key=operator.itemgetter("timestamp")) # Maintenance maintenance = [] for m in Maintenance.objects.filter( affected_objects__object=self.object.id, is_completed=False, start__lte=now + datetime.timedelta(hours=1), ): maintenance += [ { "maintenance": m, "id": m.id, "subject": m.subject, "start": m.start, "stop": m.stop, "in_progress": m.start <= now, } ] # Get Inventory inv = [] for p in self.object.get_inventory(): c = self.get_nested_inventory(p) c["name"] = p.name or self.object.name inv += [c] # Build result if self.object.platform is not None: platform = self.object.platform.name else: platform = "Unknown" if self.object.version is not None: version = self.object.version.version else: version = "" r = { "id": self.object.id, "object": self.object, "name": self.object.name, "address": self.object.address, "platform": platform, # self.object.platform.name if self.object.platform else "Unknown", "version": version, # self.object.version.version if self.object.version else "", "description": self.object.description, "object_profile": self.object.object_profile.id, "object_profile_name": self.object.object_profile.name, "hostname": hostname, "macs": ", ".join(sorted(macs)), "segment": self.object.segment, "firmware_status": FirmwarePolicy.get_status(self.object.platform, self.object.version), "firmware_recommended": FirmwarePolicy.get_recommended_version(self.object.platform), "service_summary": service_summary, "container_path": cp, "current_state": current_state, # Start of uptime/downtime "current_start": current_start, # Current uptime/downtime "current_duration": duration, "service_groups": service_groups, "client_groups": client_groups, "tt": [], "links": links, "alarms": alarm_list, "interfaces": interfaces, "metrics": meta, "sensors": s_meta, "maintenance": maintenance, "redundancy": redundancy, "inventory": self.flatten_inventory(inv), "serial_number": self.object.get_attr("Serial Number"), "attributes": list( ManagedObjectAttribute.objects.filter(managed_object=self.object.id) ), "confdb": None, } try: r["confdb"] = self.object.get_confdb() except (SyntaxError, ValueError): pass return r