Explorar el Código

Merge pull request #943 from porter-dev/segment-infra-metrics

Segment infra metrics
abelanger5 hace 4 años
padre
commit
917fce3d6e

+ 1 - 0
internal/analytics/track_events.go

@@ -5,4 +5,5 @@ type SegmentEvent string
 const (
 	NewUser            SegmentEvent = "New User"
 	RedeployViaWebhook SegmentEvent = "Triggered Re-deploy via Webhook"
+	NewClusterEvent    SegmentEvent = "New Cluster Event"
 )

+ 44 - 3
internal/analytics/tracks.go

@@ -18,8 +18,8 @@ type segmentNewUserTrack struct {
 	userEmail string
 }
 
-// Constructor for track of type "New User"
-// Tracks when a user has registered
+// CreateSegmentNewUserTrack creates a track of type "New User", which
+// tracks when a user has registered
 func CreateSegmentNewUserTrack(user *models.User) *segmentNewUserTrack {
 	userId := fmt.Sprintf("%v", user.ID)
 
@@ -46,7 +46,7 @@ type segmentRedeployViaWebhookTrack struct {
 	repository string
 }
 
-// Constructor for track of type "Triggered Re-deploy via Webhook"
+// CreateSegmentRedeployViaWebhookTrack creates a track of type "Triggered Re-deploy via Webhook", which
 // tracks whenever a repository is redeployed via webhook call
 func CreateSegmentRedeployViaWebhookTrack(userId string, repository string) *segmentRedeployViaWebhookTrack {
 	return &segmentRedeployViaWebhookTrack{
@@ -66,3 +66,44 @@ func (t *segmentRedeployViaWebhookTrack) getEvent() SegmentEvent {
 func (t *segmentRedeployViaWebhookTrack) getProperties() segment.Properties {
 	return segment.NewProperties().Set("repository", t.repository)
 }
+
+type segmentNewClusterEventTrack struct {
+	userId      string
+	projId      string
+	clusterName string
+	clusterType string // EKS, DOKS, or GKE
+	eventType   string // connected, provisioned, or destroyed
+}
+
+// NewClusterEventOpts are the parameters for creating a "New Cluster Event" track
+type NewClusterEventOpts struct {
+	UserId      string
+	ProjId      string
+	ClusterName string
+	ClusterType string // EKS, DOKS, or GKE
+	EventType   string // connected, provisioned, or destroyed
+}
+
+// CreateSegmentNewClusterEvent creates a track of type "New Cluster Event", which
+// tracks whenever a cluster is newly provisioned, connected, or destroyed.
+func CreateSegmentNewClusterEvent(opts *NewClusterEventOpts) *segmentNewClusterEventTrack {
+	return &segmentNewClusterEventTrack{
+		userId:      opts.UserId,
+		projId:      opts.ProjId,
+		clusterName: opts.ClusterName,
+		clusterType: opts.ClusterType,
+		eventType:   opts.EventType,
+	}
+}
+
+func (t *segmentNewClusterEventTrack) getUserId() string {
+	return t.userId
+}
+
+func (t *segmentNewClusterEventTrack) getEvent() SegmentEvent {
+	return NewClusterEvent
+}
+
+func (t *segmentNewClusterEventTrack) getProperties() segment.Properties {
+	return segment.NewProperties().Set("Project ID", t.projId).Set("Cluster Name", t.clusterName).Set("Cluster Type", t.clusterType).Set("Event Type", t.eventType)
+}

+ 21 - 0
server/api/cluster_handler.go

@@ -2,10 +2,12 @@ package api
 
 import (
 	"encoding/json"
+	"fmt"
 	"net/http"
 	"strconv"
 
 	"github.com/go-chi/chi"
+	"github.com/porter-dev/porter/internal/analytics"
 	"github.com/porter-dev/porter/internal/forms"
 	"github.com/porter-dev/porter/internal/kubernetes"
 	"github.com/porter-dev/porter/internal/kubernetes/domain"
@@ -15,6 +17,7 @@ import (
 // HandleCreateProjectCluster creates a new cluster
 func (app *App) HandleCreateProjectCluster(w http.ResponseWriter, r *http.Request) {
 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil || projID == 0 {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -54,6 +57,15 @@ func (app *App) HandleCreateProjectCluster(w http.ResponseWriter, r *http.Reques
 	}
 
 	app.Logger.Info().Msgf("New cluster created: %d", cluster.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", projID),
+			ClusterName: cluster.Name,
+			ClusterType: "EKS",
+			EventType:   "connected",
+		},
+	))
 
 	w.WriteHeader(http.StatusCreated)
 
@@ -435,6 +447,15 @@ func (app *App) HandleResolveClusterCandidate(w http.ResponseWriter, r *http.Req
 	}
 
 	app.Logger.Info().Msgf("New cluster created: %d", cluster.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", projID),
+			ClusterName: cluster.Name,
+			ClusterType: "",
+			EventType:   "connected",
+		},
+	))
 
 	clusterExt := cluster.Externalize()
 

+ 1 - 1
server/api/dns_record_handler.go

@@ -11,7 +11,7 @@ import (
 	"github.com/porter-dev/porter/internal/kubernetes/domain"
 )
 
-// HandleCreateProjectCluster creates a new cluster
+// HandleCreateDNSRecord creates a new DNS record
 func (app *App) HandleCreateDNSRecord(w http.ResponseWriter, r *http.Request) {
 	vals, err := url.ParseQuery(r.URL.RawQuery)
 

+ 63 - 0
server/api/provision_handler.go

@@ -7,6 +7,9 @@ import (
 
 	"github.com/go-chi/chi"
 
+	"fmt"
+
+	"github.com/porter-dev/porter/internal/analytics"
 	"github.com/porter-dev/porter/internal/forms"
 	"github.com/porter-dev/porter/internal/kubernetes"
 	"github.com/porter-dev/porter/internal/kubernetes/provisioner"
@@ -302,6 +305,7 @@ func (app *App) HandleDestroyAWSECRInfra(w http.ResponseWriter, r *http.Request)
 // HandleProvisionAWSEKSInfra provisions a new aws EKS instance for a project
 func (app *App) HandleProvisionAWSEKSInfra(w http.ResponseWriter, r *http.Request) {
 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil || projID == 0 {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -374,6 +378,15 @@ func (app *App) HandleProvisionAWSEKSInfra(w http.ResponseWriter, r *http.Reques
 	}
 
 	app.Logger.Info().Msgf("New aws eks infra created: %d", infra.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", infra.ProjectID),
+			ClusterName: form.EKSName,
+			ClusterType: "EKS",
+			EventType:   "provisioned",
+		},
+	))
 
 	w.WriteHeader(http.StatusCreated)
 
@@ -389,6 +402,7 @@ func (app *App) HandleProvisionAWSEKSInfra(w http.ResponseWriter, r *http.Reques
 func (app *App) HandleDestroyAWSEKSInfra(w http.ResponseWriter, r *http.Request) {
 	// get path parameters
 	infraID, err := strconv.ParseUint(chi.URLParam(r, "infra_id"), 10, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -455,6 +469,15 @@ func (app *App) HandleDestroyAWSEKSInfra(w http.ResponseWriter, r *http.Request)
 	}
 
 	app.Logger.Info().Msgf("AWS EKS infra marked for destruction: %d", infra.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", infra.ProjectID),
+			ClusterName: form.EKSName,
+			ClusterType: "EKS",
+			EventType:   "destroyed",
+		},
+	))
 
 	w.WriteHeader(http.StatusOK)
 }
@@ -546,6 +569,7 @@ func (app *App) HandleProvisionGCPGCRInfra(w http.ResponseWriter, r *http.Reques
 // HandleProvisionGCPGKEInfra provisions a new GKE instance for a project
 func (app *App) HandleProvisionGCPGKEInfra(w http.ResponseWriter, r *http.Request) {
 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil || projID == 0 {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -617,6 +641,15 @@ func (app *App) HandleProvisionGCPGKEInfra(w http.ResponseWriter, r *http.Reques
 	}
 
 	app.Logger.Info().Msgf("New gcp gke infra created: %d", infra.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", infra.ProjectID),
+			ClusterName: form.GKEName,
+			ClusterType: "GKE",
+			EventType:   "provisioned",
+		},
+	))
 
 	w.WriteHeader(http.StatusCreated)
 
@@ -632,6 +665,7 @@ func (app *App) HandleProvisionGCPGKEInfra(w http.ResponseWriter, r *http.Reques
 func (app *App) HandleDestroyGCPGKEInfra(w http.ResponseWriter, r *http.Request) {
 	// get path parameters
 	infraID, err := strconv.ParseUint(chi.URLParam(r, "infra_id"), 10, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -697,6 +731,15 @@ func (app *App) HandleDestroyGCPGKEInfra(w http.ResponseWriter, r *http.Request)
 	}
 
 	app.Logger.Info().Msgf("GCP GKE infra marked for destruction: %d", infra.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", infra.ProjectID),
+			ClusterName: form.GKEName,
+			ClusterType: "GKE",
+			EventType:   "destroyed",
+		},
+	))
 
 	w.WriteHeader(http.StatusOK)
 }
@@ -910,6 +953,7 @@ func (app *App) HandleDestroyDODOCRInfra(w http.ResponseWriter, r *http.Request)
 // HandleProvisionDODOKSInfra provisions a new DO DOKS instance for a project
 func (app *App) HandleProvisionDODOKSInfra(w http.ResponseWriter, r *http.Request) {
 	projID, err := strconv.ParseUint(chi.URLParam(r, "project_id"), 0, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil || projID == 0 {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -983,6 +1027,15 @@ func (app *App) HandleProvisionDODOKSInfra(w http.ResponseWriter, r *http.Reques
 	}
 
 	app.Logger.Info().Msgf("New do doks infra created: %d", infra.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", infra.ProjectID),
+			ClusterName: form.DOKSName,
+			ClusterType: "DOKS",
+			EventType:   "provisioned",
+		},
+	))
 
 	w.WriteHeader(http.StatusCreated)
 
@@ -998,6 +1051,7 @@ func (app *App) HandleProvisionDODOKSInfra(w http.ResponseWriter, r *http.Reques
 func (app *App) HandleDestroyDODOKSInfra(w http.ResponseWriter, r *http.Request) {
 	// get path parameters
 	infraID, err := strconv.ParseUint(chi.URLParam(r, "infra_id"), 10, 64)
+	userID, err := app.getUserIDFromRequest(r)
 
 	if err != nil {
 		app.handleErrorFormDecoding(err, ErrProjectDecode, w)
@@ -1065,6 +1119,15 @@ func (app *App) HandleDestroyDODOKSInfra(w http.ResponseWriter, r *http.Request)
 	}
 
 	app.Logger.Info().Msgf("DO DOKS infra marked for destruction: %d", infra.ID)
+	app.analyticsClient.Track(analytics.CreateSegmentNewClusterEvent(
+		&analytics.NewClusterEventOpts{
+			UserId:      fmt.Sprintf("%d", userID),
+			ProjId:      fmt.Sprintf("%d", infra.ProjectID),
+			ClusterName: form.DOKSName,
+			ClusterType: "DOKS",
+			EventType:   "destroyed",
+		},
+	))
 
 	w.WriteHeader(http.StatusOK)
 }