Skip to content

Emit Kubernetes events for FA experiment transitions#3037

Merged
levan-m merged 11 commits into
mainfrom
levan-m/experiment-events
May 27, 2026
Merged

Emit Kubernetes events for FA experiment transitions#3037
levan-m merged 11 commits into
mainfrom
levan-m/experiment-events

Conversation

@levan-m

@levan-m levan-m commented May 22, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Produce k8s events on experiment signals and transition. Option enabled by

        - name: DD_FLEET_MANAGEMENT_EVENTS_ENABLED
          value: "true"

and collected in DD by adding

spec:
  features:
    eventCollection:
      collectKubernetesEvents: true
      unbundleEvents: true
      collectedEventTypes:
        - kind: DatadogAgent
          reasons:
            - ExperimentStartProcessed
            - ExperimentPromoted
            - ExperimentAborted
            - ExperimentTimedOut
            - ExperimentRolledBack
            - RemoteTaskReceived
            - RemoteTaskRejected
            - RemoteTaskCompleted
            - LocalTerminationPublishedToRC
            - InstallerStateRehydrated
experiment transitions in reconciler

    - ExperimentStartProcessed         Normal   (nil → Running)
    - ExperimentPromoted                Normal   (Running → Promoted)
    - ExperimentAborted                 Warning  (Running → Aborted)
    - ExperimentTimedOut                Warning  (Running → Terminated/timed_out)
    - ExperimentRolledBack              Normal   (Running → Terminated/stopped)

fleet daemon incoming/outgoing signals

    - RemoteTaskReceived               Normal   (handleTask entry)
    - RemoteTaskRejected               Warning  (after setTaskState INVALID_STATE/ERROR)
    - RemoteTaskCompleted              Normal   (after setTaskState DONE in finishPendingOperation)
    - LocalTerminationPublishedToRC    Normal   (timeout or abort published to RC)
    - InstallerStateRehydrated         Normal   (state seeded from DDA on daemon startup)

Motivation

What inspired you to submit this pull request?

Additional Notes

Anything else we should know when reviewing?

Minimum Agent Versions

Are there minimum versions of the Datadog Agent and/or Cluster Agent required?

  • Agent: vX.Y.Z
  • Cluster Agent: vX.Y.Z

Describe your test plan

Enabled events, run experiment and describe DDA to see events

Events:
  Type    Reason                    Age    From          Message
  ----    ------                    ----   ----          -------
  Normal  RemoteTaskReceived        5m56s  fleet-daemon  Received start task "c03e6686-0b61-41c5-9f2c-ce7fc91a42ce" for experiment "p2wg-tvmn-g14r"
  Normal  RemoteTaskCompleted       5m56s  fleet-daemon  Task "c03e6686-0b61-41c5-9f2c-ce7fc91a42ce" (start) reported to Fleet Automation as DONE
  Normal  ExperimentStartProcessed  5m56s  DatadogAgent  Experiment "p2wg-tvmn-g14r" started (task "c03e6686-0b61-41c5-9f2c-ce7fc91a42ce")
  Normal  RemoteTaskReceived        5m25s  fleet-daemon  Received promote task "5b5ba1f1-df31-4aa2-849b-d17f845f6ec9" for experiment ""
  Normal  ExperimentPromoted        5m25s  DatadogAgent  Experiment "p2wg-tvmn-g14r" promoted
  Normal  RemoteTaskCompleted       5m25s  fleet-daemon  Task "5b5ba1f1-df31-4aa2-849b-d17f845f6ec9" (promote) reported to Fleet Automation as DONE
  Normal  RemoteTaskReceived        68s    fleet-daemon  Received start task "c3985b4a-7f1d-4bae-b1ab-058ff978e795" for experiment "djsg-awhw-oxg7"
  Normal  RemoteTaskCompleted       68s    fleet-daemon  Task "c3985b4a-7f1d-4bae-b1ab-058ff978e795" (start) reported to Fleet Automation as DONE
  Normal  RemoteTaskReceived        47s    fleet-daemon  Received promote task "9de4334d-b049-4955-aca6-956454c236f6" for experiment ""
  Normal  ExperimentPromoted        47s    DatadogAgent  Experiment "djsg-awhw-oxg7" promoted
  Normal  RemoteTaskCompleted       47s    fleet-daemon  Task "9de4334d-b049-4955-aca6-956454c236f6" (promote) reported to Fleet Automation as DONE

Checklist

  • PR has at least one valid label: bug, enhancement, refactoring, documentation, tooling, and/or dependencies
  • PR has a milestone or the qa/skip-qa label
  • All commits are signed (see: signing commits)

@levan-m levan-m added this to the v1.27.0 milestone May 22, 2026
@levan-m levan-m added the enhancement New feature or request label May 22, 2026
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented May 22, 2026

Copy link
Copy Markdown

Code Coverage

🎯 Code Coverage (details)
Patch Coverage: 82.95%
Overall Coverage: 42.92% (+0.15%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 785b9bb | Docs | Datadog PR Page | Give us feedback!

@levan-m
levan-m force-pushed the levan-m/experiment-events branch from 1518df1 to 9c50323 Compare May 22, 2026 01:54
@codecov-commenter

codecov-commenter commented May 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.00000% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.59%. Comparing base (c85321f) to head (785b9bb).

Files with missing lines Patch % Lines
pkg/fleet/events.go 82.22% 7 Missing and 1 partial ⚠️
pkg/fleet/daemon_worker.go 64.70% 6 Missing ⚠️
pkg/fleet/daemon.go 88.88% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3037      +/-   ##
==========================================
+ Coverage   42.43%   42.59%   +0.15%     
==========================================
  Files         337      339       +2     
  Lines       29020    29120     +100     
==========================================
+ Hits        12315    12404      +89     
- Misses      15895    15906      +11     
  Partials      810      810              
Flag Coverage Δ
unittests 42.59% <85.00%> (+0.15%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...controller/datadogagent/controller_reconcile_v2.go 52.52% <100.00%> (+0.48%) ⬆️
...ernal/controller/datadogagent/experiment_events.go 100.00% <100.00%> (ø)
pkg/fleet/daemon.go 72.11% <88.88%> (+2.76%) ⬆️
pkg/fleet/daemon_worker.go 76.92% <64.70%> (-1.26%) ⬇️
pkg/fleet/events.go 82.22% <82.22%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c85321f...785b9bb. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@levan-m
levan-m marked this pull request as ready for review May 22, 2026 14:24
@levan-m
levan-m requested review from a team as code owners May 22, 2026 14:24
@levan-m levan-m changed the title feat(experiment): emit Kubernetes events for state transitions and Fl… Emit Kubernetes events for FA experiment transitions May 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3b8301f66

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

return
}
switch {
case oldPhase == "" && newStatus.Phase == v2alpha1.ExperimentPhaseRunning:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Emit start event for restarted experiments

emitExperimentTransitionEvent only emits ExperimentStartProcessed for oldPhase == "", but processStartSignal can legitimately start a new experiment from non-running terminal phases (for example Promoted or Terminated). In those common follow-up runs, status still transitions to Running but no start event is produced, so users miss controller-side start signals for every experiment after the first one.

Useful? React with 👍 / 👎.

Comment thread pkg/fleet/daemon.go Outdated
Comment on lines +308 to +310
d.emitInstallerStateRehydratedEvent(ctx,
types.NamespacedName{Namespace: dda.Namespace, Name: dda.Name},
exp.ID, exp.Phase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid cache lookup for startup rehydration event

This startup path reads DatadogAgents with apiReader specifically because cache data may not be populated yet, but the new emitInstallerStateRehydratedEvent call resolves the same DDA again through emitDDAEventf (d.client.Get) and silently drops the event on cache miss. Because rehydration is one-time during daemon start, InstallerStateRehydrated can be permanently lost on cold starts even when rehydration succeeds.

Useful? React with 👍 / 👎.

if oldStatus != nil {
oldPhase = oldStatus.Phase
}
if newStatus == nil || newStatus.Phase == oldPhase {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: in which scenario would the newStatus be nil?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

experimentStatus set only if experiment has run so all existing DDAs and fresh clusters will start with nil.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

..however in practice, if oldStatus isn't nil on line 56, new status can't be nil based, we don't clean up experiment status after it's promoted. But I'd still keep this to be more defensive.

@adel121 adel121 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Left minor questions

Base automatically changed from levan-m/experiment-fixes to main May 27, 2026 14:22
@levan-m
levan-m requested a review from a team as a code owner May 27, 2026 14:22
@levan-m
levan-m merged commit 1e1aeff into main May 27, 2026
38 checks passed
@levan-m
levan-m deleted the levan-m/experiment-events branch May 27, 2026 18:46
levan-m added a commit that referenced this pull request May 27, 2026
* fix(experiment): anchor timeout on Status.Experiment.StartedAt

* fix(fleet): rehydrate installer state from DatadogAgent on daemon startup

* fix(experiment): report TaskState_ERROR for the original start task on timeout

* refactor(experiment): single experiment-state annotation on revisions

* fix(fleet): publish abort to Fleet Automation the same way as timeout

* feat(experiment): emit Kubernetes events for state transitions and Fleet tasks

* fix linter

* fix(experiment): cover all phase transitions and emit completed event for idempotent tasks

* fix(fleet): bypass cache when emitting rehydrate event

* fix linter

(cherry picked from commit 1e1aeff)

Co-authored-by: levan-m <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants