Merge ~vtqanh/cloud-init:UpdateReporterForAnalyze into cloud-init:master

Proposed by Anh Vo (MSFT)
Status: Work in progress
Proposed branch: ~vtqanh/cloud-init:UpdateReporterForAnalyze
Merge into: cloud-init:master
Diff against target: 120 lines (+32/-14)
4 files modified
cloudinit/analyze/show.py (+24/-11)
cloudinit/cmd/main.py (+1/-1)
cloudinit/reporting/events.py (+6/-1)
cloudinit/sources/helpers/azure.py (+1/-1)
Reviewer Review Type Date Requested Status
Dan Watkins Needs Fixing
Server Team CI bot continuous-integration Approve
Review via email: mp+370156@code.launchpad.net

Commit message

analyze: fix poor formatting due to additional datasource events

DataSourceAzure is emitting additional events into the cloud-init
log which causes analyze module to produce somewhat confusing output.
This is due to two issues: 1) DataSourceAzure does not emit the
stage (e.g., init-local) and analyze expects to see it in the event
output. 2) analyze did not correctly process nested stages.
This change saves the stage name into the reporting module so that
other reporter can use it to know which stage it is in and fixes the
analyze module to process multiple levels of nested events.

LP: #1833731

To post a comment you must log in.
e48f66c... by Azure CloudInit Build

remove unnecessary change

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:e48f66cd2128b1c15472e9634345418ae4fd8364
https://jenkins.ubuntu.com/server/job/cloud-init-ci/780/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/780/rebuild

review: Approve (continuous-integration)
Revision history for this message
Dan Watkins (oddbloke) wrote :

I have some concerns about using a global for the stage here; it opens us up to easily breaking reporting on Azure. I _think_ it would be better if we could find a way to get the top-level reporter through to the Azure classes so they can use parent=... instead, though I haven't dealt with the reporting code before so my intuition may be off-base here.

Other than that, we'll also need some tests around the stage changes, so that we don't regress this in future.

review: Needs Fixing
Revision history for this message
Ryan Harper (raharper) wrote :

Could you update the Author of the commits to the person instead of the azure-ci lp account?

Unmerged commits

e48f66c... by Azure CloudInit Build

remove unnecessary change

2e775f0... by Ryan Harper

Update analyze to handle nested events within a config module

c4ab7e9... by Azure CloudInit Build

adding global_stage to the right class

21a801d... by Azure CloudInit Build

first attempt at properly stacking azure events within analyze

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/analyze/show.py b/cloudinit/analyze/show.py
2index 3e778b8..b15cd2c 100644
3--- a/cloudinit/analyze/show.py
4+++ b/cloudinit/analyze/show.py
5@@ -94,6 +94,10 @@ def event_parent(event):
6 return None
7
8
9+def event_is_stage(event):
10+ return '/' not in event_name(event)
11+
12+
13 def event_timestamp(event):
14 return float(event.get('timestamp'))
15
16@@ -146,7 +150,9 @@ def generate_records(events, blame_sort=False,
17 next_evt = None
18
19 if event_type(event) == 'start':
20- if event.get('name') in stages_seen:
21+ stage_name = event_parent(event)
22+ if stage_name == event_name(event) and stage_name in stages_seen:
23+ # new boot record
24 records.append(total_time_record(total_time))
25 boot_records.append(records)
26 records = []
27@@ -166,19 +172,26 @@ def generate_records(events, blame_sort=False,
28 event,
29 next_evt)))
30 else:
31- # This is a parent event
32- records.append("Starting stage: %s" % event.get('name'))
33- unprocessed.append(event)
34- stages_seen.append(event.get('name'))
35- continue
36+ if event_is_stage(event):
37+ records.append("Starting stage: %s" % event.get('name'))
38+ unprocessed.append(event)
39+ stages_seen.append(event.get('name'))
40+ else:
41+ # Start of a substage event
42+ records.append(format_record(print_format,
43+ event_record(start_time,
44+ event,
45+ next_evt)))
46+
47 else:
48 prev_evt = unprocessed.pop()
49 if event_name(event) == event_name(prev_evt):
50- record = event_record(start_time, prev_evt, event)
51- records.append(format_record("Finished stage: "
52- "(%n) %d seconds ",
53- record) + "\n")
54- total_time += record.get('delta')
55+ if event_is_stage(event):
56+ record = event_record(start_time, prev_evt, event)
57+ records.append(format_record("Finished stage: "
58+ "(%n) %d seconds ",
59+ record) + "\n")
60+ total_time += record.get('delta')
61 else:
62 # not a match, put it back
63 unprocessed.append(prev_evt)
64diff --git a/cloudinit/cmd/main.py b/cloudinit/cmd/main.py
65index a5446da..bcac69e 100644
66--- a/cloudinit/cmd/main.py
67+++ b/cloudinit/cmd/main.py
68@@ -885,7 +885,7 @@ def main(sysv_args=None):
69 report_on = False
70
71 args.reporter = events.ReportEventStack(
72- rname, rdesc, reporting_enabled=report_on)
73+ rname, rdesc, reporting_enabled=report_on, global_stage=rname)
74
75 with args.reporter:
76 retval = util.log_time(
77diff --git a/cloudinit/reporting/events.py b/cloudinit/reporting/events.py
78index e5dfab3..a750ba3 100644
79--- a/cloudinit/reporting/events.py
80+++ b/cloudinit/reporting/events.py
81@@ -28,6 +28,7 @@ class _nameset(set):
82
83
84 status = _nameset(("SUCCESS", "WARN", "FAIL"))
85+reporting_stage = None
86
87
88 class ReportingEvent(object):
89@@ -153,7 +154,7 @@ class ReportEventStack(object):
90 """
91 def __init__(self, name, description, message=None, parent=None,
92 reporting_enabled=None, result_on_exception=status.FAIL,
93- post_files=None):
94+ post_files=None, global_stage=None):
95 self.parent = parent
96 self.name = name
97 self.description = description
98@@ -178,6 +179,10 @@ class ReportEventStack(object):
99 self.fullname = self.name
100 self.children = {}
101
102+ global reporting_stage
103+ if global_stage is not None:
104+ reporting_stage = global_stage
105+
106 def __repr__(self):
107 return ("ReportEventStack(%s, %s, reporting_enabled=%s)" %
108 (self.name, self.description, self.reporting_enabled))
109diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
110index 82c4c8c..b862d58 100755
111--- a/cloudinit/sources/helpers/azure.py
112+++ b/cloudinit/sources/helpers/azure.py
113@@ -25,7 +25,7 @@ LOG = logging.getLogger(__name__)
114 DEFAULT_WIRESERVER_ENDPOINT = "a8:3f:81:10"
115
116 azure_ds_reporter = events.ReportEventStack(
117- name="azure-ds",
118+ name="%s/azure-ds" % events.reporting_stage,
119 description="initialize reporter for azure ds",
120 reporting_enabled=True)
121

Subscribers

People subscribed via source and target branches