From 97256e832aeca26bc37aef65b117948b89b65395 Mon Sep 17 00:00:00 2001 From: ianedwards Date: Fri, 22 Sep 2023 16:15:32 -0400 Subject: [PATCH] track events with validate apply v2 ff (#3636) Co-authored-by: Feroze Mohideen --- api/server/handlers/porter_app/analytics.go | 6 ++ dashboard/src/lib/hooks/useAppAnalytics.ts | 6 +- .../app-dashboard/app-view/tabs/Settings.tsx | 4 +- .../app-dashboard/create-app/CreateApp.tsx | 14 ++-- internal/analytics/tracks.go | 66 +++++++++++-------- 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/api/server/handlers/porter_app/analytics.go b/api/server/handlers/porter_app/analytics.go index e198b5de0f..be9e4e57ce 100644 --- a/api/server/handlers/porter_app/analytics.go +++ b/api/server/handlers/porter_app/analytics.go @@ -35,6 +35,7 @@ func (v *PorterAppAnalyticsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req return } + validateApplyV2 := project.GetFeatureFlag(models.ValidateApplyV2, v.Config().LaunchDarklyClient) if request.Step == "stack-launch-start" { v.Config().AnalyticsClient.Track(analytics.StackLaunchStartTrack(&analytics.StackLaunchStartOpts{ ProjectScopedTrackOpts: analytics.GetProjectScopedTrackOpts(user.ID, project.ID), @@ -42,6 +43,7 @@ func (v *PorterAppAnalyticsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req FirstName: user.FirstName, LastName: user.LastName, CompanyName: user.CompanyName, + ValidateApplyV2: validateApplyV2, })) } @@ -53,6 +55,7 @@ func (v *PorterAppAnalyticsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req FirstName: user.FirstName, LastName: user.LastName, CompanyName: user.CompanyName, + ValidateApplyV2: validateApplyV2, })) } @@ -64,6 +67,7 @@ func (v *PorterAppAnalyticsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req FirstName: user.FirstName, LastName: user.LastName, CompanyName: user.CompanyName, + ValidateApplyV2: validateApplyV2, })) } @@ -76,6 +80,7 @@ func (v *PorterAppAnalyticsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req LastName: user.LastName, CompanyName: user.CompanyName, ErrorMessage: request.ErrorMessage, + ValidateApplyV2: validateApplyV2, })) } @@ -88,6 +93,7 @@ func (v *PorterAppAnalyticsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req LastName: user.LastName, CompanyName: user.CompanyName, DeleteWorkflowFile: request.DeleteWorkflowFile, + ValidateApplyV2: validateApplyV2, })) } diff --git a/dashboard/src/lib/hooks/useAppAnalytics.ts b/dashboard/src/lib/hooks/useAppAnalytics.ts index fa145d5dcb..691cd061aa 100644 --- a/dashboard/src/lib/hooks/useAppAnalytics.ts +++ b/dashboard/src/lib/hooks/useAppAnalytics.ts @@ -9,14 +9,16 @@ type AppStep = | "stack-launch-failure" | "stack-deletion"; -export const useAppAnalytics = (appName?: string) => { +export const useAppAnalytics = () => { const { currentCluster, currentProject } = useContext(Context); const updateAppStep = async ({ + appName, step, errorMessage = "", deleteWorkflow = false, }: { + appName?: string; step: AppStep; errorMessage?: string; deleteWorkflow?: boolean; @@ -38,7 +40,7 @@ export const useAppAnalytics = (appName?: string) => { project_id: currentProject.id, } ); - } catch (err) {} + } catch (err) { } }; return { diff --git a/dashboard/src/main/home/app-dashboard/app-view/tabs/Settings.tsx b/dashboard/src/main/home/app-dashboard/app-view/tabs/Settings.tsx index ceb1985f40..48b075cb09 100644 --- a/dashboard/src/main/home/app-dashboard/app-view/tabs/Settings.tsx +++ b/dashboard/src/main/home/app-dashboard/app-view/tabs/Settings.tsx @@ -17,7 +17,7 @@ const Settings: React.FC = () => { const history = useHistory(); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const { porterApp, clusterId, projectId } = useLatestRevision(); - const { updateAppStep } = useAppAnalytics(porterApp.name); + const { updateAppStep } = useAppAnalytics(); const [isDeleting, setIsDeleting] = useState(false); const githubWorkflowFilename = `porter_stack_${porterApp.name}.yml`; @@ -98,7 +98,7 @@ const Settings: React.FC = () => { window.open(res.data.url, "_blank", "noreferrer"); } - updateAppStep({ step: "stack-deletion", deleteWorkflow: true }); + updateAppStep({ step: "stack-deletion", deleteWorkflow: true, appName: porterApp.name }); history.push("/apps"); return; } diff --git a/dashboard/src/main/home/app-dashboard/create-app/CreateApp.tsx b/dashboard/src/main/home/app-dashboard/create-app/CreateApp.tsx index 2a18767843..d9ef98792b 100644 --- a/dashboard/src/main/home/app-dashboard/create-app/CreateApp.tsx +++ b/dashboard/src/main/home/app-dashboard/create-app/CreateApp.tsx @@ -189,7 +189,7 @@ const CreateApp: React.FC = ({ history }) => { appName: "", // only want to know if porter.yaml has name set, otherwise use name from input }); const deploymentTarget = useDefaultDeploymentTarget(); - const { updateAppStep } = useAppAnalytics(name.value); + const { updateAppStep } = useAppAnalytics(); const { validateApp } = useAppValidation({ deploymentTargetID: deploymentTarget?.deployment_target_id, creating: true, @@ -238,7 +238,7 @@ const CreateApp: React.FC = ({ history }) => { }) => { setIsDeploying(true); // log analytics event that we started form submission - updateAppStep({ step: "stack-launch-complete" }); + updateAppStep({ step: "stack-launch-complete", appName: name.value }); try { if (!currentProject?.id || !currentCluster?.id) { @@ -308,7 +308,7 @@ const CreateApp: React.FC = ({ history }) => { ); // log analytics event that we successfully deployed - updateAppStep({ step: "stack-launch-success" }); + updateAppStep({ step: "stack-launch-success", appName: name.value }); if (source.type === "docker-registry") { history.push(`/apps/${app.name}`); @@ -320,6 +320,7 @@ const CreateApp: React.FC = ({ history }) => { updateAppStep({ step: "stack-launch-failure", errorMessage: err.response?.data?.error, + appName: name.value, }); setDeployError(err.response?.data?.error); return false; @@ -327,7 +328,7 @@ const CreateApp: React.FC = ({ history }) => { const msg = "An error occurred while deploying your application. Please try again."; - updateAppStep({ step: "stack-launch-failure", errorMessage: msg }); + updateAppStep({ step: "stack-launch-failure", errorMessage: msg, appName: name.value }); setDeployError(msg); return false; } finally { @@ -593,9 +594,8 @@ const CreateApp: React.FC = ({ history }) => { } > {detectedServices.count > 0 - ? `Detected ${detectedServices.count} service${ - detectedServices.count > 1 ? "s" : "" - } from porter.yaml.` + ? `Detected ${detectedServices.count} service${detectedServices.count > 1 ? "s" : "" + } from porter.yaml.` : `Could not detect any services from porter.yaml. Make sure it exists in the root of your repo.`} diff --git a/internal/analytics/tracks.go b/internal/analytics/tracks.go index edb338dbcb..69214e1ca7 100644 --- a/internal/analytics/tracks.go +++ b/internal/analytics/tracks.go @@ -783,10 +783,11 @@ func ClusterDestroyingSuccessTrack(opts *ClusterDestroyingSuccessTrackOpts) segm type StackLaunchStartOpts struct { *ProjectScopedTrackOpts - Email string - FirstName string - LastName string - CompanyName string + Email string + FirstName string + LastName string + CompanyName string + ValidateApplyV2 bool } // StackLaunchStartTrack returns a track for when a user starts creating a stack @@ -795,6 +796,7 @@ func StackLaunchStartTrack(opts *StackLaunchStartOpts) segmentTrack { additionalProps["email"] = opts.Email additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -806,11 +808,12 @@ func StackLaunchStartTrack(opts *StackLaunchStartOpts) segmentTrack { type StackLaunchCompleteOpts struct { *ProjectScopedTrackOpts - StackName string - Email string - FirstName string - LastName string - CompanyName string + StackName string + Email string + FirstName string + LastName string + CompanyName string + ValidateApplyV2 bool } // StackLaunchCompleteTrack returns a track for when a user completes creating a stack @@ -820,6 +823,7 @@ func StackLaunchCompleteTrack(opts *StackLaunchCompleteOpts) segmentTrack { additionalProps["email"] = opts.Email additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -831,11 +835,12 @@ func StackLaunchCompleteTrack(opts *StackLaunchCompleteOpts) segmentTrack { type StackLaunchSuccessOpts struct { *ProjectScopedTrackOpts - StackName string - Email string - FirstName string - LastName string - CompanyName string + StackName string + Email string + FirstName string + LastName string + CompanyName string + ValidateApplyV2 bool } // StackLaunchCompleteTrack returns a track for when a user completes creating a stack @@ -845,6 +850,7 @@ func StackLaunchSuccessTrack(opts *StackLaunchSuccessOpts) segmentTrack { additionalProps["email"] = opts.Email additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -856,12 +862,13 @@ func StackLaunchSuccessTrack(opts *StackLaunchSuccessOpts) segmentTrack { type StackLaunchFailureOpts struct { *ProjectScopedTrackOpts - StackName string - Email string - FirstName string - LastName string - CompanyName string - ErrorMessage string + StackName string + Email string + FirstName string + LastName string + CompanyName string + ErrorMessage string + ValidateApplyV2 bool } // StackLaunchFailureTrack returns a track for when a user fails creating a stack @@ -872,6 +879,7 @@ func StackLaunchFailureTrack(opts *StackLaunchFailureOpts) segmentTrack { additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName additionalProps["error_message"] = opts.ErrorMessage + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -889,6 +897,7 @@ type StackDeletionOpts struct { LastName string CompanyName string DeleteWorkflowFile bool + ValidateApplyV2 bool } // StackDeletionTrack returns a track for when a user deletes a stack @@ -899,6 +908,7 @@ func StackDeletionTrack(opts *StackDeletionOpts) segmentTrack { additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName additionalProps["delete_workflow_file"] = opts.DeleteWorkflowFile + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -910,12 +920,13 @@ func StackDeletionTrack(opts *StackDeletionOpts) segmentTrack { type StackBuildOpts struct { *ProjectScopedTrackOpts - StackName string - ErrorMessage string - Email string - FirstName string - LastName string - CompanyName string + StackName string + ErrorMessage string + Email string + FirstName string + LastName string + CompanyName string + ValidateApplyV2 bool } // StackBuildFailureTrack returns a track for when a stack fails to build @@ -926,6 +937,7 @@ func StackBuildFailureTrack(opts *StackBuildOpts) segmentTrack { additionalProps["email"] = opts.Email additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -940,6 +952,7 @@ func StackBuildSuccessTrack(opts *StackBuildOpts) segmentTrack { additionalProps["email"] = opts.Email additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts, @@ -954,6 +967,7 @@ func StackBuildProgressingTrack(opts *StackBuildOpts) segmentTrack { additionalProps["email"] = opts.Email additionalProps["name"] = opts.FirstName + " " + opts.LastName additionalProps["company"] = opts.CompanyName + additionalProps["validate_apply_v2"] = opts.ValidateApplyV2 return getSegmentProjectTrack( opts.ProjectScopedTrackOpts,