From 262a9ad6c2d7a65bb9b53ec6810862b66ce28fd0 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Mon, 4 May 2020 16:28:10 -0400 Subject: [PATCH] analyze/dump: add support for Amazon Linux 2 log lines Amazon Linux 2 is configured with a log format different to the one shipped by upstream, which means analyze fails to parse any of the log lines. This updates the code to know how to parse such lines. LP: #1876323 --- cloudinit/analyze/dump.py | 14 ++++++++++++-- cloudinit/analyze/tests/test_dump.py | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/cloudinit/analyze/dump.py b/cloudinit/analyze/dump.py index 1f3060d0ccf..f5762854c57 100644 --- a/cloudinit/analyze/dump.py +++ b/cloudinit/analyze/dump.py @@ -74,8 +74,11 @@ def parse_ci_logline(line): # # 2017-05-22 18:02:01,088 - util.py[DEBUG]: Cloud-init v. 0.7.9 running \ # 'init-local' at Mon, 22 May 2017 18:02:01 +0000. Up 2.0 seconds. + # + # Apr 30 19:39:11 cloud-init[2673]: handlers.py[DEBUG]: start: \ + # init-local/check-cache: attempting to read from cache [check] - separators = [' - ', ' [CLOUDINIT] '] + separators = [' - ', ' [CLOUDINIT] ', ' cloud-init['] found = False for sep in separators: if sep in line: @@ -98,7 +101,14 @@ def parse_ci_logline(line): hostname = extra.split()[-1] else: hostname = timehost.split()[-1] - timestampstr = timehost.split(hostname)[0].strip() + if sep == ' cloud-init[': + # This is an Amazon Linux style line, with no hostname and a PID. + # Use the whole of timehost as timestampstr, and strip off the PID + # from the start of eventstr. + timestampstr = timehost.strip() + eventstr = eventstr.split(maxsplit=1)[1] + else: + timestampstr = timehost.split(hostname)[0].strip() if 'Cloud-init v.' in eventstr: event_type = 'start' if 'running' in eventstr: diff --git a/cloudinit/analyze/tests/test_dump.py b/cloudinit/analyze/tests/test_dump.py index db2a667bf91..d6fbd381241 100644 --- a/cloudinit/analyze/tests/test_dump.py +++ b/cloudinit/analyze/tests/test_dump.py @@ -119,6 +119,23 @@ def test_parse_logline_returns_event_for_finish_events(self, m_parse_from_date.assert_has_calls( [mock.call("2016-08-30 21:53:25.972325+00:00")]) + def test_parse_logline_returns_event_for_amazon_linux_2_line(self): + line = ( + "Apr 30 19:39:11 cloud-init[2673]: handlers.py[DEBUG]: start:" + " init-local/check-cache: attempting to read from cache [check]") + # Generate the expected value using `datetime`, so that TZ + # determination is consistent with the code under test. + timestamp_dt = datetime.strptime( + "Apr 30 19:39:11", "%b %d %H:%M:%S" + ).replace(year=datetime.now().year) + expected = { + 'description': 'attempting to read from cache [check]', + 'event_type': 'start', + 'name': 'init-local/check-cache', + 'origin': 'cloudinit', + 'timestamp': timestamp_dt.timestamp()} + self.assertEqual(expected, parse_ci_logline(line)) + SAMPLE_LOGS = dedent("""\ Nov 03 06:51:06.074410 x2 cloud-init[106]: [CLOUDINIT] util.py[DEBUG]:\