make application with base logic
This commit is contained in:
17
internal/common/decorator/command.go
Normal file
17
internal/common/decorator/command.go
Normal file
@ -0,0 +1,17 @@
|
||||
package decorator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type CommandHandler[T any] interface {
|
||||
Handle(ctx context.Context, params T) error
|
||||
}
|
||||
|
||||
func ApplyCommandDecorators[T any](base CommandHandler[T], log *slog.Logger) CommandHandler[T] {
|
||||
return commandLoggingDecorator[T]{
|
||||
base: base,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
64
internal/common/decorator/logging.go
Normal file
64
internal/common/decorator/logging.go
Normal file
@ -0,0 +1,64 @@
|
||||
package decorator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"git.loyso.art/frx/kurious/internal/common/xcontext"
|
||||
)
|
||||
|
||||
type commandLoggingDecorator[T any] struct {
|
||||
base CommandHandler[T]
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
func (c commandLoggingDecorator[T]) Handle(ctx context.Context, cmd T) (err error) {
|
||||
handlerName := getTypeName[T]()
|
||||
|
||||
ctx = xcontext.WithLogFields(ctx, slog.String("handler", handlerName))
|
||||
xcontext.LogDebug(ctx, c.log, "executing command")
|
||||
start := time.Now()
|
||||
|
||||
defer func() {
|
||||
elapsed := slog.Duration("elapsed", time.Since(start))
|
||||
if err == nil {
|
||||
xcontext.LogInfo(ctx, c.log, "command executed successfuly", elapsed)
|
||||
} else {
|
||||
xcontext.LogError(ctx, c.log, "command execution failed", elapsed, slog.Any("err", err))
|
||||
}
|
||||
}()
|
||||
|
||||
return c.base.Handle(ctx, cmd)
|
||||
}
|
||||
|
||||
type queryLoggingDecorator[Q, U any] struct {
|
||||
base QueryHandler[Q, U]
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
func (q queryLoggingDecorator[Q, U]) Handle(ctx context.Context, query Q) (entity U, err error) {
|
||||
handlerName := getTypeName[Q]()
|
||||
ctx = xcontext.WithLogFields(ctx, slog.String("handler", handlerName))
|
||||
xcontext.LogDebug(ctx, q.log, "executing command")
|
||||
start := time.Now()
|
||||
|
||||
defer func() {
|
||||
elapsed := slog.Duration("elapsed", time.Since(start))
|
||||
if err == nil {
|
||||
xcontext.LogInfo(ctx, q.log, "command executed successfuly", elapsed)
|
||||
} else {
|
||||
xcontext.LogError(ctx, q.log, "command execution failed", elapsed, slog.Any("err", err))
|
||||
}
|
||||
}()
|
||||
|
||||
return q.base.Handle(ctx, query)
|
||||
|
||||
}
|
||||
|
||||
func getTypeName[T any]() string {
|
||||
var t T
|
||||
out := fmt.Sprintf("%T", t)
|
||||
return out
|
||||
}
|
||||
17
internal/common/decorator/query.go
Normal file
17
internal/common/decorator/query.go
Normal file
@ -0,0 +1,17 @@
|
||||
package decorator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type QueryHandler[Q, U any] interface {
|
||||
Handle(ctx context.Context, query Q) (entity U, err error)
|
||||
}
|
||||
|
||||
func AddQueryDecorators[Q, U any](base QueryHandler[Q, U], log *slog.Logger) QueryHandler[Q, U] {
|
||||
return queryLoggingDecorator[Q, U]{
|
||||
base: base,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user