Source code for logflow.treebuilding.Workflow

# Copyright 2020 BULL SAS All rights reserved #
import numpy as np # type: ignore
from logflow.treebuilding.Inference import Inference
from logflow.treebuilding.Dataset import Dataset
from logflow.treebuilding.Tree import Tree
from logflow.treebuilding.Log import Log
from loguru import logger
import time

[docs]class Workflow: """Computes the tree of correlations. Args: dataset (Dataset): dataset containing the data for the inference and the tree building. """ def __init__(self, dataset : Dataset): self.dataset = dataset self.models = dataset.LSTM self.inference = Inference(self.models)
[docs] def get_tree(self, index_line : int): """Get the tree associated to the line at the index "index_line" Args: index_line (int): index of the line Returns: Exception: Index of the line is after the maximum loaded index. """ if index_line > len(self.dataset): logger.error("Asking for a line after the last line loaded. Check your index_line_max") raise Exception("Asking for a line after the last line loaded. Check your index_line_max") self.detect_workflow(index_line)
[docs] def detect_workflow(self, index_line : int) -> str: """Detect the workflow (i.e. the correlations tree) Args: index_line (int): index of the line Returns: str: representation of the three to be used with graphviz. """ # begin = time.time() local_tree = Tree() first_log = self.dataset.get_slice(index_line) # Add the first log to the tree if first_log != -1: local_tree.add_node(log=first_log, id=0, parent=-1, processed=False, weight=0) else: return "-1" depth = 0 id = 1 continue_while = True nb_node_merged = 0 nb_logs_analysed = 0 # While the condition is valid while continue_while: continue_while = False # For all the nodes in the tree for index in range(len(local_tree)) : node = local_tree.get_node(index) # If node wasn't predicted if not node.processed: continue_while = True nb_logs_analysed += 1 # Get its correlations list_best_log = self.inference.test(node.log.slice, node.log) # No correlations if list_best_log == [-1]: invalid_log = Log("-1") invalid_log.usable = False local_tree.add_node(log=invalid_log, id=id , parent=node.id, processed=True, weight=0) id += 1 else: # Else add the correlations to the tree to predict them later. for index_log in list_best_log: log = self.dataset.list_logs[index_log["log"]] log.weigth = index_log["weigth"] log_to_add = self.dataset.get_slice(log.index_line) # Invalid log if log_to_add == -1: local_tree.add_node(log=Log("-1"), id=id, parent=node.id, processed=True, weight=log.weight) else: local_tree.add_node(log=log_to_add, id=id, parent=node.id, processed=False, weight=log.weight) id += 1 local_tree.update_node(index) local_tree.merge_tree() # No new nodes added, we can stop the exploration. if nb_node_merged == local_tree.get_number_nodes_merged(): break else: nb_node_merged = local_tree.get_number_nodes_merged() depth += 1 # Avoiding while true loop if depth > 6: logger.warning("Exploration is stopped due to depth exceeded") break local_tree.merge_tree() #logger.debug(str("Timing workflow: ") + str((time.time() - begin) / nb_logs_analysed)) return self.write_workflow_merged(local_tree=local_tree)
[docs] def write_workflow_merged(self, local_tree : Tree) -> str: """Write the tree following the graphviz syntax Args: local_tree (Tree): tree to be written. Returns: str: representation of the tree. """ local_tree.merge_link() string_tree = "digraph prof {ratio = fill; node [style=filled]; \n" for node in local_tree.list_node_merge: string_tree += str(node.id) + " [labelfontsize=20, label=\"" + str(node.message) + " / " + str(node.cardinality) + "\"]; \n" for start in local_tree.dict_link: for end in local_tree.dict_link[start]: string_tree += str(start) + " -> " + str(end) + "[labelfontsize=20, headlabel=\"" + str(np.mean(local_tree.dict_link[start][end]))[:4] + "/" + str(len(local_tree.dict_link[start][end])) + "\"]; \n" # str(self.dict_link[start][end])[:4] string_tree += "}" print(" Tree is:", string_tree) return string_tree