Telemetry baseline: durable analytics outbox, session tracking, UI-framework marker#987
Open
johnml1135 wants to merge 2 commits into
Open
Telemetry baseline: durable analytics outbox, session tracking, UI-framework marker#987johnml1135 wants to merge 2 commits into
johnml1135 wants to merge 2 commits into
Conversation
…on baseline, and forward-compatible UI-framework marker Grounds a prior strategic-review recommendation (accrue a Legacy-UI telemetry baseline ahead of the Avalonia rollout) against actual code on origin/main via grill-with-docs. Adds the openspec change (proposal/design/specs/tasks) plus grounded Analytics/Telemetry terminology and ADR decisions in CONTEXT.md. No production code yet; this is planning artifacts only. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sion baseline, usage enrichment Adds AnalyticsOutbox, a durable local queue in front of DesktopAnalytics Track/ReportException so events survive being generated while offline instead of being silently dropped. Migrates all six existing call sites to the new facade, adds session-start/end tracking with clean-vs-crashed classification, and sets a UiFramework=WinForms application property as forward-compatible scaffolding for a future Avalonia UI split. Found and fixed during implementation: System.IO.File.Move does not reliably report failure to the losing thread when two callers race an identical rename on .NET Framework - both can return without throwing even though the OS performs exactly one physical rename (verified with an isolated repro, ~99% reproducible). The outbox's claim mechanism now follows the rename with a FileShare.None exclusive open as the real single-owner check (design.md D14). Caught by the concurrent-flush unit test, which failed intermittently before this fix. 390 FwUtilsTests pass (15 new AnalyticsOutboxTests), plus zero regressions in LexTextDllTests, FieldWorksTests, and ITextDllTests. tasks.md documents three remaining test gaps (session-baseline and dwell-time unit tests blocked on cross-assembly test-seam access) and two manual verification steps (end-to-end offline queueing, privacy toggle behavior) not yet performed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
commit f92d4d0398: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Establishes a FieldWorks-only telemetry baseline (openspec change:
telemetry-migration-baseline) ahead of the planned Avalonia UI migration, so there's a "legacy WinForms" usage/crash/session baseline to compare against later.AnalyticsOutbox(Src/Common/FwUtils/AnalyticsOutbox.cs): a durable local queue in front ofDesktopAnalytics.Analytics.Track/ReportException. Today, an event generated while offline is silently dropped (DesktopAnalyticsis fire-and-forget with no retry). The outbox persists each event as its own small JSON file, flushes on enqueue/startup/shutdown, and re-checks consent at flush time (not just enqueue time) so revoking consent stops even already-queued data from going out.Analytics.Track/ReportExceptioncall sites are migrated to the new facade (FieldWorks.cs,AreaListener.cs,TrackingHelper.cs,ConcordanceContainer.cs,ConfigureInterlinDialog.cs,ObtainProjectMethod.cs).Analytics.SetApplicationProperty("UiFramework", "WinForms")set once at startup (forward-compatible — a future Avalonia surface sets a different value on the same property), plusduration(dwell time) added to the existing throttledSwitchToToolevent.Bug found and fixed during implementation
While writing the concurrency test for the outbox's file-claim logic, I found that
System.IO.File.Movedoes not reliably report failure to the "losing" thread when two callers race an identical rename on .NET Framework — both can return without throwing, even though the OS performs exactly one physical rename. Verified with an isolated repro outside this codebase (~99% reproducible across hundreds of trials; confirmed via on-disk state that only one physical rename ever occurs, so the underlying filesystem operation is correct — the wrapper's exception surfacing for the loser is not). This invalidated the original "atomic rename = exclusive claim" design. Fixed by following the rename with aFileShare.Noneexclusive open as the real, OS-enforced single-owner check (documented as design.md D14). This was caught byAnalyticsOutboxTests.Flush_ConcurrentFlushCalls_DeliverEachEventExactlyOnce, which failed intermittently (11-20 deliveries instead of 10) before the fix, and now passes deterministically.Test plan
.\build.ps1— full managed build succeeds, no native rebuild triggered..\test.ps1onFwUtilsTests— 390/390 pass, including 15 newAnalyticsOutboxTests(consent gating, FIFO delivery, cap eviction by count/age, claim-race exactly-once delivery, orphan recovery with staleness gating, delivery-failure rollback)..\test.ps1onLexTextDllTests,FieldWorksTests,ITextDllTests— zero regressions from the call-site migration.FieldWorks.cs) orSwitchToTooldwell-time computation (AreaListener.cs) — both are blocked on cross-assembly access toAnalyticsOutbox's test seams (currentlyInternalsVisibleToonly coversFwUtilsTests). Documented as a follow-up intasks.md§3.6/§4.6.UiFrameworkapplication property actually attaches to outgoing events — that's internal to theDesktopAnalytics/Mixpanel client.tasks.md§4.2.%LocalAppData%\SIL\FieldWorks\Analytics\Outbox\, reconnect, relaunch, confirm the directory empties).tasks.md§5.3.OkToPingBasicUsageData) still gates all telemetry, including already-queued-but-unflushed events.tasks.md§5.4.🤖 Generated with Claude Code
This change is