Repository: RedHatInsights/insights-core

Issue:
Systemd_analyze parser is raising lots of exceptions in production
The SystemdAnalyzeBlame parser is throwing a large number of the exception ValueError('too many values to unpack (expected 2)',) in production.


Discussion:

Resolving patch:
diff --git a/insights/parsers/systemd_analyze.py b/insights/parsers/systemd_analyze.py
--- a/insights/parsers/systemd_analyze.py
+++ b/insights/parsers/systemd_analyze.py
@@ -55,10 +55,34 @@ def parse_content(self, content):
             raise SkipException
 
         for c in content:
-            time, service = c.split()
-            if time.endswith('ms'):
-                _time = round(float(time.strip('ms')) / 1000, 5)
-            else:
-                _time = round(float(time.strip('ms')), 5)
+            cols = c.split()
+            # Check to make sure that the first character of the first
+            # entry is a number. This will hopefully exclude any errors
+            # that are outputted in the file.
+            if cols[0][0].isdigit():
+                # The service should be the last column, so just
+                # remove the last column from the list before looping.
+                service = cols.pop()
+                time = 0
+                for x in cols:
+                    # Convert each column to seconds, and add them up.
+                    if x.endswith('y'):
+                        # Pulled the 31557600 from systemd src.
+                        time += int(x.strip('y')) * 31557600
+                    elif x.endswith('month'):
+                        # Pulled the 2629800 from systemd src.
+                        time += int(x.strip('month')) * 2629800
+                    elif x.endswith('w'):
+                        time += int(x.strip('w')) * 7 * 24 * 60 ** 2
+                    elif x.endswith('d'):
+                        time += int(x.strip('d')) * 24 * 60 ** 2
+                    elif x.endswith('h'):
+                        time += int(x.strip('h')) * 60 ** 2
+                    elif x.endswith('min'):
+                        time += int(x.strip('min')) * 60
+                    elif x.endswith('ms'):
+                        time += float(x.strip('ms')) / 1000
+                    elif x.endswith('s'):
+                        time += float(x.strip('s'))
 
-            self[service] = _time
+                self[service] = time


Test patch:
diff --git a/insights/parsers/tests/test_systemd_analyze.py b/insights/parsers/tests/test_systemd_analyze.py
--- a/insights/parsers/tests/test_systemd_analyze.py
+++ b/insights/parsers/tests/test_systemd_analyze.py
@@ -7,6 +7,12 @@
 
 
 OUTPUT = """
+1y 1month 2w 6d 1h 33min 53.782s dev-sdy.device
+2month 3w 4d 7h 10min 17.082s dev-sdm.device
+1w 5d 2h 8min 12.802s dev-sdw.device
+3d 8h 57min 30.859s dev-sdd.device
+2h 56min 26.721s dev-mapper-vg_root\x2dlv_root.device
+5min 230ms splunk.service
 33.080s cloud-init-local.service
 32.423s unbound-anchor.service
  2.773s kdump.service
@@ -24,7 +30,11 @@ def test_output():
     assert ('cloud-init-local.service' in output) is True
 
     # Test time(seconds)
+    assert output.get('tuned.service', 0) == 0.872
     assert output.get('cloud-init.service', 0) == 1.304
+    assert output.get('splunk.service', 0) == 300.23
+    assert output.get('dev-sdd.device', 0) == 291450.859
+    assert output.get('dev-sdy.device', 0) == 35921033.782
 
     with pytest.raises(SkipException):
         assert systemd_analyze.SystemdAnalyzeBlame(context_wrap("")) is None