feat: tracing

This commit is contained in:
Dawid Wysokiński 2022-09-10 13:28:27 +02:00
parent 8135a8dcb4
commit e6a2b3bed5
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
3 changed files with 136 additions and 4 deletions

View File

@ -6,6 +6,9 @@ import (
"fmt"
"time"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
)
@ -40,8 +43,15 @@ func NewEnnoblement(repo EnnoblementRepository, client EnnoblementsGetter) *Enno
}
func (e *Ennoblement) Refresh(ctx context.Context, key, url string) error {
ctx, span := tracer.Start(ctx, "Ennoblement.Refresh", trace.WithAttributes(
attribute.String("server.key", key),
attribute.String("server.url", url),
))
defer span.End()
latestEnnoblement, err := e.getLatestEnnoblement(ctx, key)
if err != nil && !errors.Is(err, errEnnoblementNotFound) {
span.RecordError(err)
return fmt.Errorf("EnnoblementService.getLatestEnnoblements: %w", err)
}
@ -50,8 +60,11 @@ func (e *Ennoblement) Refresh(ctx context.Context, key, url string) error {
since = latestEnnoblement.CreatedAt
}
span.SetAttributes(attribute.Int64("since", since.Unix()))
ennoblements, err := e.client.GetEnnoblements(ctx, url, since)
if err != nil {
span.RecordError(err)
return fmt.Errorf("TWClient.GetEnnoblements: %w", err)
}
@ -71,6 +84,7 @@ func (e *Ennoblement) Refresh(ctx context.Context, key, url string) error {
})
}
if err := e.repo.Create(ctx, params...); err != nil {
span.RecordError(err)
return fmt.Errorf("EnnoblementRepository.Create: %w", err)
}
}
@ -79,6 +93,9 @@ func (e *Ennoblement) Refresh(ctx context.Context, key, url string) error {
}
func (e *Ennoblement) List(ctx context.Context, params domain.ListEnnoblementsParams) ([]domain.Ennoblement, int64, error) {
ctx, span := tracer.Start(ctx, "Ennoblement.List")
defer span.End()
if len(params.Sort) == 0 {
params.Sort = []domain.EnnoblementSort{
{
@ -89,12 +106,14 @@ func (e *Ennoblement) List(ctx context.Context, params domain.ListEnnoblementsPa
}
if len(params.Sort) > ennoblementSortMaxLen {
return nil, 0, domain.ValidationError{
err := domain.ValidationError{
Field: "sort",
Err: domain.MaxLengthError{
Max: ennoblementSortMaxLen,
},
}
span.RecordError(err)
return nil, 0, err
}
if params.Pagination.Limit == 0 {
@ -102,11 +121,13 @@ func (e *Ennoblement) List(ctx context.Context, params domain.ListEnnoblementsPa
}
if err := validatePagination(params.Pagination, ennoblementMaxLimit); err != nil {
span.RecordError(err)
return nil, 0, fmt.Errorf("validatePagination: %w", err)
}
ennoblements, count, err := e.repo.List(ctx, params)
if err != nil {
span.RecordError(err)
return nil, 0, fmt.Errorf("EnnoblementRepository.List: %w", err)
}
@ -114,6 +135,11 @@ func (e *Ennoblement) List(ctx context.Context, params domain.ListEnnoblementsPa
}
func (e *Ennoblement) getLatestEnnoblement(ctx context.Context, key string) (domain.Ennoblement, error) {
ctx, span := tracer.Start(ctx, "Ennoblement.getLatestEnnoblement", trace.WithAttributes(
attribute.String("server.key", key),
))
defer span.End()
ennoblements, _, err := e.repo.List(ctx, domain.ListEnnoblementsParams{
ServerKeys: []string{key},
Pagination: domain.Pagination{
@ -125,10 +151,13 @@ func (e *Ennoblement) getLatestEnnoblement(ctx context.Context, key string) (dom
Count: false,
})
if err != nil {
span.RecordError(err)
return domain.Ennoblement{}, fmt.Errorf("EnnoblementRepository.List: %w", err)
}
if len(ennoblements) == 0 {
span.RecordError(errEnnoblementNotFound)
return domain.Ennoblement{}, errEnnoblementNotFound
}
return ennoblements[0], nil
}

View File

@ -6,6 +6,8 @@ import (
"sort"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
const (
@ -36,16 +38,25 @@ func NewPlayer(repo PlayerRepository, client PlayersGetter) *Player {
}
func (p *Player) Refresh(ctx context.Context, key, url string) (int64, error) {
ctx, span := tracer.Start(ctx, "Player.Refresh", trace.WithAttributes(
attribute.String("server.key", key),
attribute.String("server.url", url),
))
defer span.End()
players, err := p.client.GetPlayers(ctx, url)
if err != nil {
span.RecordError(err)
return 0, fmt.Errorf("TWClient.GetPlayers: %w", err)
}
if err := p.createOrUpdate(ctx, key, players); err != nil {
span.RecordError(err)
return 0, err
}
if err := p.delete(ctx, key, players); err != nil {
span.RecordError(err)
return 0, err
}
@ -53,6 +64,11 @@ func (p *Player) Refresh(ctx context.Context, key, url string) (int64, error) {
}
func (p *Player) createOrUpdate(ctx context.Context, key string, players []domain.BasePlayer) error {
ctx, span := tracer.Start(ctx, "Player.createOrUpdate", trace.WithAttributes(
attribute.String("server.key", key),
))
defer span.End()
for i := 0; i < len(players); i += playerChunkSize {
end := i + playerChunkSize
if end > len(players) {
@ -69,6 +85,7 @@ func (p *Player) createOrUpdate(ctx context.Context, key string, players []domai
})
}
if err := p.repo.CreateOrUpdate(ctx, params...); err != nil {
span.RecordError(err)
return fmt.Errorf("PlayerRepository.CreateOrUpdate: %w", err)
}
}
@ -77,6 +94,11 @@ func (p *Player) createOrUpdate(ctx context.Context, key string, players []domai
}
func (p *Player) delete(ctx context.Context, key string, existing []domain.BasePlayer) error {
ctx, span := tracer.Start(ctx, "Player.delete", trace.WithAttributes(
attribute.String("server.key", key),
))
defer span.End()
//nolint:prealloc
var playersToDelete []int64
var lastID int64
@ -99,6 +121,7 @@ func (p *Player) delete(ctx context.Context, key string, existing []domain.BaseP
},
})
if err != nil {
span.RecordError(err)
return fmt.Errorf("PlayerRepository.List: %w", err)
}
@ -120,6 +143,7 @@ func (p *Player) delete(ctx context.Context, key string, existing []domain.BaseP
}
if err := p.repo.DeleteByID(ctx, playersToDelete...); err != nil {
span.RecordError(err)
return fmt.Errorf("PlayerRepository.DeleteByID: %w", err)
}
@ -127,6 +151,9 @@ func (p *Player) delete(ctx context.Context, key string, existing []domain.BaseP
}
func (p *Player) List(ctx context.Context, params domain.ListPlayersParams) ([]domain.Player, int64, error) {
ctx, span := tracer.Start(ctx, "Player.List")
defer span.End()
if len(params.Sort) == 0 {
params.Sort = []domain.PlayerSort{
{
@ -137,12 +164,14 @@ func (p *Player) List(ctx context.Context, params domain.ListPlayersParams) ([]d
}
if len(params.Sort) > playerSortMaxLen {
return nil, 0, domain.ValidationError{
err := domain.ValidationError{
Field: "sort",
Err: domain.MaxLengthError{
Max: playerSortMaxLen,
},
}
span.RecordError(err)
return nil, 0, err
}
if params.Pagination.Limit == 0 {
@ -150,11 +179,13 @@ func (p *Player) List(ctx context.Context, params domain.ListPlayersParams) ([]d
}
if err := validatePagination(params.Pagination, playerMaxLimit); err != nil {
span.RecordError(err)
return nil, 0, fmt.Errorf("validatePagination: %w", err)
}
players, count, err := p.repo.List(ctx, params)
if err != nil {
span.RecordError(err)
return nil, 0, fmt.Errorf("PlayerRepository.List: %w", err)
}
@ -162,6 +193,12 @@ func (p *Player) List(ctx context.Context, params domain.ListPlayersParams) ([]d
}
func (p *Player) GetByServerKeyAndID(ctx context.Context, serverKey string, id int64, includeTribe bool) (domain.Player, error) {
ctx, span := tracer.Start(ctx, "Player.GetByServerKeyAndID", trace.WithAttributes(
attribute.String("server.key", serverKey),
attribute.Int64("player.id", id),
))
defer span.End()
players, _, err := p.repo.List(ctx, domain.ListPlayersParams{
IDs: []int64{id},
ServerKeys: []string{serverKey},
@ -171,12 +208,16 @@ func (p *Player) GetByServerKeyAndID(ctx context.Context, serverKey string, id i
},
})
if err != nil {
span.RecordError(err)
return domain.Player{}, fmt.Errorf("PlayerRepository.List: %w", err)
}
if len(players) == 0 {
return domain.Player{}, domain.PlayerNotFoundError{
err = domain.PlayerNotFoundError{
ID: id,
}
span.RecordError(err)
return domain.Player{}, err
}
return players[0], nil
}

View File

@ -6,6 +6,8 @@ import (
"time"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
const (
@ -37,8 +39,15 @@ func NewServer(repo ServerRepository, client OpenServersConfigsGetter) *Server {
}
func (s *Server) Refresh(ctx context.Context, host, versionCode string) ([]domain.Server, error) {
ctx, span := tracer.Start(ctx, "Server.Refresh", trace.WithAttributes(
attribute.String("version.code", versionCode),
attribute.String("version.host", host),
))
defer span.End()
openServers, err := s.client.GetOpenServers(ctx, host)
if err != nil {
span.RecordError(err)
return nil, fmt.Errorf("TWClient.GetOpenServers: %w", err)
}
@ -48,6 +57,7 @@ func (s *Server) Refresh(ctx context.Context, host, versionCode string) ([]domai
Count: false,
})
if err != nil {
span.RecordError(err)
return nil, fmt.Errorf("ServerRepository.List: %w", err)
}
@ -57,6 +67,7 @@ func (s *Server) Refresh(ctx context.Context, host, versionCode string) ([]domai
Count: false,
})
if err != nil {
span.RecordError(err)
return nil, fmt.Errorf("ServerRepository.List: %w", err)
}
@ -88,24 +99,35 @@ func (s *Server) Refresh(ctx context.Context, host, versionCode string) ([]domai
upsertedServers, err := s.repo.CreateOrUpdate(ctx, params...)
if err != nil {
span.RecordError(err)
return nil, fmt.Errorf("ServerRepository.CreateOrUpdate: %w", err)
}
return upsertedServers, nil
}
func (s *Server) UpdateInfoAndConfig(ctx context.Context, key, url string) error {
ctx, span := tracer.Start(ctx, "Server.UpdateInfoAndConfig", trace.WithAttributes(
attribute.String("server.key", key),
attribute.String("server.url", url),
))
defer span.End()
cfg, err := s.client.GetServerConfig(ctx, url)
if err != nil {
span.RecordError(err)
return fmt.Errorf("TWClient.GetServerConfig: %w", err)
}
buildingInfo, err := s.client.GetBuildingInfo(ctx, url)
if err != nil {
span.RecordError(err)
return fmt.Errorf("TWClient.GetBuildingInfo: %w", err)
}
unitInfo, err := s.client.GetUnitInfo(ctx, url)
if err != nil {
span.RecordError(err)
return fmt.Errorf("TWClient.GetUnitInfo: %w", err)
}
@ -124,6 +146,7 @@ func (s *Server) UpdateInfoAndConfig(ctx context.Context, key, url string) error
},
})
if err != nil {
span.RecordError(err)
return fmt.Errorf("ServerRepository.UpdateByKey: %w", err)
}
@ -131,6 +154,12 @@ func (s *Server) UpdateInfoAndConfig(ctx context.Context, key, url string) error
}
func (s *Server) UpdateNumPlayers(ctx context.Context, key string, numPlayers int64) error {
ctx, span := tracer.Start(ctx, "Server.UpdateNumPlayers", trace.WithAttributes(
attribute.String("server.key", key),
attribute.Int64("num_players", numPlayers),
))
defer span.End()
_, err := s.repo.UpdateByKey(ctx, key, domain.UpdateServerParams{
NumPlayers: domain.NullInt64{
Valid: true,
@ -139,12 +168,20 @@ func (s *Server) UpdateNumPlayers(ctx context.Context, key string, numPlayers in
PlayerDataUpdatedAt: time.Now(),
})
if err != nil {
span.RecordError(err)
return fmt.Errorf("ServerRepository.UpdateByKey: %w", err)
}
return nil
}
func (s *Server) UpdateNumTribes(ctx context.Context, key string, numTribes int64) error {
ctx, span := tracer.Start(ctx, "Server.UpdateNumTribes", trace.WithAttributes(
attribute.String("server.key", key),
attribute.Int64("num_tribes", numTribes),
))
defer span.End()
_, err := s.repo.UpdateByKey(ctx, key, domain.UpdateServerParams{
NumTribes: domain.NullInt64{
Valid: true,
@ -153,12 +190,20 @@ func (s *Server) UpdateNumTribes(ctx context.Context, key string, numTribes int6
TribeDataUpdatedAt: time.Now(),
})
if err != nil {
span.RecordError(err)
return fmt.Errorf("ServerRepository.UpdateByKey: %w", err)
}
return nil
}
func (s *Server) UpdateNumVillages(ctx context.Context, key string, numVillages int64) error {
ctx, span := tracer.Start(ctx, "Server.UpdateNumVillages", trace.WithAttributes(
attribute.String("server.key", key),
attribute.Int64("num_villages", numVillages),
))
defer span.End()
_, err := s.repo.UpdateByKey(ctx, key, domain.UpdateServerParams{
NumVillages: domain.NullInt64{
Valid: true,
@ -167,22 +212,29 @@ func (s *Server) UpdateNumVillages(ctx context.Context, key string, numVillages
VillageDataUpdatedAt: time.Now(),
})
if err != nil {
span.RecordError(err)
return fmt.Errorf("ServerRepository.UpdateByKey: %w", err)
}
return nil
}
func (s *Server) List(ctx context.Context, params domain.ListServersParams) ([]domain.Server, int64, error) {
ctx, span := tracer.Start(ctx, "Server.List")
defer span.End()
if params.Pagination.Limit == 0 {
params.Pagination.Limit = serverMaxLimit
}
if err := validatePagination(params.Pagination, serverMaxLimit); err != nil {
span.RecordError(err)
return nil, 0, fmt.Errorf("validatePagination: %w", err)
}
servers, count, err := s.repo.List(ctx, params)
if err != nil {
span.RecordError(err)
return nil, 0, fmt.Errorf("ServerRepository.List: %w", err)
}
@ -190,6 +242,12 @@ func (s *Server) List(ctx context.Context, params domain.ListServersParams) ([]d
}
func (s *Server) GetNormalByVersionCodeAndKey(ctx context.Context, versionCode, key string) (domain.Server, error) {
ctx, span := tracer.Start(ctx, "Server.GetNormalByVersionCodeAndKey", trace.WithAttributes(
attribute.String("version.code", versionCode),
attribute.String("server.key", key),
))
defer span.End()
servers, _, err := s.repo.List(ctx, domain.ListServersParams{
Special: domain.NullBool{
Bool: false,
@ -202,13 +260,17 @@ func (s *Server) GetNormalByVersionCodeAndKey(ctx context.Context, versionCode,
},
})
if err != nil {
span.RecordError(err)
return domain.Server{}, fmt.Errorf("ServerRepository.List: %w", err)
}
if len(servers) == 0 {
return domain.Server{}, domain.ServerNotFoundError{
err = domain.ServerNotFoundError{
Key: key,
}
span.RecordError(err)
return domain.Server{}, err
}
return servers[0], nil
}