Skip to content

feat(telemetry): opt-out phone-home telemetry for the CLI and cli.deepgram.com#59

Merged
lukeocodes merged 2 commits intomainfrom
feat/telemetry
May 7, 2026
Merged

feat(telemetry): opt-out phone-home telemetry for the CLI and cli.deepgram.com#59
lukeocodes merged 2 commits intomainfrom
feat/telemetry

Conversation

@lukeocodes
Copy link
Copy Markdown
Member

Summary

Phone-home telemetry for both the CLI and cli.deepgram.com, both reporting into the existing dx-cli Sentry project. Opt-out by default-on, configurable per user, can be killed entirely with one env var for CI runs.

Sits alongside the new (disabled-pending-budget) Sentry uptime detector for cli.deepgram.com so both sides of the project produce signal once budget lands.

What changed

CLI (packages/deepctl-telemetry)

  • new workspace package deepctl-telemetry with three exports:
    • init_telemetry(config) — lazy sentry_sdk.init if telemetry is on, otherwise a no-op. Idempotent.
    • is_enabled(config) — env override (DEEPCTL_TELEMETRY_DISABLED=1) wins, then config.telemetry.enabled (default True)
    • install_help_notice(config) — monkey-patches click.Command.get_help once at startup so every --help output (group, subcommand, plugin command, anywhere) ends with a dim one-line footer
  • baked DSN points at dx-cli. Override via DEEPCTL_TELEMETRY_DSN for forks/self-hosted Sentry
  • before_send hook scrubs request bodies, headers, cookies, email/IP/username from user, plus send_default_pii=False. Defense-in-depth — Sentry SDK does most of this but breadcrumbs/exception messages can still leak project IDs and file paths
  • traces_sample_rate=0 and profiles_sample_rate=0 so we ship errors and breadcrumbs only, no perf data
  • 5 unit tests covering env override, config off, default on, both notice variants

CLI wiring

  • deepctl_core.config.DeepgramConfig gets a telemetry: TelemetryConfig field with enabled: bool = True
  • src/deepctl/main.py calls init_telemetry() and install_help_notice() at the very top of main(), wrapped in a bare try/except so a broken telemetry dep can never crash the CLI itself
  • Hard-dep enforced via root pyproject.toml and [tool.uv.sources] workspace member entry, same as every other shippable package. pip install deepctl pulls it in; you can't remove it without uninstalling the CLI
  • Release-please config and test workflow updated with the new component

Web (web/)

  • @sentry/astro integration in astro.config.mjs, init code in web/sentry.client.config.ts
  • Init reads localStorage.dg_telemetry. If 'off', Sentry never initializes that page load
  • Footer next to the copyright shows Telemetry: on/off with a toggle button that flips the flag and reloads
  • tracesSampleRate/replaysSessionSampleRate/replaysOnErrorSampleRate all 0. Errors only

Notice copy

Telemetry is on (anonymous error reports). Disable: dg config set telemetry.enabled false

When opted out:

Telemetry is off.

Rendered with click.style(..., dim=True) so it sits quietly under the help.

Test plan

  • make check — ruff format/lint + mypy strict, all 115 source files clean
  • uv run pytest packages/deepctl-telemetry/tests — 5 pass
  • uv run dg --help — footer shows on telemetry on
  • DEEPCTL_TELEMETRY_DISABLED=1 uv run dg --help — footer shows "off"
  • uv run dg api --help — footer also shows on subcommand help (monkey-patch propagation)
  • npm run build in web/ — builds clean, source maps upload to Sentry when SENTRY_AUTH_TOKEN is set in CI

Pre-existing failures

5 tests in packages/deepctl-core/tests/unit/test_base.py::TestBaseCommand::test_output_result_* fail on this branch and on bare main. Not introduced here.

Related

  • Notion plan: SDKs Observability — Sentry chosen as phone-home backend in the 2026-03-17 update, replacing the older custom collector at telemetry.dx.deepgram.com
  • Sentry uptime detector for cli.deepgram.com already created (id 7211778), sits disabled until on-demand seat budget is approved

lukeocodes added 2 commits May 6, 2026 14:41
Adds packages/deepctl-telemetry, a workspace-required Sentry client that ships with every install of deepctl. Errors phone home to the dx-cli Sentry project by default; users can opt out anywhere with: dg config set telemetry.enabled false  (or DEEPCTL_TELEMETRY_DISABLED=1 for one-shot CI runs).

Wired into src/deepctl/main.py before plugin loads, with a Click monkey-patch that appends a dim one-line notice to every --help output (group, subcommand, plugin command — anywhere Click formats help). The init/notice failure path is wrapped in try/except so a broken telemetry dep cannot crash the CLI.

Hard-dep enforced via the root pyproject.toml dependencies list (same pattern as deepctl-core, deepctl-shared-utils, and every command package). Release-please config and test workflow updated. Default Sentry DSN points at the existing dx-cli project; override via DEEPCTL_TELEMETRY_DSN for forks or self-hosted Sentry.
Adds @sentry/astro to the marketing site, pointed at the same dx-cli Sentry project as the CLI itself. Sentry init runs from web/sentry.client.config.ts and skips if localStorage.dg_telemetry === 'off'.

Footer toggle next to the copyright line lets visitors flip the flag and reload. State is rendered on every page load so the displayed value stays in sync with what's actually about to happen on the next visit.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds opt-out (default-on) Sentry-backed “phone-home” telemetry to both the Deepgram CLI and cli.deepgram.com, including a per-user toggle for the website and a --help footer notice for the CLI.

Changes:

  • Introduces new packages/deepctl-telemetry package to gate/init Sentry and append a telemetry notice to all Click help output.
  • Wires CLI startup to initialize telemetry early and extends deepctl_core config with telemetry.enabled (default true).
  • Adds @sentry/astro client initialization for the website plus a localStorage-backed “Telemetry: on/off” toggle in the footer.

Reviewed changes

Copilot reviewed 18 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
web/src/pages/index.astro Adds footer UI + client-side localStorage toggle to opt out of web telemetry.
web/sentry.client.config.ts Initializes Sentry on the client only when not opted out via localStorage.
web/package.json Adds @sentry/astro dependency.
web/package-lock.json Locks Sentry (and transitive) dependencies.
web/astro.config.mjs Registers Sentry Astro integration + source map upload configuration.
src/deepctl/main.py Initializes CLI telemetry and installs Click help footer early in startup.
README.md Documents new deepctl-telemetry workspace package.
pyproject.toml Adds deepctl-telemetry as a root dependency + workspace source.
packages/deepctl-telemetry/tests/unit/test_telemetry.py Unit tests for enablement logic and notice rendering.
packages/deepctl-telemetry/tests/unit/init.py Test package marker.
packages/deepctl-telemetry/tests/init.py Test package marker.
packages/deepctl-telemetry/src/deepctl_telemetry/notice.py Implements Click get_help monkey-patch and notice rendering.
packages/deepctl-telemetry/src/deepctl_telemetry/client.py Implements Sentry init + opt-out + event scrubbing.
packages/deepctl-telemetry/src/deepctl_telemetry/init.py Public exports + version for telemetry package.
packages/deepctl-telemetry/README.md Package-level documentation and usage notes.
packages/deepctl-telemetry/pyproject.toml New package metadata and dependencies.
packages/deepctl-telemetry/CHANGELOG.md Initializes changelog for release-please.
packages/deepctl-core/src/deepctl_core/config.py Adds TelemetryConfig and DeepgramConfig.telemetry field.
.github/workflows/test.yml Includes telemetry package tests in CI pytest invocation.
.github/release-please-config.json Adds release-please configuration for telemetry package.
.github/.release-please-manifest.json Adds telemetry package to release-please manifest.
Files not reviewed (1)
  • web/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/deepctl/main.py
Comment on lines +244 to +246
telemetry_config = Config()
init_telemetry(telemetry_config)
install_help_notice(telemetry_config)
Comment on lines +37 to +45
def init_telemetry(config: Config) -> bool:
"""Initialize the Sentry SDK if telemetry is enabled.

Idempotent — safe to call multiple times. Returns whether init ran.
"""
global _initialized
if _initialized:
return True
if not is_enabled(config):
Comment thread web/src/pages/index.astro
Comment on lines +1115 to +1122
const render = () => {
const off = localStorage.getItem(STORAGE_KEY) === 'off';
stateEl.textContent = off ? 'off' : 'on';
};
toggleEl.addEventListener('click', () => {
const off = localStorage.getItem(STORAGE_KEY) === 'off';
if (off) localStorage.removeItem(STORAGE_KEY);
else localStorage.setItem(STORAGE_KEY, 'off');
Comment on lines +4 to +7
const optedOut =
typeof window !== 'undefined' &&
window.localStorage?.getItem(STORAGE_KEY) === 'off';

@lukeocodes lukeocodes merged commit 8e20b16 into main May 7, 2026
43 checks passed
@lukeocodes lukeocodes deleted the feat/telemetry branch May 7, 2026 11:53
@github-actions github-actions Bot mentioned this pull request May 7, 2026
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