Skip to content

feat(telemetry): flow events foundations#238

Merged
LorrisSaintGenez merged 4 commits into
feat/events-flowfrom
fix/telemetry-client-lifecycle
Jun 11, 2026
Merged

feat(telemetry): flow events foundations#238
LorrisSaintGenez merged 4 commits into
feat/events-flowfrom
fix/telemetry-client-lifecycle

Conversation

@LorrisSaintGenez

@LorrisSaintGenez LorrisSaintGenez commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What

Foundations for the CLI flow events (GROUT-349), one atomic commit per step:

  1. Telemetry client lifecycle fixgo telemetryClient.Close() ran in PersistentPreRunE, closing the client before the command executed and racing with process exit. The client is now closed via defer in Execute(), bounded by a 3s timeout so an unreachable telemetry endpoint never delays exit. createContext falls back to NoOpTelemetryClient instead of storing a nil interface, and analytics-go Verbose logging is enabled in debug mode.
  2. Track with custom properties + sequenceTrack(ctx, event, properties) merges custom properties with the base ones (base written last, so call sites cannot override them). Every event carries a monotonic sequence (atomic counter): the exact order of one invocation can be reconstructed downstream by sorting on (invocation_id, sequence) — Segment stores millisecond-precision timestamps, so back-to-back events can tie.
  3. Event catalog + Command Completedpkg/telemetry/events.go holds the event name constants, the Flow/Step/Direction enums, FlowTracker (current step + flow duration) and ErrorClass (first informative type of the error chain, never the error message). Execute() now emits Command Completed (succeeded, exit_code, duration_ms, plus error_class/user_cancelled on failure) right before the final flush.
  4. Independent review fixes — no orphan Command Completed when PersistentPreRunE never ran (--help, --version, unknown flag/command, failed auth check: no paired Command Invoked, and the command property would be empty); duration_ms is measured right after execution so it never includes the update-notifier wait; tests for trackCommandCompleted and for sequence uniqueness under concurrency.

Test

# network on: verbose telemetry logs show the final batch
# (Identify + Command Invoked + Command Completed)
DEBUG=1 go run ./cmd/algolia application plans

# network off: the command fails on its own network error,
# exit adds at most ~3s for the telemetry flush (no hang)
time DEBUG=1 go run ./cmd/algolia application plans

# no telemetry at all for --help / --version / typos
DEBUG=1 go run ./cmd/algolia --help
DEBUG=1 go run ./cmd/algolia doesnotexist

GROUT-349

- go telemetryClient.Close() ran in PersistentPreRunE, closing the
  client before the command executed and racing with process exit
- close the client in Execute() via defer, bounded by a 3s timeout so
  an unreachable telemetry endpoint never delays exit
- fall back to NoOpTelemetryClient when the analytics client cannot be
  created instead of storing a nil interface in the context
- enable analytics-go verbose logging in debug mode so successful
  flushes are visible with DEBUG=1

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Jun 10, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 19 complexity · 16 duplication

Metric Results
Complexity 19
Duplication 16

View in Codacy

TIP This summary will be updated as you push new changes.

@LorrisSaintGenez LorrisSaintGenez self-assigned this Jun 10, 2026
@LorrisSaintGenez LorrisSaintGenez changed the base branch from feat/events-flow to main June 10, 2026 18:37
@LorrisSaintGenez LorrisSaintGenez changed the base branch from main to feat/events-flow June 10, 2026 18:38
@LorrisSaintGenez LorrisSaintGenez marked this pull request as draft June 10, 2026 18:44
LorrisSaintGenez and others added 2 commits June 10, 2026 12:39
…umber

- Track now takes a properties map, merged with the base properties;
  base properties are written last so call sites cannot override them
- each Track event carries a monotonic sequence number (atomic counter)
  so the exact order of one invocation can be reconstructed downstream:
  Segment stores timestamps with millisecond precision, so back-to-back
  events can tie

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- events.go: typed catalog for the flow events (event name constants,
  Flow/Step/Direction enums), FlowTracker helper (current step and
  flow duration) and ErrorClass (root cause type only, never the
  message, which could contain user data)
- Execute() reports a Command Completed event with succeeded,
  exit_code, duration_ms, and error_class/user_cancelled on failure,
  through a deferred read of the named return value

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@LorrisSaintGenez LorrisSaintGenez changed the title fix(telemetry): flush events after the command instead of before feat(telemetry): flow events foundations Jun 10, 2026
- don't emit an orphan Command Completed when PersistentPreRunE never
  ran (--help, --version, unknown flag/command, failed auth check):
  no Command Invoked was sent, and the command property would be empty
- measure the command duration right after execution, so duration_ms
  never includes the update-notifier wait (which only happens on the
  success path and would bias the metric)
- ErrorClass keeps the first informative type of the error chain
  instead of unwrapping to the root, which collapsed every CLI error
  into *errors.errorString
- tests: trackCommandCompleted (skip/success/failure), sequence
  uniqueness under concurrency, informative wrapper type

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@LorrisSaintGenez LorrisSaintGenez marked this pull request as ready for review June 10, 2026 22:20
@LorrisSaintGenez LorrisSaintGenez merged commit 57aeac1 into feat/events-flow Jun 11, 2026
2 checks passed
@LorrisSaintGenez LorrisSaintGenez deleted the fix/telemetry-client-lifecycle branch June 11, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants