better loggings for shortlinks

This commit is contained in:
Sergey Chubaryan 2024-09-03 17:42:38 +03:00
parent ceac105645
commit d8541f7386
7 changed files with 62 additions and 10 deletions

View File

@ -70,4 +70,15 @@ class BackendApi():
def health_get(self):
response = self.http.client.get("/health")
if response.status_code != 200:
raise AssertionError('something wrong')
raise AssertionError('something wrong')
def shortlink_create(self, url: string) -> string:
response = self.http.client.post("/s/new?url=" + url)
if response.status_code != 200:
raise AssertionError('can not login user')
link = response.json()['link']
if link == '':
raise AssertionError('empty user token')
return link

View File

@ -0,0 +1,13 @@
from locust import FastHttpUser, task
from api import BackendApi
class ShortlinkCreate(FastHttpUser):
api: BackendApi
@task
def user_create_test(self):
self.api.shortlink_create("https://ya.ru")
def on_start(self):
self.api = BackendApi(self)

View File

@ -114,7 +114,7 @@ func (a *App) Run(p RunParams) {
}
tracerProvider := traceSdk.NewTracerProvider(
traceSdk.WithSampler(traceSdk.AlwaysSample()),
traceSdk.WithSampler(traceSdk.TraceIDRatioBased(0.1)),
traceSdk.WithBatcher(
tracerExporter,
traceSdk.WithMaxQueueSize(8192),

View File

@ -10,6 +10,11 @@ import (
"time"
)
var (
ErrShortlinkNotexist = fmt.Errorf("shortlink does not exist or expired")
ErrShortlinkExpired = fmt.Errorf("shortlink expired")
)
type ShortlinkService interface {
CreateShortlink(ctx context.Context, url string) (string, error)
GetShortlink(ctx context.Context, id string) (string, error)
@ -66,7 +71,10 @@ func (s *shortlinkService) GetShortlink(ctx context.Context, id string) (string,
return "", err
}
if link == nil {
return "", fmt.Errorf("link does not exist or expired")
return "", ErrShortlinkNotexist
}
if time.Now().After(link.Expiration) {
return "", ErrShortlinkExpired
}
return link.Url, nil

View File

@ -2,6 +2,7 @@ package handlers
import (
"backend/src/core/services"
"backend/src/logger"
"encoding/json"
"fmt"
"net/url"
@ -13,23 +14,28 @@ type shortlinkCreateOutput struct {
Link string `json:"link"`
}
func NewShortlinkCreateHandler(shortlinkService services.ShortlinkService) gin.HandlerFunc {
func NewShortlinkCreateHandler(logger logger.Logger, shortlinkService services.ShortlinkService) gin.HandlerFunc {
return func(ctx *gin.Context) {
ctxLogger := logger.WithContext(ctx)
rawUrl := ctx.Query("url")
if rawUrl == "" {
ctx.AbortWithError(400, fmt.Errorf("no url param"))
ctxLogger.Error().Msg("url query param missing")
ctx.AbortWithError(400, fmt.Errorf("url query param missing"))
return
}
u, err := url.Parse(rawUrl)
if err != nil {
ctx.Data(500, "plain/text", []byte(err.Error()))
ctxLogger.Error().Err(err).Msg("error parsing url param")
ctx.Data(400, "plain/text", []byte(err.Error()))
return
}
u.Scheme = "https"
linkId, err := shortlinkService.CreateShortlink(ctx, u.String())
if err != nil {
ctxLogger.Error().Err(err).Msg("err creating shortlink")
ctx.Data(500, "plain/text", []byte(err.Error()))
return
}
@ -38,6 +44,7 @@ func NewShortlinkCreateHandler(shortlinkService services.ShortlinkService) gin.H
Link: "https://nucrea.ru/s/" + linkId,
})
if err != nil {
ctxLogger.Error().Err(err).Msg("err marshalling shortlink")
ctx.AbortWithError(500, err)
return
}
@ -46,12 +53,25 @@ func NewShortlinkCreateHandler(shortlinkService services.ShortlinkService) gin.H
}
}
func NewShortlinkResolveHandler(shortlinkService services.ShortlinkService) gin.HandlerFunc {
func NewShortlinkResolveHandler(logger logger.Logger, shortlinkService services.ShortlinkService) gin.HandlerFunc {
return func(ctx *gin.Context) {
ctxLogger := logger.WithContext(ctx)
linkId := ctx.Param("linkId")
linkUrl, err := shortlinkService.GetShortlink(ctx, linkId)
if err == services.ErrShortlinkNotexist {
ctxLogger.Error().Err(err).Msg("err getting shortlink")
ctx.AbortWithError(404, err)
return
}
if err == services.ErrShortlinkExpired {
ctxLogger.Error().Err(err).Msg("err getting shortlink")
ctx.AbortWithError(404, err)
return
}
if err != nil {
ctxLogger.Error().Err(err).Msg("unexpected err getting shortlink")
ctx.AbortWithError(500, err)
return
}

View File

@ -50,7 +50,7 @@ func NewUserCreateHandler(logger logger.Logger, userService services.UserService
return
}
if err != nil {
ctxLogger.Error().Err(err).Msg("create user error")
ctxLogger.Error().Err(err).Msg("unexpected create user error")
c.Data(500, "plain/text", []byte(err.Error()))
return
}

View File

@ -50,8 +50,8 @@ func New(opts NewServerOpts) *Server {
r.GET("/pooling", handlers.NewLongPoolingHandler(opts.Logger, opts.Notifier))
linkGroup := r.Group("/s")
linkGroup.POST("/new", handlers.NewShortlinkCreateHandler(opts.ShortlinkService))
linkGroup.GET("/:linkId", handlers.NewShortlinkResolveHandler(opts.ShortlinkService))
linkGroup.POST("/new", handlers.NewShortlinkCreateHandler(opts.Logger, opts.ShortlinkService))
linkGroup.GET("/:linkId", handlers.NewShortlinkResolveHandler(opts.Logger, opts.ShortlinkService))
userGroup := r.Group("/user")
userGroup.POST("/create", handlers.NewUserCreateHandler(opts.Logger, opts.UserService))