feat(telemetry): Implement OpenTelemetry tracing and logging in tag management functions

This commit is contained in:
SoXX 2024-08-11 22:17:24 +02:00
parent 2d9db01d72
commit a368f59234

View File

@ -5,12 +5,25 @@ import (
"errors" "errors"
otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error" otterError "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/error"
"git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models" "git.anthrove.art/Anthrove/otter-space-sdk/v2/pkg/models"
log "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute"
"gorm.io/gorm" "gorm.io/gorm"
) )
func CreateTag(ctx context.Context, tagName models.TagName, tagType models.TagType) (models.Tag, error) { func CreateTag(ctx context.Context, tagName models.TagName, tagType models.TagType) (models.Tag, error) {
ctx, span := tracer.Start(ctx, "CreateTag")
defer span.End()
span.SetAttributes(
attribute.String("tag_name", string(tagName)),
attribute.String("tag_type", string(tagType)),
)
span.AddEvent("Starting tag creation")
if client == nil { if client == nil {
logger.WithContext(ctx).Error(otterError.DatabaseIsNotConnected)
span.RecordError(&otterError.Database{Reason: otterError.DatabaseIsNotConnected})
return models.Tag{}, &otterError.Database{Reason: otterError.DatabaseIsNotConnected} return models.Tag{}, &otterError.Database{Reason: otterError.DatabaseIsNotConnected}
} }
@ -19,63 +32,142 @@ func CreateTag(ctx context.Context, tagName models.TagName, tagType models.TagTy
Type: tagType, Type: tagType,
} }
logger.WithContext(ctx).WithFields(log.Fields{
"name": tagName,
"type": tagType,
}).Debug("attempting to create tag")
result := client.WithContext(ctx).Create(&tag) result := client.WithContext(ctx).Create(&tag)
if result.Error != nil { if result.Error != nil {
if errors.Is(result.Error, gorm.ErrDuplicatedKey) { if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
logger.WithContext(ctx).WithFields(log.Fields{
"name": tagName,
"type": tagType,
}).Error(otterError.DuplicateKey)
span.RecordError(&otterError.Database{Reason: otterError.DuplicateKey})
return models.Tag{}, &otterError.Database{Reason: otterError.DuplicateKey} return models.Tag{}, &otterError.Database{Reason: otterError.DuplicateKey}
} }
logger.WithContext(ctx).WithFields(log.Fields{
"name": tagName,
"type": tagType,
}).Error(result.Error)
span.RecordError(result.Error)
return models.Tag{}, result.Error return models.Tag{}, result.Error
} }
logger.WithContext(ctx).WithFields(log.Fields{
"name": tagName,
"type": tagType,
}).Debug("tag created")
span.AddEvent("Tag created successfully")
return tag, nil return tag, nil
} }
func CreateTagInBatch(ctx context.Context, tags []models.Tag, batchSize int) error { func CreateTagInBatch(ctx context.Context, tags []models.Tag, batchSize int) error {
ctx, span := tracer.Start(ctx, "CreateTagInBatch")
defer span.End()
span.SetAttributes(
attribute.Int64("batch_size", int64(batchSize)),
attribute.Int64("tag_count", int64(len(tags))),
)
span.AddEvent("Starting batch tag creation")
if client == nil { if client == nil {
logger.WithContext(ctx).Error(otterError.DatabaseIsNotConnected)
span.RecordError(&otterError.Database{Reason: otterError.DatabaseIsNotConnected})
return &otterError.Database{Reason: otterError.DatabaseIsNotConnected} return &otterError.Database{Reason: otterError.DatabaseIsNotConnected}
} }
if tags == nil { if tags == nil || len(tags) == 0 {
return &otterError.EntityValidationFailed{Reason: otterError.TagListIsEmpty} logger.WithContext(ctx).Error(otterError.TagListIsEmpty)
} span.RecordError(&otterError.EntityValidationFailed{Reason: otterError.TagListIsEmpty})
if len(tags) == 0 {
return &otterError.EntityValidationFailed{Reason: otterError.TagListIsEmpty} return &otterError.EntityValidationFailed{Reason: otterError.TagListIsEmpty}
} }
if batchSize == 0 { if batchSize == 0 {
logger.WithContext(ctx).Error(otterError.BatchSizeIsEmpty)
span.RecordError(&otterError.EntityValidationFailed{Reason: otterError.BatchSizeIsEmpty})
return &otterError.EntityValidationFailed{Reason: otterError.BatchSizeIsEmpty} return &otterError.EntityValidationFailed{Reason: otterError.BatchSizeIsEmpty}
} }
logger.WithContext(ctx).WithFields(log.Fields{
"tag_length": len(tags),
}).Debug("attempting to create tags")
result := client.WithContext(ctx).CreateInBatches(&tags, batchSize) result := client.WithContext(ctx).CreateInBatches(&tags, batchSize)
if result.Error != nil { if result.Error != nil {
if errors.Is(result.Error, gorm.ErrDuplicatedKey) { if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
logger.WithContext(ctx).WithFields(log.Fields{
"tag_length": len(tags),
}).Error(otterError.DuplicateKey)
span.RecordError(&otterError.Database{Reason: otterError.DuplicateKey})
return &otterError.Database{Reason: otterError.DuplicateKey} return &otterError.Database{Reason: otterError.DuplicateKey}
} }
logger.WithContext(ctx).WithFields(log.Fields{
"tag_length": len(tags),
}).Error(result.Error)
span.RecordError(result.Error)
return result.Error return result.Error
} }
logger.WithContext(ctx).WithFields(log.Fields{
"tag_length": len(tags),
}).Debug("tags created")
span.AddEvent("Batch tags created successfully")
return nil return nil
} }
func DeleteTag(ctx context.Context, tagName models.TagName) error { func DeleteTag(ctx context.Context, tagName models.TagName) error {
ctx, span := tracer.Start(ctx, "DeleteTag")
defer span.End()
span.SetAttributes(
attribute.String("tag_name", string(tagName)),
)
span.AddEvent("Starting tag deletion")
var tag models.Tag var tag models.Tag
if client == nil { if client == nil {
logger.WithContext(ctx).Error(otterError.DatabaseIsNotConnected)
span.RecordError(&otterError.Database{Reason: otterError.DatabaseIsNotConnected})
return &otterError.Database{Reason: otterError.DatabaseIsNotConnected} return &otterError.Database{Reason: otterError.DatabaseIsNotConnected}
} }
if len(tagName) == 0 { if len(tagName) == 0 {
logger.WithContext(ctx).Error(otterError.TagNameIsEmpty)
span.RecordError(&otterError.EntityValidationFailed{Reason: otterError.TagNameIsEmpty})
return &otterError.EntityValidationFailed{Reason: otterError.TagNameIsEmpty} return &otterError.EntityValidationFailed{Reason: otterError.TagNameIsEmpty}
} }
logger.WithContext(ctx).WithFields(log.Fields{
"tag_name": tagName,
}).Debug("attempting to delete tag")
result := client.WithContext(ctx).Delete(&tag, tagName) result := client.WithContext(ctx).Delete(&tag, tagName)
if result.Error != nil { if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) { if errors.Is(result.Error, gorm.ErrRecordNotFound) {
span.RecordError(&otterError.Database{Reason: otterError.NoDataFound})
return &otterError.Database{Reason: otterError.NoDataFound} return &otterError.Database{Reason: otterError.NoDataFound}
} }
span.RecordError(result.Error)
return result.Error return result.Error
} }
logger.WithContext(ctx).WithFields(log.Fields{
"tag_name": tagName,
}).Debug("tag deleted")
span.AddEvent("Tag deleted successfully")
return nil return nil
} }