Refactor logging

This commit is contained in:
Alexander
2026-05-07 16:50:40 +02:00
parent fb2e4b9107
commit 3d111f9008
14 changed files with 683 additions and 58 deletions
+68 -18
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"github.com/rs/zerolog"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -22,13 +23,16 @@ func NewMetadataServer(services map[metadatav1.Provider]*service.MetadataService
return &MetadataServer{services: services}
}
func (s *MetadataServer) getService(p metadatav1.Provider) (*service.MetadataService, error) {
func (s *MetadataServer) getService(ctx context.Context, p metadatav1.Provider) (*service.MetadataService, error) {
if p == metadatav1.Provider_PROVIDER_UNSPECIFIED {
p = metadatav1.Provider_PROVIDER_MUSICBRAINZ
}
zerolog.Ctx(ctx).Debug().Str("provider", p.String()).Msg("resolved provider")
svc, ok := s.services[p]
if !ok {
zerolog.Ctx(ctx).Warn().Str("provider", p.String()).Msg("unknown provider requested")
return nil, status.Errorf(codes.InvalidArgument, "unknown provider: %v", p)
}
@@ -36,7 +40,9 @@ func (s *MetadataServer) getService(p metadatav1.Provider) (*service.MetadataSer
}
func (s *MetadataServer) GetArtist(ctx context.Context, req *metadatav1.GetArtistRequest) (*metadatav1.Artist, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
@@ -45,22 +51,28 @@ func (s *MetadataServer) GetArtist(ctx context.Context, req *metadatav1.GetArtis
switch v := req.Identifier.(type) {
case *metadatav1.GetArtistRequest_Id:
id = v.Id
log.Debug().Str("lookup", "id").Str("artist_id", id).Msg("getting artist")
case *metadatav1.GetArtistRequest_External:
id = v.External.SourceId
log.Debug().Str("lookup", "external").Str("source_id", id).Str("source", v.External.Source).Msg("getting artist")
default:
log.Warn().Msg("get artist called without identifier")
return nil, status.Error(codes.InvalidArgument, "identifier required")
}
artist, err := svc.GetArtist(ctx, id)
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
log.Trace().Str("artist_id", artist.ID).Str("name", artist.Name).Msg("artist found")
return toProtoArtist(artist), nil
}
func (s *MetadataServer) SearchArtists(ctx context.Context, req *metadatav1.SearchArtistsRequest) (*metadatav1.SearchArtistsResponse, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
@@ -70,9 +82,11 @@ func (s *MetadataServer) SearchArtists(ctx context.Context, req *metadatav1.Sear
limit = 25
}
log.Debug().Str("query", req.Query).Int("limit", limit).Int("offset", int(req.Offset)).Msg("searching artists")
result, err := svc.SearchArtists(ctx, req.Query, limit, int(req.Offset))
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
resp := &metadatav1.SearchArtistsResponse{
@@ -83,11 +97,14 @@ func (s *MetadataServer) SearchArtists(ctx context.Context, req *metadatav1.Sear
resp.Artists = append(resp.Artists, toProtoArtist(&a))
}
log.Trace().Int("total", result.Total).Int("returned", len(resp.Artists)).Msg("artist search complete")
return resp, nil
}
func (s *MetadataServer) SearchAlbums(ctx context.Context, req *metadatav1.SearchAlbumsRequest) (*metadatav1.SearchAlbumsResponse, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
@@ -97,9 +114,11 @@ func (s *MetadataServer) SearchAlbums(ctx context.Context, req *metadatav1.Searc
limit = 25
}
log.Debug().Str("query", req.Query).Str("artist", req.Artist).Int("limit", limit).Int("offset", int(req.Offset)).Msg("searching albums")
result, err := svc.SearchAlbums(ctx, req.Query, req.Artist, limit, int(req.Offset))
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
resp := &metadatav1.SearchAlbumsResponse{
@@ -110,11 +129,14 @@ func (s *MetadataServer) SearchAlbums(ctx context.Context, req *metadatav1.Searc
resp.Albums = append(resp.Albums, toProtoAlbum(&a))
}
log.Trace().Int("total", result.Total).Int("returned", len(resp.Albums)).Msg("album search complete")
return resp, nil
}
func (s *MetadataServer) GetAlbum(ctx context.Context, req *metadatav1.GetAlbumRequest) (*metadatav1.Album, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
@@ -123,22 +145,28 @@ func (s *MetadataServer) GetAlbum(ctx context.Context, req *metadatav1.GetAlbumR
switch v := req.Identifier.(type) {
case *metadatav1.GetAlbumRequest_Id:
id = v.Id
log.Debug().Str("lookup", "id").Str("album_id", id).Msg("getting album")
case *metadatav1.GetAlbumRequest_External:
id = v.External.SourceId
log.Debug().Str("lookup", "external").Str("source_id", id).Str("source", v.External.Source).Msg("getting album")
default:
log.Warn().Msg("get album called without identifier")
return nil, status.Error(codes.InvalidArgument, "identifier required")
}
album, err := svc.GetAlbum(ctx, id)
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
log.Trace().Str("album_id", album.ID).Str("title", album.Title).Msg("album found")
return toProtoAlbum(album), nil
}
func (s *MetadataServer) GetArtistAlbums(ctx context.Context, req *metadatav1.GetArtistAlbumsRequest) (*metadatav1.GetArtistAlbumsResponse, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
@@ -148,9 +176,11 @@ func (s *MetadataServer) GetArtistAlbums(ctx context.Context, req *metadatav1.Ge
limit = 25
}
log.Debug().Str("artist_id", req.ArtistId).Int("limit", limit).Int("offset", int(req.Offset)).Msg("getting artist albums")
result, err := svc.GetArtistAlbums(ctx, req.ArtistId, limit, int(req.Offset))
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
resp := &metadatav1.GetArtistAlbumsResponse{
@@ -161,11 +191,14 @@ func (s *MetadataServer) GetArtistAlbums(ctx context.Context, req *metadatav1.Ge
resp.Albums = append(resp.Albums, toProtoAlbum(&a))
}
log.Trace().Int("total", result.Total).Int("returned", len(resp.Albums)).Msg("artist albums retrieved")
return resp, nil
}
func (s *MetadataServer) GetTrack(ctx context.Context, req *metadatav1.GetTrackRequest) (*metadatav1.Track, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
@@ -174,42 +207,51 @@ func (s *MetadataServer) GetTrack(ctx context.Context, req *metadatav1.GetTrackR
switch v := req.Identifier.(type) {
case *metadatav1.GetTrackRequest_Id:
log.Debug().Str("lookup", "id").Str("track_id", v.Id).Msg("getting track")
t, err := svc.GetTrack(ctx, v.Id)
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
track = toProtoTrack(t)
case *metadatav1.GetTrackRequest_External:
log.Debug().Str("lookup", "external").Str("source_id", v.External.SourceId).Str("source", v.External.Source).Msg("getting track")
t, err := svc.GetTrack(ctx, v.External.SourceId)
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
track = toProtoTrack(t)
case *metadatav1.GetTrackRequest_Isrc:
log.Debug().Str("lookup", "isrc").Str("isrc", v.Isrc).Msg("getting track")
t, err := svc.GetTrackByISRC(ctx, v.Isrc)
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
track = toProtoTrack(t)
default:
log.Warn().Msg("get track called without identifier")
return nil, status.Error(codes.InvalidArgument, "identifier required")
}
log.Trace().Str("track_id", track.Id).Str("title", track.Title).Msg("track found")
return track, nil
}
func (s *MetadataServer) GetAlbumTracks(ctx context.Context, req *metadatav1.GetAlbumTracksRequest) (*metadatav1.GetAlbumTracksResponse, error) {
svc, err := s.getService(req.Provider)
log := zerolog.Ctx(ctx)
svc, err := s.getService(ctx, req.Provider)
if err != nil {
return nil, err
}
log.Debug().Str("album_id", req.AlbumId).Msg("getting album tracks")
tracks, err := svc.GetAlbumTracks(ctx, req.AlbumId)
if err != nil {
return nil, toGRPCError(err)
return nil, toGRPCError(ctx, err)
}
resp := &metadatav1.GetAlbumTracksResponse{}
@@ -217,29 +259,37 @@ func (s *MetadataServer) GetAlbumTracks(ctx context.Context, req *metadatav1.Get
resp.Tracks = append(resp.Tracks, toProtoTrack(&t))
}
log.Trace().Int("track_count", len(resp.Tracks)).Msg("album tracks retrieved")
return resp, nil
}
func (s *MetadataServer) SyncArtist(ctx context.Context, req *metadatav1.SyncArtistRequest) (*metadatav1.SyncArtistResponse, error) {
zerolog.Ctx(ctx).Warn().Msg("sync artist called but not implemented")
return nil, status.Error(codes.Unimplemented, "sync not yet implemented")
}
func toGRPCError(err error) error {
func toGRPCError(ctx context.Context, err error) error {
if err == nil {
return nil
}
log := zerolog.Ctx(ctx)
if errors.Is(err, repository.ErrNotFound) {
log.Debug().Msg("entity not found")
return status.Error(codes.NotFound, "not found")
}
if errors.Is(err, musicbrainz.ErrNotFound) {
log.Debug().Msg("provider entity not found")
return status.Error(codes.NotFound, "not found")
}
if errors.Is(err, musicbrainz.ErrRateLimited) {
log.Warn().Msg("provider rate limited")
return status.Error(codes.ResourceExhausted, "rate limited")
}
log.Error().Err(err).Msg("internal error")
return status.Errorf(codes.Internal, "internal error: %v", err)
}