Skip to content

[CFX-6327] feat(telemetry): send to Amplitude EU ingest - #740

Open
ajalon1 wants to merge 7 commits into
datarobot-oss:mainfrom
ajalon1:cfx-6327-telemetry-server-zone
Open

[CFX-6327] feat(telemetry): send to Amplitude EU ingest#740
ajalon1 wants to merge 7 commits into
datarobot-oss:mainfrom
ajalon1:cfx-6327-telemetry-server-zone

Conversation

@ajalon1

@ajalon1 ajalon1 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ DO NOT MERGE — pending production security review. This PR is open for review/CI only. Please do not merge until prod sec has signed off. Tracking: CFX-6327.

RATIONALE

The CLI telemetry client hard-codes Amplitude's US ingest endpoint. To support EU data-residency requirements without per-region builds, the Amplitude ServerZone must be selectable at runtime. CFX-6327 specifies inference from the configured datarobot_instance URL with an explicit user-controlled override. The sibling ticket CFX-6328 covers injecting the override env var at Codespace provisioning and depends on this CLI-side support.

CHANGES

  • internal/telemetry/serverzone.go (new): inferServerZone(baseURL) derives US/EU from the DataRobot endpoint (host contains .eu. or ends with .eu → EU, else US); resolveServerZone() applies an explicit telemetry-server-zone override (flag/env/config) with precedence over inference, case-insensitive US/EU, and invalid-value fallback to the inferred zone with a warning.
  • internal/telemetry/telemetry.go: NewClient now sets config.ServerZone = resolveServerZone() and logs the chosen zone at debug level.
  • cmd/root.go: registers the --telemetry-server-zone persistent root flag and wires it as a universal flag via bindUniversal, so DATAROBOT_CLI_TELEMETRY_SERVER_ZONE is forwarded to plugin subprocesses. This mirrors --disable-telemetry and keeps behavior consistent with the Codespace env-injection path (CFX-6328), where the variable is already inherited by every process. Plugins that don't emit telemetry simply ignore it.
  • internal/config/constants.go: adds the shared TelemetryServerZone config-key constant.
  • No change to config.PersistableKeys: follows the disable-telemetry precedent — bound to viper but not written back to drconfig.yaml.

Env var / flag / config surface

Method How
Flag dr --telemetry-server-zone EU <command>
Environment variable DATAROBOT_CLI_TELEMETRY_SERVER_ZONE=EU
Config file telemetry-server-zone: EU in drconfig.yaml

NOTES

  • Universal flag: --telemetry-server-zone is wired through bindUniversal, so DATAROBOT_CLI_TELEMETRY_SERVER_ZONE is injected into plugin subprocess environments. Rationale: mirrors --disable-telemetry, is non-coercive (plugins that don't emit telemetry ignore it), is forward-compatible for plugins that do emit analytics, and gives behavioral parity with the Codespace env-injection path (CFX-6328) where the variable is already inherited by all processes. (Revised from an earlier "non-universal" decision — see the updated comment on CFX-6327.)
  • APAC: Amplitude has no APAC data center. APAC/JP users should use disable-telemetry: true; telemetry-server-zone does not accept an APAC value (invalid values warn and fall back to inference).
  • ServerURL (the SDK's lower-level endpoint override) is intentionally not exposed.
  • Invalid override behavior: a value other than US/EU logs a warning to .dr-tui-debug.log and falls back to the inferred zone; telemetry init never blocks or errors visibly.

TESTING

  • New internal/telemetry/serverzone_test.go: covers inference (incl. .europe false-positive guard, case-insensitive host), override-wins-over-inference, case-insensitive override, invalid-value fallback to inferred, and whitespace-as-unset.
  • New cmd/root_test.go::TestTelemetryServerZoneFlagRegistered: guards that the flag is registered, IS marked universal, and maps to the TELEMETRY_SERVER_ZONE env-var suffix.
  • go test -race ./internal/telemetry/... ./cmd — pass.
  • task lint — 0 issues.
  • go run . --help confirms --telemetry-server-zone is registered and visible.

RELATED

  • JIRA: CFX-6327 (CLI-side, this PR)
  • JIRA: CFX-6328 (Codespace provisioning, depends on this)
  • JIRA: CFX-7451 (follow-up: auto-disable telemetry for APAC/JP endpoints — deliberately out of scope for this PR)

Note

Medium Risk
Changes where usage analytics are sent (data residency) and adds a new universal env var for plugins; behavior is designed to fail safe with inference fallback and no user-visible errors on bad values.

Overview
Adds runtime Amplitude ingest region (US vs EU) so telemetry can meet EU data-residency without separate builds.

--telemetry-server-zone is a new persistent root flag (plus DATAROBOT_CLI_TELEMETRY_SERVER_ZONE / telemetry-server-zone in config). It is a universal flag, forwarded to plugins like --disable-telemetry. NewClient now sets the Amplitude SDK ServerZone via resolveServerZone(): explicit US/EU wins over inference from the DataRobot endpoint (.eu. in host or .eu suffix → EU); invalid values warn and fall back without failing the CLI.

Docs cover EU endpoint allowlisting and user configuration. Tests cover inference, override precedence, and flag registration.

Reviewed by Cursor Bugbot for commit dbee015. Configure here.

@datarobot-pr-review-router

Copy link
Copy Markdown

🎫 Jira: CFX-6327 — telemetry - Infer Amplitude server zone from datarobot_instance with explicit overrides

ajalon1 and others added 3 commits August 5, 2026 17:11
Select the Amplitude ServerZone at runtime rather than hard-coding the
US ingest endpoint. The zone is inferred from the configured DataRobot
endpoint (host contains ".eu." or ends with ".eu" -> EU, else US), with
an explicit telemetry-server-zone override taking precedence. The
override is settable via the --telemetry-server-zone flag, the
DATAROBOT_CLI_TELEMETRY_SERVER_ZONE env var, or the telemetry-server-zone
config-file key (case-insensitive US/EU). An invalid value logs a warning
to .dr-tui-debug.log and falls back to the inferred zone; telemetry
initialization never blocks or errors visibly.

The flag is deliberately NOT a universal flag -- telemetry events are
emitted by the parent CLI process, not by plugin subprocesses, so
forwarding the env var into plugins serves no purpose (decision recorded
on CFX-6327; revisit if plugins ever emit their own telemetry).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Flip --telemetry-server-zone from a non-universal persistent flag to a
universal flag so DATAROBOT_CLI_TELEMETRY_SERVER_ZONE is forwarded to
plugin subprocesses. Rationale:

- Mirrors --disable-telemetry, which is already universal, keeping the
  telemetry-preference surface uniform.
- Non-coercive: plugins that don't emit telemetry ignore it; plugins
  that do emit their own analytics can honor the user's data-residency
  preference without a future API change.
- Behavioral parity with the Codespace env-injection path (CFX-6328),
  where the variable is already inherited by every process in the
  container -- making the flag universal means the --flag path behaves
  the same as the env-injection path.

Revises the earlier "non-universal" decision recorded on CFX-6327. The
parent CLI's own zone resolution is unaffected (bindUniversal only
controls subprocess env injection). Test guard updated to assert the
universal annotation and the TELEMETRY_SERVER_ZONE env-var suffix.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…8 baseline

CFX-7448 removed EU references from the telemetry docs to reflect the
state of main (no EU support). This PR re-introduces EU server-zone
support, so re-align the docs:

- Re-add the api.eu.amplitude.com row to the network-endpoints table
  (only used when ServerZone is set to EU).
- Make the "stored in the USA" statements conditional on the selected
  server zone, in both docs/development/telemetry.md and
  docs/user-guide/configuration.md, cross-linking the Server zone /
  data residency section.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@ajalon1
ajalon1 force-pushed the cfx-6327-telemetry-server-zone branch from 6fb38b5 to 6fbbba8 Compare August 6, 2026 00:13
@ajalon1
ajalon1 marked this pull request as ready for review August 6, 2026 00:47
@ajalon1
ajalon1 requested a review from a team as a code owner August 6, 2026 00:47
@datarobot-pr-review-router

Copy link
Copy Markdown

Code Ownership

Cli Maintainers

  • cmd/root.go
  • cmd/root_test.go
  • docs/development/telemetry.md
  • docs/user-guide/configuration.md
  • internal/config/constants.go
  • internal/telemetry/serverzone.go
  • internal/telemetry/serverzone_test.go
  • internal/telemetry/telemetry.go

Review requested from the teams above. Labels will be removed automatically upon approval.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit dbee015. Configure here.

Comment thread internal/telemetry/serverzone.go
Comment thread internal/telemetry/serverzone.go Outdated
ajalon1 and others added 2 commits August 5, 2026 18:00
…up header

Address Cursor Bugbot review findings on internal/telemetry/serverzone.go:

1. (Medium) inferServerZone ran the ".eu" host rules on the full base URL
   instead of the hostname. GetBaseURL keeps an explicit port, so an EU
   endpoint with a port (e.g. https://mytenant.eu:8443) failed the
   HasSuffix(".eu") check and was misclassified as US, routing
   residency-sensitive telemetry to the wrong Amplitude zone. Now parse
   the URL and match against u.Hostname() (port-stripped), falling back
   to the lowercased full string when parsing fails or no host is present.
   Added table-test cases for EU hosts with explicit ports.

2. (Low) Removed the duplicate Apache license header (introduced by the
   prior "chore: copyright" commit) so the file carries a single header.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add explicit inferServerZone table cases for the canonical MTS prod
hosts from dr auth set-url / the hostpicker:
- app.datarobot.com -> US (already present)
- app.eu.datarobot.com -> EU (already present)
- app.jp.datarobot.com -> US (new): locks in the intentional Japan
  routing. Amplitude has no APAC data center, so Japan infers US; the
  auto-disable follow-up is tracked in CFX-7451.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@ajalon1

ajalon1 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

/approve-smoke-tests

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

🔐 Fork PR smoke tests triggered by @ajalon1

⚠️ Security Notice: This will run tests with access to repository secrets.

What happens next:

  1. Security scans will run automatically (Trivy, gosec)
  2. If security scans pass, smoke tests will run
  3. Results will be posted as PR comments

⚠️ Important: Review the PR code carefully before approving!

@ajalon1 ajalon1 changed the title [CFX-6327] feat(telemetry): support DATAROBOT_CLI_TELEMETRY_SERVER_ZONE [CFX-6327] feat(telemetry): send to Amplitude EU ingest Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

🔐 Fork smoke tests started by maintainer

⏳ Security scans passed. Running smoke tests...

Commit: aeb0078d51778f3a56f6f3e113856b9f79e0c417
View run

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

All smoke tests passed! (Fork PR)

✅ Security Scan: success
✅ Linux: success
✅ Windows: success

View run details

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.

1 participant