Skip to content

fix: close structural telemetry gaps (issue #255)#259

Merged
clrudolphi merged 3 commits into
masterfrom
feature/255-telemetry-structural-gaps
Jul 21, 2026
Merged

fix: close structural telemetry gaps (issue #255)#259
clrudolphi merged 3 commits into
masterfrom
feature/255-telemetry-structural-gaps

Conversation

@clrudolphi

@clrudolphi clrudolphi commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Part of #255

Summary

  • Rider had no consumer for telemetry/event at all, so every already-implemented event (discovery, go-to-step, rename, comment-toggle, find-unused-steps, go-to-hook) produced zero telemetry data for Rider users. Adds ReqnrollTelemetryEventInterceptor + RiderTelemetryTransmitter, giving Rider parity with VS's TelemetryEventInterceptor and VS Code's telemetry.ts by forwarding to the same Application Insights resource. The telemetryEvent hook point was confirmed against JetBrains' public mirror at the exact pinned platform version (Rider 2024.3.5 / branch 243), not guessed.
  • The LSP server was wired with NullTelemetryService for ITelemetryService, so MonitorError calls from LSP.Core parsing (DeveroomGherkinParser/DeveroomTagParser) were silently dropped in production. Adds LspErrorTelemetryService, which forwards MonitorError to ILspTelemetryService as an Error event (redacting filesystem paths from the message per the architecture doc's privacy requirement) while keeping every other host-UI-only member a no-op.

Update: also folds in an Interface Segregation refactor of ITelemetryService, prompted by review discussion on this PR. Only 1 of its ~16 members (MonitorError) was ever genuinely shared between LSP.Core and the VS host — every other member is a VS-lifecycle concern (project wizards, welcome/upgrade dialogs) that forced every LSP-side implementation to stub out ~15 unrelated no-ops. This commit:

  • Adds IErrorTelemetryService (MonitorError only); ITelemetryService now extends it. DeveroomGherkinParser, DeveroomTagParser, and CompletionContextResolver depend on the narrow interface directly. IIdeScope.TelemetryService stays typed as the full ITelemetryService (VS's wizard flows genuinely need it) — both interfaces resolve to the same DI singleton on the LSP server.
  • Fixes a second, previously-unnoticed silent-drop bug this surfaced: LspIdeScope.TelemetryService was hardcoded to NullTelemetryService instead of the DI-registered service, so errors reported through that path (e.g. WatchedFilesHandler's config-load exceptions) were still being dropped even after the MonitorError fix above.
  • Closes 4 legacy-compatibility gaps found while auditing the interface: wires up MonitorOpenFeatureFile (implementation was real, never called — hooked into VsProjectEventMonitor's document-activation phase machine) and MonitorExtensionDaysOfUsage (WelcomeService tracked the count but never reported it); restores the "Extension loaded" signal (MonitorOpenProjectSystem) at its new trigger point; deletes MonitorLoadProjectSystem (confirmed fully inert everywhere). MonitorParserParse/MonitorReqnrollGeneration are documented rather than wired — the former is superseded by perf-sampling telemetry, the latter has no live feature to hook into.

Structural gaps only — usage-event additions are #260, also part of #255. Not using a closing keyword here since #255 isn't fully addressed until both PRs land.

Test plan

  • dotnet build Reqnroll.IdeSupport.slnx — clean, 0 warnings/errors
  • dotnet test tests/LSP/Reqnroll.IdeSupport.LSP.Server.Tests — 622/622 passing
  • dotnet test tests/VisualStudio/Reqnroll.VisualStudio.Tests — 118/118 passing
  • dotnet test tests/VisualStudio/Reqnroll.IdeSupport.VisualStudio.Wizards.Tests — 65/65 passing (2 new tests for MonitorExtensionDaysOfUsage)
  • dotnet test tests/LSP/Reqnroll.IdeSupport.LSP.Server.Specs — 144/144 passing (18 pre-existing skips, unrelated)
  • Rider side (ReqnrollTelemetryEventInterceptor/RiderTelemetryTransmitter) could not be built/tested in this environment — the sandbox's JVM can't complete the Gradle wrapper's TLS handshake to download Gradle 8.10 (unrelated to the code change; reviewed manually against the real platform API, but needs a ./gradlew build/runIde pass before merge)
  • MonitorOpenFeatureFile's new wiring in VsProjectEventMonitor (DTE/COM-heavy) has no automated coverage — the existing test file for this class only covers the IVsTrackProjectDocumentsEvents2 file-tracking half, not the WindowActivated flow; the addition is defensively try/caught so it can't break document activation, but hasn't been verified live in VS

🤖 Generated with Claude Code

Rider had no consumer for telemetry/event at all, so every already-implemented
event (discovery, go-to-step, rename, etc.) produced zero data for Rider users.
Add ReqnrollTelemetryEventInterceptor + RiderTelemetryTransmitter, giving Rider
parity with VS's TelemetryEventInterceptor and VS Code's telemetry.ts by
forwarding to the same Application Insights resource.

Separately, the LSP server was wired with NullTelemetryService for
ITelemetryService, so MonitorError calls from LSP.Core parsing
(DeveroomGherkinParser/DeveroomTagParser) were silently dropped in production.
Add LspErrorTelemetryService, which forwards MonitorError to
ILspTelemetryService as an Error event (redacting filesystem paths per the
architecture doc's privacy requirement) while keeping every other
host-UI-only member a no-op.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
clrudolphi and others added 2 commits July 21, 2026 09:09
…anges

Updates the aspirational telemetry design section to reflect what's actually
implemented: Rider now has its own telemetry/event interceptor + transmitter
(previously only VS and VS Code did), and the LSP server's ITelemetryService
no longer no-ops MonitorError — LSP.Core exceptions now reach an Error
telemetry/event with paths redacted, closing the privacy requirement already
documented but previously unimplemented on the server side.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ility gaps

ITelemetryService had ~16 members but only MonitorError was ever genuinely
shared between LSP.Core and the VS host — every other member is a VS-lifecycle
concern (project wizards, welcome/upgrade dialogs) that LSP.Core has no
business depending on, forcing every LSP-side implementation
(NullTelemetryService, LspErrorTelemetryService) to stub out ~15 unrelated
no-ops just to satisfy the interface.

- Add IErrorTelemetryService (MonitorError only); ITelemetryService now
  extends it. DeveroomGherkinParser, DeveroomTagParser, and
  CompletionContextResolver depend on the narrow interface directly.
  IIdeScope.TelemetryService stays typed as the full ITelemetryService, since
  VS's wizard flows genuinely need it — both interfaces resolve to the same DI
  singleton on the LSP server.
- Fix a previously-unnoticed bug surfaced by this split: LspIdeScope.TelemetryService
  was hardcoded to NullTelemetryService instead of the DI-registered service,
  so errors reported through that access path (e.g. WatchedFilesHandler's
  config-load exceptions) were silently dropped even after the earlier
  MonitorError fix.
- Wire MonitorOpenFeatureFile: implementation was real but never called;
  hooked into VsProjectEventMonitor's document-activation phase machine
  (fires once per open-lifetime).
- Wire MonitorExtensionDaysOfUsage: WelcomeService already tracked
  status.UsageDays but never reported it.
- Restore the "Extension loaded" signal (MonitorOpenProjectSystem) at
  ReqnrollPluginPackage's WelcomeService trigger point, without reintroducing
  the old wizard-trigger coupling.
- Delete MonitorLoadProjectSystem: confirmed fully inert everywhere, including
  in its own "real" VS implementation.
- Document (not wire) MonitorParserParse and MonitorReqnrollGeneration:
  the former is superseded by perf-sampling telemetry (VS no longer parses
  locally), the latter has no live feature to hook into (code-behind
  generation isn't implemented anywhere in this repo).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@clrudolphi
clrudolphi merged commit 2feb9ad into master Jul 21, 2026
16 checks passed
@clrudolphi
clrudolphi deleted the feature/255-telemetry-structural-gaps branch July 21, 2026 15:37
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.

1 participant