Blame SOURCES/0009-Analyzer-support-parallel-requests-parsing.patch

e461c1
From d22ea2df62b6e245eef75d7201b678601bf63e98 Mon Sep 17 00:00:00 2001
e461c1
From: Justin Stephenson <jstephen@redhat.com>
e461c1
Date: Fri, 19 Aug 2022 14:44:11 -0400
e461c1
Subject: [PATCH 9/9] Analyzer: support parallel requests parsing
e461c1
MIME-Version: 1.0
e461c1
Content-Type: text/plain; charset=UTF-8
e461c1
Content-Transfer-Encoding: 8bit
e461c1
e461c1
Analyzer code(primarily the list verbose command) needs
e461c1
changes to handle parsing the necessary lines from
e461c1
NSS/PAM log files when multiple intermixed/parallel
e461c1
client requests are sent to SSSD.
e461c1
e461c1
Resolves: https://github.com/SSSD/sssd/issues/6307
e461c1
e461c1
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
e461c1
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
e461c1
e461c1
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
e461c1
---
e461c1
 src/tools/analyzer/modules/request.py | 119 +++++++++++++++-----------
e461c1
 1 file changed, 67 insertions(+), 52 deletions(-)
e461c1
e461c1
diff --git a/src/tools/analyzer/modules/request.py b/src/tools/analyzer/modules/request.py
e461c1
index 935e13adc..b9fe3caf8 100644
e461c1
--- a/src/tools/analyzer/modules/request.py
e461c1
+++ b/src/tools/analyzer/modules/request.py
e461c1
@@ -16,7 +16,6 @@ class RequestAnalyzer:
e461c1
     """
e461c1
     module_parser = None
e461c1
     consumed_logs = []
e461c1
-    done = ""
e461c1
     list_opts = [
e461c1
         Option('--verbose', 'Verbose output', bool, '-v'),
e461c1
         Option('--pam', 'Filter only PAM requests', bool),
e461c1
@@ -149,58 +148,74 @@ class RequestAnalyzer:
e461c1
                 print(line)
e461c1
         return found_results
e461c1
 
e461c1
-    def print_formatted(self, line, verbose):
e461c1
+    def print_formatted_verbose(self, source, patterns):
e461c1
+        """
e461c1
+        Parse line and print formatted verbose list_requests output
e461c1
+
e461c1
+        Args:
e461c1
+            source (Reader): source Reader object
e461c1
+            patterns (list): List of regex patterns to use for
e461c1
+                matching lines
e461c1
+        """
e461c1
+        # Get CID number, and print the basic line first
e461c1
+        for line in self.matched_line(source, patterns):
e461c1
+            cid = self.print_formatted(line)
e461c1
+
e461c1
+            # Loop through each line with this CID number to extract and
e461c1
+            # print the verbose data needed
e461c1
+            verbose_patterns = ["(cache_req_send|cache_req_process_input|"
e461c1
+                                "cache_req_search_send)"]
e461c1
+            for cidline in self.matched_line(source, verbose_patterns):
e461c1
+                plugin = ""
e461c1
+                name = ""
e461c1
+                id = ""
e461c1
+
e461c1
+                # skip any lines not pertaining to this CID
e461c1
+                if f"CID#{cid}]" not in cidline:
e461c1
+                    continue
e461c1
+                if "refreshed" in cidline:
e461c1
+                    continue
e461c1
+                # CR Plugin name
e461c1
+                if re.search("cache_req_send", cidline):
e461c1
+                    plugin = cidline.split('\'')[1]
e461c1
+                # CR Input name
e461c1
+                elif re.search("cache_req_process_input", cidline):
e461c1
+                    name = cidline.rsplit('[')[-1]
e461c1
+                # CR Input id
e461c1
+                elif re.search("cache_req_search_send", cidline):
e461c1
+                    id = cidline.rsplit()[-1]
e461c1
+
e461c1
+                if plugin:
e461c1
+                    print("   - " + plugin)
e461c1
+                if name:
e461c1
+                    print("       - " + name[:-2])
e461c1
+                if (id and ("UID" in cidline or "GID" in cidline)):
e461c1
+                    print("       - " + id)
e461c1
+
e461c1
+    def print_formatted(self, line):
e461c1
         """
e461c1
         Parse line and print formatted list_requests output
e461c1
 
e461c1
         Args:
e461c1
             line (str): line to parse
e461c1
-            verbose (bool): If true, enable verbose output
e461c1
+        Returns:
e461c1
+            Client ID from printed line, 0 otherwise
e461c1
         """
e461c1
-        plugin = ""
e461c1
-        name = ""
e461c1
-        id = ""
e461c1
-
e461c1
         # exclude backtrace logs
e461c1
         if line.startswith('   *  '):
e461c1
-            return
e461c1
-        fields = line.split("[")
e461c1
-        cr_field = fields[3][7:]
e461c1
-        cr = cr_field.split(":")[0][4:]
e461c1
+            return 0
e461c1
         if "refreshed" in line:
e461c1
-            return
e461c1
-        # CR Plugin name
e461c1
-        if re.search("cache_req_send", line):
e461c1
-            plugin = line.split('\'')[1]
e461c1
-        # CR Input name
e461c1
-        elif re.search("cache_req_process_input", line):
e461c1
-            name = line.rsplit('[')[-1]
e461c1
-        # CR Input id
e461c1
-        elif re.search("cache_req_search_send", line):
e461c1
-            id = line.rsplit()[-1]
e461c1
-        # CID and client process name
e461c1
-        else:
e461c1
-            ts = line.split(")")[0]
e461c1
-            ts = ts[1:]
e461c1
-            fields = line.split("[")
e461c1
-            cid = fields[3][4:-9]
e461c1
-            cmd = fields[4][4:-1]
e461c1
-            uid = fields[5][4:-1]
e461c1
-            if not uid.isnumeric():
e461c1
-                uid = fields[6][4:-1]
e461c1
-            print(f'{ts}: [uid {uid}] CID #{cid}: {cmd}')
e461c1
-
e461c1
-        if verbose:
e461c1
-            if plugin:
e461c1
-                print("   - " + plugin)
e461c1
-            if name:
e461c1
-                if cr not in self.done:
e461c1
-                    print("       - " + name[:-2])
e461c1
-                    self.done = cr
e461c1
-            if id:
e461c1
-                if cr not in self.done:
e461c1
-                    print("       - " + id)
e461c1
-                    self.done = cr
e461c1
+            return 0
e461c1
+        ts = line.split(")")[0]
e461c1
+        ts = ts[1:]
e461c1
+        fields = line.split("[")
e461c1
+        cid = fields[3][4:-9]
e461c1
+        cmd = fields[4][4:-1]
e461c1
+        uid = fields[5][4:-1]
e461c1
+        if not uid.isnumeric():
e461c1
+            uid = fields[6][4:-1]
e461c1
+        print(f'{ts}: [uid {uid}] CID #{cid}: {cmd}')
e461c1
+        return cid
e461c1
 
e461c1
     def list_requests(self, args):
e461c1
         """
e461c1
@@ -215,20 +230,20 @@ class RequestAnalyzer:
e461c1
         # Log messages matching the following regex patterns contain
e461c1
         # the useful info we need to produce list output
e461c1
         patterns = [r'\[cmd']
e461c1
-        patterns.append("(cache_req_send|cache_req_process_input|"
e461c1
-                        "cache_req_search_send)")
e461c1
         if args.pam:
e461c1
             component = source.Component.PAM
e461c1
             resp = "pam"
e461c1
 
e461c1
         logger.info(f"******** Listing {resp} client requests ********")
e461c1
         source.set_component(component, False)
e461c1
-        self.done = ""
e461c1
-        for line in self.matched_line(source, patterns):
e461c1
-            if isinstance(source, Journald):
e461c1
-                print(line)
e461c1
-            else:
e461c1
-                self.print_formatted(line, args.verbose)
e461c1
+        if args.verbose:
e461c1
+            self.print_formatted_verbose(source, patterns)
e461c1
+        else:
e461c1
+            for line in self.matched_line(source, patterns):
e461c1
+                if isinstance(source, Journald):
e461c1
+                    print(line)
e461c1
+                else:
e461c1
+                    self.print_formatted(line)
e461c1
 
e461c1
     def track_request(self, args):
e461c1
         """
e461c1
-- 
e461c1
2.37.1
e461c1