code: def parse_log(
      file_path: str, verbose: bool = False
  ) -> ResultDictType:
      """Finds ResultStore links, and tries to determine their status."""
      with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
          log_lines = f.read().splitlines()
  
      result_store_links: ResultDictType = {}
      current_url = None
      for i in range(len(log_lines)):
          line = log_lines[i]
          result_store_line_match = re.search(
              RESULT_STORE_LINK_RE, line
          )
          if not result_store_line_match:
              continue
  
          url = result_store_line_match.group(1)
          url_lines = result_store_links.setdefault(url, {})
          # Each bazel RBE invocation should produce two
          # 'Streaming build results to: ...' lines, one at the start, and one at the
          # end of the invocation.
          # If there's a failure message, it will be found in-between these two.
  
          if not current_url:
              url_lines["start"] = i
          elif current_url == url:
              url_lines["end"] = i
          else:
              result_store_links[current_url]["next_url"] = i
              url_lines["start"] = i
          current_url = url
  
      previous_end_line = None
      for url, lines in result_store_links.items():
          lines["status"] = InvokeStatus.passed  # default to passed
          start_line = lines["start"]
          end_line = (
              lines.get("end", lines.get("next_url", len(log_lines)))
              - 1
          )
          k = end_line
          while k > start_line:
              backtrack_line = log_lines[k]
              build_failed = backtrack_line.startswith(
                  FAILED_BUILD_LINE
              )
              if build_failed or not backtrack_line.startswith(
                  BUILD_STATUS_LINE
              ):
                  tests_failed = False
              else:
                  tests_failed = re.search(
                      TESTS_FAILED_RE, backtrack_line
                  )
              if build_failed or tests_failed:
                  log_fragment = "\n".join(
                      log_lines[
                          max(k - 20, 0) : min(
                              end_line + 1, len(log_lines) - 1
                          )
                      ]
                  )
                  lines["log_fragment"] = log_fragment
                  lines["status"] = (
                      InvokeStatus.build_failed
                      if build_failed
                      else InvokeStatus.tests_failed
                  )
                  if verbose:
                      print(
                          f'Found failed invocation: {url.rsplit("/")[-1]}\n'
                          f"Log fragment:\n"
                          f"```\n{log_fragment}\n```\n"
                          f'{"=" * 140}'
                      )
                  break
              k -= 1
  
          # A low-effort attempt to find the bazel command that triggered the
          # invocation.
          bazel_comm_min_line_i = (
              previous_end_line if previous_end_line is not None else 0
          )
          while k > bazel_comm_min_line_i:
              backtrack_line = log_lines[k]
              # Don't attempt to parse multi-line commands broken up by backslashes
              if (
                  "bazel " in backtrack_line
                  and not backtrack_line.endswith("\\")
              ):
                  bazel_line = BAZEL_COMMAND_RE.search(backtrack_line)
                  if bazel_line:
                      lines["command"] = bazel_line.group("command")
                      lines["command_type"] = bazel_line.group("type")
                      break
              k -= 1
              continue
          previous_end_line = lines.get("end") or start_line
  
      return result_store_links
  
file_path: tensorflow/ci/official/utilities/extract_resultstore_links.py
imports: import argparse
  import datetime
  import os
  import re
  from typing import Dict, Union
  import xml.etree.ElementTree
label_desc: Use image node_id 2 for calling a global function with example usage: parse_log(file_path, verbose) and returns: result_store_links