better loggings for shortlinks
This commit is contained in:
parent
ceac105645
commit
d8541f7386
@ -70,4 +70,15 @@ class BackendApi():
|
|||||||
def health_get(self):
|
def health_get(self):
|
||||||
response = self.http.client.get("/health")
|
response = self.http.client.get("/health")
|
||||||
if response.status_code != 200:
|
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
|
||||||
13
load_tests/tests/shortlink.py
Normal file
13
load_tests/tests/shortlink.py
Normal 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)
|
||||||
@ -114,7 +114,7 @@ func (a *App) Run(p RunParams) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tracerProvider := traceSdk.NewTracerProvider(
|
tracerProvider := traceSdk.NewTracerProvider(
|
||||||
traceSdk.WithSampler(traceSdk.AlwaysSample()),
|
traceSdk.WithSampler(traceSdk.TraceIDRatioBased(0.1)),
|
||||||
traceSdk.WithBatcher(
|
traceSdk.WithBatcher(
|
||||||
tracerExporter,
|
tracerExporter,
|
||||||
traceSdk.WithMaxQueueSize(8192),
|
traceSdk.WithMaxQueueSize(8192),
|
||||||
|
|||||||
@ -10,6 +10,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrShortlinkNotexist = fmt.Errorf("shortlink does not exist or expired")
|
||||||
|
ErrShortlinkExpired = fmt.Errorf("shortlink expired")
|
||||||
|
)
|
||||||
|
|
||||||
type ShortlinkService interface {
|
type ShortlinkService interface {
|
||||||
CreateShortlink(ctx context.Context, url string) (string, error)
|
CreateShortlink(ctx context.Context, url string) (string, error)
|
||||||
GetShortlink(ctx context.Context, id 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
|
return "", err
|
||||||
}
|
}
|
||||||
if link == nil {
|
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
|
return link.Url, nil
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"backend/src/core/services"
|
"backend/src/core/services"
|
||||||
|
"backend/src/logger"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -13,23 +14,28 @@ type shortlinkCreateOutput struct {
|
|||||||
Link string `json:"link"`
|
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) {
|
return func(ctx *gin.Context) {
|
||||||
|
ctxLogger := logger.WithContext(ctx)
|
||||||
|
|
||||||
rawUrl := ctx.Query("url")
|
rawUrl := ctx.Query("url")
|
||||||
if rawUrl == "" {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := url.Parse(rawUrl)
|
u, err := url.Parse(rawUrl)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
u.Scheme = "https"
|
u.Scheme = "https"
|
||||||
|
|
||||||
linkId, err := shortlinkService.CreateShortlink(ctx, u.String())
|
linkId, err := shortlinkService.CreateShortlink(ctx, u.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
ctxLogger.Error().Err(err).Msg("err creating shortlink")
|
||||||
ctx.Data(500, "plain/text", []byte(err.Error()))
|
ctx.Data(500, "plain/text", []byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -38,6 +44,7 @@ func NewShortlinkCreateHandler(shortlinkService services.ShortlinkService) gin.H
|
|||||||
Link: "https://nucrea.ru/s/" + linkId,
|
Link: "https://nucrea.ru/s/" + linkId,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
ctxLogger.Error().Err(err).Msg("err marshalling shortlink")
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
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) {
|
return func(ctx *gin.Context) {
|
||||||
|
ctxLogger := logger.WithContext(ctx)
|
||||||
|
|
||||||
linkId := ctx.Param("linkId")
|
linkId := ctx.Param("linkId")
|
||||||
|
|
||||||
linkUrl, err := shortlinkService.GetShortlink(ctx, 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 {
|
if err != nil {
|
||||||
|
ctxLogger.Error().Err(err).Msg("unexpected err getting shortlink")
|
||||||
ctx.AbortWithError(500, err)
|
ctx.AbortWithError(500, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ func NewUserCreateHandler(logger logger.Logger, userService services.UserService
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil {
|
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()))
|
c.Data(500, "plain/text", []byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,8 +50,8 @@ func New(opts NewServerOpts) *Server {
|
|||||||
r.GET("/pooling", handlers.NewLongPoolingHandler(opts.Logger, opts.Notifier))
|
r.GET("/pooling", handlers.NewLongPoolingHandler(opts.Logger, opts.Notifier))
|
||||||
|
|
||||||
linkGroup := r.Group("/s")
|
linkGroup := r.Group("/s")
|
||||||
linkGroup.POST("/new", handlers.NewShortlinkCreateHandler(opts.ShortlinkService))
|
linkGroup.POST("/new", handlers.NewShortlinkCreateHandler(opts.Logger, opts.ShortlinkService))
|
||||||
linkGroup.GET("/:linkId", handlers.NewShortlinkResolveHandler(opts.ShortlinkService))
|
linkGroup.GET("/:linkId", handlers.NewShortlinkResolveHandler(opts.Logger, opts.ShortlinkService))
|
||||||
|
|
||||||
userGroup := r.Group("/user")
|
userGroup := r.Group("/user")
|
||||||
userGroup.POST("/create", handlers.NewUserCreateHandler(opts.Logger, opts.UserService))
|
userGroup.POST("/create", handlers.NewUserCreateHandler(opts.Logger, opts.UserService))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user