From 7f2714823f8b6caac9a19229a77ca59ddda19350 Mon Sep 17 00:00:00 2001 From: Valera Shaitorov <shaitorov@perx.ru> Date: Mon, 17 Apr 2023 19:01:09 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20References=20middlewares?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../middleware/client_encode_middleware.go | 42 +++++++++++ .../middleware/error_logging_middleware.go | 41 ++++++++++ .../middleware/logging_middleware.go | 74 +++++++++++++++++++ pkg/references/middleware/middleware.go | 28 +++++++ .../middleware/recovering_middleware.go | 44 +++++++++++ 5 files changed, 229 insertions(+) create mode 100644 pkg/references/middleware/client_encode_middleware.go create mode 100644 pkg/references/middleware/error_logging_middleware.go create mode 100644 pkg/references/middleware/logging_middleware.go create mode 100644 pkg/references/middleware/middleware.go create mode 100644 pkg/references/middleware/recovering_middleware.go diff --git a/pkg/references/middleware/client_encode_middleware.go b/pkg/references/middleware/client_encode_middleware.go new file mode 100644 index 00000000..1cd9cb2f --- /dev/null +++ b/pkg/references/middleware/client_encode_middleware.go @@ -0,0 +1,42 @@ +package service + +import ( + "context" + + "git.perx.ru/perxis/perxis-go/pkg/collections" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/references" +) + +// ClientEncodeMiddleware выполняет операции encode/decode для передаваемых данных +func ClientEncodeMiddleware(colls collections.Collections) Middleware { + return func(refs references.References) references.References { + return &encodeDecodeMiddleware{ + next: refs, + colls: colls, + } + } +} + +type encodeDecodeMiddleware struct { + next references.References + colls collections.Collections +} + +func (m *encodeDecodeMiddleware) Get(ctx context.Context, spaceId, envId string, refs []*references.Reference) (items []*items.Item, notfound []*references.Reference, err error) { + items, notfound, err = m.next.Get(ctx, spaceId, envId, refs) + if err == nil && len(items) > 0 { + for i, item := range items { + col, err := m.colls.Get(ctx, item.SpaceID, item.EnvID, item.CollectionID) + if err != nil { + return nil, nil, err + } + + if item, err = item.Decode(ctx, col.Schema); err != nil { + return nil, nil, err + } + items[i] = item + } + } + return +} diff --git a/pkg/references/middleware/error_logging_middleware.go b/pkg/references/middleware/error_logging_middleware.go new file mode 100644 index 00000000..e68bade9 --- /dev/null +++ b/pkg/references/middleware/error_logging_middleware.go @@ -0,0 +1,41 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/error_log +// gowrap: http://github.com/hexdigest/gowrap + +package service + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" + +import ( + "context" + + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/references" + "go.uber.org/zap" +) + +// errorLoggingMiddleware implements references.References that is instrumented with logging +type errorLoggingMiddleware struct { + logger *zap.Logger + next references.References +} + +// ErrorLoggingMiddleware instruments an implementation of the references.References with simple logging +func ErrorLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next references.References) references.References { + return &errorLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *errorLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string, references []*references.Reference) (items []*items.Item, notfound []*references.Reference, err error) { + logger := m.logger + defer func() { + if err != nil { + logger.Warn("response error", zap.Error(err)) + } + }() + return m.next.Get(ctx, spaceId, envId, references) +} diff --git a/pkg/references/middleware/logging_middleware.go b/pkg/references/middleware/logging_middleware.go new file mode 100644 index 00000000..692e298d --- /dev/null +++ b/pkg/references/middleware/logging_middleware.go @@ -0,0 +1,74 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log +// gowrap: http://github.com/hexdigest/gowrap + +package service + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/access_log -o logging_middleware.go -l "" + +import ( + "context" + "fmt" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/references" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// loggingMiddleware implements references.References that is instrumented with logging +type loggingMiddleware struct { + logger *zap.Logger + next references.References +} + +// LoggingMiddleware instruments an implementation of the references.References with simple logging +func LoggingMiddleware(logger *zap.Logger) Middleware { + return func(next references.References) references.References { + return &loggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, envId string, references []*references.Reference) (items []*items.Item, notfound []*references.Reference, err error) { + begin := time.Now() + var fields []zapcore.Field + for k, v := range map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "references": references} { + if k == "ctx" { + fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx)))) + continue + } + fields = append(fields, zap.Reflect(k, v)) + } + + m.logger.Debug("Get.Request", fields...) + + items, notfound, err = m.next.Get(ctx, spaceId, envId, references) + + fields = []zapcore.Field{ + zap.Duration("time", time.Since(begin)), + zap.Error(err), + } + + for k, v := range map[string]interface{}{ + "items": items, + "notfound": notfound, + "err": err} { + if k == "err" { + continue + } + fields = append(fields, zap.Reflect(k, v)) + } + + m.logger.Debug("Get.Response", fields...) + + return items, notfound, err +} diff --git a/pkg/references/middleware/middleware.go b/pkg/references/middleware/middleware.go new file mode 100644 index 00000000..dfed8dc0 --- /dev/null +++ b/pkg/references/middleware/middleware.go @@ -0,0 +1,28 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/middleware +// gowrap: http://github.com/hexdigest/gowrap + +package service + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" + +import ( + "git.perx.ru/perxis/perxis-go/pkg/references" + "go.uber.org/zap" +) + +type Middleware func(references.References) references.References + +func WithLog(s references.References, logger *zap.Logger, log_access bool) references.References { + if logger == nil { + logger = zap.NewNop() + } + + logger = logger.Named("References") + s = ErrorLoggingMiddleware(logger)(s) + if log_access { + s = LoggingMiddleware(logger)(s) + } + s = RecoveringMiddleware(logger)(s) + return s +} diff --git a/pkg/references/middleware/recovering_middleware.go b/pkg/references/middleware/recovering_middleware.go new file mode 100644 index 00000000..b1a4eb6b --- /dev/null +++ b/pkg/references/middleware/recovering_middleware.go @@ -0,0 +1,44 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/recovery +// gowrap: http://github.com/hexdigest/gowrap + +package service + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/recovery -o recovering_middleware.go -l "" + +import ( + "context" + "fmt" + + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/references" + "go.uber.org/zap" +) + +// recoveringMiddleware implements references.References that is instrumented with logging +type recoveringMiddleware struct { + logger *zap.Logger + next references.References +} + +// RecoveringMiddleware instruments an implementation of the references.References with simple logging +func RecoveringMiddleware(logger *zap.Logger) Middleware { + return func(next references.References) references.References { + return &recoveringMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *recoveringMiddleware) Get(ctx context.Context, spaceId string, envId string, references []*references.Reference) (items []*items.Item, notfound []*references.Reference, err error) { + logger := m.logger + defer func() { + if r := recover(); r != nil { + logger.Error("panic", zap.Error(fmt.Errorf("%v", r))) + err = fmt.Errorf("%v", r) + } + }() + + return m.next.Get(ctx, spaceId, envId, references) +} -- GitLab