コード例 #1
0
    def filter_records(self, start, end, records, name, dependencies):
        """
        This function transforms the data returned by Neo4j into a format we
        can use to search data in our TimeSeries database.

        We also take this opportunity to filter inactive nodes or nodes with
        inactive relationship.
        """
        data = {}
        for record in records:
            node = record.get(name)

            # Remove inactive nodes
            if not is_active_node(start, end, node):
                self.log.info("{node} is no longer active, skip it.".format(
                    node=node["name"]))
                continue

            # Transform the records
            data[node["name"]] = []
            for dependency in dependencies:

                # For each dependency in this label
                for n in record.get(dependency["node"]) or []:

                    # Do not use inactive dependencies or dependencies with inactive relation
                    if not is_active_node(
                            start, end,
                            n["node"]) or not has_active_relationship(
                                start, end, n["rel"]["periods"]):
                        self.log.info(
                            "Dependency {node} is no longer active, skip it.".
                            format(node=n["node"]["name"]))
                        continue

                    # This dependency can be used to compute the QOS of the main node
                    data[node["name"]].append({
                        "label": dependency["label"],
                        "name": n["node"]["name"]
                    })

        # Remove nodes without any dependency
        data = {k: v for k, v in data.items() if v}

        return data
コード例 #2
0
    def get_node_dependencies(
        cls,
        team_id,
        label,
        node,
        day=None,
        filter_on_config=False,
        include_inactive=False,
    ):
        topic = TeamController._get({"Team": {"id": team_id}}).kafka_topic
        query = cls._build_dependencies_query(team_id, topic, label, node,
                                              filter_on_config)
        dependencies = {
            "dependencies": {},
            "graph": {
                "nodes": [],
                "relationships": []
            }
        }
        records = get_records(query)

        # Loop on all relationships
        for idx, record in enumerate(records):

            # Handle the main node
            if idx == 0:
                node = record.get("n")
                title = list(node.labels)[0][len(topic) + 1:]

                if title not in dependencies["dependencies"]:
                    dependencies["dependencies"][title] = []
                dependencies["dependencies"][title].append(dict(node.items()))

                dependencies["graph"]["nodes"].append({
                    "id":
                    node.id,
                    "label":
                    dict(node.items())["name"],
                    "title":
                    title
                })

            # Handle the relationship
            rel = record.get("r")
            if not rel:
                continue

            # Check inactive nodes
            start_node = rel.start_node
            end_node = rel.end_node
            start = arrow.get(day, "YYYY-MM-DD").floor("day").timestamp
            end = arrow.get(day, "YYYY-MM-DD").ceil("day").timestamp

            if (not is_active_node(start, end,
                                   end_node)) or (not has_active_relationship(
                                       start, end, rel.get("periods"))):
                if not include_inactive:
                    continue
                else:
                    setattr(end_node, "inactive", True)

            # The label is 'acme_Mylabel', we just want 'Mylabel'
            title = list(end_node.labels)[0][len(topic) + 1:]

            if title not in dependencies["dependencies"]:
                dependencies["dependencies"][title] = []
            dependencies["dependencies"][title].append({
                **dict(end_node.items()),
                **{
                    "periods": list(rel.get("periods")),
                    "inactive": getattr(end_node, "inactive", False),
                },
            })

            dependencies["graph"]["nodes"].append({
                "id":
                end_node.id,
                "label":
                dict(end_node.items())["name"],
                "title":
                title,
            })

            dependencies["graph"]["relationships"].append({
                "id":
                rel.id,
                "from":
                start_node.id,
                "to":
                end_node.id,
                "arrows":
                "to",
                "periods":
                list(rel.get("periods")),
            })

        return dependencies
コード例 #3
0
ファイル: rule_operator.py プロジェクト: dingcycle/depc
    def execute(self, context):
        from depc.controllers import NotFoundError
        from depc.controllers.rules import RuleController
        from depc.extensions import redis_scheduler as redis
        from depc.utils import get_start_end_ts

        ds = context["ds"]
        start, end = get_start_end_ts(ds)

        with self.app.app_context():

            # Get the nodes for this team and this label
            query = ("MATCH(n:{label}) RETURN n AS Node "
                     "ORDER BY Node.name "
                     "SKIP {skip} LIMIT {limit}")
            query = query.format(label=self.full_label,
                                 skip=self.skip,
                                 limit=int(self.length))

            records = get_records(query)
            nodes = [dict(record.get("Node").items()) for record in records]

            # Remove old nodes
            nodes = [n for n in nodes if is_active_node(start, end, n)]

            # Get the rule associated to the label for this team
            try:
                rule = RuleController.get(filters={
                    "Rule": {
                        "name": self.rule_name,
                        "team_id": self.team_id
                    }
                })
            except NotFoundError:
                self.log.warning(
                    "[{0}] The label {1} has no associated rule in DEPC".
                    format(self.team_name, self.label))
                return False

            has_qos = False
            auto_fill = check_enable_auto_fill(rule["id"], self.team_id)
            for node in nodes:
                result = RuleController.execute(
                    rule_id=rule["id"],
                    auto_fill=auto_fill,
                    name=node["name"],
                    start=start,
                    end=end,
                )

                if result["qos"]["qos"] != "unknown":
                    has_qos = True
                    self.log.info("[{0}/{1}] The QOS of {2} is {3}%".format(
                        self.team_name,
                        self.label,
                        node["name"],
                        result["qos"]["qos"],
                    ))

                    # Saving to Beamium
                    self.write_metric(
                        metric="depc.qos.node",
                        ts=start,
                        value=result["qos"]["qos"],
                        tags={
                            "label": self.label,
                            "name": node["name"],
                            "team": self.team_id,
                        },
                    )

                    # Used for average computing
                    key = "{ds}.{team}.{label}".format(ds=ds,
                                                       team=self.team_name,
                                                       label=self.label)

                    if not self.excluded_from_label_average(
                            self.team_name, self.label, node["name"]):
                        redis.zadd("{}.sorted".format(key), node["name"],
                                   result["qos"]["qos"])

                    # Save information to reuse it later (`bools_dps` is used in
                    # OperationOperator and `qos` is used in AggregationOperator)
                    redis.set(
                        "{}.{}.node".format(key, node["name"]),
                        json.dumps({
                            "bools_dps": result["qos"]["bools_dps"],
                            "qos": result["qos"]["qos"],
                        }),
                    )

                else:
                    self.log.warning("[{0}/{1}] No QOS for {2}".format(
                        self.team_name, self.label, node["name"]))

                    # Add it in redis to compute some stats in AfterSubdagOperator
                    redis.sadd(
                        "{ds}.{team}.{label}.noqos".format(ds=ds,
                                                           team=self.team_name,
                                                           label=self.label),
                        node["name"],
                    )

            if not has_qos:
                self.log.warning("[{0}/{1}] No QOS found for any items".format(
                    self.team_name, self.label))