Blame SOURCES/0012-Analyzer-Optimize-list-verbose-output.patch

1c5238
From 70e254653edb21923d7565c80704e1ce6865d991 Mon Sep 17 00:00:00 2001
1c5238
From: Justin Stephenson <jstephen@redhat.com>
1c5238
Date: Wed, 12 Oct 2022 08:48:45 -0400
1c5238
Subject: [PATCH] Analyzer: Optimize list verbose output
1c5238
MIME-Version: 1.0
1c5238
Content-Type: text/plain; charset=UTF-8
1c5238
Content-Transfer-Encoding: 8bit
1c5238
1c5238
Modify the analyzer to parse the responder log file in one pass. This
1c5238
avoids repeated parsing of a single log file. This operation will now
1c5238
store log lines in a dictionary on a single pass then format and print
1c5238
the output accordingly. Does not affect 'list' or 'show' output.
1c5238
1c5238
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
1c5238
Reviewed-by: Tomáš Halman <thalman@redhat.com>
1c5238
1c5238
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
1c5238
Reviewed-by: Tomáš Halman <thalman@redhat.com>
1c5238
---
1c5238
 src/tools/analyzer/modules/request.py | 71 ++++++++++++++++++---------
1c5238
 1 file changed, 48 insertions(+), 23 deletions(-)
1c5238
1c5238
diff --git a/src/tools/analyzer/modules/request.py b/src/tools/analyzer/modules/request.py
1c5238
index b9fe3caf8..15c8e6bfb 100644
1c5238
--- a/src/tools/analyzer/modules/request.py
1c5238
+++ b/src/tools/analyzer/modules/request.py
1c5238
@@ -148,36 +148,57 @@ class RequestAnalyzer:
1c5238
                 print(line)
1c5238
         return found_results
1c5238
 
1c5238
-    def print_formatted_verbose(self, source, patterns):
1c5238
+    def print_formatted_verbose(self, source):
1c5238
         """
1c5238
-        Parse line and print formatted verbose list_requests output
1c5238
+        Parse log file and print formatted verbose list_requests output
1c5238
 
1c5238
         Args:
1c5238
             source (Reader): source Reader object
1c5238
-            patterns (list): List of regex patterns to use for
1c5238
-                matching lines
1c5238
         """
1c5238
-        # Get CID number, and print the basic line first
1c5238
-        for line in self.matched_line(source, patterns):
1c5238
-            cid = self.print_formatted(line)
1c5238
-
1c5238
-            # Loop through each line with this CID number to extract and
1c5238
-            # print the verbose data needed
1c5238
-            verbose_patterns = ["(cache_req_send|cache_req_process_input|"
1c5238
-                                "cache_req_search_send)"]
1c5238
-            for cidline in self.matched_line(source, verbose_patterns):
1c5238
+        data = {}
1c5238
+        # collect cid log lines from single run through of parsing the log
1c5238
+        # into dictionary # (cid, ts) -> logline_output
1c5238
+        for line in source:
1c5238
+            if "CID#" not in line:
1c5238
+                continue
1c5238
+
1c5238
+            # parse CID and ts from line, key is a tuple of (cid,ts)
1c5238
+            fields = line.split("[")
1c5238
+            # timestamp to the minute, cut off seconds, ms
1c5238
+            ts = fields[0][:17]
1c5238
+            result = re.search('CID#[0-9]*', fields[3])
1c5238
+            cid = result.group(0)
1c5238
+
1c5238
+            # if mapping exists, append line to output. Otherwise create new mapping
1c5238
+            if (cid, ts) in data.keys():
1c5238
+                data[(cid, ts)] += line
1c5238
+            else:
1c5238
+                data[(cid, ts)] = line
1c5238
+
1c5238
+        # pretty print the data
1c5238
+        for k, v in data.items():
1c5238
+            cr_done = []
1c5238
+            id_done = []
1c5238
+            for cidline in v.splitlines():
1c5238
                 plugin = ""
1c5238
                 name = ""
1c5238
                 id = ""
1c5238
 
1c5238
-                # skip any lines not pertaining to this CID
1c5238
-                if f"CID#{cid}]" not in cidline:
1c5238
-                    continue
1c5238
-                if "refreshed" in cidline:
1c5238
-                    continue
1c5238
+                # CR number
1c5238
+                fields = cidline.split("[")
1c5238
+                cr_field = fields[3][7:]
1c5238
+                cr = cr_field.split(":")[0][4:]
1c5238
+                # Client connected, top-level info line
1c5238
+                if re.search(r'\[cmd', cidline):
1c5238
+                    self.print_formatted(cidline)
1c5238
                 # CR Plugin name
1c5238
                 if re.search("cache_req_send", cidline):
1c5238
                     plugin = cidline.split('\'')[1]
1c5238
+                    id_done.clear()
1c5238
+                    # Extract CR number
1c5238
+                    fields = cidline.split("[")
1c5238
+                    cr_field = fields[3][7:]
1c5238
+                    cr = cr_field.split(":")[0][4:]
1c5238
                 # CR Input name
1c5238
                 elif re.search("cache_req_process_input", cidline):
1c5238
                     name = cidline.rsplit('[')[-1]
1c5238
@@ -188,9 +209,14 @@ class RequestAnalyzer:
1c5238
                 if plugin:
1c5238
                     print("   - " + plugin)
1c5238
                 if name:
1c5238
-                    print("       - " + name[:-2])
1c5238
+                    # Avoid duplicate output with the same CR #
1c5238
+                    if cr not in cr_done:
1c5238
+                        print("       - " + name[:-1])
1c5238
+                        cr_done.append(cr)
1c5238
                 if (id and ("UID" in cidline or "GID" in cidline)):
1c5238
-                    print("       - " + id)
1c5238
+                    if id not in id_done:
1c5238
+                        print("       - " + id)
1c5238
+                        id_done.append(id)
1c5238
 
1c5238
     def print_formatted(self, line):
1c5238
         """
1c5238
@@ -237,7 +263,7 @@ class RequestAnalyzer:
1c5238
         logger.info(f"******** Listing {resp} client requests ********")
1c5238
         source.set_component(component, False)
1c5238
         if args.verbose:
1c5238
-            self.print_formatted_verbose(source, patterns)
1c5238
+            self.print_formatted_verbose(source)
1c5238
         else:
1c5238
             for line in self.matched_line(source, patterns):
1c5238
                 if isinstance(source, Journald):
1c5238
@@ -258,8 +284,7 @@ class RequestAnalyzer:
1c5238
         be_results = False
1c5238
         component = source.Component.NSS
1c5238
         resp = "nss"
1c5238
-        pattern = [rf'REQ_TRACE.*\[CID #{cid}\]']
1c5238
-        pattern.append(rf"\[CID#{cid}\]")
1c5238
+        pattern = [rf"\[CID#{cid}\]"]
1c5238
 
1c5238
         if args.pam:
1c5238
             component = source.Component.PAM
1c5238
-- 
1c5238
2.37.3
1c5238