cloud-init icon indicating copy to clipboard operation
cloud-init copied to clipboard

feat(reporting): report duration on finish events

Open peytonr18 opened this issue 2 months ago • 6 comments

Proposed Commit Message

feat(reporting): report duration on finish events

- Ensure `ReportEventStack` computes elapsed time and passes it through `FinishReportingEvent` so all reporting handlers can emit durations.
- Capture the `duration` field in Hyper-V KVP metadata and adjust unit tests to assert the value is present.
- Note: any external callers constructing `FinishReportingEvent` will need to provide a duration argument.

Additional Context

  • ReportEventStack now records a start timestamp and calculates duration on exit, feeding it into report_finish_event.
  • FinishReportingEvent exposes the duration in as_dict and string representations, allowing downstream consumers to quantify elapsed time without recomputing.
  • HyperVKvpReportingHandler includes the duration field when serializing finish events, ensuring Azure KVP telemetry captures timing data.
  • Unit tests in tests/unittests/reporting/test_reporting.py and tests/unittests/reporting/test_reporting_hyperv.py were updated to pass explicit durations and verify the new field, including the multi-slice Hyper-V KVP scenario.
  • Production test shows duration in .kvp_pool_1 entries for finish events:
CLOUD_INIT|1762464987|finish|modules-config/config-apt_configure|d0058170-3c82-412a-8437-e2f43a7c4258{"name":"modules-config/config-apt_configure","type":"finish","ts":"2025-11-06T21:36:51.542257+00:00","result":"SUCCESS","msg":"config-apt_configure ran successfully and took 0.089 seconds","duration":0.08879551900000138}

Merge type

  • [x] Squash merge using "Proposed Commit Message"

peytonr18 avatar Oct 30 '25 16:10 peytonr18

The description text got mixed up with the other PR.

cjp256 avatar Nov 11 '25 14:11 cjp256

It looks like this is waiting for updates per the latest review (and CLA signature), so I'll hold off on reviewing it for now.

holmanb avatar Nov 20 '25 19:11 holmanb

@holmanb @cjp256 I had added the duration to start events after an offline discussion, but have no preference on whether or not start events have one. Can adopt whatever approach you all think is best!

peytonr18 avatar Dec 08 '25 20:12 peytonr18

I think having duration in both start and finish events will allow us to not having to treat start/finish event differently, similar to how the result field exists for both start and finish events, even though you can't know the result of an operation at the start event

anhvoms avatar Dec 08 '25 20:12 anhvoms

I think having duration in both start and finish events will allow us to not having to treat start/finish event differently, similar to how the result field exists for both start and finish events, even though you can't know the result of an operation at the start event

Start event doesn't have a result. Example:

 {
  "description": "running config-install_hotplug with frequency once-per-instance",
  "event_type": "start",
  "name": "modules-final/config-install_hotplug",
  "origin": "cloudinit",
  "timestamp": 1765216665.916
 },
 {
  "description": "config-install_hotplug ran successfully and took 0.001 seconds",
  "event_type": "finish",
  "name": "modules-final/config-install_hotplug",
  "origin": "cloudinit",
  "result": "SUCCESS",
  "timestamp": 1765216665.917
 },

Result is only defined for finished event:

https://github.com/canonical/cloud-init/blob/4537f0bb5c028b8005f451f82a60aacb74ddeea8/cloudinit/reporting/events.py#L86

cjp256 avatar Dec 08 '25 22:12 cjp256

I think having duration in both start and finish events will allow us to not having to treat start/finish event differently, similar to how the result field exists for both start and finish events, even though you can't know the result of an operation at the start event

Start event doesn't have a result. Example:

 {
  "description": "running config-install_hotplug with frequency once-per-instance",
  "event_type": "start",
  "name": "modules-final/config-install_hotplug",
  "origin": "cloudinit",
  "timestamp": 1765216665.916
 },
 {
  "description": "config-install_hotplug ran successfully and took 0.001 seconds",
  "event_type": "finish",
  "name": "modules-final/config-install_hotplug",
  "origin": "cloudinit",
  "result": "SUCCESS",
  "timestamp": 1765216665.917
 },

Result is only defined for finished event:

https://github.com/canonical/cloud-init/blob/4537f0bb5c028b8005f451f82a60aacb74ddeea8/cloudinit/reporting/events.py#L86

My bad. Somehow I've been hallucinated into thinking that we had result for both start and finish. If this is the case, it makes sense to only have duration in the finish event. Thanks Chris for the fact-checking!

anhvoms avatar Dec 08 '25 22:12 anhvoms