Skip to content

Commit

Permalink
Rework traces
Browse files Browse the repository at this point in the history
  • Loading branch information
cedi committed Mar 8, 2023
1 parent 7d59235 commit 6442c1d
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 84 deletions.
34 changes: 19 additions & 15 deletions pkg/controller/handle_create_shortlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,32 @@ import (
// @Tags api/v1/
// @Router /api/v1/shortlink/{shortlink} [post]
// @Security bearerAuth
func (s *ShortlinkController) HandleCreateShortLink(c *gin.Context) {
shortlinkName := c.Param("shortlink")
contentType := c.Request.Header.Get("accept")
func (s *ShortlinkController) HandleCreateShortLink(ctx *gin.Context) {
shortlinkName := ctx.Param("shortlink")
contentType := ctx.Request.Header.Get("accept")

// Call the HTML method of the Context to render a template
ctx, span := s.tracer.Start(c.Request.Context(), "ShortlinkController.HandleGetShortLink", trace.WithAttributes(attribute.String("shortlink", shortlinkName), attribute.String("accepted_content_type", contentType)))
defer span.End()
span := trace.SpanFromContext(ctx)

bearerToken := c.Request.Header.Get("Authorization")
span.SetAttributes(
attribute.String("shortlink", shortlinkName),
attribute.String("content_type", contentType),
attribute.String("referrer", ctx.Request.Referer()),
)

bearerToken := ctx.Request.Header.Get("Authorization")
bearerToken = strings.TrimPrefix(bearerToken, "Bearer")
bearerToken = strings.TrimPrefix(bearerToken, "token")
if len(bearerToken) == 0 {
err := fmt.Errorf("no credentials provided")
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

githubUser, err := getGitHubUserInfo(ctx, bearerToken)
if err != nil {
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

Expand All @@ -68,29 +72,29 @@ func (s *ShortlinkController) HandleCreateShortLink(c *gin.Context) {
Spec: v1alpha1.ShortLinkSpec{},
}

jsonData, err := io.ReadAll(c.Request.Body)
jsonData, err := io.ReadAll(ctx.Request.Body)
if err != nil {
observability.RecordError(span, s.log, err, "Failed to read request-body")
ginReturnError(c, http.StatusInternalServerError, contentType, err.Error())
ginReturnError(ctx, http.StatusInternalServerError, contentType, err.Error())
return
}

if err := json.Unmarshal([]byte(jsonData), &shortlink.Spec); err != nil {
observability.RecordError(span, s.log, err, "Failed to read spec-json")
ginReturnError(c, http.StatusInternalServerError, contentType, err.Error())
ginReturnError(ctx, http.StatusInternalServerError, contentType, err.Error())
return
}

if err := s.authenticatedClient.Create(ctx, githubUser.Login, &shortlink); err != nil {
observability.RecordError(span, s.log, err, "Failed to create ShortLink")
ginReturnError(c, http.StatusInternalServerError, contentType, err.Error())
ginReturnError(ctx, http.StatusInternalServerError, contentType, err.Error())
return
}

if contentType == ContentTypeTextPlain {
c.Data(http.StatusOK, contentType, []byte(fmt.Sprintf("%s: %s\n", shortlink.Name, shortlink.Spec.Target)))
ctx.Data(http.StatusOK, contentType, []byte(fmt.Sprintf("%s: %s\n", shortlink.Name, shortlink.Spec.Target)))
} else if contentType == ContentTypeApplicationJSON {
c.JSON(http.StatusOK, ShortLink{
ctx.JSON(http.StatusOK, ShortLink{
Name: shortlink.Name,
Spec: shortlink.Spec,
Status: shortlink.Status,
Expand Down
28 changes: 16 additions & 12 deletions pkg/controller/handle_delete_shortlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,33 @@ import (
// @Tags api/v1/
// @Router /api/v1/shortlink/{shortlink} [delete]
// @Security bearerAuth
func (s *ShortlinkController) HandleDeleteShortLink(c *gin.Context) {
shortlinkName := c.Param("shortlink")
func (s *ShortlinkController) HandleDeleteShortLink(ctx *gin.Context) {
shortlinkName := ctx.Param("shortlink")

contentType := c.Request.Header.Get("accept")
contentType := ctx.Request.Header.Get("accept")

// Call the HTML method of the Context to render a template
ctx, span := s.tracer.Start(c.Request.Context(), "ShortlinkController.HandleGetShortLink", trace.WithAttributes(attribute.String("shortlink", shortlinkName), attribute.String("accepted_content_type", contentType)))
defer span.End()
span := trace.SpanFromContext(ctx)

bearerToken := c.Request.Header.Get("Authorization")
span.SetAttributes(
attribute.String("shortlink", shortlinkName),
attribute.String("content_type", contentType),
attribute.String("referrer", ctx.Request.Referer()),
)

bearerToken := ctx.Request.Header.Get("Authorization")
bearerToken = strings.TrimPrefix(bearerToken, "Bearer")
bearerToken = strings.TrimPrefix(bearerToken, "token")
if len(bearerToken) == 0 {
err := fmt.Errorf("no credentials provided")
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

githubUser, err := getGitHubUserInfo(ctx, bearerToken)
if err != nil {
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

Expand All @@ -62,13 +66,13 @@ func (s *ShortlinkController) HandleDeleteShortLink(c *gin.Context) {
statusCode = http.StatusNotFound
}

ginReturnError(c, statusCode, contentType, err.Error())
ginReturnError(ctx, statusCode, contentType, err.Error())
return
}

// When shortlink was not found
if shortlink == nil {
ginReturnError(c, http.StatusNotFound, contentType, "Shortlink not found")
ginReturnError(ctx, http.StatusNotFound, contentType, "Shortlink not found")
return
}

Expand All @@ -81,7 +85,7 @@ func (s *ShortlinkController) HandleDeleteShortLink(c *gin.Context) {

observability.RecordError(span, s.log, err, "Failed to delete ShortLink")

ginReturnError(c, statusCode, contentType, err.Error())
ginReturnError(ctx, statusCode, contentType, err.Error())
return
}
}
27 changes: 15 additions & 12 deletions pkg/controller/handle_get_shortlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,32 @@ import (
// @Tags api/v1/
// @Router /api/v1/shortlink/{shortlink} [get]
// @Security bearerAuth
func (s *ShortlinkController) HandleGetShortLink(c *gin.Context) {
shortlinkName := c.Param("shortlink")
func (s *ShortlinkController) HandleGetShortLink(ctx *gin.Context) {
shortlinkName := ctx.Param("shortlink")
contentType := ctx.Request.Header.Get("accept")

contentType := c.Request.Header.Get("accept")
span := trace.SpanFromContext(ctx)

// Call the HTML method of the Context to render a template
ctx, span := s.tracer.Start(c.Request.Context(), "ShortlinkController.HandleGetShortLink", trace.WithAttributes(attribute.String("shortlink", shortlinkName), attribute.String("accepted_content_type", contentType)))
defer span.End()
span.SetAttributes(
attribute.String("shortlink", shortlinkName),
attribute.String("content_type", contentType),
attribute.String("referrer", ctx.Request.Referer()),
)

bearerToken := c.Request.Header.Get("Authorization")
bearerToken := ctx.Request.Header.Get("Authorization")
bearerToken = strings.TrimPrefix(bearerToken, "Bearer")
bearerToken = strings.TrimPrefix(bearerToken, "token")
if len(bearerToken) == 0 {
err := fmt.Errorf("no credentials provided")
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

githubUser, err := getGitHubUserInfo(ctx, bearerToken)
if err != nil {
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

Expand All @@ -62,14 +65,14 @@ func (s *ShortlinkController) HandleGetShortLink(c *gin.Context) {
statusCode = http.StatusNotFound
}

ginReturnError(c, statusCode, contentType, err.Error())
ginReturnError(ctx, statusCode, contentType, err.Error())
return
}

if contentType == ContentTypeTextPlain {
c.Data(http.StatusOK, contentType, []byte(shortlink.Spec.Target))
ctx.Data(http.StatusOK, contentType, []byte(shortlink.Spec.Target))
} else if contentType == ContentTypeApplicationJSON {
c.JSON(http.StatusOK, ShortLink{
ctx.JSON(http.StatusOK, ShortLink{
Name: shortlink.Name,
Spec: shortlink.Spec,
Status: shortlink.Status,
Expand Down
25 changes: 13 additions & 12 deletions pkg/controller/handle_list_shortlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,30 @@ import (
// @Tags api/v1/
// @Router /api/v1/shortlink/ [get]
// @Security bearerAuth
func (s *ShortlinkController) HandleListShortLink(c *gin.Context) {
contentType := c.Request.Header.Get("accept")
func (s *ShortlinkController) HandleListShortLink(ctx *gin.Context) {
contentType := ctx.Request.Header.Get("accept")

trace.SpanFromContext(c)
span := trace.SpanFromContext(ctx)

// Call the HTML method of the Context to render a template
ctx, span := s.tracer.Start(c.Request.Context(), "ShortlinkController.HandleListShortLink", trace.WithAttributes(attribute.String("accepted_content_type", contentType)))
defer span.End()
span.SetAttributes(
attribute.String("content_type", contentType),
attribute.String("referrer", ctx.Request.Referer()),
)

bearerToken := c.Request.Header.Get("Authorization")
bearerToken := ctx.Request.Header.Get("Authorization")
bearerToken = strings.TrimPrefix(bearerToken, "Bearer")
bearerToken = strings.TrimPrefix(bearerToken, "token")
if len(bearerToken) == 0 {
err := fmt.Errorf("no credentials provided")
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

githubUser, err := getGitHubUserInfo(ctx, bearerToken)
if err != nil {
span.RecordError(err)
ginReturnError(c, http.StatusUnauthorized, contentType, err.Error())
ginReturnError(ctx, http.StatusUnauthorized, contentType, err.Error())
return
}

Expand All @@ -61,7 +62,7 @@ func (s *ShortlinkController) HandleListShortLink(c *gin.Context) {
statusCode = http.StatusNotFound
}

ginReturnError(c, statusCode, contentType, err.Error())
ginReturnError(ctx, statusCode, contentType, err.Error())
return
}

Expand All @@ -76,12 +77,12 @@ func (s *ShortlinkController) HandleListShortLink(c *gin.Context) {
}

if contentType == ContentTypeApplicationJSON {
c.JSON(http.StatusOK, targetList)
ctx.JSON(http.StatusOK, targetList)
} else if contentType == ContentTypeTextPlain {
shortLinks := ""
for _, shortlink := range targetList {
shortLinks += fmt.Sprintf("%s: %s\n", shortlink.Name, shortlink.Spec.Target)
}
c.Data(http.StatusOK, contentType, []byte(shortLinks))
ctx.Data(http.StatusOK, contentType, []byte(shortLinks))
}
}
32 changes: 15 additions & 17 deletions pkg/controller/handle_shortlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,30 @@ import (
// @Failure 500 {object} int "InternalServerError"
// @Tags default
// @Router /{shortlink} [get]
func (s *ShortlinkController) HandleShortLink(c *gin.Context) {
shortlinkName := c.Param("shortlink")
func (s *ShortlinkController) HandleShortLink(ctx *gin.Context) {
shortlinkName := ctx.Param("shortlink")

// Call the HTML method of the Context to render a template
ctx, span := s.tracer.Start(c.Request.Context(), "ShortlinkController.HandleShortLink", trace.WithAttributes(attribute.String("shortlink", shortlinkName)))
defer span.End()
span := trace.SpanFromContext(ctx)

span.SetAttributes(
attribute.String("shortlink", shortlinkName),
attribute.String("referrer", ctx.Request.Referer()),
)

span.AddEvent("shortlink", trace.WithAttributes(attribute.String("shortlink", shortlinkName)))

c.Header("Cache-Control", "public, max-age=900, stale-if-error=3600") // max-age = 15min; stale-if-error = 1h
ctx.Header("Cache-Control", "public, max-age=900, stale-if-error=3600") // max-age = 15min; stale-if-error = 1h

shortlink, err := s.client.Get(ctx, shortlinkName)
if err != nil {
if strings.Contains(err.Error(), "not found") {
observability.RecordError(span, s.log, err, "Path not found")
span.SetAttributes(attribute.String("path", c.Request.URL.Path))
span.SetAttributes(attribute.String("path", ctx.Request.URL.Path))

c.HTML(http.StatusNotFound, "404.html", gin.H{})
ctx.HTML(http.StatusNotFound, "404.html", gin.H{})
} else {
observability.RecordError(span, s.log, err, "Failed to get ShortLink")
c.HTML(http.StatusInternalServerError, "500.html", gin.H{})
ctx.HTML(http.StatusInternalServerError, "500.html", gin.H{})
}
return
}
Expand All @@ -75,19 +78,14 @@ func (s *ShortlinkController) HandleShortLink(c *gin.Context) {

if shortlink.Spec.Code != 200 {
// Redirect
c.Redirect(shortlink.Spec.Code, target)
ctx.Redirect(shortlink.Spec.Code, target)
} else {
// Redirect via JS/HTML
c.HTML(
// Set the HTTP status to 200 (OK)
ctx.HTML(
http.StatusOK,

// Use the index.html template
"redirect.html",

// Pass the data that the page uses (in this case, 'title')
gin.H{
"redirectFrom": c.Request.URL.Path,
"redirectFrom": ctx.Request.URL.Path,
"redirectTo": target,
"redirectAfter": shortlink.Spec.RedirectAfter,
},
Expand Down
Loading

0 comments on commit 6442c1d

Please sign in to comment.