Explorar o código

add telemetry to slack integration (#4200)

d-g-town %!s(int64=2) %!d(string=hai) anos
pai
achega
bda6689b30

+ 12 - 6
api/server/handlers/handler.go

@@ -1,9 +1,12 @@
 package handlers
 
 import (
+	"context"
 	"fmt"
 	"net/http"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
@@ -18,6 +21,7 @@ type PorterHandler interface {
 	HandleAPIError(w http.ResponseWriter, r *http.Request, err apierrors.RequestError)
 	HandleAPIErrorNoWrite(w http.ResponseWriter, r *http.Request, err apierrors.RequestError)
 	PopulateOAuthSession(
+		ctx context.Context,
 		w http.ResponseWriter,
 		r *http.Request,
 		state string,
@@ -89,6 +93,7 @@ func IgnoreAPIError(w http.ResponseWriter, r *http.Request, err apierrors.Reques
 }
 
 func (d *DefaultPorterHandler) PopulateOAuthSession(
+	ctx context.Context,
 	w http.ResponseWriter,
 	r *http.Request,
 	state string,
@@ -96,9 +101,12 @@ func (d *DefaultPorterHandler) PopulateOAuthSession(
 	integrationClient types.OAuthIntegrationClient,
 	integrationID uint,
 ) error {
+	ctx, span := telemetry.NewSpan(ctx, "handler-populate-oauth-session")
+	defer span.End()
+
 	session, err := d.Config().Store.Get(r, d.Config().ServerConf.CookieName)
 	if err != nil {
-		return err
+		return telemetry.Error(ctx, span, err, "could not get session")
 	}
 
 	// need state parameter to validate when redirected
@@ -111,9 +119,8 @@ func (d *DefaultPorterHandler) PopulateOAuthSession(
 
 	if isProject {
 		project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
-
 		if project == nil {
-			return fmt.Errorf("could not read project")
+			return telemetry.Error(ctx, span, nil, "could not read project")
 		}
 
 		session.Values["project_id"] = project.ID
@@ -121,9 +128,8 @@ func (d *DefaultPorterHandler) PopulateOAuthSession(
 
 	if isUser {
 		user, _ := r.Context().Value(types.UserScope).(*models.User)
-
 		if user == nil {
-			return fmt.Errorf("could not read user")
+			return telemetry.Error(ctx, span, nil, "could not read user")
 		}
 
 		session.Values["user_id"] = user.ID
@@ -135,7 +141,7 @@ func (d *DefaultPorterHandler) PopulateOAuthSession(
 	}
 
 	if err := session.Save(r, w); err != nil {
-		return err
+		return telemetry.Error(ctx, span, err, "could not save session")
 	}
 
 	return nil

+ 19 - 6
api/server/handlers/oauth_callback/slack.go

@@ -6,6 +6,8 @@ import (
 	"net/http"
 	"net/url"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
@@ -28,31 +30,41 @@ func NewOAuthCallbackSlackHandler(
 }
 
 func (p *OAuthCallbackSlackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-oauth-callback-slack")
+	defer span.End()
+
+	r = r.Clone(ctx)
+
 	session, err := p.Config().Store.Get(r, p.Config().ServerConf.CookieName)
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "session could not be retrieved")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
 	if _, ok := session.Values["state"]; !ok {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, nil, "state not found in session")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
 	if r.URL.Query().Get("state") != session.Values["state"] {
-		p.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		err = telemetry.Error(ctx, span, nil, "state does not match")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
 	token, err := p.Config().SlackConf.Exchange(context.TODO(), r.URL.Query().Get("code"))
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "exchange failed")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
 	slackInt, err := slack.TokenToSlackIntegration(token)
 	if err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "token to slack integration failed")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 
@@ -63,7 +75,8 @@ func (p *OAuthCallbackSlackHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
 	slackInt.ProjectID = projID
 
 	if _, err = p.Repo().SlackIntegration().CreateSlackIntegration(slackInt); err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+		err = telemetry.Error(ctx, span, err, "create slack integration failed")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 

+ 8 - 1
api/server/handlers/project_oauth/digitalocean.go

@@ -3,6 +3,8 @@ package project_oauth
 import (
 	"net/http"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"golang.org/x/oauth2"
 
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -27,9 +29,14 @@ func NewProjectOAuthDOHandler(
 }
 
 func (p *ProjectOAuthDOHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-project-oauth-digital-ocean")
+	defer span.End()
+
+	r = r.Clone(ctx)
+
 	state := oauth.CreateRandomState()
 
-	if err := p.PopulateOAuthSession(w, r, state, true, false, "", 0); err != nil {
+	if err := p.PopulateOAuthSession(ctx, w, r, state, true, false, "", 0); err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}

+ 8 - 1
api/server/handlers/project_oauth/gitlab.go

@@ -5,6 +5,8 @@ import (
 	"net/http"
 	"strconv"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"github.com/porter-dev/porter/api/server/handlers"
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
@@ -32,6 +34,11 @@ func NewProjectOAuthGitlabHandler(
 }
 
 func (p *ProjectOAuthGitlabHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-project-gitlab")
+	defer span.End()
+
+	r = r.Clone(ctx)
+
 	proj, _ := r.Context().Value(types.ProjectScope).(*models.Project)
 
 	integrationIDStr := r.URL.Query().Get("integration_id")
@@ -62,7 +69,7 @@ func (p *ProjectOAuthGitlabHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
 
 	state := oauth.CreateRandomState()
 
-	if err := p.PopulateOAuthSession(w, r, state, true, true, types.OAuthGitlab, uint(integrationID)); err != nil {
+	if err := p.PopulateOAuthSession(ctx, w, r, state, true, true, types.OAuthGitlab, uint(integrationID)); err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}

+ 10 - 2
api/server/handlers/project_oauth/slack.go

@@ -3,6 +3,8 @@ package project_oauth
 import (
 	"net/http"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"golang.org/x/oauth2"
 
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -27,10 +29,16 @@ func NewProjectOAuthSlackHandler(
 }
 
 func (p *ProjectOAuthSlackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-project-oauth-slack")
+	defer span.End()
+
+	r = r.Clone(ctx)
+
 	state := oauth.CreateRandomState()
 
-	if err := p.PopulateOAuthSession(w, r, state, true, false, "", 0); err != nil {
-		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
+	if err := p.PopulateOAuthSession(ctx, w, r, state, true, false, "", 0); err != nil {
+		err = telemetry.Error(ctx, span, err, "population oauth session failed")
+		p.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
 		return
 	}
 

+ 8 - 1
api/server/handlers/user/github_start.go

@@ -3,6 +3,8 @@ package user
 import (
 	"net/http"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"golang.org/x/oauth2"
 
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -27,9 +29,14 @@ func NewUserOAuthGithubHandler(
 }
 
 func (p *UserOAuthGithubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-project-oauth-github")
+	defer span.End()
+
+	r = r.Clone(ctx)
+
 	state := oauth.CreateRandomState()
 
-	if err := p.PopulateOAuthSession(w, r, state, false, false, "", 0); err != nil {
+	if err := p.PopulateOAuthSession(ctx, w, r, state, false, false, "", 0); err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}

+ 8 - 1
api/server/handlers/user/google_start.go

@@ -3,6 +3,8 @@ package user
 import (
 	"net/http"
 
+	"github.com/porter-dev/porter/internal/telemetry"
+
 	"golang.org/x/oauth2"
 
 	"github.com/porter-dev/porter/api/server/handlers"
@@ -27,9 +29,14 @@ func NewUserOAuthGoogleHandler(
 }
 
 func (p *UserOAuthGoogleHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	ctx, span := telemetry.NewSpan(r.Context(), "serve-project-oauth-google")
+	defer span.End()
+
+	r = r.Clone(ctx)
+
 	state := oauth.CreateRandomState()
 
-	if err := p.PopulateOAuthSession(w, r, state, false, false, "", 0); err != nil {
+	if err := p.PopulateOAuthSession(ctx, w, r, state, false, false, "", 0); err != nil {
 		p.HandleAPIError(w, r, apierrors.NewErrInternal(err))
 		return
 	}

+ 2 - 0
api/server/router/middleware/panic.go

@@ -3,6 +3,7 @@ package middleware
 import (
 	"fmt"
 	"net/http"
+	"runtime/debug"
 
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
@@ -21,6 +22,7 @@ func (pmw *PanicMiddleware) Middleware(next http.Handler) http.Handler {
 		defer func() {
 			err := recover()
 			if err != nil {
+				pmw.config.Logger.Error().Msg(string(debug.Stack()))
 				apierrors.HandleAPIError(pmw.config.Logger, pmw.config.Alerter, w, r, apierrors.NewErrInternal(fmt.Errorf("%v", err)), true)
 			}
 		}()

+ 1 - 1
api/server/shared/config/loader/loader.go

@@ -262,8 +262,8 @@ func (e *EnvConfigLoader) LoadConfig() (res *config.Config, err error) {
 			},
 			BaseURL: sc.ServerURL,
 		})
+		res.Logger.Info().Msg("Created Slack client")
 	}
-	res.Logger.Info().Msg("Created Slack client")
 
 	res.WSUpgrader = &websocket.Upgrader{
 		WSUpgrader: &gorillaws.Upgrader{