From 8092c1a7922949a295d75ecc4acbe91ae02b7e00 Mon Sep 17 00:00:00 2001 From: Kent Huang Date: Fri, 3 Jan 2025 15:27:50 +0800 Subject: [PATCH] [Feature] DRC-986 Telemetry for single environment experiment Signed-off-by: Kent Huang Co-authored-by: Wei-Chun, Chang --- js/src/components/lineage/NodeView.tsx | 7 +++++-- js/src/components/lineage/PreviewChangeView.tsx | 7 +++++++ .../onboarding-guide/OnboardingGuide.tsx | 8 ++++++++ js/src/lib/api/track.ts | 14 ++++++++++++++ js/src/lib/hooks/LineageGraphContext.tsx | 3 +++ js/src/lib/hooks/useGuideToast.tsx | 12 +++++++++++- recce/event/CONFIG | 2 +- recce/event/__init__.py | 10 +++++++++- recce/server.py | 7 ++++--- 9 files changed, 62 insertions(+), 8 deletions(-) diff --git a/js/src/components/lineage/NodeView.tsx b/js/src/components/lineage/NodeView.tsx index 68a723a9..bd9a4170 100644 --- a/js/src/components/lineage/NodeView.tsx +++ b/js/src/components/lineage/NodeView.tsx @@ -46,7 +46,7 @@ import { is } from "date-fns/locale"; import { run } from "node:test"; import { DisableTooltipMessages } from "@/constants/tooltipMessage"; import { PreviewChangeView } from "./PreviewChangeView"; -import { trackPreviewChange } from "@/lib/api/track"; +import { trackPreviewChange, trackSingleEnvironment } from "@/lib/api/track"; import { useRecceServerFlag } from "@/lib/hooks/useRecceServerFlag"; interface NodeViewProps { @@ -298,7 +298,10 @@ export function NodeView({ node, onCloseNode }: NodeViewProps) { setPrimaryKeys(primaryKey !== undefined ? [primaryKey] : undefined); } onPreviewChangeOpen(); - trackPreviewChange({ action: "explore", node: node.name }); + trackSingleEnvironment({ + action: "preview_changes", + node: node.name, + }); }} > Preview Changes diff --git a/js/src/components/lineage/PreviewChangeView.tsx b/js/src/components/lineage/PreviewChangeView.tsx index 83c792f5..3829a8c1 100644 --- a/js/src/components/lineage/PreviewChangeView.tsx +++ b/js/src/components/lineage/PreviewChangeView.tsx @@ -36,6 +36,7 @@ import { useRecceQueryContext } from "@/lib/hooks/RecceQueryContext"; import { trackPreviewChange, trackPreviewChangeFeedback, + trackSingleEnvironment, } from "@/lib/api/track"; import { useGuideToast } from "@/lib/hooks/useGuideToast"; import { useRecceServerFlag } from "@/lib/hooks/useRecceServerFlag"; @@ -222,6 +223,12 @@ export function PreviewChangeView({ externalLink: "https://datarecce.io/docs/get-started/#prepare-dbt-artifacts", externalLinkText: "Learn how.", + onExternalLinkClick: () => + trackSingleEnvironment({ + action: "external_link", + from: "preview_changes", + node: current?.name, + }), }); useEffect(() => { diff --git a/js/src/components/onboarding-guide/OnboardingGuide.tsx b/js/src/components/onboarding-guide/OnboardingGuide.tsx index d10c0a8e..0604fdba 100644 --- a/js/src/components/onboarding-guide/OnboardingGuide.tsx +++ b/js/src/components/onboarding-guide/OnboardingGuide.tsx @@ -21,6 +21,7 @@ import { useEffect, useState } from "react"; import { markOnboardingCompleted } from "@/lib/api/flag"; import { useRecceServerFlag } from "@/lib/hooks/useRecceServerFlag"; import { InfoOutlineIcon } from "@chakra-ui/icons"; +import { trackSingleEnvironment } from "@/lib/api/track"; interface GuideProps { isGuideOpen: boolean; @@ -80,6 +81,12 @@ const SingleEnvGuide = ({ isGuideOpen, closeGuide }: GuideProps) => { textDecor="underline" isExternal href="https://datarecce.io/docs/get-started/#prepare-dbt-artifacts" + onClick={() => + trackSingleEnvironment({ + action: "external_link", + from: "onboarding", + }) + } > Learn how. @@ -111,6 +118,7 @@ const OnboardingGuide = () => { const singleEnvMode = flags.single_env_onboarding; if (singleEnvMode && showOnboardingGuide) { setISSingleEnvGuideOpen(true); + trackSingleEnvironment({ action: "onboarding" }); return; } diff --git a/js/src/lib/api/track.ts b/js/src/lib/api/track.ts index b8d07fe7..4b625ed2 100644 --- a/js/src/lib/api/track.ts +++ b/js/src/lib/api/track.ts @@ -58,3 +58,17 @@ interface PreviewChangeFeedbackProps { export function trackPreviewChangeFeedback(props: PreviewChangeFeedbackProps) { amplitude.track("[Experiment] preview_change", props); } + +interface SingleEnvironmentProps { + action: + | "onboarding" + | "external_link" + | "preview_changes" + | `target_base_added`; + from?: "onboarding" | "preview_changes"; + node?: string; +} + +export function trackSingleEnvironment(props: SingleEnvironmentProps) { + amplitude.track("[Experiment] single_environment", props); +} diff --git a/js/src/lib/hooks/LineageGraphContext.tsx b/js/src/lib/hooks/LineageGraphContext.tsx index beaf5027..97f766c6 100644 --- a/js/src/lib/hooks/LineageGraphContext.tsx +++ b/js/src/lib/hooks/LineageGraphContext.tsx @@ -34,6 +34,7 @@ import path from "path"; import { aggregateRuns, RunsAggregated } from "../api/runs"; import { markRelaunchHintCompleted } from "../api/flag"; import { useRecceServerFlag } from "./useRecceServerFlag"; +import { trackSingleEnvironment } from "../api/track"; interface EnvInfo { adapterType?: string; @@ -249,7 +250,9 @@ export function LineageGraphContextProvider({ children }: LineageGraphProps) { flags?.single_env_onboarding && flags?.show_relaunch_hint ) { + // User has added a target-base folder setRelaunchHintOpen(true); + trackSingleEnvironment({ action: "target_base_added" }); } else { setRelaunchHintOpen(false); } diff --git a/js/src/lib/hooks/useGuideToast.tsx b/js/src/lib/hooks/useGuideToast.tsx index 3ff151a1..96680b51 100644 --- a/js/src/lib/hooks/useGuideToast.tsx +++ b/js/src/lib/hooks/useGuideToast.tsx @@ -13,9 +13,16 @@ export function useGuideToast(options: { description: string; externalLink?: string; externalLinkText?: string; + onExternalLinkClick?: () => void; }) { const toast = useToast(); - const { guideId, description, externalLink, externalLinkText } = options; + const { + guideId, + description, + externalLink, + externalLinkText, + onExternalLinkClick, + } = options; function guideToast() { if (toast.isActive(guideId)) { @@ -48,6 +55,9 @@ export function useGuideToast(options: { isExternal href={externalLink} onClick={() => { + if (onExternalLinkClick) { + onExternalLinkClick(); + } onClose(); }} > diff --git a/recce/event/CONFIG b/recce/event/CONFIG index cbbd4f50..0e2be95b 100644 --- a/recce/event/CONFIG +++ b/recce/event/CONFIG @@ -1 +1 @@ -event_api_key: \ No newline at end of file +event_api_key: diff --git a/recce/event/__init__.py b/recce/event/__init__.py index 070b6eda..34006a86 100644 --- a/recce/event/__init__.py +++ b/recce/event/__init__.py @@ -12,9 +12,9 @@ from recce import is_ci_env, get_version, get_runner from recce import yaml as pyml from recce.event.collector import Collector +from recce.git import current_branch, hosting_repo from recce.github import is_github_codespace, get_github_codespace_info, get_github_codespace_name, \ get_github_codespace_available_at -from recce.git import current_branch, hosting_repo USER_HOME = os.path.expanduser('~') RECCE_USER_HOME = os.path.join(USER_HOME, '.recce') @@ -249,6 +249,14 @@ def log_codespaces_events(command): _collector.send_events() +def log_single_env_event(): + prop = dict( + action='launch_server', + ) + log_event(prop, '[Experiment] single_environment') + _collector.send_events() + + def capture_exception(e): user_id = load_user_profile().get('user_id') if is_ci_env() is True: diff --git a/recce/server.py b/recce/server.py index 62df7184..80722504 100644 --- a/recce/server.py +++ b/recce/server.py @@ -22,7 +22,7 @@ from .apis.run_api import run_router from .config import RecceConfig from .core import load_context, default_context -from .event import log_api_event +from .event import log_api_event, log_single_env_event from .exceptions import RecceException from .run import load_preset_checks from .state import RecceStateLoader @@ -48,8 +48,10 @@ async def lifespan(fastapi: FastAPI): kwargs = app_state.kwargs ctx = load_context(**kwargs, state_loader=state_loader) ctx.start_monitor_artifacts(callback=dbt_artifacts_updated_callback) - if app_state.flag.get("single_env_onboarding", False): + if app_state.flag.get("single_env_onboarding", False) is True: + # [Experiment 2] Start with Single Environment ctx.start_monitor_base_env(callback=dbt_env_updated_callback) + log_single_env_event() # Initialize Recce Config config = RecceConfig(config_file=kwargs.get('config')) @@ -108,7 +110,6 @@ def dbt_artifacts_updated_callback(file_changed_event: Any): def dbt_env_updated_callback(): - logger.info("Detect 'manifest.json' and 'catalog.json' are generated under 'target-base' directory") broadcast_command = { 'command': 'relaunch',