From 6711e56dfbab7fa3a68a070735189c3704b1e099 Mon Sep 17 00:00:00 2001
From: "Bryn M. Reeves" <bmr@redhat.com>
Date: Sat, 21 Jun 2014 13:03:06 +0100
Subject: [PATCH] [sar] Handle compressed sar binary data files better

    commit 6145fe2c40ae284fcd72f7e7e70dfa51e0a8266d
    Author: Peter Portante <portante@redhat.com>
    Date:   Sat Apr 19 14:03:46 2014 +0100

        Handle compressed sar binary data files better

        We now collect all compressed and uncompressed sar?? and sa?? data
        files. Given that tailing the text output is not very useful, we add an
        option to not perform the tail when we have reached the limit.

        NOTES:

          * The 20 MB limit applies to each *set* of files being collected, so
            there there is a 20 MB limit for the total number of sa??* files and
            _separate_ 20 MB limit for sar??* files collected

          * The 20 MB limit *does not apply* to the generated command output, so
            if there is a 200+ MB sa?? data file present, that file won't be
            collected, but the resulting 200+ MB sar?? and sar??.xml files will
            still be collected in full

          * The generated command output for missing sar files is only generated
            from uncompressed binary data files

          * The generated command output for the XML files is also only
            generated from uncompressed binary data files

        Signed-off-by: Peter Portante <peter.portante@redhat.com>
        Signed-off-by: Bryn M. Reeves <bmr@redhat.com>
---
 sos/plugins/sar.py | 50 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/sos/plugins/sar.py b/sos/plugins/sar.py
index bb8361e..c6e0388 100644
--- a/sos/plugins/sar.py
+++ b/sos/plugins/sar.py
@@ -19,25 +19,55 @@ class sar(sos.plugintools.PluginBase):
     """Generate the sar file from /var/log/sa/saXX files
     """
 
+    packages = ('sysstat',)
     sa_path = "/var/log/sa"
+    optionList = [("all_sar", "gather all system activity records", "", False)]
+
+    # size-limit SAR data collected by default (MB)
+    sa_size = 20
 
     def setup(self):
+        if self.getOption("all_sar"):
+            self.sa_size = 0
+
+        # Copy all sa??, sar??, sa??.* and sar??.* files, which will net
+        # compressed and uncompressed versions, typically.
+        for suffix in ('', '.*'):
+            self.addCopySpecLimit(
+                os.path.join(self.sa_path, "sa[0-3][0-9]" + suffix),
+                sizelimit=self.sa_size, tailit=False
+            )
+            self.addCopySpecLimit(
+                os.path.join(self.sa_path, "sar[0-3][0-9]" + suffix),
+                sizelimit=self.sa_size, tailit=False
+            )
+            
         try:
             dirList=os.listdir(self.sa_path)
         except:
-            self.soslog.error("sar: could not list /var/log/sa")
+            self.soslog.error("sar: could not list %s" % self.sa_path)
             return
         # find all the sa file that don't have an existing sar file
         for fname in dirList:
-            if fname[0:2] == 'sa' and fname[2] != 'r':
-                sar_filename = 'sar' + fname[2:4]
-                sa_data_path = os.path.join(self.sa_path, fname)
-                if sar_filename not in dirList:
-                    sar_command = "/usr/bin/sar -A -f /var/log/sa/" + fname
-                    self.collectOutputNow(sar_command, sar_filename, symlink=sar_filename)
-                sadf_cmd = "/usr/bin/sadf -x %s" % sa_data_path
-                self.collectExtOutput(sadf_cmd, "%s.xml" % fname)
-        return
+            if fname.startswith('sar'):
+                continue
+            if not fname.startswith('sa'):
+                continue
+            if len(fname) != 4:
+                # We either have an "sa" or "sa?" file, or more likely, a
+                # compressed data file like, "sa??.xz".
+                #
+                # FIXME: We don't have a detector for the kind of compression
+                # use for this file right now, so skip these kinds of files.
+                continue
+            sa_data_path = os.path.join(self.sa_path, fname)
+            sar_filename = 'sar' + fname[2:]
+            if sar_filename not in dirList:
+                sar_cmd = 'sh -c "sar -A -f %s"' % sa_data_path
+                self.collectExtOutput(sar_cmd, sar_filename)
+            sadf_cmd = "sadf -x %s" % sa_data_path
+            self.collectExtOutput(sadf_cmd, "%s.xml" % fname)
+
 
     def checkenabled(self):
         if os.path.exists("/var/log/sa") and os.path.exists("/usr/bin/sar"):
-- 
1.9.3

