def parse_logs()

in tools/log_parser.py [0:0]


def parse_logs(log_lines, verbose=False):
    """
    Returns ngraph metrics parsed out of the specified log output. 

    Regular log parsing will return:
    - Number of nodes in the graph
    - Number of nodes marked for clustering
    - Number of ngraph clusters

    Verbose log parsing will return all of the above, in addition to:
    - Percentage of nodes clustered
    - Has deadness issues
    - Has static input issues
    - Reasons why edge connected clusters did not merge
    - Reasons why edge connected encapsulates did not merge
    - Nodes per cluster
    - Types of edges
    - Op not supported
    - Op failed type constraint
    """
    if type(log_lines) == type(''):
        log_lines = log_lines.split('\n')
    else:
        assert type(log_lines) == type(
            []
        ), "If log_lines if not a string, it should have been a list, but instead it is a " + type(
            log_lines)
    assert all([
        type(i) == type('') and '\n' not in i for i in log_lines
    ]), 'Each element of the list should be a string and not contain new lines'
    all_results = {}
    curr_result = {}
    ctr = 0
    prev_line = ""
    for line in log_lines:
        start_of_subgraph = "NGTF_SUMMARY: Op_not_supported:" in line
        # If logs of a new sub-graph is starting, save the old one
        if start_of_subgraph:
            if len(curr_result) > 0:
                all_results[str(ctr)] = curr_result
                curr_result = {}
                ctr += 1
        # keep collecting information in curr_result
        if line.startswith('NGTF_SUMMARY'):
            if 'Number of nodes in the graph' in line:
                curr_result['num_nodes_in_graph'] = int(
                    line.split(':')[-1].strip())
            elif 'Number of nodes marked for clustering' in line:
                curr_result['num_nodes_marked_for_clustering'] = int(
                    line.split(':')[-1].strip().split(' ')[0].strip())
                if verbose:
                    # get percentage of total nodes
                    match = re.search("(\d+(\.\d+)?%)", line)
                    nodes_clustered = ""
                    if match:
                        nodes_clustered = match.group(0)
                    curr_result["percentage_nodes_clustered"] = nodes_clustered
            elif 'Number of ngraph clusters' in line:
                curr_result['num_ng_clusters'] = int(
                    line.split(':')[-1].strip())
            if verbose and ('DEADNESS' in line and 'STATICINPUT' in line):
                line = line[len("NGTF_SUMMARY:"):]
                reasons = dict([i.strip()
                                for i in item.split(":")]
                               for item in line.split(","))
                if "reasons why a pair of edge connected encapsulates did not merge" in prev_line:
                    curr_result[
                        'why_edge_connected_encapsulates_did_not_merge'] = reasons
                elif "reasons why a pair of edge connected clusters did not merge" in prev_line:
                    curr_result[
                        'why_edge_connected_clusters_did_not_merge'] = reasons

                # default has_deadness_issues and has_static_input_issues to 'No'
                if 'has_deadness_issues' not in curr_result.keys():
                    curr_result['has_deadness_issues'] = "No"
                if 'has_static_input_issues' not in curr_result.keys():
                    curr_result['has_static_input_issues'] = "No"

                # set has deadness/static input issues to 'Yes' if the value is > 0
                if int(reasons['DEADNESS']) > 0:
                    curr_result['has_deadness_issues'] = "Yes"
                if int(reasons['STATICINPUT']) > 0:
                    curr_result['has_static_input_issues'] = "Yes"
            elif verbose and 'Nodes per cluster' in line:
                curr_result['nodes_per_cluster'] = float(
                    line.split(':')[-1].strip())
            elif verbose and 'Types of edges::' in line:
                line = line[len("NGTF_SUMMARY: Types of edges:: "):]
                edge_types = dict([i.strip()
                                   for i in item.split(":")]
                                  for item in line.split(","))
                curr_result["types_of_edges"] = edge_type
                s
            elif verbose and 'Op_not_supported' in line:
                curr_result["op_not_supported"] = \
                    [i.strip() for i in line[len("NGTF_SUMMARY: Op_not_supported:  "):].split(",")]
            elif verbose and 'Op_failed_type_constraint' in line:
                curr_result["op_failed_type_constraint"] = \
                    [i.strip() for i in line[len(
                        "NGTF_SUMMARY: Op_failed_type_constraint:  "):].split(",")]
        prev_line = line

    # add the last section to the results
    all_results[str(ctr)] = curr_result

    return all_results