Unverified 提交 aceda415 authored 作者: wwwillchen-bot's avatar wwwillchen-bot 提交者: GitHub

Add telemetry sampling for non-Pro users (#2642)

## Summary - Store Dyad Pro status in localStorage for telemetry access - Sample 10% of events for non-Pro users (error events always sent) - Pro users continue to send all events ## Test plan - Verify telemetry events are sampled correctly for non-Pro users - Confirm error events are always sent regardless of Pro status - Test Pro users still send all events 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2642" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds telemetry sampling for non‑Pro users to reduce event volume while keeping error visibility. Stores Dyad Pro status in localStorage; Pro users keep sending all events. - **New Features** - Save Dyad Pro status in localStorage (dyadProStatus) and expose isDyadProUser(). - Sample PostHog events for non‑Pro: send 10% of non‑error events; always send errors. - No change for Pro users; all events continue to be sent. <sup>Written for commit 685922c99bc83c6c1d3c6e58a99761037894bc2b. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> Co-authored-by: 's avatarWill Chen <willchen90@gmail.com> Co-authored-by: 's avatarClaude Opus 4.5 <noreply@anthropic.com>
上级 065bab97
...@@ -10,6 +10,7 @@ import { queryKeys } from "@/lib/queryKeys"; ...@@ -10,6 +10,7 @@ import { queryKeys } from "@/lib/queryKeys";
const TELEMETRY_CONSENT_KEY = "dyadTelemetryConsent"; const TELEMETRY_CONSENT_KEY = "dyadTelemetryConsent";
const TELEMETRY_USER_ID_KEY = "dyadTelemetryUserId"; const TELEMETRY_USER_ID_KEY = "dyadTelemetryUserId";
const DYAD_PRO_STATUS_KEY = "dyadProStatus";
export function isTelemetryOptedIn() { export function isTelemetryOptedIn() {
return window.localStorage.getItem(TELEMETRY_CONSENT_KEY) === "opted_in"; return window.localStorage.getItem(TELEMETRY_CONSENT_KEY) === "opted_in";
...@@ -19,6 +20,10 @@ export function getTelemetryUserId(): string | null { ...@@ -19,6 +20,10 @@ export function getTelemetryUserId(): string | null {
return window.localStorage.getItem(TELEMETRY_USER_ID_KEY); return window.localStorage.getItem(TELEMETRY_USER_ID_KEY);
} }
export function isDyadProUser(): boolean {
return window.localStorage.getItem(DYAD_PRO_STATUS_KEY) === "true";
}
let isInitialLoad = false; let isInitialLoad = false;
export function useSettings() { export function useSettings() {
...@@ -121,4 +126,9 @@ function processSettingsForTelemetry(settings: UserSettings) { ...@@ -121,4 +126,9 @@ function processSettingsForTelemetry(settings: UserSettings) {
} else { } else {
window.localStorage.removeItem(TELEMETRY_USER_ID_KEY); window.localStorage.removeItem(TELEMETRY_USER_ID_KEY);
} }
// Store Pro status for telemetry sampling
window.localStorage.setItem(
DYAD_PRO_STATUS_KEY,
hasDyadProKey(settings) ? "true" : "false",
);
} }
...@@ -4,7 +4,11 @@ import { router } from "./router"; ...@@ -4,7 +4,11 @@ import { router } from "./router";
import { RouterProvider } from "@tanstack/react-router"; import { RouterProvider } from "@tanstack/react-router";
import { PostHogProvider } from "posthog-js/react"; import { PostHogProvider } from "posthog-js/react";
import posthog from "posthog-js"; import posthog from "posthog-js";
import { getTelemetryUserId, isTelemetryOptedIn } from "./hooks/useSettings"; import {
getTelemetryUserId,
isTelemetryOptedIn,
isDyadProUser,
} from "./hooks/useSettings";
// Initialize i18next before any rendering // Initialize i18next before any rendering
import "./i18n"; import "./i18n";
...@@ -87,6 +91,20 @@ const posthogClient = posthog.init( ...@@ -87,6 +91,20 @@ const posthogClient = posthog.init(
event.properties["$ip"] = null; event.properties["$ip"] = null;
} }
// For non-Pro users, only send 10% of events (but always send errors)
if (!isDyadProUser()) {
const isErrorEvent =
event?.event === "$exception" ||
event?.event?.toLowerCase().includes("error") ||
event?.properties?.$exception_type ||
event?.properties?.error;
if (!isErrorEvent && Math.random() > 0.1) {
console.debug("Non-Pro user: sampling out event", event?.event);
return null;
}
}
console.debug( console.debug(
"Telemetry opted in - UUID:", "Telemetry opted in - UUID:",
telemetryUserId, telemetryUserId,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论