diff --git a/assets/templates/middleware/access_log b/assets/templates/middleware/access_log deleted file mode 100755 index 86b4fe25ef6247f78dd491578f5b6bf05fa8e992..0000000000000000000000000000000000000000 --- a/assets/templates/middleware/access_log +++ /dev/null @@ -1,65 +0,0 @@ -import ( - "fmt" - "time" - "context" - - "go.uber.org/zap" -) - -{{ $funcName := (or .Vars.FuncName ("LoggingMiddleware")) }} -{{ $decorator := (or .Vars.DecoratorName ("loggingMiddleware")) }} - -// {{$decorator}} implements {{.Interface.Type}} that is instrumented with logging -type {{$decorator}} struct { - logger *zap.Logger - next {{.Interface.Type}} -} - -// {{$funcName}} instruments an implementation of the {{.Interface.Type}} with simple logging -func {{$funcName}}(logger *zap.Logger) Middleware { - return func(next {{.Interface.Type}}) {{.Interface.Type}} { - return &{{$decorator}}{ - next: next, - logger: logger, - } - } -} - -{{range $method := .Interface.Methods}} - func (m *{{$decorator}}) {{$method.Declaration}} { - begin := time.Now() - var fields []zapcore.Field - {{- if $method.HasParams}} - for k, v := range {{$method.ParamsMap}} { - if k == "ctx" { - fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx)))) - continue - } - fields = append(fields, zap.Reflect(k,v)) - } - {{end}} - - m.logger.Debug("{{$method.Name}}.Request",fields...) - - {{ $method.ResultsNames }} = m.next.{{ $method.Call }} - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - {{ if $method.HasResults}} - for k, v := range {{$method.ResultsMap}} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k,v)) - } - {{end}} - - m.logger.Debug("{{$method.Name}}.Response", fields...) - - return {{ $method.ResultsNames }} - } -{{end}} diff --git a/assets/templates/middleware/access_log.tmpl b/assets/templates/middleware/access_log.tmpl new file mode 100755 index 0000000000000000000000000000000000000000..9f9899b835a1ec46652da008035f3a8931dc472d --- /dev/null +++ b/assets/templates/middleware/access_log.tmpl @@ -0,0 +1,58 @@ +import ( + "fmt" + "time" + "context" + + "go.uber.org/zap" +) + +{{ $funcName := (or .Vars.FuncName ("AccessLoggingMiddleware")) }} +{{ $decorator := (or .Vars.DecoratorName ("accessLoggingMiddleware")) }} +{{ $objectName := (trimSuffix "s" (split "." .Interface.Type)._1) }} + +// {{$decorator}} implements {{.Interface.Type}} that is instrumented with logging +type {{$decorator}} struct { + logger *zap.Logger + next {{.Interface.Type}} +} + +// {{$funcName}} instruments an implementation of the {{.Interface.Type}} with simple logging +func {{$funcName}}(logger *zap.Logger) Middleware { + return func(next {{.Interface.Type}}) {{.Interface.Type}} { + return &{{$decorator}}{ + next: next, + logger: logger, + } + } +} + +{{range $method := .Interface.Methods}} + func (m *{{$decorator}}) {{$method.Declaration}} { + begin := time.Now() + + m.logger.Debug("{{$method.Name}}.Request", + {{- range $param := $method.Params -}} + {{- if (eq $param.Name "ctx") }} + zap.Reflect("principal", auth.GetPrincipal(ctx)), + {{- else }} + zap.Reflect("{{$param.Name}}", {{$param.Name}}), + {{- end -}} + {{ end }} + ) + + {{ $method.ResultsNames }} = m.next.{{ $method.Call }} + + m.logger.Debug("{{$method.Name}}.Response", + zap.Duration("time", time.Since(begin)), + {{- range $param := $method.Results -}} + {{- if (eq $param.Name "err") }} + zap.Error(err), + {{- else }} + zap.Reflect("{{$param.Name}}", {{$param.Name}}), + {{- end -}} + {{ end }} + ) + + return {{ $method.ResultsNames }} + } +{{end}} diff --git a/assets/templates/middleware/log.tmpl b/assets/templates/middleware/log.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..ab91909fb61f1044fe74810390a64d469a6cb614 --- /dev/null +++ b/assets/templates/middleware/log.tmpl @@ -0,0 +1,73 @@ +{{/* +Ртот шаблон предназначен только для первичной генерации LoggingMiddleware, +поскольку РѕРЅ РЅРµ может учесть РІСЃРµ сигнатуры логгируемых методов. После генерации +необходимо внести правки РІ РєРѕРґ РІ местах, помеченных 'TODO' + +Сгенерировать middleware: +```shell +gowrap gen -p git.perx.ru/perxis/perxis-go/<package_name> -i <interface> -t ../../../assets/templates/middleware/logging.tmpl -o info_logging_middleware.go -g +``` + */}} + +import ( + "fmt" + "time" + "context" + + logzap "git.perx.ru/perxis/perxis-go/zap" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +{{ $funcName := (or .Vars.FuncName ("LoggingMiddleware")) }} +{{ $decorator := (or .Vars.DecoratorName ("loggingMiddleware")) }} +{{ $packageName := (split "." .Interface.Type)._0 }} +{{ $serviceName := (split "." .Interface.Type)._1 }} +{{ $objectName := (trimSuffix "s" (split "." .Interface.Type)._1) }} +{{ $writeMethods := list "Archive" "Create" "Delete" "Publish" "Unarchive" "Undelete" "Unpublish" "Update" "SetSchema" "Migrate" }} + +type {{ $decorator }} struct { + logger *zap.Logger + next {{ .Interface.Type }} +} + +func {{ $funcName }} (logger *zap.Logger) Middleware { + return func(next {{ .Interface.Type }}) {{ .Interface.Type }} { + return &{{ $decorator }}{ + next: next, + logger: logger.With(logzap.Component("{{ (lower $serviceName ) }}")), + } + } +} + +{{ range $method := .Interface.Methods }} +func (m *{{ $decorator }}) {{ $method.Declaration }} { + logger := m.logger.With( + {{- if $method.AcceptsContext }} + logzap.CallerFromContext(ctx), + {{ end -}} + {{- if has $method.Name $writeMethods -}} + logzap.Event({{ $packageName }}.Event{{ $objectName }}{{ $method.Name }}), + logzap.Object(TODO), + {{ end -}} + ) + + {{ $method.ResultsNames }} = m.next.{{ $method.Call }} + + {{- if $method.ReturnsError }} + if err != nil { + logger.Error("Failed to {{ (lower $method.Name) }}", zap.Error(err) + {{- if has $method.Name $writeMethods -}} + , logzap.Channels(logzap.Userlog, logzap.Syslog) + {{- end -}}) + return + } + {{ end }} + + {{ if has $method.Name $writeMethods }} + logger.Info("Successfully {{ (lower (trimSuffix "e" $method.Name)) }}ed", logzap.Channels(logzap.Userlog)) + {{ end -}} + + return {{ $method.ResultsNames }} +} +{{ end }} diff --git a/assets/templates/middleware/middleware b/assets/templates/middleware/middleware.tmpl similarity index 55% rename from assets/templates/middleware/middleware rename to assets/templates/middleware/middleware.tmpl index 89877774c933840c2bdd569f2beed8105588aae2..7a34d393cbe71648913dd708d49118da36da1105 100755 --- a/assets/templates/middleware/middleware +++ b/assets/templates/middleware/middleware.tmpl @@ -2,20 +2,23 @@ import ( "go.uber.org/zap" ) -type Middleware func({{.Interface.Type}}) {{.Interface.Type}} +{{ $serviceName := (split "." .Interface.Type)._1 }} +type Middleware func({{.Interface.Type}}) {{.Interface.Type}} func WithLog(s {{.Interface.Type}}, logger *zap.Logger, log_access bool) {{.Interface.Type}} { if logger == nil { logger = zap.NewNop() } - - logger = logger.Named("{{ .Interface.Name }}") - s = ErrorLoggingMiddleware(logger)(s) + logger = logger.Named("{{ .Interface.Name }}") if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + {{- if (has $serviceName (list "Items" "Collections") ) }} + s = LoggingMiddleware(logger)(s) + {{ else }} + s = ErrorLoggingMiddleware(logger)(s) + {{ end }} s = RecoveringMiddleware(logger)(s) return s } - diff --git a/id/bson.go b/id/bson.go deleted file mode 100644 index 9d44c5a8074361b381524dd7c99ad77906cfc68c..0000000000000000000000000000000000000000 --- a/id/bson.go +++ /dev/null @@ -1,32 +0,0 @@ -package id - -import ( - "git.perx.ru/perxis/perxis-go/pkg/errors" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/bson/bsonrw" - "go.mongodb.org/mongo-driver/bson/bsontype" -) - -func (id *ID) MarshalBSONValue() (bsontype.Type, []byte, error) { - return bson.MarshalValue(id.String()) -} - -func (id *ID) UnmarshalBSONValue(btype bsontype.Type, data []byte) error { - if btype != bson.TypeString { - return errors.New("cannot unmarshal non-string bson value to ID") - } - dec, err := bson.NewDecoder(bsonrw.NewBSONValueReader(btype, data)) - if err != nil { - return err - } - var str string - if err = dec.Decode(&str); err != nil { - return err - } - t, err := Parse(str) - if err != nil { - return err - } - *id = *t - return nil -} diff --git a/id/bson_test.go b/id/bson_test.go index c8080b5d7ae12181343a8f6502e76484c414e578..7ae62ccba4e1dbc2e74ac48b8c5890216a6cba50 100644 --- a/id/bson_test.go +++ b/id/bson_test.go @@ -11,64 +11,64 @@ import ( func TestID_MarshalUnmarshalBSON(t *testing.T) { tests := []struct { name string - id *ID + id *ObjectId }{ { name: "OrganizationID", - id: &ID{Descriptor: &OrganizationID{OrganizationID: "1"}}, + id: &ObjectId{Descriptor: &OrganizationId{OrganizationID: "1"}}, }, { name: "UserID", - id: &ID{Descriptor: &UserID{UserID: "1"}}, + id: &ObjectId{Descriptor: &UserId{UserID: "1"}}, }, { name: "ServiceID", - id: &ID{Descriptor: &ServiceID{ServiceID: "1"}}, + id: &ObjectId{Descriptor: &ServiceId{ServiceID: "1"}}, }, { - name: "SpaceID", - id: &ID{Descriptor: &SpaceID{SpaceID: "1"}}, + name: "SpaceId", + id: &ObjectId{Descriptor: &SpaceId{SpaceID: "1"}}, }, { name: "EnvironmentID", - id: &ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + id: &ObjectId{Descriptor: &EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}, }, { name: "ClientID", - id: &ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + id: &ObjectId{Descriptor: &ClientId{ClientID: "1", SpaceId: SpaceId{SpaceID: "1"}}}, }, { name: "RoleID", - id: &ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + id: &ObjectId{Descriptor: &RoleId{RoleID: "1", SpaceId: SpaceId{SpaceID: "1"}}}, }, { - name: "CollectionID", - id: &ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + name: "CollectionId", + id: &ObjectId{Descriptor: &CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}, }, { name: "SchemaID", - id: &ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + id: &ObjectId{Descriptor: &SchemaId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}, }, { - name: "ItemID", - id: &ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}, + name: "ItemId", + id: &ObjectId{Descriptor: &ItemId{ItemID: "1", CollectionId: CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}}, }, { name: "RevisionID", - id: &ID{Descriptor: &RevisionID{RevisionID: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + id: &ObjectId{Descriptor: &RevisionId{RevisionID: "1", ItemId: ItemId{ItemID: "1", CollectionId: CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}}}, }, { - name: "FieldID", - id: &ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + name: "FieldId", + id: &ObjectId{Descriptor: &FieldId{Field: "1", ItemId: ItemId{ItemID: "1", CollectionId: CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}}}, }, { name: "SystemID", - id: &ID{Descriptor: &SystemID{}}, + id: &ObjectId{Descriptor: &SystemId{}}, }, } type test struct { Text string - ID *ID + ID *ObjectId } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -86,13 +86,14 @@ func TestID_MarshalUnmarshalBSON(t *testing.T) { func TestID_ExampleBSON(t *testing.T) { type data struct { - ID *ID + ID *ObjectId + Text string Number int } test := &data{ - ID: &ID{Descriptor: &SpaceID{SpaceID: Space}}, + ID: &ObjectId{Descriptor: &SpaceId{SpaceID: Space}}, Text: "text", Number: 1, } diff --git a/id/client.go b/id/client.go index db941c5ad54b539551193004674ac15f15d314be..99c2cedf3e86a809be30fb3e2b4ab61ab93eb5ee 100644 --- a/id/client.go +++ b/id/client.go @@ -1,61 +1,65 @@ package id +import ( + "fmt" +) + const ( Client = "client" ClientsPrefix = "clients" ) -type ClientID struct { - SpaceID +var _ Descriptor = &ClientId{} + +type ClientId struct { + SpaceId ClientID string `json:"client_id,omitempty" bson:"client_id,omitempty"` } -func (t *ClientID) Type() string { return Client } - -func (t *ClientID) String() string { - return Join(t.SpaceID.String(), ClientsPrefix, t.ClientID) - +func (id *ClientId) New() Descriptor { + return &ClientId{} } -func (t *ClientID) ToMap() map[string]any { - m := t.SpaceID.ToMap() - m["client_id"] = t.ClientID - m["type"] = Client - return m +func (id *ClientId) Type() string { return Client } + +func (id *ClientId) String() string { + return Join(id.SpaceId.String(), ClientsPrefix, id.ClientID) } -func (t *ClientID) FromMap(m map[string]any) error { - if err := t.SpaceID.FromMap(m); err != nil { +func (id *ClientId) FromParts(parts []string) error { + if len(parts) != 4 || parts[2] != ClientsPrefix { + return ErrInvalidID + } + if err := id.SpaceId.FromParts(parts[:2]); err != nil { return err } - t.ClientID = m["client_id"].(string) + id.ClientID = parts[3] return nil } -func (t *ClientID) Validate() error { - if t.ClientID == "" { - return ErrInvalidID - } - - return t.SpaceID.Validate() +func (id *ClientId) Map() map[string]any { + m := id.SpaceId.Map() + m["client_id"] = id.ClientID + m["type"] = Client + return m } -func parseClientID(parts []string) (*ClientID, error) { - if len(parts) != 4 || parts[2] != ClientsPrefix { - return nil, ErrInvalidID +func (id *ClientId) FromMap(m map[string]any) error { + id.ClientID, _ = m["client_id"].(string) + if id.ClientID == "" { + return fmt.Errorf("%w: ClientID required", ErrInvalidID) } + return id.SpaceId.FromMap(m) +} - spaceID, err := parseSpaceID(parts[:2]) - if err != nil { - return nil, err +func (id *ClientId) Validate() error { + if id.ClientID == "" { + return fmt.Errorf("%w: ClientID required", ErrInvalidID) } - var id ClientID - id.SpaceID = *spaceID - id.ClientID = parts[3] - return &id, nil + return id.SpaceId.Validate() } -func NewClientID(spaceID, id string) *ID { - return &ID{Descriptor: &ClientID{SpaceID: SpaceID{SpaceID: spaceID}, ClientID: id}} +func NewClientId(spaceID, id string) *ObjectId { + return &ObjectId{Descriptor: &ClientId{SpaceId: SpaceId{SpaceID: spaceID}, ClientID: id}} } diff --git a/id/collection.go b/id/collection.go index e0f37585b41e77b58530cc50f249283beb6d8eca..f507d66c85e35de208468243383c377f09c88259 100644 --- a/id/collection.go +++ b/id/collection.go @@ -1,60 +1,64 @@ package id +import ( + "fmt" +) + const ( Collection = "collection" CollectionsPrefix = "cols" ) -type CollectionID struct { - EnvironmentID +var _ Descriptor = &CollectionId{} + +type CollectionId struct { + EnvironmentId CollectionID string `json:"col_id,omitempty" bson:"col_id, omitempty"` } -func (t *CollectionID) Type() string { return Collection } +func (id *CollectionId) New() Descriptor { + return &CollectionId{EnvironmentId: EnvironmentId{SpaceId: SpaceId{}}} +} + +func (id *CollectionId) Type() string { return Collection } -func (t *CollectionID) String() string { - return Join(t.EnvironmentID.String(), CollectionsPrefix, t.CollectionID) +func (id *CollectionId) String() string { + return Join(id.EnvironmentId.String(), CollectionsPrefix, id.CollectionID) } -func (t *CollectionID) ToMap() map[string]any { - m := t.EnvironmentID.ToMap() - m["col_id"] = t.CollectionID +func (id *CollectionId) Map() map[string]any { + m := id.EnvironmentId.Map() + m["col_id"] = id.CollectionID m["type"] = Collection return m } -func (t *CollectionID) FromMap(m map[string]any) error { - if err := t.EnvironmentID.FromMap(m); err != nil { +func (id *CollectionId) FromParts(parts []string) error { + if len(parts) != 6 || parts[4] != CollectionsPrefix { + return ErrInvalidID + } + if err := id.EnvironmentId.FromParts(parts[:4]); err != nil { return err } - t.CollectionID = m["col_id"].(string) + id.CollectionID = parts[5] return nil } -func (t *CollectionID) Validate() error { - if t.CollectionID == "" { - return ErrInvalidID +func (id *CollectionId) FromMap(m map[string]any) error { + id.CollectionID, _ = m["col_id"].(string) + if id.CollectionID == "" { + return fmt.Errorf("%w: CollectionID required", ErrInvalidID) } - - return t.EnvironmentID.Validate() + return id.EnvironmentId.FromMap(m) } -func parseCollectionID(parts []string) (*CollectionID, error) { - if len(parts) != 6 || parts[4] != CollectionsPrefix { - return nil, ErrInvalidID - } - - envID, err := parseEnvironmentID(parts[:4]) - if err != nil { - return nil, err +func (id *CollectionId) Validate() error { + if id.CollectionID == "" { + return fmt.Errorf("%w: CollectionID required", ErrInvalidID) } - - var id CollectionID - id.CollectionID = parts[5] - id.EnvironmentID = *envID - return &id, nil + return id.EnvironmentId.Validate() } -func NewCollectionID(spaceID, envID, id string) *ID { - return &ID{Descriptor: &CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: id}} +func NewCollectionId(spaceID, envID, id string) *ObjectId { + return &ObjectId{Descriptor: &CollectionId{EnvironmentId: EnvironmentId{SpaceId: SpaceId{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: id}} } diff --git a/id/environment.go b/id/environment.go index d42df3e658bc04ae70989d199257a7836bd30f00..364529f681c2f9e4dc8c785eb338afc554ae3642 100644 --- a/id/environment.go +++ b/id/environment.go @@ -1,61 +1,65 @@ package id +import ( + "fmt" +) + const ( Environment = "environment" EnvironmentsPrefix = "envs" ) -type EnvironmentID struct { - SpaceID +var _ Descriptor = &EnvironmentId{} + +type EnvironmentId struct { + SpaceId EnvironmentID string `json:"env_id,omitempty" bson:"env_id,omitempty"` } -func (t *EnvironmentID) Type() string { return Environment } +func (id *EnvironmentId) New() Descriptor { + return &EnvironmentId{} +} + +func (id *EnvironmentId) Type() string { return "environment" } -func (t *EnvironmentID) String() string { - return Join(t.SpaceID.String(), EnvironmentsPrefix, t.EnvironmentID) +func (id *EnvironmentId) String() string { + return Join(id.SpaceId.String(), EnvironmentsPrefix, id.EnvironmentID) } -func (t *EnvironmentID) ToMap() map[string]any { - m := t.SpaceID.ToMap() - m["env_id"] = t.EnvironmentID +func (id *EnvironmentId) Map() map[string]any { + m := id.SpaceId.Map() + m["env_id"] = id.EnvironmentID m["type"] = Environment return m } -func (t *EnvironmentID) FromMap(m map[string]any) error { - if err := t.SpaceID.FromMap(m); err != nil { +func (id *EnvironmentId) FromParts(parts []string) error { + if len(parts) != 4 || parts[2] != EnvironmentsPrefix { + return ErrInvalidID + } + if err := id.SpaceId.FromParts(parts[:2]); err != nil { return err } - t.EnvironmentID = m["env_id"].(string) + id.EnvironmentID = parts[3] return nil } -func (t *EnvironmentID) Validate() error { - if t.EnvironmentID == "" { - return ErrInvalidID +func (id *EnvironmentId) FromMap(m map[string]any) error { + id.EnvironmentID, _ = m["env_id"].(string) + if id.EnvironmentID == "" { + return fmt.Errorf("%w: EnviromentID required", ErrInvalidID) } - - return t.SpaceID.Validate() + return id.SpaceId.FromMap(m) } -func parseEnvironmentID(parts []string) (*EnvironmentID, error) { - if len(parts) != 4 || parts[2] != EnvironmentsPrefix { - return nil, ErrInvalidID - } - - spaceID, err := parseSpaceID(parts[:2]) - if err != nil { - return nil, err +func (id *EnvironmentId) Validate() error { + if id.EnvironmentID == "" { + return fmt.Errorf("%w: EnvironmetnID required", ErrInvalidID) } - - var id EnvironmentID - id.EnvironmentID = parts[3] - id.SpaceID = *spaceID - return &id, nil + return id.SpaceId.Validate() } -func NewEnvironmentID(spaceID, id string) *ID { - return &ID{Descriptor: &EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: id}} +func NewEnvironmentId(spaceID, id string) *ObjectId { + return &ObjectId{Descriptor: &EnvironmentId{SpaceId: SpaceId{SpaceID: spaceID}, EnvironmentID: id}} } diff --git a/id/error.go b/id/error.go new file mode 100644 index 0000000000000000000000000000000000000000..e8332dc96a651e337cdc34ec83d06442ff27048e --- /dev/null +++ b/id/error.go @@ -0,0 +1,11 @@ +package id + +import "errors" + +var ( + ErrInvalidID = errors.New("invalid ObjectId") + ErrUnknownType = errors.New("unknown ObjectId type") + ErrHandlerNotFound = errors.New("ObjectId handler not found") + ErrTypeNotFound = errors.New("type key not found in map") + ErrInvalidType = errors.New("ObjectId should be a string") +) diff --git a/id/field.go b/id/field.go index ca1577552dc7df38d555549ddfc53a51e70e63f1..024732f2d44d7a2ac4db63418ba113563a379c8d 100644 --- a/id/field.go +++ b/id/field.go @@ -1,60 +1,82 @@ package id +import "fmt" + const ( Field = "field" FieldsPrefix = "fields" ) -type FieldID struct { - ItemID - FieldName string `json:"field_name,omitempty" bson:"field_name,omitempty"` +type FieldId struct { + ItemId + Field string `json:"field,omitempty" bson:"field,omitempty"` } -func (t *FieldID) Type() string { return Field } - -func (t *FieldID) String() string { - return Join(t.ItemID.String(), FieldsPrefix, t.FieldName) +var _ Descriptor = &FieldId{} +func (id *FieldId) New() Descriptor { + return &FieldId{} } -func (t *FieldID) ToMap() map[string]any { - m := t.ItemID.ToMap() - m["field_name"] = t.FieldName - m["type"] = Field - return m +func (id *FieldId) Type() string { return Field } + +func (id *FieldId) String() string { + return Join(id.ItemId.String(), FieldsPrefix, id.Field) + } -func (t *FieldID) FromMap(m map[string]any) error { - if err := t.ItemID.FromMap(m); err != nil { +func (id *FieldId) FromParts(parts []string) error { + if len(parts) != 10 || parts[8] != FieldsPrefix { + return ErrInvalidID + } + if err := id.ItemId.FromParts(parts[:8]); err != nil { return err } - t.FieldName = m["field_name"].(string) + id.Field = parts[9] return nil } -func (t *FieldID) Validate() error { - if t.FieldName == "" { - return ErrInvalidID - } - - return t.ItemID.Validate() +func (id *FieldId) Map() map[string]any { + m := id.ItemId.Map() + m["field"] = id.Field + m["type"] = Field + return m } -func parseFieldID(parts []string) (*FieldID, error) { - if len(parts) != 10 || parts[8] != FieldsPrefix { - return nil, ErrInvalidID +func (id *FieldId) FromMap(m map[string]any) error { + id.Field = m["field"].(string) + if id.Field == "" { + return fmt.Errorf("%w: Field required", ErrInvalidID) + } + + if err := id.ItemId.FromMap(m); err != nil { + return err } + return nil +} - itemID, err := parseItemID(parts[:8]) - if err != nil { - return nil, err +func (id *FieldId) Validate() error { + if id.Field == "" { + return fmt.Errorf("%w: Field required", ErrInvalidID) } - var id FieldID - id.ItemID = *itemID - id.FieldName = parts[9] - return &id, nil + return id.ItemId.Validate() } -func NewFieldID(spaceID, envID, collID, itemID, id string) *ID { - return &ID{Descriptor: &FieldID{ItemID: ItemID{CollectionID: CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: itemID}, FieldName: id}} + +func NewFieldId(spaceID, envID, collID, itemID, id string) *ObjectId { + return &ObjectId{Descriptor: &FieldId{ + ItemId: ItemId{ + CollectionId: CollectionId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{ + SpaceID: spaceID, + }, + EnvironmentID: envID, + }, + CollectionID: collID, + }, + ItemID: itemID, + }, + Field: id, + }} } diff --git a/id/id.go b/id/id.go deleted file mode 100644 index ca75c29f94b6fe9100b435e8f546835991bc9fa3..0000000000000000000000000000000000000000 --- a/id/id.go +++ /dev/null @@ -1,143 +0,0 @@ -package id - -import ( - "strings" - - "git.perx.ru/perxis/perxis-go/pkg/errors" -) - -const Separator = '/' - -var ( - ErrInvalidID = errors.New("invalid id") -) - -type Descriptor interface { - String() string - Type() string - ToMap() map[string]any - FromMap(map[string]any) error - Validate() error -} - -type ID struct { - Descriptor -} - -func Parse(s string) (*ID, error) { - parts := Split(s) - - if id, _ := parseServiceID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseUserID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseOrganizationID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseSpaceID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseEnvironmentID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseClientID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseRoleID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseCollectionID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseSchemaID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseItemID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseRevisionID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseFieldID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - if id, _ := parseSystemID(parts); id != nil { - return &ID{Descriptor: id}, nil - } - - return nil, ErrInvalidID -} - -func Split(id string) []string { - if id[0] != Separator { - return nil - } - return strings.Split(id[1:], string(Separator)) -} - -func Join(parts ...string) string { - s := strings.Join(parts, string(Separator)) - if s[0] != Separator { - s = string(Separator) + s - } - return s -} - -func FromMap(m map[string]any) (*ID, error) { - if m == nil { - return nil, errors.New("nil map") - } - - v := new(ID) - - switch m["type"] { - case Organization: - v.Descriptor = new(OrganizationID) - case Service: - v.Descriptor = new(ServiceID) - case User: - v.Descriptor = new(UserID) - case Space: - v.Descriptor = new(SpaceID) - case Environment: - v.Descriptor = new(EnvironmentID) - case Client: - v.Descriptor = new(ClientID) - case Role: - v.Descriptor = new(RoleID) - case Collection: - v.Descriptor = new(CollectionID) - case Schema: - v.Descriptor = new(SchemaID) - case Item: - v.Descriptor = new(ItemID) - case Revision: - v.Descriptor = new(RevisionID) - case Field: - v.Descriptor = new(FieldID) - case System: - v.Descriptor = new(SystemID) - default: - return nil, errors.New("unknown type") - } - - if err := v.Descriptor.FromMap(m); err != nil { - return nil, err - } - - return v, nil -} diff --git a/id/id_test.go b/id/id_test.go deleted file mode 100644 index 041f1cdc6018e6c84c0c4c6a4be4b3944ef34082..0000000000000000000000000000000000000000 --- a/id/id_test.go +++ /dev/null @@ -1,301 +0,0 @@ -package id - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_ParseID(t *testing.T) { - tests := []struct { - name string - id string - result *ID - wantError bool - }{ - { - name: "ServiceID", - id: "/services/<service_id>", - result: &ID{Descriptor: &ServiceID{ServiceID: "<service_id>"}}, - }, - { - name: "UserID", - id: "/users/<user_id>", - result: &ID{Descriptor: &UserID{UserID: "<user_id>"}}, - }, - { - name: "OrganizationID", - id: "/orgs/<org_id>", - result: &ID{Descriptor: &OrganizationID{OrganizationID: "<org_id>"}}, - }, - { - name: "SpaceID", - id: "/spaces/<space_id>", - result: &ID{Descriptor: &SpaceID{SpaceID: "<space_id>"}}, - }, - { - name: "ClientID", - id: "/spaces/<space_id>/clients/<client_id>", - result: &ID{Descriptor: &ClientID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - ClientID: "<client_id>", - }}, - }, - { - name: "RoleID", - id: "/spaces/<space_id>/roles/<role_id>", - result: &ID{Descriptor: &RoleID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - RoleID: "<role_id>", - }}, - }, - { - name: "EnvironmentID", - id: "/spaces/<space_id>/envs/<env_id>", - result: &ID{Descriptor: &EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }}, - }, - { - name: "CollectionID", - id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>", - result: &ID{Descriptor: &CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }}, - }, - { - name: "SchemaID", - id: "/spaces/<space_id>/envs/<env_id>/schema/<collection_id>", - result: &ID{Descriptor: &SchemaID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }}, - }, - { - name: "ItemID", - id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>", - result: &ID{Descriptor: &ItemID{ - CollectionID: CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }, - ItemID: "<item_id>", - }}, - }, - { - name: "RevisionID", - id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id>", - result: &ID{Descriptor: &RevisionID{ - ItemID: ItemID{ - CollectionID: CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }, - ItemID: "<item_id>", - }, - RevisionID: "<rev_id>", - }}, - }, - { - name: "FieldID", - id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field_name>", - result: &ID{Descriptor: &FieldID{ - ItemID: ItemID{ - CollectionID: CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }, - ItemID: "<item_id>", - }, - FieldName: "<field_name>", - }}, - }, - { - name: "SystemID", - id: "/system", - result: &ID{Descriptor: &SystemID{}}, - }, - { - name: "With error #1: no backslash in the beginning of id", - id: "spaces/<space_id>", - result: nil, - wantError: true, - }, - { - name: "With error #2: backslash in the end of id", - id: "/spaces/<space_id>/", - result: nil, - wantError: true, - }, - { - name: "With error #3: typo in 'spaces'", - id: "/space/<space_id>", - result: nil, - wantError: true, - }, - { - name: "With error #4: no space_id in id", - id: "/spaces", - result: nil, - wantError: true, - }, - { - name: "With error #5: multiple backslashes in the end of id", - id: "/spaces/<space_id>///", - result: nil, - wantError: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - id, err := Parse(tt.id) - if tt.wantError { - require.Error(t, err) - return - } - require.NoError(t, err) - require.Equal(t, tt.result, id) - require.Equal(t, tt.id, id.String(), "проверяем корректность работы метода String, полученное ID должно совпадать СЃ исходным") - }) - } -} - -func Test_Map(t *testing.T) { - tests := []struct { - name string - id *ID - }{ - { - name: "ServiceID", - id: &ID{Descriptor: &ServiceID{ServiceID: "<service_id>"}}, - }, - { - name: "UserID", - id: &ID{Descriptor: &UserID{UserID: "<user_id>"}}, - }, - { - name: "OrganizationID", - id: &ID{Descriptor: &OrganizationID{OrganizationID: "<org_id>"}}, - }, - { - name: "SpaceID", - id: &ID{Descriptor: &SpaceID{SpaceID: "<space_id>"}}, - }, - { - name: "ClientID", - id: &ID{Descriptor: &ClientID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - ClientID: "<client_id>", - }}, - }, - { - name: "RoleID", - id: &ID{Descriptor: &RoleID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - RoleID: "<role_id>", - }}, - }, - { - name: "EnvironmentID", - id: &ID{Descriptor: &EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }}, - }, - { - name: "CollectionID", - id: &ID{Descriptor: &CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }}, - }, - { - name: "Schema ID", - id: &ID{Descriptor: &SchemaID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }}, - }, - { - name: "ItemID", - id: &ID{Descriptor: &ItemID{ - CollectionID: CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }, - ItemID: "<item_id>", - }}, - }, - { - name: "RevisionID", - id: &ID{Descriptor: &RevisionID{ - ItemID: ItemID{ - CollectionID: CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }, - ItemID: "<item_id>", - }, - RevisionID: "<rev_id>", - }}, - }, - { - name: "FieldID", - id: &ID{Descriptor: &FieldID{ - ItemID: ItemID{ - CollectionID: CollectionID{ - EnvironmentID: EnvironmentID{ - SpaceID: SpaceID{SpaceID: "<space_id>"}, - EnvironmentID: "<env_id>", - }, - CollectionID: "<collection_id>", - }, - ItemID: "<item_id>", - }, - FieldName: "<field_name>", - }}, - }, - { - name: "SystemID", - id: &ID{Descriptor: &SystemID{}}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - v, err := FromMap(tt.id.ToMap()) - require.NoError(t, err) - assert.Equal(t, tt.id, v, "проверка FromMap для типа ID, должен быть равен РёСЃС…РѕРґРЅРѕРјСѓ значению") - assert.Equal(t, v.ToMap(), tt.id.ToMap()) - }) - } -} diff --git a/id/item.go b/id/item.go index 70c3e7be95b517a85e07e487eb00f94f9f73e14f..968175a2cb4f4429199d8848bd9409828461b08a 100644 --- a/id/item.go +++ b/id/item.go @@ -1,61 +1,68 @@ package id +import ( + "fmt" +) + const ( Item = "item" ItemsPrefix = "items" ) -type ItemID struct { - CollectionID +type ItemId struct { + CollectionId ItemID string `json:"item_id,omitempty" bson:"item_id,omitempty"` } -func (t *ItemID) Type() string { return Item } +var _ Descriptor = &ItemId{} + +func (i *ItemId) New() Descriptor { + return &ItemId{} +} + +func (i *ItemId) Type() string { return Item } -func (t *ItemID) String() string { - return Join(t.CollectionID.String(), ItemsPrefix, t.ItemID) +func (i *ItemId) String() string { + return Join(i.CollectionId.String(), ItemsPrefix, i.ItemID) } -func (t *ItemID) ToMap() map[string]any { - m := t.CollectionID.ToMap() - m["item_id"] = t.ItemID +func (i *ItemId) Map() map[string]any { + m := i.CollectionId.Map() + m["item_id"] = i.ItemID m["type"] = Item return m } -func (t *ItemID) FromMap(m map[string]any) error { - if err := t.CollectionID.FromMap(m); err != nil { +func (i *ItemId) FromParts(parts []string) error { + if len(parts) != 8 || parts[6] != ItemsPrefix { + return ErrInvalidID + } + + if err := i.CollectionId.FromParts(parts[:6]); err != nil { return err } - t.ItemID = m["item_id"].(string) + + i.ItemID = parts[7] return nil } -func (t *ItemID) Validate() error { - if t.ItemID == "" { - return ErrInvalidID +func (i *ItemId) FromMap(m map[string]any) error { + i.ItemID = m["item_id"].(string) + if i.ItemID == "" { + return fmt.Errorf("%w: ItemId required", ErrInvalidID) } - return t.CollectionID.Validate() + return i.CollectionId.FromMap(m) } -func parseItemID(parts []string) (*ItemID, error) { - if len(parts) != 8 || parts[6] != ItemsPrefix { - return nil, ErrInvalidID +func (i *ItemId) Validate() error { + if i.ItemID == "" { + return fmt.Errorf("%w: ItemId required", ErrInvalidID) } - - collID, err := parseCollectionID(parts[:6]) - if err != nil { - return nil, err - } - - var id ItemID - id.CollectionID = *collID - id.ItemID = parts[7] - return &id, nil + return i.CollectionId.Validate() } -func NewItemID(spaceID, envID, collID, id string) *ID { - return &ID{Descriptor: &ItemID{CollectionID: CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: id}} +func NewItemId(spaceID, envID, collID, id string) *ObjectId { + return &ObjectId{Descriptor: &ItemId{CollectionId: CollectionId{EnvironmentId: EnvironmentId{SpaceId: SpaceId{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: id}} } diff --git a/id/json.go b/id/json.go deleted file mode 100644 index 34b87589dfd81e6b793c5812fb2b90f43fb724f1..0000000000000000000000000000000000000000 --- a/id/json.go +++ /dev/null @@ -1,23 +0,0 @@ -package id - -import ( - jsoniter "github.com/json-iterator/go" -) - -func (id *ID) MarshalJSON() ([]byte, error) { - return jsoniter.Marshal(id.String()) -} - -func (id *ID) UnmarshalJSON(b []byte) error { - var s string - var err error - if err = jsoniter.Unmarshal(b, &s); err != nil { - return err - } - t, err := Parse(s) - if err != nil { - return err - } - *id = *t - return nil -} diff --git a/id/json_test.go b/id/json_test.go index afe831d4ef6038eaa6bc8a565b0623334cdf6bc8..0da4f292db94ffc93558b76ba702f63b0ce5a121 100644 --- a/id/json_test.go +++ b/id/json_test.go @@ -11,59 +11,59 @@ import ( func TestID_MarshalUnmarshalJSON(t *testing.T) { tests := []struct { name string - id *ID + id *ObjectId }{ { name: "OrganizationID", - id: &ID{Descriptor: &OrganizationID{OrganizationID: "1"}}, + id: &ObjectId{Descriptor: &OrganizationId{OrganizationID: "1"}}, }, { name: "UserID", - id: &ID{Descriptor: &UserID{UserID: "1"}}, + id: &ObjectId{Descriptor: &UserId{UserID: "1"}}, }, { name: "ServiceID", - id: &ID{Descriptor: &ServiceID{ServiceID: "1"}}, + id: &ObjectId{Descriptor: &ServiceId{ServiceID: "1"}}, }, { - name: "SpaceID", - id: &ID{Descriptor: &SpaceID{SpaceID: "1"}}, + name: "SpaceId", + id: &ObjectId{Descriptor: &SpaceId{SpaceID: "1"}}, }, { name: "EnvironmentID", - id: &ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + id: &ObjectId{Descriptor: &EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}, }, { name: "ClientID", - id: &ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + id: &ObjectId{Descriptor: &ClientId{ClientID: "1", SpaceId: SpaceId{SpaceID: "1"}}}, }, { name: "RoleID", - id: &ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}}, + id: &ObjectId{Descriptor: &RoleId{RoleID: "1", SpaceId: SpaceId{SpaceID: "1"}}}, }, { - name: "CollectionID", - id: &ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + name: "CollectionId", + id: &ObjectId{Descriptor: &CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}, }, { name: "SchemaID", - id: &ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}, + id: &ObjectId{Descriptor: &SchemaId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}, }, { - name: "ItemID", - id: &ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}, + name: "ItemId", + id: &ObjectId{Descriptor: &ItemId{ItemID: "1", CollectionId: CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}}, }, { name: "RevisionID", - id: &ID{Descriptor: &RevisionID{RevisionID: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + id: &ObjectId{Descriptor: &RevisionId{RevisionID: "1", ItemId: ItemId{ItemID: "1", CollectionId: CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}}}, }, { - name: "FieldID", - id: &ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}}, + name: "FieldId", + id: &ObjectId{Descriptor: &FieldId{Field: "1", ItemId: ItemId{ItemID: "1", CollectionId: CollectionId{CollectionID: "1", EnvironmentId: EnvironmentId{EnvironmentID: "1", SpaceId: SpaceId{SpaceID: "1"}}}}}}, }, { name: "SystemID", - id: &ID{Descriptor: &SystemID{}}, + id: &ObjectId{Descriptor: &SystemId{}}, }, } for _, tt := range tests { @@ -71,7 +71,7 @@ func TestID_MarshalUnmarshalJSON(t *testing.T) { b, err := jsoniter.Marshal(&tt.id) require.NoError(t, err) - var i ID + var i ObjectId require.NoError(t, jsoniter.Unmarshal(b, &i)) assert.Equal(t, tt.id, &i, "после Unmarshal объект должен быть идентичен РёСЃС…РѕРґРЅРѕРјСѓ") }) @@ -80,13 +80,13 @@ func TestID_MarshalUnmarshalJSON(t *testing.T) { func TestID_ExampleJSON(t *testing.T) { type data struct { - ID *ID + ID *ObjectId Text string Number int } test := &data{ - ID: &ID{Descriptor: &SpaceID{SpaceID: Space}}, + ID: &ObjectId{Descriptor: &SpaceId{SpaceID: Space}}, Text: "text", Number: 1, } diff --git a/id/object_id.go b/id/object_id.go new file mode 100644 index 0000000000000000000000000000000000000000..e84ea1c0fff9960bfef7584fbd68699509cfa2a6 --- /dev/null +++ b/id/object_id.go @@ -0,0 +1,102 @@ +package id + +import ( + jsoniter "github.com/json-iterator/go" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" + "strings" +) + +const Separator = '/' + +type Descriptor interface { + New() Descriptor + String() string + Type() string + Map() map[string]any + Validate() error + FromMap(map[string]any) error + FromParts([]string) error +} + +type ObjectId struct { + Descriptor +} + +func NewObjectId(in any) (*ObjectId, error) { + switch v := in.(type) { + case Descriptor: + return &ObjectId{Descriptor: v}, nil + case string: + return FromString(v) + case map[string]any: + return FromMap(v) + } + return FromObject(in) +} + +func MustObjectId(in any) *ObjectId { + oid, err := NewObjectId(in) + if err != nil { + panic(err) + } + return oid +} + +func (oid *ObjectId) MarshalJSON() ([]byte, error) { + return jsoniter.Marshal(oid.String()) +} + +func (oid *ObjectId) UnmarshalJSON(b []byte) error { + var s string + var err error + if err = jsoniter.Unmarshal(b, &s); err != nil { + return err + } + t, err := FromString(s) + if err != nil { + return err + } + *oid = *t + return nil +} + +func (oid *ObjectId) MarshalBSONValue() (bsontype.Type, []byte, error) { + return bson.MarshalValue(oid.String()) +} + +func (oid *ObjectId) UnmarshalBSONValue(btype bsontype.Type, data []byte) error { + if btype != bson.TypeString { + return ErrInvalidType + } + dec, err := bson.NewDecoder(bsonrw.NewBSONValueReader(btype, data)) + if err != nil { + return err + } + var str string + if err = dec.Decode(&str); err != nil { + return err + } + t, err := FromString(str) + if err != nil { + return err + } + *oid = *t + return nil +} + +func Join(parts ...string) string { + s := strings.Join(parts, string(Separator)) + if s[0] != Separator { + s = string(Separator) + s + } + return s +} + +func Split(id string) []string { + if id[0] != Separator { + return nil + } + return strings.Split(id[1:], string(Separator)) +} diff --git a/id/object_id_test.go b/id/object_id_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4f8d018139ce0b125e09124e5113e94c8031f5b3 --- /dev/null +++ b/id/object_id_test.go @@ -0,0 +1,253 @@ +package id + +import ( + "testing" + + "git.perx.ru/perxis/perxis-go/pkg/items" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_ParseID(t *testing.T) { + tests := []struct { + name string + id any + result *ObjectId + wantError bool + }{ + { + name: "SpaceId", + id: "/spaces/<space_id>", + result: MustObjectId("/spaces/<space_id>"), + }, + { + name: "ServiceID", + id: "/services/<service_id>", + result: MustObjectId("/services/<service_id>"), + }, + { + name: "UserID", + id: "/users/<user_id>", + result: MustObjectId("/users/<user_id>"), + }, + { + name: "OrganizationID", + id: "/orgs/<org_id>", + result: MustObjectId("/orgs/<org_id>"), + }, + { + name: "ClientID", + id: "/spaces/<space_id>/clients/<client_id>", + result: MustObjectId("/spaces/<space_id>/clients/<client_id>"), + }, + { + name: "RoleID", + id: "/spaces/<space_id>/roles/<role_id>", + result: MustObjectId("/spaces/<space_id>/roles/<role_id>"), + }, + { + name: "EnvironmentID", + id: "/spaces/<space_id>/envs/<env_id>", + result: MustObjectId("/spaces/<space_id>/envs/<env_id>"), + }, + { + name: "CollectionId", + id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>", + result: MustObjectId("/spaces/<space_id>/envs/<env_id>/cols/<collection_id>"), + }, + { + name: "SchemaID", + id: "/spaces/<space_id>/envs/<env_id>/schema/<collection_id>", + result: MustObjectId("/spaces/<space_id>/envs/<env_id>/schema/<collection_id>"), + }, + { + name: "ItemId", + id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>", + result: MustObjectId("/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>"), + }, + { + name: "RevisionID", + id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id>", + result: MustObjectId("/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id>"), + }, + { + name: "FieldId", + id: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field_name>", + result: MustObjectId("/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field_name>"), + }, + { + name: "With error #1: no backslash in the beginning of id", + id: "spaces/<space_id>", + result: nil, + wantError: true, + }, + { + name: "With error #2: backslash in the end of id", + id: "/spaces/<space_id>/", + result: nil, + wantError: true, + }, + { + name: "With error #3: typo in 'spaces'", + id: "/space/<space_id>", + result: nil, + wantError: true, + }, + { + name: "With error #4: no space_id in id", + id: "/spaces", + result: nil, + wantError: true, + }, + { + name: "With error #5: multiple backslashes in the end of id", + id: "/spaces/<space_id>///", + result: nil, + wantError: true, + }, + { + name: "With error #6: nil value", + id: nil, + wantError: true, + }, + { + name: "With error #7: nil object value", + id: (*items.Item)(nil), + wantError: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + id, err := NewObjectId(tt.id) + if tt.wantError { + require.Error(t, err) + return + } + require.NoError(t, err) + require.Equal(t, tt.result, id) + require.Equal(t, tt.id, id.String()) + }) + } +} + +func Test_Map(t *testing.T) { + tests := []struct { + name string + id *ObjectId + }{ + { + name: "ServiceID", + id: &ObjectId{Descriptor: &ServiceId{ServiceID: "<service_id>"}}, + }, + { + name: "UserID", + id: &ObjectId{Descriptor: &UserId{UserID: "<user_id>"}}, + }, + { + name: "OrganizationID", + id: &ObjectId{Descriptor: &OrganizationId{OrganizationID: "<org_id>"}}, + }, + { + name: "SpaceId", + id: &ObjectId{Descriptor: &SpaceId{SpaceID: "<space_id>"}}, + }, + { + name: "ClientID", + id: &ObjectId{Descriptor: &ClientId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + }, + { + name: "RoleID", + id: &ObjectId{Descriptor: &RoleId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + }, + { + name: "EnvironmentID", + id: &ObjectId{Descriptor: &EnvironmentId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + }, + { + name: "CollectionId", + id: &ObjectId{Descriptor: &CollectionId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }}, + }, + { + name: "Schema ID", + id: &ObjectId{Descriptor: &SchemaId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }}, + }, + { + name: "ItemId", + id: &ObjectId{Descriptor: &ItemId{ + CollectionId: CollectionId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }}, + }, + { + name: "RevisionID", + id: &ObjectId{Descriptor: &RevisionId{ + ItemId: ItemId{ + CollectionId: CollectionId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }, + RevisionID: "<rev_id>", + }}, + }, + { + name: "FieldId", + id: &ObjectId{Descriptor: &FieldId{ + ItemId: ItemId{ + CollectionId: CollectionId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }, + Field: "<field_name>", + }}, + }, + { + name: "SystemID", + id: &ObjectId{Descriptor: &SystemId{}}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v, err := FromMap(tt.id.Map()) + require.NoError(t, err) + assert.Equal(t, tt.id, v, "проверка FromMap для типа ID, должен быть равен РёСЃС…РѕРґРЅРѕРјСѓ значению") + assert.Equal(t, v.Map(), tt.id.Map()) + }) + } +} diff --git a/id/organization.go b/id/organization.go index fe9d22837977b486e78689ebee5f426bdee80fcf..5aedfb709ef6ff5bde9fd7f06bcba49f07fbd643 100644 --- a/id/organization.go +++ b/id/organization.go @@ -1,49 +1,60 @@ package id +import ( + "fmt" +) + const ( Organization = "organization" OrganizationsPrefix = "orgs" ) -type OrganizationID struct { +var _ Descriptor = &OrganizationId{} + +type OrganizationId struct { OrganizationID string `json:"organization_id,omitempty" bson:"organization_id,omitempty"` } -func (t *OrganizationID) Type() string { return Organization } +func (id *OrganizationId) New() Descriptor { + return &OrganizationId{} +} + +func (id *OrganizationId) Type() string { return Organization } -func (t *OrganizationID) String() string { - return Join(OrganizationsPrefix, t.OrganizationID) +func (id *OrganizationId) String() string { + return Join(OrganizationsPrefix, id.OrganizationID) } -func (t *OrganizationID) ToMap() map[string]any { - return map[string]any{ - "organization_id": t.OrganizationID, - "type": Organization, +func (id *OrganizationId) FromParts(parts []string) error { + if len(parts) != 2 || parts[0] != OrganizationsPrefix { + return ErrInvalidID } + id.OrganizationID = parts[1] + return nil } -func (t *OrganizationID) FromMap(m map[string]any) error { - t.OrganizationID = m["organization_id"].(string) - return nil +func (id *OrganizationId) Map() map[string]any { + return map[string]any{ + "organization_id": id.OrganizationID, + "type": id.Type(), + } } -func (t *OrganizationID) Validate() error { - if t.OrganizationID == "" { - return ErrInvalidID +func (id *OrganizationId) FromMap(m map[string]any) error { + id.OrganizationID, _ = m["organization_id"].(string) + if id.OrganizationID == "" { + return fmt.Errorf("%w: OrganizationId required", ErrInvalidID) } return nil } -func parseOrganizationID(parts []string) (*OrganizationID, error) { - var id OrganizationID - if len(parts) != 2 || parts[0] != OrganizationsPrefix { - return nil, ErrInvalidID +func (id *OrganizationId) Validate() error { + if id.OrganizationID == "" { + return fmt.Errorf("%w: OrganizationId required", ErrInvalidID) } - - id.OrganizationID = parts[1] - return &id, nil + return nil } -func NewOrganizationID(id string) *ID { - return &ID{Descriptor: &OrganizationID{OrganizationID: id}} +func NewOrganizationId(id string) *ObjectId { + return &ObjectId{Descriptor: &OrganizationId{OrganizationID: id}} } diff --git a/id/registry.go b/id/registry.go new file mode 100644 index 0000000000000000000000000000000000000000..0ffec0240952b742c33a4763c6ee49fa210ce4f0 --- /dev/null +++ b/id/registry.go @@ -0,0 +1,121 @@ +package id + +import ( + "fmt" + "reflect" +) + +var registry = NewRegistry() + +type ObjectHandler func(interface{}) *ObjectId + +type Registry struct { + handlers map[reflect.Type]ObjectHandler + descriptors map[string]Descriptor +} + +func NewRegistry() *Registry { + return &Registry{ + handlers: make(map[reflect.Type]ObjectHandler), + descriptors: make(map[string]Descriptor), + } +} + +// Register method adds a handler based on its type. +func (r *Registry) RegisterObjectHandler(t reflect.Type, h ObjectHandler) { + r.handlers[t] = h +} + +func (r *Registry) RegisterDescriptor(d Descriptor) { + r.descriptors[d.Type()] = d +} + +func (r *Registry) FromParts(s string) (*ObjectId, error) { + parts := Split(s) + + for _, d := range r.descriptors { + id := d.New() + if err := id.FromParts(parts); err == nil { + return &ObjectId{Descriptor: id}, nil + } + } + + return nil, fmt.Errorf("%w: %s", ErrInvalidID, s) +} + +func (r *Registry) FromMap(m map[string]interface{}) (*ObjectId, error) { + t, ok := m["type"].(string) + if !ok { + return nil, ErrTypeNotFound + } + + if d, ok := r.descriptors[t]; ok { + id := d.New() + if err := id.FromMap(m); err != nil { + return nil, err + } + return &ObjectId{Descriptor: id}, nil + } + + return nil, fmt.Errorf("%s: %s", t, ErrInvalidID) +} + +func (r *Registry) FromObject(v interface{}) (*ObjectId, error) { + value := reflect.ValueOf(v) + if v == nil || (value.Kind() == reflect.Ptr && value.IsNil()) { + return nil, fmt.Errorf("object value is nil") + } + + t := value.Type() + if handler, ok := r.handlers[t]; ok { + i := handler(v) + if i == nil { + panic(fmt.Sprintf("handler for %s returned nil", t)) + } + return i, nil + } + return nil, fmt.Errorf("%s : %w", t, ErrHandlerNotFound) +} + +func FromMap(m map[string]interface{}) (*ObjectId, error) { + return registry.FromMap(m) +} + +func FromString(s string) (*ObjectId, error) { + return registry.FromParts(s) +} + +type ObjectIdentifier interface { + ObjectId() *ObjectId +} + +func FromObject(v interface{}) (*ObjectId, error) { + if id, ok := v.(ObjectIdentifier); ok { + return id.ObjectId(), nil + } + return registry.FromObject(v) +} + +func RegisterSystemIds(r *Registry) { + r.RegisterDescriptor(&SpaceId{}) + r.RegisterDescriptor(&EnvironmentId{}) + r.RegisterDescriptor(&CollectionId{}) + r.RegisterDescriptor(&SchemaId{}) + r.RegisterDescriptor(&ItemId{}) + r.RegisterDescriptor(&RevisionId{}) + r.RegisterDescriptor(&FieldId{}) + r.RegisterDescriptor(&ClientId{}) + r.RegisterDescriptor(&RoleId{}) + r.RegisterDescriptor(&UserId{}) + r.RegisterDescriptor(&SystemId{}) + r.RegisterDescriptor(&ServiceId{}) + r.RegisterDescriptor(&OrganizationId{}) +} + +func GetRegistry() *Registry { + return registry +} + +func init() { + RegisterSystemIds(registry) +} diff --git a/id/revision.go b/id/revision.go index 0cb417e132fe1683f1e53a081e7c6244820478df..f8a2ecb4b893d71734e72bd1911a32173a3fd17c 100644 --- a/id/revision.go +++ b/id/revision.go @@ -1,61 +1,82 @@ package id +import "fmt" + const ( Revision = "revision" RevisionsPrefix = "revs" ) -type RevisionID struct { - ItemID +type RevisionId struct { + ItemId RevisionID string `json:"rev_id" bson:"rev_id,omitempty"` } -func (t *RevisionID) Type() string { return Revision } - -func (t *RevisionID) String() string { - return Join(t.ItemID.String(), RevisionsPrefix, t.RevisionID) +var _ Descriptor = &RevisionId{} +func (id *RevisionId) New() Descriptor { + return &RevisionId{} } -func (t *RevisionID) ToMap() map[string]any { - m := t.ItemID.ToMap() - m["rev_id"] = t.RevisionID - m["type"] = Revision - return m +func (id *RevisionId) Type() string { return Revision } + +func (id *RevisionId) String() string { + return Join(id.ItemId.String(), RevisionsPrefix, id.RevisionID) + } -func (t *RevisionID) FromMap(m map[string]any) error { - if err := t.ItemID.FromMap(m); err != nil { +func (id *RevisionId) FromParts(parts []string) error { + if len(parts) != 10 || parts[8] != RevisionsPrefix { + return ErrInvalidID + } + if err := id.ItemId.FromParts(parts[:8]); err != nil { return err } - t.RevisionID = m["rev_id"].(string) + id.RevisionID = parts[9] return nil } -func (t *RevisionID) Validate() error { - if t.RevisionID == "" { - return ErrInvalidID - } - - return t.ItemID.Validate() +func (id *RevisionId) Map() map[string]any { + m := id.ItemId.Map() + m["rev_id"] = id.RevisionID + m["type"] = Revision + return m } -func parseRevisionID(parts []string) (*RevisionID, error) { - if len(parts) != 10 || parts[8] != RevisionsPrefix { - return nil, ErrInvalidID +func (id *RevisionId) FromMap(m map[string]any) error { + id.RevisionID = m["rev_id"].(string) + if id.RevisionID == "" { + return fmt.Errorf("%w: RevisionId required", ErrInvalidID) } - itemID, err := parseItemID(parts[:8]) - if err != nil { - return nil, err + if err := id.ItemId.FromMap(m); err != nil { + return err } + return nil +} - var id RevisionID - id.ItemID = *itemID - id.RevisionID = parts[9] - return &id, nil +func (id *RevisionId) Validate() error { + if id.RevisionID == "" { + return fmt.Errorf("%w: RevisionId required", ErrInvalidID) + } + + return id.ItemId.Validate() } -func NewRevisionID(spaceID, envID, collID, itemID, id string) *ID { - return &ID{Descriptor: &RevisionID{ItemID: ItemID{CollectionID: CollectionID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: collID}, ItemID: itemID}, RevisionID: id}} +func NewRevisionID(spaceID, envID, collID, itemID, id string) *ObjectId { + return &ObjectId{Descriptor: &RevisionId{ + ItemId: ItemId{ + CollectionId: CollectionId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{ + SpaceID: spaceID, + }, + EnvironmentID: envID, + }, + CollectionID: collID, + }, + ItemID: itemID, + }, + RevisionID: id, + }} } diff --git a/id/role.go b/id/role.go index abb6537fc605d3f01f644a67a724cc81e3a6b54b..d9f8f01989b5bb9cca5da38acad867356b4dea92 100644 --- a/id/role.go +++ b/id/role.go @@ -1,61 +1,65 @@ package id +import ( + "fmt" +) + const ( Role = "role" RolesPrefix = "roles" ) -type RoleID struct { - SpaceID +var _ Descriptor = &RoleId{} + +type RoleId struct { + SpaceId RoleID string `json:"role_id,omitempty" bson:"role_id,omitempty"` } -func (t *RoleID) Type() string { return Role } - -func (t *RoleID) String() string { - return Join(t.SpaceID.String(), RolesPrefix, t.RoleID) - +func (id *RoleId) New() Descriptor { + return &RoleId{} } -func (t *RoleID) ToMap() map[string]any { - m := t.SpaceID.ToMap() - m["role_id"] = t.RoleID - m["type"] = Role - return m +func (id *RoleId) Type() string { return Role } + +func (id *RoleId) String() string { + return Join(id.SpaceId.String(), RolesPrefix, id.RoleID) } -func (t *RoleID) FromMap(m map[string]any) error { - if err := t.SpaceID.FromMap(m); err != nil { +func (id *RoleId) FromParts(parts []string) error { + if len(parts) != 4 || parts[2] != RolesPrefix { + return ErrInvalidID + } + if err := id.SpaceId.FromParts(parts[:2]); err != nil { return err } - t.RoleID = m["role_id"].(string) + id.RoleID = parts[3] return nil } -func (t *RoleID) Validate() error { - if t.RoleID == "" { - return ErrInvalidID - } - - return t.SpaceID.Validate() +func (id *RoleId) Map() map[string]any { + m := id.SpaceId.Map() + m["role_id"] = id.RoleID + m["type"] = Role + return m } -func parseRoleID(parts []string) (*RoleID, error) { - if len(parts) != 4 || parts[2] != RolesPrefix { - return nil, ErrInvalidID +func (id *RoleId) FromMap(m map[string]any) error { + id.RoleID = m["role_id"].(string) + if id.RoleID == "" { + return fmt.Errorf("%w: RoleID required", ErrInvalidID) } + return id.SpaceId.FromMap(m) +} - spaceID, err := parseSpaceID(parts[:2]) - if err != nil { - return nil, err +func (id *RoleId) Validate() error { + if id.RoleID == "" { + return fmt.Errorf("%w: RoleID required", ErrInvalidID) } - var id RoleID - id.SpaceID = *spaceID - id.RoleID = parts[3] - return &id, nil + return id.SpaceId.Validate() } -func NewRoleID(spaceID, id string) *ID { - return &ID{Descriptor: &RoleID{SpaceID: SpaceID{SpaceID: spaceID}, RoleID: id}} +func NewRoleId(spaceID, id string) *ObjectId { + return &ObjectId{Descriptor: &RoleId{SpaceId: SpaceId{SpaceID: spaceID}, RoleID: id}} } diff --git a/id/schema.go b/id/schema.go index e3afee8c6cf29bca6cae1f1eedd72253c47362a5..b1280f81ca440ae78ce128e471292e26a2db4a97 100644 --- a/id/schema.go +++ b/id/schema.go @@ -1,60 +1,70 @@ package id +import "fmt" + const ( Schema = "schema" SchemaPrefix = "schema" ) -type SchemaID struct { - EnvironmentID +var _ Descriptor = &SchemaId{} + +type SchemaId struct { + EnvironmentId CollectionID string `json:"col_id" bson:"col_id,omitempty"` } -func (t *SchemaID) Type() string { return Schema } +func (id *SchemaId) New() Descriptor { + return &SchemaId{} +} + +func (id *SchemaId) Type() string { return Schema } -func (t *SchemaID) String() string { - return Join(t.EnvironmentID.String(), SchemaPrefix, t.CollectionID) +func (id *SchemaId) String() string { + return Join(id.EnvironmentId.String(), SchemaPrefix, id.CollectionID) } -func (t *SchemaID) ToMap() map[string]any { - m := t.EnvironmentID.ToMap() - m["col_id"] = t.CollectionID +func (id *SchemaId) Map() map[string]any { + m := id.EnvironmentId.Map() + m["col_id"] = id.CollectionID m["type"] = Schema return m } -func (t *SchemaID) FromMap(m map[string]any) error { - if err := t.EnvironmentID.FromMap(m); err != nil { +func (id *SchemaId) FromParts(parts []string) error { + if len(parts) != 6 || parts[4] != SchemaPrefix { + return ErrInvalidID + } + if err := id.EnvironmentId.FromParts(parts[:4]); err != nil { return err } - t.CollectionID = m["col_id"].(string) + id.CollectionID = parts[5] return nil } -func (t *SchemaID) Validate() error { - if t.CollectionID == "" { - return ErrInvalidID +func (id *SchemaId) FromMap(m map[string]any) error { + id.CollectionID, _ = m["col_id"].(string) + if id.CollectionID == "" { + return fmt.Errorf("%w: SchemaID required", ErrInvalidID) } - - return t.EnvironmentID.Validate() + return id.EnvironmentId.FromMap(m) } -func parseSchemaID(parts []string) (*SchemaID, error) { - if len(parts) != 6 || parts[4] != SchemaPrefix { - return nil, ErrInvalidID +func (id *SchemaId) Validate() error { + if id.CollectionID == "" { + return fmt.Errorf("%w: SchemaID required", ErrInvalidID) } - - envID, err := parseEnvironmentID(parts[:4]) - if err != nil { - return nil, err - } - - var id SchemaID - id.EnvironmentID = *envID - id.CollectionID = parts[5] - return &id, nil + return id.EnvironmentId.Validate() } -func NewSchemaID(spaceID, envID, id string) *ID { - return &ID{Descriptor: &SchemaID{EnvironmentID: EnvironmentID{SpaceID: SpaceID{SpaceID: spaceID}, EnvironmentID: envID}, CollectionID: id}} +func NewSchemaId(spaceID, envID, id string) *ObjectId { + return &ObjectId{Descriptor: &SchemaId{ + EnvironmentId: EnvironmentId{ + SpaceId: SpaceId{ + SpaceID: spaceID, + }, + EnvironmentID: envID, + }, + CollectionID: id, + }} } diff --git a/id/service.go b/id/service.go index 23bb23aa500fbba082e1aae578eae6da5624a5b9..29c44ec635f763b9f35223f710f2d530f2dfb159 100644 --- a/id/service.go +++ b/id/service.go @@ -1,49 +1,58 @@ package id +import "fmt" + const ( Service = "service" ServicesPrefix = "services" ) -type ServiceID struct { +type ServiceId struct { ServiceID string `json:"service_id,omitempty" bson:"service_id,omitempty"` } -func (t *ServiceID) Type() string { return Service } +var _ Descriptor = &ServiceId{} -func (t *ServiceID) String() string { - return Join(ServicesPrefix, t.ServiceID) +func (id *ServiceId) New() Descriptor { + return &ServiceId{} } -func (t *ServiceID) ToMap() map[string]any { - return map[string]any{ - "service_id": t.ServiceID, - "type": Service, - } -} +func (id *ServiceId) Type() string { return Service } -func (t *ServiceID) FromMap(m map[string]any) error { - t.ServiceID = m["service_id"].(string) - return nil +func (id *ServiceId) String() string { + return Join(ServicesPrefix, id.ServiceID) } -func (t *ServiceID) Validate() error { - if t.ServiceID == "" { +func (id *ServiceId) FromParts(parts []string) error { + if len(parts) != 2 || parts[0] != ServicesPrefix { return ErrInvalidID } + id.ServiceID = parts[1] return nil } -func parseServiceID(parts []string) (*ServiceID, error) { - var id ServiceID - if len(parts) != 2 || parts[0] != ServicesPrefix { - return nil, ErrInvalidID +func (id *ServiceId) Map() map[string]any { + return map[string]any{ + "service_id": id.ServiceID, + "type": id.Type(), } +} - id.ServiceID = parts[1] - return &id, nil +func (id *ServiceId) FromMap(m map[string]any) error { + id.ServiceID, _ = m["service_id"].(string) + if id.ServiceID == "" { + return fmt.Errorf("%w: ServiceId required", ErrInvalidID) + } + return nil +} + +func (id *ServiceId) Validate() error { + if id.ServiceID == "" { + return fmt.Errorf("%w: ServiceId required", ErrInvalidID) + } + return nil } -func NewServiceID(id string) *ID { - return &ID{Descriptor: &ServiceID{ServiceID: id}} +func NewServiceID(id string) *ObjectId { + return &ObjectId{Descriptor: &ServiceId{ServiceID: id}} } diff --git a/id/space.go b/id/space.go index 39096673456d74462ef203b10814396fe48b2bcf..9859a4788b05fb906f6a22f230a4b88366ab9311 100644 --- a/id/space.go +++ b/id/space.go @@ -1,48 +1,61 @@ package id +import ( + "fmt" +) + const ( Space = "space" SpacesPrefix = "spaces" ) -type SpaceID struct { +var _ Descriptor = &SpaceId{} + +type SpaceId struct { SpaceID string `json:"space_id,omitempty" bson:"space_id,omitempty"` } -func (t *SpaceID) Type() string { return Space } +func (id *SpaceId) New() Descriptor { + return &SpaceId{} +} + +func (id *SpaceId) Type() string { return Space } -func (t *SpaceID) String() string { - return Join(SpacesPrefix, t.SpaceID) +func (id *SpaceId) String() string { + return Join(SpacesPrefix, id.SpaceID) } -func (t *SpaceID) ToMap() map[string]any { - return map[string]any{ - "space_id": t.SpaceID, - "type": Space, +func (id *SpaceId) FromParts(parts []string) error { + if len(parts) != 2 || parts[0] != SpacesPrefix { + return ErrInvalidID } -} -func (t *SpaceID) FromMap(m map[string]any) error { - t.SpaceID = m["space_id"].(string) + id.SpaceID = parts[1] return nil } -func (t *SpaceID) Validate() error { - if t.SpaceID == "" { - return ErrInvalidID +func (id *SpaceId) Map() map[string]any { + return map[string]any{ + "space_id": id.SpaceID, + "type": id.Type(), } - return nil } -func parseSpaceID(parts []string) (*SpaceID, error) { - var id SpaceID - if len(parts) != 2 || parts[0] != SpacesPrefix { - return nil, ErrInvalidID +func (id *SpaceId) FromMap(m map[string]any) error { + id.SpaceID, _ = m["space_id"].(string) + if id.SpaceID == "" { + return fmt.Errorf("%w: SpaceId required", ErrInvalidID) } + return nil +} - id.SpaceID = parts[1] - return &id, nil +func (id *SpaceId) Validate() error { + if id.SpaceID == "" { + return fmt.Errorf("%w: SpaceId required", ErrInvalidID) + } + return nil } -func NewSpaceID(id string) *ID { - return &ID{Descriptor: &SpaceID{SpaceID: id}} + +func NewSpaceId(id string) *ObjectId { + return &ObjectId{Descriptor: &SpaceId{SpaceID: id}} } diff --git a/id/system.go b/id/system.go index de2f3c2571896e448f8aad17be32df58b73a6ea4..f8f82faaf7ace71c255c32fb37657a1d7b28296a 100644 --- a/id/system.go +++ b/id/system.go @@ -2,21 +2,23 @@ package id const System = "system" -type SystemID struct{} +type SystemId struct{} -func (t *SystemID) Type() string { return Space } -func (t *SystemID) String() string { return string(Separator) + System } -func (t *SystemID) ToMap() map[string]any { return map[string]any{"type": System} } -func (t *SystemID) FromMap(m map[string]any) error { return nil } -func (t *SystemID) Validate() error { return nil } +var _ Descriptor = &SystemId{} -func parseSystemID(parts []string) (*SystemID, error) { - var id SystemID +func (id *SystemId) New() Descriptor { + return &SystemId{} +} + +func (id *SystemId) Type() string { return System } +func (id *SystemId) String() string { return string(Separator) + System } +func (id *SystemId) FromParts(parts []string) error { if len(parts) != 1 || parts[0] != System { - return nil, ErrInvalidID + return ErrInvalidID } - return &id, nil -} -func NewSystemID() *ID { - return &ID{Descriptor: &SystemID{}} + return nil } +func (id *SystemId) Map() map[string]any { return map[string]any{"type": System} } +func (id *SystemId) FromMap(m map[string]any) error { return nil } +func (id *SystemId) Validate() error { return nil } +func NewSystemId() *ObjectId { return &ObjectId{Descriptor: &SystemId{}} } diff --git a/id/system/system.go b/id/system/system.go new file mode 100644 index 0000000000000000000000000000000000000000..77084f5dcb8dc702b2b14337e97cdc97fd80930b --- /dev/null +++ b/id/system/system.go @@ -0,0 +1,97 @@ +package system + +import ( + "context" + "reflect" + + "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/clients" + "git.perx.ru/perxis/perxis-go/pkg/collections" + "git.perx.ru/perxis/perxis-go/pkg/environments" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/organizations" + "git.perx.ru/perxis/perxis-go/pkg/roles" + "git.perx.ru/perxis/perxis-go/pkg/spaces" + "git.perx.ru/perxis/perxis-go/pkg/users" +) + +func Handler(obj any) *id.ObjectId { + switch val := obj.(type) { + case *organizations.Organization: + var i id.OrganizationId + i.OrganizationID = val.ID + return id.MustObjectId(&i) + case *spaces.Space: + var i id.SpaceId + i.SpaceID = val.ID + return id.MustObjectId(&i) + case *environments.Environment: + var i id.EnvironmentId + i.SpaceID = val.SpaceID + i.EnvironmentID = val.ID + return id.MustObjectId(&i) + case *collections.Collection: + var i id.CollectionId + i.SpaceID = val.SpaceID + i.EnvironmentID = val.EnvID + i.CollectionID = val.ID + return id.MustObjectId(&i) + case *items.Item: + var i id.ItemId + i.SpaceID = val.SpaceID + i.EnvironmentID = val.EnvID + i.CollectionID = val.CollectionID + i.ItemID = val.ID + return id.MustObjectId(&i) + case *users.User: + var i id.UserId + i.UserID = val.ID + return id.MustObjectId(&i) + case *clients.Client: + var i id.ClientId + i.SpaceID = val.SpaceID + i.ClientID = val.ID + return id.MustObjectId(&i) + case *roles.Role: + var i id.RoleId + i.SpaceID = val.SpaceID + i.RoleID = val.ID + return id.MustObjectId(&i) + case *auth.UserPrincipal: + var i id.UserId + i.UserID = val.GetID(context.TODO()) + return id.MustObjectId(&i) + case *auth.ClientPrincipal: + var i id.ClientId + i.ClientID = val.GetID(context.TODO()) + return id.MustObjectId(&i) + case *auth.SystemPrincipal: + return id.MustObjectId(&id.SystemId{}) + case *auth.Anonymous: + var i id.UserId + i.UserID = val.GetID(context.TODO()) + return id.MustObjectId(&i) + } + return nil +} + +// Register registers object handler for system types into the provided Registry. +func Register(r *id.Registry) { + r.RegisterObjectHandler(reflect.TypeOf(&organizations.Organization{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&spaces.Space{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&environments.Environment{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&collections.Collection{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&items.Item{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&clients.Client{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&roles.Role{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&users.User{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&auth.UserPrincipal{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&auth.ClientPrincipal{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&auth.SystemPrincipal{}), Handler) + r.RegisterObjectHandler(reflect.TypeOf(&auth.Anonymous{}), Handler) +} + +func init() { + Register(id.GetRegistry()) +} diff --git a/id/test/object_id_test.go b/id/test/object_id_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f97e50e49068173b5aa1968de33abc4d8a44817b --- /dev/null +++ b/id/test/object_id_test.go @@ -0,0 +1,801 @@ +package test + +import ( + "testing" + + "git.perx.ru/perxis/perxis-go/id" + _ "git.perx.ru/perxis/perxis-go/id/system" + "git.perx.ru/perxis/perxis-go/pkg/clients" + "git.perx.ru/perxis/perxis-go/pkg/collections" + "git.perx.ru/perxis/perxis-go/pkg/environments" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/organizations" + "git.perx.ru/perxis/perxis-go/pkg/roles" + "git.perx.ru/perxis/perxis-go/pkg/spaces" + "git.perx.ru/perxis/perxis-go/pkg/users" + "github.com/stretchr/testify/require" +) + +func Test_OrganizationId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/orgs/<org_id>", + result: &id.ObjectId{Descriptor: &id.OrganizationId{OrganizationID: "<org_id>"}}, + }, + { + name: "valid object", + in: &organizations.Organization{ID: "<org_id>"}, + out: "/orgs/<org_id>", + result: &id.ObjectId{Descriptor: &id.OrganizationId{OrganizationID: "<org_id>"}}, + }, + { + name: "valid map", + in: map[string]any{"type": "organization", "organization_id": "<org_id>"}, + out: "/orgs/<org_id>", + result: &id.ObjectId{Descriptor: &id.OrganizationId{OrganizationID: "<org_id>"}}, + }, + { + name: "invalid map", + in: map[string]any{"type": "organization"}, + out: "/orgs/<org_id>", + result: &id.ObjectId{Descriptor: &id.OrganizationId{OrganizationID: "<org_id>"}}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_ServiceId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/services/<service_id>", + result: &id.ObjectId{Descriptor: &id.ServiceId{ServiceID: "<service_id>"}}, + }, + { + name: "valid map", + in: map[string]any{"type": "service", "service_id": "<service_id>"}, + out: "/services/<service_id>", + result: &id.ObjectId{Descriptor: &id.ServiceId{ServiceID: "<service_id>"}}, + }, + { + name: "invalid map", + in: map[string]any{"type": "service"}, + out: "/services/<service_id>", + result: &id.ObjectId{Descriptor: &id.ServiceId{ServiceID: "<service_id>"}}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_UserId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/users/<user_id>", + result: &id.ObjectId{Descriptor: &id.UserId{UserID: "<user_id>"}}, + }, + { + name: "valid object", + in: &users.User{ID: "<user_id>"}, + out: "/users/<user_id>", + result: &id.ObjectId{Descriptor: &id.UserId{UserID: "<user_id>"}}, + }, + { + name: "valid map", + in: map[string]any{"type": "user", "user_id": "<user_id>"}, + out: "/users/<user_id>", + result: &id.ObjectId{Descriptor: &id.UserId{UserID: "<user_id>"}}, + }, + { + name: "invalid map", + in: map[string]any{"type": "user"}, + out: "/users/<user_id>", + result: &id.ObjectId{Descriptor: &id.UserId{UserID: "<user_id>"}}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_SpaceId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>", + result: &id.ObjectId{Descriptor: &id.SpaceId{SpaceID: "<space_id>"}}, + }, + { + name: "valid object", + in: &spaces.Space{ID: "<space_id>"}, + out: "/spaces/<space_id>", + result: &id.ObjectId{Descriptor: &id.SpaceId{SpaceID: "<space_id>"}}, + }, + { + name: "valid map", + in: map[string]any{"type": "space", "space_id": "<space_id>"}, + out: "/spaces/<space_id>", + result: &id.ObjectId{Descriptor: &id.SpaceId{SpaceID: "<space_id>"}}, + }, + { + name: "invalid map", + in: map[string]any{"type": "space"}, + out: "/spaces/<space_id>", + result: &id.ObjectId{Descriptor: &id.SpaceId{SpaceID: "<space_id>"}}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_EnvironmentId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/envs/<env_id>", + result: &id.ObjectId{Descriptor: &id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + }, + { + name: "invalid string", + in: "/envs/<env_id>", + result: &id.ObjectId{Descriptor: &id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + err: id.ErrInvalidID, + }, + { + name: "valid object", + in: &environments.Environment{SpaceID: "<space_id>", ID: "<env_id>"}, + out: "/spaces/<space_id>/envs/<env_id>", + result: &id.ObjectId{Descriptor: &id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "environment", "space_id": "<space_id>", "env_id": "<env_id>"}, + out: "/spaces/<space_id>/envs/<env_id>", + result: &id.ObjectId{Descriptor: &id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + }, + { + name: "invalid map 1", + in: map[string]any{"type": "environment", "space_id": "<space_id>"}, + out: "/spaces/<space_id>/envs/<env_id>", + result: &id.ObjectId{Descriptor: &id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + err: id.ErrInvalidID, + }, + { + name: "invalid map 2", + in: map[string]any{"type": "environment", "env_id": "<env_id>"}, + out: "/spaces/<space_id>/envs/<env_id>", + result: &id.ObjectId{Descriptor: &id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_ClientId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/clients/<client_id>", + result: &id.ObjectId{Descriptor: &id.ClientId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + }, + { + name: "invalid string", + in: "/clients/<client_id>", + result: &id.ObjectId{Descriptor: &id.ClientId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + err: id.ErrInvalidID, + }, + { + name: "valid object", + in: &clients.Client{SpaceID: "<space_id>", ID: "<client_id>"}, + out: "/spaces/<space_id>/clients/<client_id>", + result: &id.ObjectId{Descriptor: &id.ClientId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "client", "space_id": "<space_id>", "client_id": "<client_id>"}, + out: "/spaces/<space_id>/clients/<client_id>", + result: &id.ObjectId{Descriptor: &id.ClientId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + }, + { + name: "invalid map 1", + in: map[string]any{"type": "client", "space_id": "<space_id>"}, + out: "/spaces/<space_id>/clients/<client_id>", + result: &id.ObjectId{Descriptor: &id.ClientId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + err: id.ErrInvalidID, + }, + { + name: "invalid map 2", + in: map[string]any{"type": "client", "client_id": "<client_id>"}, + out: "/spaces/<space_id>/clients/<client_id>", + result: &id.ObjectId{Descriptor: &id.ClientId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + ClientID: "<client_id>", + }}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_RoleId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/roles/<role_id>", + result: &id.ObjectId{Descriptor: &id.RoleId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + }, + { + name: "invalid string", + in: "/roles/<role_id>", + result: &id.ObjectId{Descriptor: &id.RoleId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + err: id.ErrInvalidID, + }, + { + name: "valid object", + in: &roles.Role{SpaceID: "<space_id>", ID: "<role_id>"}, + out: "/spaces/<space_id>/roles/<role_id>", + result: &id.ObjectId{Descriptor: &id.RoleId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "role", "space_id": "<space_id>", "role_id": "<role_id>"}, + out: "/spaces/<space_id>/roles/<role_id>", + result: &id.ObjectId{Descriptor: &id.RoleId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + }, + { + name: "invalid map 1", + in: map[string]any{"type": "client", "space_id": "<space_id>"}, + out: "/spaces/<space_id>/roles/<role_id>", + result: &id.ObjectId{Descriptor: &id.RoleId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + err: id.ErrInvalidID, + }, + { + name: "invalid map 2", + in: map[string]any{"type": "role", "role_id": "<role_id>"}, + out: "/spaces/<space_id>/roles/<role_id>", + result: &id.ObjectId{Descriptor: &id.RoleId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + RoleID: "<role_id>", + }}, + err: id.ErrInvalidID, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_CollectionId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>", + result: &id.ObjectId{Descriptor: &id.CollectionId{ + EnvironmentId: id.EnvironmentId{SpaceId: id.SpaceId{SpaceID: "<space_id>"}, EnvironmentID: "<env_id>"}, + CollectionID: "<collection_id>", + }}, + }, + { + name: "valid object", + in: &collections.Collection{SpaceID: "<space_id>", EnvID: "<env_id>", ID: "<collection_id>"}, + out: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>", + result: &id.ObjectId{Descriptor: &id.CollectionId{ + EnvironmentId: id.EnvironmentId{SpaceId: id.SpaceId{SpaceID: "<space_id>"}, EnvironmentID: "<env_id>"}, + CollectionID: "<collection_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "collection", "space_id": "<space_id>", "env_id": "<env_id>", "col_id": "<collection_id>"}, + out: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>", + result: &id.ObjectId{Descriptor: &id.CollectionId{ + EnvironmentId: id.EnvironmentId{SpaceId: id.SpaceId{SpaceID: "<space_id>"}, EnvironmentID: "<env_id>"}, + CollectionID: "<collection_id>", + }}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_SchemaId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/envs/<env_id>/schema/<collection_id>", + result: &id.ObjectId{Descriptor: &id.SchemaId{ + EnvironmentId: id.EnvironmentId{SpaceId: id.SpaceId{SpaceID: "<space_id>"}, EnvironmentID: "<env_id>"}, + CollectionID: "<collection_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "schema", "space_id": "<space_id>", "env_id": "<env_id>", "col_id": "<collection_id>"}, + out: "/spaces/<space_id>/envs/<env_id>/schema/<collection_id>", + result: &id.ObjectId{Descriptor: &id.SchemaId{ + EnvironmentId: id.EnvironmentId{SpaceId: id.SpaceId{SpaceID: "<space_id>"}, EnvironmentID: "<env_id>"}, + CollectionID: "<collection_id>", + }}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_ItemId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>", + result: &id.ObjectId{Descriptor: &id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }}, + }, + { + name: "valid object", + in: &items.Item{SpaceID: "<space_id>", EnvID: "<env_id>", CollectionID: "<collection_id>", ID: "<item_id>"}, + out: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>", + result: &id.ObjectId{Descriptor: &id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "item", "space_id": "<space_id>", "env_id": "<env_id>", "col_id": "<collection_id>", "item_id": "<item_id>"}, + out: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>", + result: &id.ObjectId{Descriptor: &id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_FieldId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field>", + result: &id.ObjectId{Descriptor: &id.FieldId{ + ItemId: id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }, + Field: "<field>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "field", "space_id": "<space_id>", "env_id": "<env_id>", "col_id": "<collection_id>", "item_id": "<item_id>", "field": "<field>"}, + out: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field>", + result: &id.ObjectId{Descriptor: &id.FieldId{ + ItemId: id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }, + Field: "<field>", + }}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} + +func Test_RevisionId(t *testing.T) { + + tests := []struct { + name string + in any + out string + result *id.ObjectId + err error + }{ + { + name: "valid string", + in: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id>", + result: &id.ObjectId{Descriptor: &id.RevisionId{ + ItemId: id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }, + RevisionID: "<rev_id>", + }}, + }, + { + name: "valid map", + in: map[string]any{"type": "revision", "space_id": "<space_id>", "env_id": "<env_id>", "col_id": "<collection_id>", "item_id": "<item_id>", "rev_id": "<rev_id>"}, + out: "/spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id>", + result: &id.ObjectId{Descriptor: &id.RevisionId{ + ItemId: id.ItemId{ + CollectionId: id.CollectionId{ + EnvironmentId: id.EnvironmentId{ + SpaceId: id.SpaceId{SpaceID: "<space_id>"}, + EnvironmentID: "<env_id>", + }, + CollectionID: "<collection_id>", + }, + ItemID: "<item_id>", + }, + RevisionID: "<rev_id>", + }}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i, err := id.NewObjectId(tt.in) + + if tt.err != nil { + require.ErrorIs(t, err, tt.err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.result, i) + if tt.out == "" { + require.Equal(t, tt.in, i.String()) + } else { + require.Equal(t, tt.out, i.String()) + } + }) + } +} diff --git a/id/user.go b/id/user.go index c76f6c9fa0e8ce440a1ef15e36bbb82a73301be5..85459c7e29e94bcaf3edce684ec2d28eb8669a50 100644 --- a/id/user.go +++ b/id/user.go @@ -1,49 +1,60 @@ package id +import ( + "fmt" +) + const ( User = "user" UsersPrefix = "users" ) -type UserID struct { +type UserId struct { UserID string `json:"user_id,omitempty" bson:"user_id,omitempty"` } -func (t *UserID) Type() string { return User } +var _ Descriptor = &UserId{} -func (t *UserID) String() string { - return Join(UsersPrefix, t.UserID) +func (id *UserId) New() Descriptor { + return &UserId{} } -func (t *UserID) ToMap() map[string]any { - return map[string]any{ - "user_id": t.UserID, - "type": User, - } -} +func (id *UserId) Type() string { return User } -func (t *UserID) FromMap(m map[string]any) error { - t.UserID = m["user_id"].(string) - return nil +func (id *UserId) String() string { + return Join(UsersPrefix, id.UserID) } -func (t *UserID) Validate() error { - if t.UserID == "" { +func (id *UserId) FromParts(parts []string) error { + if len(parts) != 2 || parts[0] != UsersPrefix { return ErrInvalidID } + id.UserID = parts[1] return nil } -func parseUserID(parts []string) (*UserID, error) { - var id UserID - if len(parts) != 2 || parts[0] != UsersPrefix { - return nil, ErrInvalidID +func (id *UserId) Map() map[string]any { + return map[string]any{ + "user_id": id.UserID, + "type": id.Type(), } +} - id.UserID = parts[1] - return &id, nil +func (id *UserId) FromMap(m map[string]any) error { + id.UserID, _ = m["user_id"].(string) + if id.UserID == "" { + return fmt.Errorf("%w: UserId required", ErrInvalidID) + } + return nil +} + +func (id *UserId) Validate() error { + if id.UserID == "" { + return fmt.Errorf("%w: UserId required", ErrInvalidID) + } + return nil } -func NewUserID(id string) *ID { - return &ID{Descriptor: &UserID{UserID: id}} +func NewUserId(id string) *ObjectId { + return &ObjectId{Descriptor: &UserId{UserID: id}} } diff --git a/images/middleware/access_logging_middleware.go b/images/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..0a5f5ec2374db349e5eea81ec147d8258649412f --- /dev/null +++ b/images/middleware/access_logging_middleware.go @@ -0,0 +1,53 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/images" + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/files" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements images.Images that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next images.Images +} + +// AccessLoggingMiddleware instruments an implementation of the images.Images with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next images.Images) images.Images { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, source *files.File, opts *images.GetOptions) (result *files.File, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("source", source), + zap.Reflect("opts", opts), + ) + + result, err = m.next.Get(ctx, source, opts) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("result", result), + zap.Error(err), + ) + + return result, err +} diff --git a/images/middleware/logging_middleware.go b/images/middleware/logging_middleware.go deleted file mode 100644 index a69a56ee6a236aab96b1d22340691a63e36fdc01..0000000000000000000000000000000000000000 --- a/images/middleware/logging_middleware.go +++ /dev/null @@ -1,73 +0,0 @@ -// Code generated by gowrap. DO NOT EDIT. -// template: ../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -package middleware - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/access_log -o logging_middleware.go -l "" - -import ( - "context" - "fmt" - "time" - - "git.perx.ru/perxis/perxis-go/images" - "git.perx.ru/perxis/perxis-go/pkg/auth" - "git.perx.ru/perxis/perxis-go/pkg/files" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements images.Images that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next images.Images -} - -// LoggingMiddleware instruments an implementation of the images.Images with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next images.Images) images.Images { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Get(ctx context.Context, source *files.File, opts *images.GetOptions) (result *files.File, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "source": source, - "opts": opts} { - 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...) - - result, err = m.next.Get(ctx, source, opts) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "result": result, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return result, err -} diff --git a/images/middleware/middleware.go b/images/middleware/middleware.go index e29bdeb8c6e7a5e2d6b298d01069f4566481e80a..bf07dd54eb80280edf4ea7edc2ac43d66085ae2d 100644 --- a/images/middleware/middleware.go +++ b/images/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/images" @@ -17,12 +17,12 @@ func WithLog(s images.Images, logger *zap.Logger, log_access bool) images.Images if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Images") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/images/middleware/recovering_middleware.go b/images/middleware/recovering_middleware.go index 9ad61603a2584b58f4635c9ee8296f67f047b7a5..9c0a447e802a95d3002f6e45060a2a359024ff5a 100644 --- a/images/middleware/recovering_middleware.go +++ b/images/middleware/recovering_middleware.go @@ -1,5 +1,5 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/recovery +// template: ../../assets/templates/middleware/recovery // gowrap: http://github.com/hexdigest/gowrap package middleware diff --git a/logs/client.go b/logs/client.go new file mode 100644 index 0000000000000000000000000000000000000000..fc6a5b901343514c27a9f39e2c5c50ab234f1be7 --- /dev/null +++ b/logs/client.go @@ -0,0 +1,71 @@ +package logs + +import ( + "context" + + errorsgrpc "git.perx.ru/perxis/perxis-go/pkg/errors/grpc" + "git.perx.ru/perxis/perxis-go/pkg/options" + pb "git.perx.ru/perxis/perxis-go/proto/logs" + "google.golang.org/grpc" +) + +type Client struct { + client pb.LogsServiceClient +} + +var _ Service = &Client{} + +func NewClient(conn *grpc.ClientConn) *Client { + return &Client{ + client: pb.NewLogsServiceClient(conn), + } +} + +func (c *Client) Log(ctx context.Context, entries []*Entry) error { + var pbEntries []*pb.LogEntry + for _, e := range entries { + pbEntries = append(pbEntries, EntryToPB(e)) + } + response, err := c.client.Log(ctx, &pb.LogRequest{Entries: pbEntries}) + if err != nil { + return err + } + if response.GetError() != nil { + return errorsgrpc.ErrorFromProto(nil, response.GetError()) + } + return nil +} + +func (c *Client) Find(ctx context.Context, filter *Filter, opts *options.FindOptions) (*FindResult, error) { + request := new(pb.FindRequest) + + if filter != nil { + request.Filter = &pb.Filter{Q: filter.Q} + } + + request.Options = options.FindOptionsToPB(opts) + + response, err := c.client.Find(ctx, request) + if err != nil { + return nil, err + } + if response.GetError() != nil { + return nil, errorsgrpc.ErrorFromProto(nil, response.GetError()) + } + return FindResultFromPB(response.GetResult()), nil +} + +func (c *Client) Delete(ctx context.Context, filter *Filter) error { + request := new(pb.DeleteRequest) + if filter != nil { + request.Filter = &pb.Filter{Q: filter.Q} + } + response, err := c.client.Delete(ctx, &pb.DeleteRequest{Filter: &pb.Filter{Q: filter.Q}}) + if err != nil { + return err + } + if response.GetError() != nil { + return errorsgrpc.ErrorFromProto(nil, response.GetError()) + } + return nil +} diff --git a/logs/log.go b/logs/log.go new file mode 100644 index 0000000000000000000000000000000000000000..2bc9dedf82c450e54d46363fbe63eceb44b1a50d --- /dev/null +++ b/logs/log.go @@ -0,0 +1,127 @@ +package logs + +import ( + "time" + + "git.perx.ru/perxis/perxis-go/id" + pb "git.perx.ru/perxis/perxis-go/proto/logs" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type Level int + +const ( + Info = Level(pb.LogLevel_INFO) + Warning = Level(pb.LogLevel_WARNING) + Error = Level(pb.LogLevel_ERROR) + Critical = Level(pb.LogLevel_CRITICAL) + Fatal = Level(pb.LogLevel_FATAL) +) + +func (l Level) String() string { + s := pb.LogLevel_name[int32(l)] + if s == "" { + s = "UNKNOWN" + } + return s +} + +type Entry struct { + ID string `json:"id" bson:"id" mapstructure:"id"` + Timestamp time.Time `json:"timestamp,omitempty" bson:"timestamp,omitempty" mapstructure:"timestamp,omitempty"` + LogLevel Level `json:"log_level,omitempty" bson:"log_level,omitempty" mapstructure:"log_level,omitempty"` + Message string `json:"message,omitempty" bson:"message,omitempty" mapstructure:"message,omitempty"` + Category string `json:"category,omitempty" bson:"category,omitempty" mapstructure:"category,omitempty"` + Component string `json:"component,omitempty" bson:"component,omitempty" mapstructure:"component,omitempty"` + Event string `json:"event,omitempty" bson:"event,omitempty" mapstructure:"event,omitempty"` + ObjectID *id.ObjectId `json:"object_id,omitempty" bson:"object_id,omitempty" mapstructure:"object_id,omitempty"` + CallerID *id.ObjectId `json:"caller_id,omitempty" bson:"caller_id,omitempty" mapstructure:"caller_id,omitempty"` + Attr interface{} `json:"attr,omitempty" bson:"attr,omitempty" mapstructure:"attr,omitempty"` + Tags []string `json:"tags,omitempty" bson:"tags,omitempty" mapstructure:"tags,omitempty"` +} + +//func convertInterfaceToAny(v interface{}) (*any.Any, error) { +// anyValue := &any.Any{} +// bytes, _ := json.Marshal(v) +// bytesValue := &wrappers.BytesValue{ +// Value: bytes, +// } +// err := anypb.MarshalFrom(anyValue, bytesValue, proto.MarshalOptions{}) +// return anyValue, err +//} + +func EntryToPB(entry *Entry) *pb.LogEntry { + logEntry := &pb.LogEntry{ + Id: entry.ID, + Timestamp: timestamppb.New(entry.Timestamp), + Level: pb.LogLevel(entry.LogLevel), + Message: entry.Message, + Category: entry.Category, + Component: entry.Component, + Event: entry.Event, + Attr: nil, //implement + Tags: entry.Tags, + } + if entry.ObjectID != nil { + logEntry.ObjectId = entry.ObjectID.String() + } + if entry.CallerID != nil { + logEntry.CallerId = entry.CallerID.String() + } + + return logEntry +} + +func EntryFromPB(request *pb.LogEntry) *Entry { + logEntry := &Entry{ + ID: request.Id, + Timestamp: request.Timestamp.AsTime(), + LogLevel: Level(request.Level), + Message: request.Message, + Category: request.Category, + Component: request.Component, + Event: request.Event, + } + + if request.ObjectId != "" { + logEntry.ObjectID, _ = id.NewObjectId(request.ObjectId) + } + if request.CallerId != "" { + logEntry.CallerID, _ = id.NewObjectId(request.CallerId) + } + if request.Attr != nil { + logEntry.Attr = request.Attr // todo: как СЃ этим работать? + } + if request.Tags != nil { + logEntry.Tags = request.Tags + } + + return logEntry +} + +func (e *Entry) ToMap() map[string]any { + res := map[string]any{ + "id": e.ID, + "timestamp": e.Timestamp, + "log_level": e.LogLevel, + "message": e.Message, + "category": e.Category, + "component": e.Component, + "event": e.Event, + } + if e.ObjectID != nil { + res["object_id"] = e.ObjectID.String() + res["object"] = e.ObjectID.Map() + } + if e.CallerID != nil { + res["caller_id"] = e.CallerID.String() + res["caller"] = e.CallerID.Map() + } + if e.Attr != nil { + res["attr"] = e.Attr + } + if e.Tags != nil { + res["tags"] = e.Tags + } + return res +} diff --git a/logs/log_test.go b/logs/log_test.go new file mode 100644 index 0000000000000000000000000000000000000000..9ccb7e7065cccf5b3945339b6085a108e6b0fae2 --- /dev/null +++ b/logs/log_test.go @@ -0,0 +1,66 @@ +package logs + +import ( + "testing" + "time" + + "git.perx.ru/perxis/perxis-go/id" + "github.com/stretchr/testify/assert" +) + +func TestEntry_ToMap(t *testing.T) { + type fields struct { + ID string + Timestamp time.Time + LogLevel Level + Message string + Category string + Component string + Event string + ObjectId *id.ObjectId + CallerId *id.ObjectId + Attr interface{} + Tags []string + } + tests := []struct { + name string + fields fields + want map[string]interface{} + }{ + { + "#1", + fields{ + "1", + time.Time{}, + 0, + "message", + "", + "", + "", + id.MustObjectId("/spaces/<space_id>/envs/<env_id>"), + id.MustObjectId("/users/<user_id>"), + nil, + nil, + }, + map[string]interface{}{"caller": map[string]interface{}{"type": "user", "user_id": "<user_id>"}, "caller_id": "/users/<user_id>", "category": "", "component": "", "event": "", "id": "1", "log_level": Level(0), "message": "message", "object": map[string]interface{}{"env_id": "<env_id>", "space_id": "<space_id>", "type": "environment"}, "object_id": "/spaces/<space_id>/envs/<env_id>", "timestamp": time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &Entry{ + ID: tt.fields.ID, + Timestamp: tt.fields.Timestamp, + LogLevel: tt.fields.LogLevel, + Message: tt.fields.Message, + Category: tt.fields.Category, + Component: tt.fields.Component, + Event: tt.fields.Event, + ObjectID: tt.fields.ObjectId, + CallerID: tt.fields.CallerId, + Attr: tt.fields.Attr, + Tags: tt.fields.Tags, + } + assert.Equal(t, tt.want, e.ToMap()) + }) + } +} diff --git a/logs/middleware/error_logging_middleware.go b/logs/middleware/error_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..5d6ab71065765f8c366dcf4f6528f944e27f87b1 --- /dev/null +++ b/logs/middleware/error_logging_middleware.go @@ -0,0 +1,61 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../assets/templates/middleware/error_log +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/logs -i Service -t ../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" + +import ( + "context" + + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/options" + "go.uber.org/zap" +) + +// errorLoggingMiddleware implements logs.Service that is instrumented with logging +type errorLoggingMiddleware struct { + logger *zap.Logger + next logs.Service +} + +// ErrorLoggingMiddleware instruments an implementation of the logs.Service with simple logging +func ErrorLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next logs.Service) logs.Service { + return &errorLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *errorLoggingMiddleware) Delete(ctx context.Context, filter *logs.Filter) (err error) { + logger := m.logger + defer func() { + if err != nil { + logger.Warn("response error", zap.Error(err)) + } + }() + return m.next.Delete(ctx, filter) +} + +func (m *errorLoggingMiddleware) Find(ctx context.Context, filter *logs.Filter, options *options.FindOptions) (fp1 *logs.FindResult, err error) { + logger := m.logger + defer func() { + if err != nil { + logger.Warn("response error", zap.Error(err)) + } + }() + return m.next.Find(ctx, filter, options) +} + +func (m *errorLoggingMiddleware) Log(ctx context.Context, entries []*logs.Entry) (err error) { + logger := m.logger + defer func() { + if err != nil { + logger.Warn("response error", zap.Error(err)) + } + }() + return m.next.Log(ctx, entries) +} diff --git a/logs/middleware/logging_middleware.go b/logs/middleware/logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..3a425bf03a64b0f5fa6d998db8d4076f92755d29 --- /dev/null +++ b/logs/middleware/logging_middleware.go @@ -0,0 +1,89 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/logs -i Service -t ../../assets/templates/middleware/access_log.tmpl -o logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/options" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements logs.Service that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next logs.Service +} + +// AccessLoggingMiddleware instruments an implementation of the logs.Service with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next logs.Service) logs.Service { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, filter *logs.Filter) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("filter", filter), + ) + + err = m.next.Delete(ctx, filter) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Find(ctx context.Context, filter *logs.Filter, options *options.FindOptions) (fp1 *logs.FindResult, err error) { + begin := time.Now() + + m.logger.Debug("Find.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + fp1, err = m.next.Find(ctx, filter, options) + + m.logger.Debug("Find.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("fp1", fp1), + zap.Error(err), + ) + + return fp1, err +} + +func (m *accessLoggingMiddleware) Log(ctx context.Context, entries []*logs.Entry) (err error) { + begin := time.Now() + + m.logger.Debug("Log.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("entries", entries), + ) + + err = m.next.Log(ctx, entries) + + m.logger.Debug("Log.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/logs/middleware/middleware.go b/logs/middleware/middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..120d2b41cc8d392ed7ca2eff73f1f8b47c3dcc14 --- /dev/null +++ b/logs/middleware/middleware.go @@ -0,0 +1,28 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../assets/templates/middleware/middleware.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/logs -i Service -t ../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" + +import ( + "git.perx.ru/perxis/perxis-go/logs" + "go.uber.org/zap" +) + +type Middleware func(logs.Service) logs.Service + +func WithLog(s logs.Service, logger *zap.Logger, log_access bool) logs.Service { + if logger == nil { + logger = zap.NewNop() + } + logger = logger.Named("Service") + if log_access { + s = AccessLoggingMiddleware(logger)(s) + } + s = ErrorLoggingMiddleware(logger)(s) + + s = RecoveringMiddleware(logger)(s) + return s +} diff --git a/logs/middleware/recovering_middleware.go b/logs/middleware/recovering_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..950963dbf13a88fb5d82cecc7f983f1a605d0f84 --- /dev/null +++ b/logs/middleware/recovering_middleware.go @@ -0,0 +1,68 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../assets/templates/middleware/recovery +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/logs -i Service -t ../../assets/templates/middleware/recovery -o recovering_middleware.go -l "" + +import ( + "context" + "fmt" + + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/options" + "go.uber.org/zap" +) + +// recoveringMiddleware implements logs.Service that is instrumented with logging +type recoveringMiddleware struct { + logger *zap.Logger + next logs.Service +} + +// RecoveringMiddleware instruments an implementation of the logs.Service with simple logging +func RecoveringMiddleware(logger *zap.Logger) Middleware { + return func(next logs.Service) logs.Service { + return &recoveringMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *recoveringMiddleware) Delete(ctx context.Context, filter *logs.Filter) (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.Delete(ctx, filter) +} + +func (m *recoveringMiddleware) Find(ctx context.Context, filter *logs.Filter, options *options.FindOptions) (fp1 *logs.FindResult, 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.Find(ctx, filter, options) +} + +func (m *recoveringMiddleware) Log(ctx context.Context, entries []*logs.Entry) (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.Log(ctx, entries) +} diff --git a/logs/middleware/telemetry_middleware.go b/logs/middleware/telemetry_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..2aebc795b22d770c369f0445bfa543bde6828ac2 --- /dev/null +++ b/logs/middleware/telemetry_middleware.go @@ -0,0 +1,151 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../assets/templates/middleware/telemetry +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/logs -i Service -t ../../assets/templates/middleware/telemetry -o telemetry_middleware.go -l "" + +// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/options" + "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + otelmetric "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" +) + +// telemetryMiddleware implements logs.Service interface instrumented with opentracing spans +type telemetryMiddleware struct { + logs.Service + _instance string + requestMetrics *metrics.RequestMetrics + _spanDecorator func(span trace.Span, params, results map[string]interface{}) +} + +// TelemetryMiddleware returns telemetryMiddleware +func TelemetryMiddleware(base logs.Service, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) telemetryMiddleware { + requestMetrics, err := metrics.GetRequestMetrics() + if err != nil { + panic(err) + } + + d := telemetryMiddleware{ + Service: base, + _instance: instance, + requestMetrics: requestMetrics, + } + + if len(spanDecorator) > 0 && spanDecorator[0] != nil { + d._spanDecorator = spanDecorator[0] + } + + return d +} + +// Delete implements logs.Service +func (_d telemetryMiddleware) Delete(ctx context.Context, filter *logs.Filter) (err error) { + attributes := otelmetric.WithAttributeSet(attribute.NewSet( + attribute.String("service", "Service"), + attribute.String("method", "Delete"), + )) + + _d.requestMetrics.Total.Add(ctx, 1, attributes) + + start := time.Now() + ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Service.Delete") + + defer func() { + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "filter": filter}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + _span.End() + }() + return _d.Service.Delete(ctx, filter) +} + +// Find implements logs.Service +func (_d telemetryMiddleware) Find(ctx context.Context, filter *logs.Filter, options *options.FindOptions) (fp1 *logs.FindResult, err error) { + attributes := otelmetric.WithAttributeSet(attribute.NewSet( + attribute.String("service", "Service"), + attribute.String("method", "Find"), + )) + + _d.requestMetrics.Total.Add(ctx, 1, attributes) + + start := time.Now() + ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Service.Find") + + defer func() { + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "filter": filter, + "options": options}, map[string]interface{}{ + "fp1": fp1, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + _span.End() + }() + return _d.Service.Find(ctx, filter, options) +} + +// Log implements logs.Service +func (_d telemetryMiddleware) Log(ctx context.Context, entries []*logs.Entry) (err error) { + attributes := otelmetric.WithAttributeSet(attribute.NewSet( + attribute.String("service", "Service"), + attribute.String("method", "Log"), + )) + + _d.requestMetrics.Total.Add(ctx, 1, attributes) + + start := time.Now() + ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Service.Log") + + defer func() { + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "entries": entries}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + _span.End() + }() + return _d.Service.Log(ctx, entries) +} diff --git a/logs/mocks/Service.go b/logs/mocks/Service.go new file mode 100644 index 0000000000000000000000000000000000000000..af4da73bc4d4c7b088fbfea7e7babc4c1ba30e36 --- /dev/null +++ b/logs/mocks/Service.go @@ -0,0 +1,97 @@ +// Code generated by mockery v2.40.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + log2 "git.perx.ru/perxis/perxis-go/logs" + mock "github.com/stretchr/testify/mock" + + options "git.perx.ru/perxis/perxis-go/pkg/options" +) + +// Service is an autogenerated mock type for the Service type +type Service struct { + mock.Mock +} + +// Delete provides a mock function with given fields: ctx, filter +func (_m *Service) Delete(ctx context.Context, filter *log2.Filter) error { + ret := _m.Called(ctx, filter) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *log2.Filter) error); ok { + r0 = rf(ctx, filter) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Find provides a mock function with given fields: ctx, filter, _a2 +func (_m *Service) Find(ctx context.Context, filter *log2.Filter, _a2 *options.FindOptions) (*log2.FindResult, error) { + ret := _m.Called(ctx, filter, _a2) + + if len(ret) == 0 { + panic("no return value specified for Find") + } + + var r0 *log2.FindResult + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *log2.Filter, *options.FindOptions) (*log2.FindResult, error)); ok { + return rf(ctx, filter, _a2) + } + if rf, ok := ret.Get(0).(func(context.Context, *log2.Filter, *options.FindOptions) *log2.FindResult); ok { + r0 = rf(ctx, filter, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*log2.FindResult) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *log2.Filter, *options.FindOptions) error); ok { + r1 = rf(ctx, filter, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Log provides a mock function with given fields: ctx, entries +func (_m *Service) Log(ctx context.Context, entries []*log2.Entry) error { + ret := _m.Called(ctx, entries) + + if len(ret) == 0 { + panic("no return value specified for Log") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []*log2.Entry) error); ok { + r0 = rf(ctx, entries) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewService creates a new instance of Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewService(t interface { + mock.TestingT + Cleanup(func()) +}) *Service { + mock := &Service{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/logs/mocks/Storage.go b/logs/mocks/Storage.go new file mode 100644 index 0000000000000000000000000000000000000000..87a6376d47ee44ece2f9d2458ee05e48a162b8ca --- /dev/null +++ b/logs/mocks/Storage.go @@ -0,0 +1,140 @@ +// Code generated by mockery v2.40.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + log2 "git.perx.ru/perxis/perxis-go/logs" + mock "github.com/stretchr/testify/mock" + + options "git.perx.ru/perxis/perxis-go/pkg/options" +) + +// Storage is an autogenerated mock type for the Storage type +type Storage struct { + mock.Mock +} + +// Delete provides a mock function with given fields: ctx, filter +func (_m *Storage) Delete(ctx context.Context, filter *log2.Filter) error { + ret := _m.Called(ctx, filter) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *log2.Filter) error); ok { + r0 = rf(ctx, filter) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Find provides a mock function with given fields: ctx, filter, _a2 +func (_m *Storage) Find(ctx context.Context, filter *log2.Filter, _a2 *options.FindOptions) ([]*log2.Entry, int, error) { + ret := _m.Called(ctx, filter, _a2) + + if len(ret) == 0 { + panic("no return value specified for Find") + } + + var r0 []*log2.Entry + var r1 int + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, *log2.Filter, *options.FindOptions) ([]*log2.Entry, int, error)); ok { + return rf(ctx, filter, _a2) + } + if rf, ok := ret.Get(0).(func(context.Context, *log2.Filter, *options.FindOptions) []*log2.Entry); ok { + r0 = rf(ctx, filter, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*log2.Entry) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *log2.Filter, *options.FindOptions) int); ok { + r1 = rf(ctx, filter, _a2) + } else { + r1 = ret.Get(1).(int) + } + + if rf, ok := ret.Get(2).(func(context.Context, *log2.Filter, *options.FindOptions) error); ok { + r2 = rf(ctx, filter, _a2) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Init provides a mock function with given fields: ctx +func (_m *Storage) Init(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Log provides a mock function with given fields: ctx, entry +func (_m *Storage) Log(ctx context.Context, entry []*log2.Entry) error { + ret := _m.Called(ctx, entry) + + if len(ret) == 0 { + panic("no return value specified for Log") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []*log2.Entry) error); ok { + r0 = rf(ctx, entry) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Reset provides a mock function with given fields: ctx +func (_m *Storage) Reset(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Reset") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewStorage creates a new instance of Storage. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewStorage(t interface { + mock.TestingT + Cleanup(func()) +}) *Storage { + mock := &Storage{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/logs/service.go b/logs/service.go new file mode 100644 index 0000000000000000000000000000000000000000..34b3b4e61bd4b24c43dea910dcc54874deab13c5 --- /dev/null +++ b/logs/service.go @@ -0,0 +1,76 @@ +package logs + +import ( + "context" + + itemstransportgrpc "git.perx.ru/perxis/perxis-go/pkg/items/transport/grpc" + "git.perx.ru/perxis/perxis-go/pkg/options" + pb "git.perx.ru/perxis/perxis-go/proto/logs" +) + +const ServiceName = "logs" + +type Service interface { + + // Log метод записи логов + Log(ctx context.Context, entries []*Entry) error + + // Find метод для РїРѕРёСЃРєР° логов РїРѕ заданным параметрам + Find(ctx context.Context, filter *Filter, options *options.FindOptions) (*FindResult, error) + + // Delete метод для удаления логов РїРѕ заданным параметрам + Delete(ctx context.Context, filter *Filter) error +} + +type Filter struct { + Q []string +} + +type FindResult struct { + Entries []*Entry + Filter *Filter + Options *options.FindOptions + Total uint32 +} + +func FindResultToPB(result *FindResult) *pb.FindResult { + findResult := &pb.FindResult{ + Total: result.Total, + } + + entries := make([]*pb.LogEntry, 0, len(result.Entries)) + for _, e := range result.Entries { + entries = append(entries, EntryToPB(e)) + } + findResult.Entries = entries + + if result.Filter != nil { + findResult.Filter.Q = result.Filter.Q + } + if result.Options != nil { + findResult.Options, _ = itemstransportgrpc.PtrServicesFindOptionsToProto(result.Options) + } + + return findResult +} + +func FindResultFromPB(result *pb.FindResult) *FindResult { + findResult := &FindResult{ + Total: result.Total, + } + + entries := make([]*Entry, 0, len(result.Entries)) + for _, e := range result.Entries { + entries = append(entries, EntryFromPB(e)) + } + findResult.Entries = entries + + if result.Filter != nil { + findResult.Filter.Q = result.Filter.Q + } + if result.Options != nil { + findResult.Options, _ = itemstransportgrpc.ProtoToPtrServicesFindOptions(result.Options) + } + + return findResult +} diff --git a/logs/storage.go b/logs/storage.go new file mode 100644 index 0000000000000000000000000000000000000000..e6271dace2fca81715c0fa2d0982191c4fa517e6 --- /dev/null +++ b/logs/storage.go @@ -0,0 +1,15 @@ +package logs + +import ( + "context" + + "git.perx.ru/perxis/perxis-go/pkg/options" +) + +type Storage interface { + Init(ctx context.Context) error + Reset(ctx context.Context) error + Log(ctx context.Context, entry []*Entry) error + Find(ctx context.Context, filter *Filter, options *options.FindOptions) ([]*Entry, int, error) + Delete(ctx context.Context, filter *Filter) error +} diff --git a/logs/zap/buffered_write_syncer.go b/logs/zap/buffered_write_syncer.go new file mode 100644 index 0000000000000000000000000000000000000000..e862a79d115ecd82bc09622276d4194d39715345 --- /dev/null +++ b/logs/zap/buffered_write_syncer.go @@ -0,0 +1,182 @@ +package zap + +import ( + "context" + "sync" + "time" + + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/errors" +) + +const ( + defaultMaxBufferSize = 1000 + defaultMaxSyncQueueSize = 16 + defaultFlushInterval = 5 * time.Second +) + +var SyncQueueOverflow = errors.New("sync queue overflow") + +// BufferedWriteSyncer это WriteSyncer, который отправляет записи РІ logs.Service. +// РљРѕРіРґР° количество буферизированных записей достигает некоторого предела или РїСЂРѕС…РѕРґРёС‚ определенный фиксированный интервал, +// записи отправляются РІ очередь для синхронизации СЃ logs.Service. +type BufferedWriteSyncer struct { + // FlushInterval устанавливает интервал, через который буферизированные записи Р±СѓРґСѓС‚ отправлены РЅР° синхронизацию. + // + // Значение РїРѕ умолчанию для этого параметра равно 5 секунд. + FlushInterval time.Duration + + // MaxBufferSize устанавливает максимальное количество записей, которые РјРѕРіСѓС‚ быть буферизованы. + // РљРѕРіРґР° количество буферизованных записей превысит этот РїРѕСЂРѕРі, РѕРЅРё Р±СѓРґСѓС‚ отправлены РЅР° синхронизацию РІ logs.Service. + // + // Значение РїРѕ умолчанию для этого параметра равно 1000. + MaxBufferSize int + + // MaxSyncQueueSize устанавливает максимальный размер очереди записей РЅР° синхронизацию СЃ logs.Service. + // + // Значение РїРѕ умолчанию для этого параметра равно 16. + MaxSyncQueueSize int + + // Service сервис для хранения записей + Service logs.Service + + wg sync.WaitGroup + mu sync.RWMutex + buffer []*logs.Entry + syncQueue chan []*logs.Entry + + flushStop chan struct{} // flushStop закрывается, РєРѕРіРґР° flushLoop должен быть остановлен + started bool // started указывает, был ли выполнен Start + stopped bool // stopped указывает, был ли выполнен Stop +} + +func (ws *BufferedWriteSyncer) start() { + if ws.Service == nil { + panic("service is required") + } + + if ws.FlushInterval == 0 { + ws.FlushInterval = defaultFlushInterval + } + + if ws.MaxBufferSize == 0 { + ws.MaxBufferSize = defaultMaxBufferSize + } + + if ws.MaxSyncQueueSize == 0 { + ws.MaxSyncQueueSize = defaultMaxSyncQueueSize + } + + ws.buffer = make([]*logs.Entry, 0, ws.MaxBufferSize) + ws.syncQueue = make(chan []*logs.Entry, ws.MaxSyncQueueSize) + ws.flushStop = make(chan struct{}) + + ws.wg.Add(2) + go ws.syncLoop() + go ws.flushLoop() + + ws.started = true +} + +func (ws *BufferedWriteSyncer) Stop() error { + ws.mu.Lock() + defer ws.mu.Unlock() + + if !ws.started || ws.stopped { + return nil + } + ws.stopped = true + + close(ws.flushStop) // завершаем flushLoop + + err := ws.flush() // очищаем оставшиеся записи + + close(ws.syncQueue) // завершаем syncLoop + + ws.wg.Wait() // дожидаемся завершения flushLoop Рё syncLoop + + return err +} + +// Write отправляет запись РІ буфер. +// РљРѕРіРґР° количество буферизованных записей превышает максимальный размер буфера, буферизированные записи Р±СѓРґСѓС‚ отправлены РЅР° синхронизацию. +func (ws *BufferedWriteSyncer) Write(entry *logs.Entry) error { + ws.mu.Lock() + defer ws.mu.Unlock() + + if !ws.started { + ws.start() + } + + // Проверяем, РЅРµ достигли ли РјС‹ предела размера буфера. Если это так, тогда освобождаем его. + if len(ws.buffer)+1 > ws.MaxBufferSize { + err := ws.flush() + if err != nil { + return err + } + } + + ws.buffer = append(ws.buffer, entry) + + return nil +} + +// Sync освобождает буфер Рё отправляет буферизированные записи РЅР° синхронизацию. +func (ws *BufferedWriteSyncer) Sync() error { + ws.mu.Lock() + defer ws.mu.Unlock() + + if ws.started { + return ws.flush() + } + + return nil +} + +// flush освобождает буфер Рё отправляет буферизированные записи РЅР° синхронизацию. +// Если очередь РЅР° синхронизацию переполнена, будет возвращена ошибка SyncQueueOverflow +// +// Р’РќРРњРђРќРР•: РќРµ является безопасным для конкурентного вызова. +func (ws *BufferedWriteSyncer) flush() error { + if len(ws.buffer) == 0 { + return nil + } + + // Проверяем, РЅРµ достигли ли РјС‹ предела размера очереди. Если это так, возвращаем ошибку. + if len(ws.syncQueue)+1 > ws.MaxSyncQueueSize { + return SyncQueueOverflow + } + + ws.syncQueue <- ws.buffer + ws.buffer = make([]*logs.Entry, 0, ws.MaxBufferSize) + + return nil +} + +// flushLoop периодически отправляет буферизированные записи РЅР° синхронизацию. +func (ws *BufferedWriteSyncer) flushLoop() { + ticker := time.NewTicker(ws.FlushInterval) + defer func() { + ticker.Stop() + ws.wg.Done() + }() + + for { + select { + case <-ticker.C: + _ = ws.Sync() + case <-ws.flushStop: + return + } + } +} + +// syncLoop синхронизирует записи СЃ logs.Service. +func (ws *BufferedWriteSyncer) syncLoop() { + defer ws.wg.Done() + + for entries := range ws.syncQueue { + _ = ws.Service.Log(auth.WithSystem(context.Background()), entries) + } +} diff --git a/logs/zap/buffered_write_syncer_test.go b/logs/zap/buffered_write_syncer_test.go new file mode 100644 index 0000000000000000000000000000000000000000..073663edc829dd1847ce416b704916ec92ccc80c --- /dev/null +++ b/logs/zap/buffered_write_syncer_test.go @@ -0,0 +1,131 @@ +package zap + +import ( + "sync" + "testing" + "time" + + "git.perx.ru/perxis/perxis-go/logs" + logmocks "git.perx.ru/perxis/perxis-go/logs/mocks" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestBufferedWriteSyncer_Write(t *testing.T) { + service := &logmocks.Service{} + service.On("Log", mock.Anything, mock.Anything). + Return(nil). + Run(func(args mock.Arguments) { + entries := args.Get(1).([]*logs.Entry) + require.Equal(t, 2, len(entries)) + }). + Once() + + ws := &BufferedWriteSyncer{Service: service} + + err := ws.Write(&logs.Entry{Message: "first log message"}) + require.NoError(t, err) + + err = ws.Write(&logs.Entry{Message: "second log message"}) + require.NoError(t, err) + + err = ws.Stop() + require.NoError(t, err) + + service.AssertExpectations(t) +} + +func TestBufferedWriteSyncer_Write_Concurrent(t *testing.T) { + service := &logmocks.Service{} + service.On("Log", mock.Anything, mock.Anything). + Return(nil). + Run(func(args mock.Arguments) { + entries := args.Get(1).([]*logs.Entry) + require.Equal(t, 100, len(entries)) + }). + Once() + + ws := &BufferedWriteSyncer{Service: service} + + var wg sync.WaitGroup + for i := 0; i < 100; i++ { + wg.Add(1) + go func(wg *sync.WaitGroup) { + defer wg.Done() + require.NoError(t, ws.Write(&logs.Entry{Message: "log message"})) + }(&wg) + } + + wg.Wait() + require.NoError(t, ws.Stop()) + + service.AssertExpectations(t) +} + +func TestBufferedWriteSyncer_Flush(t *testing.T) { + service := &logmocks.Service{} + service.On("Log", mock.Anything, mock.Anything). + Return(nil). + Run(func(args mock.Arguments) { + entries := args.Get(1).([]*logs.Entry) + require.Equal(t, 10, len(entries)) + }). + Times(10) + + ws := &BufferedWriteSyncer{Service: service} + + for i := 0; i < 10; i++ { + for j := 0; j < 10; j++ { + require.NoError(t, ws.Write(&logs.Entry{Message: "log message"})) + } + require.NoError(t, ws.Sync()) + } + + require.NoError(t, ws.Stop()) + + service.AssertExpectations(t) +} + +func TestBufferedWriteSyncer_MaxBufferSize(t *testing.T) { + service := &logmocks.Service{} + service.On("Log", mock.Anything, mock.Anything). + Return(nil). + Run(func(args mock.Arguments) { + entries := args.Get(1).([]*logs.Entry) + assert.Equal(t, 10, len(entries)) + }). + Times(10) + + ws := &BufferedWriteSyncer{Service: service, MaxBufferSize: 10} + + for i := 0; i < 100; i++ { + require.NoError(t, ws.Write(&logs.Entry{Message: "log message"})) + } + + require.NoError(t, ws.Stop()) + + service.AssertExpectations(t) +} + +func TestBufferedWriteSyncer_FlushInterval(t *testing.T) { + service := &logmocks.Service{} + service.On("Log", mock.Anything, mock.Anything). + Return(nil). + Run(func(args mock.Arguments) { + entries := args.Get(1).([]*logs.Entry) + assert.Equal(t, 10, len(entries)) + }). + Once() + + ws := &BufferedWriteSyncer{Service: service, FlushInterval: time.Second} + + for j := 0; j < 10; j++ { + require.NoError(t, ws.Write(&logs.Entry{Message: "log message"})) + } + + time.Sleep(3 * time.Second) // ждем, РїРѕРєР° сработает интервал + require.NoError(t, ws.Stop()) + + service.AssertExpectations(t) +} diff --git a/logs/zap/core.go b/logs/zap/core.go new file mode 100644 index 0000000000000000000000000000000000000000..3b0c3305f685f8dfe52628dd49c1d4716fda9e91 --- /dev/null +++ b/logs/zap/core.go @@ -0,0 +1,94 @@ +package zap + +import ( + "fmt" + + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/id" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// WriteSyncer отвечает Р·Р° хранение Рё синхронизацию logs.Entry +type WriteSyncer interface { + Write(entry *logs.Entry) error + Sync() error +} + +// Core кодирует zapcore.Entry РІ logs.Entry Рё отправляет РёС… РІ WriteSyncer +type Core struct { + zapcore.LevelEnabler + + writeSyncer WriteSyncer + fields []zap.Field +} + +func NewCore(writeSyncer WriteSyncer) *Core { + return &Core{ + LevelEnabler: zapcore.InfoLevel, + writeSyncer: writeSyncer, + } +} + +func (core *Core) With(fields []zapcore.Field) zapcore.Core { + return &Core{ + LevelEnabler: core.LevelEnabler, + writeSyncer: core.writeSyncer, + fields: append(core.fields, fields...), + } +} + +func (core *Core) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry { + if core.Enabled(entry.Level) { + return checkedEntry.AddCore(entry, core) + } + return checkedEntry +} + +func (core *Core) Write(entry zapcore.Entry, fields []zapcore.Field) error { + return core.writeSyncer.Write(core.getEntry(entry, fields)) +} + +func (core *Core) Sync() error { + return core.writeSyncer.Sync() +} + +func (core *Core) getEntry(entry zapcore.Entry, fields []zapcore.Field) *logs.Entry { + if len(core.fields) > 0 { + fields = append(fields, core.fields...) + } + + enc := zapcore.NewMapObjectEncoder() + for _, field := range fields { + field.AddTo(enc) + } + + ent := &logs.Entry{ + ID: id.GenerateNewID(), + Timestamp: entry.Time, + LogLevel: logs.Level(entry.Level), + Message: entry.Message, + } + + ent.Category, _ = enc.Fields["category"].(string) + ent.Component, _ = enc.Fields["component"].(string) + ent.Event, _ = enc.Fields["event"].(string) + ent.ObjectID, _ = enc.Fields["object"].(*oid.ObjectId) + ent.CallerID, _ = enc.Fields["caller"].(*oid.ObjectId) + ent.Attr = enc.Fields["attr"] + + if err, _ := enc.Fields["error"].(error); err != nil { + ent.Message = fmt.Sprintf("%s. Error: %s", ent.Message, err.Error()) + } + + if tags, ok := enc.Fields["tags"].([]any); ok { + for _, item := range tags { + if tag, ok := item.(string); ok { + ent.Tags = append(ent.Tags, tag) + } + } + } + + return ent +} diff --git a/logs/zap/core_test.go b/logs/zap/core_test.go new file mode 100644 index 0000000000000000000000000000000000000000..aabe9cea3da3f4eb4da1d0696c7c6fb08753cc63 --- /dev/null +++ b/logs/zap/core_test.go @@ -0,0 +1,65 @@ +package zap + +import ( + "testing" + + "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/logs" + logzap "git.perx.ru/perxis/perxis-go/zap" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func TestCore_getEntry(t *testing.T) { + core := NewCore(nil) + + tests := []struct { + name string + input struct { + entry zapcore.Entry + fields []zapcore.Field + } + want *logs.Entry + }{ + { + name: "simple", + input: struct { + entry zapcore.Entry + fields []zapcore.Field + }{ + entry: zapcore.Entry{Level: zapcore.InfoLevel, Message: "создан элемент коллекции"}, + fields: []zapcore.Field{ + zap.String("key", "val"), // будет проигнорировано + logzap.Category("create"), + logzap.Component("Items.Service"), + logzap.Event("Items.Create"), + logzap.Object("/spaces/WPNN/envs/9VGP/cols/GxNv/items/W0fl"), + logzap.Caller("/users/PHVz"), + logzap.Attr("any"), + logzap.Tags("tag1", "tag2", "tag3"), + }, + }, + want: &logs.Entry{ + LogLevel: logs.Level(zapcore.InfoLevel), + Message: "создан элемент коллекции", + Category: "create", + Component: "Items.Service", + Event: "Items.Create", + ObjectID: id.MustObjectId("/spaces/WPNN/envs/9VGP/cols/GxNv/items/W0fl"), + CallerID: id.MustObjectId("/users/PHVz"), + Attr: "any", + Tags: []string{"tag1", "tag2", "tag3"}, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := core.getEntry(tc.input.entry, tc.input.fields) + got.ID = tc.want.ID // игнорируем ID + got.Timestamp = tc.want.Timestamp // игнорируем Timestamp + require.Equal(t, tc.want, got) + }) + } +} diff --git a/logs/zap/example_test.go b/logs/zap/example_test.go new file mode 100644 index 0000000000000000000000000000000000000000..9dfd0aaa2f33820c72bffcdd6ecae965672ad838 --- /dev/null +++ b/logs/zap/example_test.go @@ -0,0 +1,97 @@ +package zap + +import ( + "context" + "reflect" + "slices" + "testing" + + "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/logs" + logmocks "git.perx.ru/perxis/perxis-go/logs/mocks" + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/users" + usersmocks "git.perx.ru/perxis/perxis-go/pkg/users/mocks" + logzap "git.perx.ru/perxis/perxis-go/zap" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func TestExample(t *testing.T) { + item := items.NewItem("WPNN", "9VGP", "GxNv", "W0fl", nil, nil) + user := &users.User{ID: "294de355"} + + wantEntries := []*logs.Entry{ + { + LogLevel: logs.Level(zapcore.InfoLevel), + Message: "Successfully created", + Component: "Items", + Event: items.EventCreateItem, + ObjectID: id.MustObjectId(item), + CallerID: id.MustObjectId(user), + Tags: []string{"tag1", "tag2", "tag3"}, + }, + { + LogLevel: logs.Level(zapcore.WarnLevel), + Message: "Successfully updated", + Component: "Items", + Event: items.EventUpdateItem, + ObjectID: id.MustObjectId(item), + CallerID: id.MustObjectId(user), + Attr: map[string]map[string]any{"title": {"old": "old title", "new": "new title"}}, + }, + } + + service := &logmocks.Service{} + service.On("Log", mock.Anything, mock.Anything). + Return(nil). + Run(func(args mock.Arguments) { + entries := args.Get(1).([]*logs.Entry) + require.True(t, slices.EqualFunc(wantEntries, entries, func(wantEntry, gotEntry *logs.Entry) bool { + require.NotEmpty(t, gotEntry.ID) + require.NotEmpty(t, gotEntry.Timestamp) + gotEntry.ID = wantEntry.ID // игнорируем ID + gotEntry.Timestamp = wantEntry.Timestamp // игнорируем Timestamp + return reflect.DeepEqual(wantEntry, gotEntry) + })) + }). + Once() + + usersService := &usersmocks.Users{} + usersService.On("GetByIdentity", mock.Anything, "74d90aaf").Return(user, nil).Once() + + factory := auth.PrincipalFactory{Users: usersService} + + ws := &BufferedWriteSyncer{Service: service} + logger := zap.New(NewCore(ws)) + + // Пример отправки логов для сервиса Items + { + logger := logger.With(logzap.Component("Items")) + ctx := auth.WithPrincipal(context.Background(), factory.User("74d90aaf")) + + // Отправка лога РїСЂРё создании item + logger.Info("Successfully created", + logzap.Event(items.EventCreateItem), + logzap.Object(item), + logzap.CallerFromContext(ctx), + logzap.Tags("tag1", "tag2", "tag3"), + ) + + // Отправка лога РїСЂРё обновлении item + logger.Warn("Successfully updated", + logzap.Event(items.EventUpdateItem), + logzap.Object(item), + logzap.CallerFromContext(ctx), + logzap.Attr(map[string]map[string]any{"title": {"old": "old title", "new": "new title"}}), + ) + } + + err := ws.Stop() + require.NoError(t, err) + + service.AssertExpectations(t) +} diff --git a/perxis-proto b/perxis-proto index 78fe6a1ea7e2fe588e4107bf14ac85293b201163..f10336dc4a4f58111c12dd95afec82be18388803 160000 --- a/perxis-proto +++ b/perxis-proto @@ -1 +1 @@ -Subproject commit 78fe6a1ea7e2fe588e4107bf14ac85293b201163 +Subproject commit f10336dc4a4f58111c12dd95afec82be18388803 diff --git a/pkg/clients/middleware/access_logging_middleware.go b/pkg/clients/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..66379ef014588aa0b6bcdb92863e00ba9f428fc5 --- /dev/null +++ b/pkg/clients/middleware/access_logging_middleware.go @@ -0,0 +1,167 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/clients" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements clients.Clients that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next clients.Clients +} + +// AccessLoggingMiddleware instruments an implementation of the clients.Clients with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next clients.Clients) clients.Clients { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, client *clients.Client) (created *clients.Client, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("client", client), + ) + + created, err = m.next.Create(ctx, client) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, spaceId string, id string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("id", id), + ) + + err = m.next.Delete(ctx, spaceId, id) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Enable(ctx context.Context, spaceId string, id string, enable bool) (err error) { + begin := time.Now() + + m.logger.Debug("Enable.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("id", id), + zap.Reflect("enable", enable), + ) + + err = m.next.Enable(ctx, spaceId, id, enable) + + m.logger.Debug("Enable.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, id string) (client *clients.Client, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("id", id), + ) + + client, err = m.next.Get(ctx, spaceId, id) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("client", client), + zap.Error(err), + ) + + return client, err +} + +func (m *accessLoggingMiddleware) GetBy(ctx context.Context, spaceId string, params *clients.GetByParams) (client *clients.Client, err error) { + begin := time.Now() + + m.logger.Debug("GetBy.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("params", params), + ) + + client, err = m.next.GetBy(ctx, spaceId, params) + + m.logger.Debug("GetBy.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("client", client), + zap.Error(err), + ) + + return client, err +} + +func (m *accessLoggingMiddleware) List(ctx context.Context, spaceId string) (clients []*clients.Client, err error) { + begin := time.Now() + + m.logger.Debug("List.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + clients, err = m.next.List(ctx, spaceId) + + m.logger.Debug("List.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("clients", clients), + zap.Error(err), + ) + + return clients, err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, client *clients.Client) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("client", client), + ) + + err = m.next.Update(ctx, client) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/clients/middleware/error_logging_middleware.go b/pkg/clients/middleware/error_logging_middleware.go index 0b96827a0c620ad1ca1aa5aaf6b93a821af6279d..3e60cc1d8e49f0712362a7e3e8f072571333a97a 100644 --- a/pkg/clients/middleware/error_logging_middleware.go +++ b/pkg/clients/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/clients/middleware/logging_middleware.go b/pkg/clients/middleware/logging_middleware.go deleted file mode 100644 index 6fa0e811c5511748b55d756742a2c81789c0cced..0000000000000000000000000000000000000000 --- a/pkg/clients/middleware/logging_middleware.go +++ /dev/null @@ -1,295 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -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/clients" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements clients.Clients that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next clients.Clients -} - -// LoggingMiddleware instruments an implementation of the clients.Clients with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next clients.Clients) clients.Clients { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Create(ctx context.Context, client *clients.Client) (created *clients.Client, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "client": client} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, client) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, spaceId string, id string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "id": id} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, spaceId, id) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Enable(ctx context.Context, spaceId string, id string, enable bool) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "id": id, - "enable": enable} { - 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("Enable.Request", fields...) - - err = m.next.Enable(ctx, spaceId, id, enable) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Enable.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, id string) (client *clients.Client, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "id": id} { - 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...) - - client, err = m.next.Get(ctx, spaceId, id) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "client": client, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return client, err -} - -func (m *loggingMiddleware) GetBy(ctx context.Context, spaceId string, params *clients.GetByParams) (client *clients.Client, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "params": params} { - 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("GetBy.Request", fields...) - - client, err = m.next.GetBy(ctx, spaceId, params) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "client": client, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("GetBy.Response", fields...) - - return client, err -} - -func (m *loggingMiddleware) List(ctx context.Context, spaceId string) (clients []*clients.Client, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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("List.Request", fields...) - - clients, err = m.next.List(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "clients": clients, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("List.Response", fields...) - - return clients, err -} - -func (m *loggingMiddleware) Update(ctx context.Context, client *clients.Client) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "client": client} { - 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("Update.Request", fields...) - - err = m.next.Update(ctx, client) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - - return err -} diff --git a/pkg/clients/middleware/middleware.go b/pkg/clients/middleware/middleware.go index a49c9b3ebb0c041c23178d457ea5ddf2d2357d91..0c72c1660e15f147a773e2da5e2f31b469b90260 100644 --- a/pkg/clients/middleware/middleware.go +++ b/pkg/clients/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/clients" @@ -17,12 +17,12 @@ func WithLog(s clients.Clients, logger *zap.Logger, log_access bool) clients.Cli if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Clients") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/collaborators/middleware/access_logging_middleware.go b/pkg/collaborators/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..505624ba33f2f91280d3b1dce338262f4a7405d3 --- /dev/null +++ b/pkg/collaborators/middleware/access_logging_middleware.go @@ -0,0 +1,129 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/collaborators" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements collaborators.Collaborators that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next collaborators.Collaborators +} + +// AccessLoggingMiddleware instruments an implementation of the collaborators.Collaborators with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next collaborators.Collaborators) collaborators.Collaborators { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, subject string) (role string, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("subject", subject), + ) + + role, err = m.next.Get(ctx, spaceId, subject) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("role", role), + zap.Error(err), + ) + + return role, err +} + +func (m *accessLoggingMiddleware) ListCollaborators(ctx context.Context, spaceId string) (collaborators []*collaborators.Collaborator, err error) { + begin := time.Now() + + m.logger.Debug("ListCollaborators.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + collaborators, err = m.next.ListCollaborators(ctx, spaceId) + + m.logger.Debug("ListCollaborators.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("collaborators", collaborators), + zap.Error(err), + ) + + return collaborators, err +} + +func (m *accessLoggingMiddleware) ListSpaces(ctx context.Context, subject string) (spaces []*collaborators.Collaborator, err error) { + begin := time.Now() + + m.logger.Debug("ListSpaces.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("subject", subject), + ) + + spaces, err = m.next.ListSpaces(ctx, subject) + + m.logger.Debug("ListSpaces.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("spaces", spaces), + zap.Error(err), + ) + + return spaces, err +} + +func (m *accessLoggingMiddleware) Remove(ctx context.Context, spaceId string, subject string) (err error) { + begin := time.Now() + + m.logger.Debug("Remove.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("subject", subject), + ) + + err = m.next.Remove(ctx, spaceId, subject) + + m.logger.Debug("Remove.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Set(ctx context.Context, spaceId string, subject string, role string) (err error) { + begin := time.Now() + + m.logger.Debug("Set.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("subject", subject), + zap.Reflect("role", role), + ) + + err = m.next.Set(ctx, spaceId, subject, role) + + m.logger.Debug("Set.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/collaborators/middleware/error_logging_middleware.go b/pkg/collaborators/middleware/error_logging_middleware.go index b0bc4518dad30925e41562f334e1891e2c4fb633..6f67ce3ff960815793c8c59d588b012980559334 100644 --- a/pkg/collaborators/middleware/error_logging_middleware.go +++ b/pkg/collaborators/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/collaborators/middleware/logging_middleware.go b/pkg/collaborators/middleware/logging_middleware.go deleted file mode 100644 index 4b4569a48b0900027cf1453779913996b5146525..0000000000000000000000000000000000000000 --- a/pkg/collaborators/middleware/logging_middleware.go +++ /dev/null @@ -1,221 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -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/collaborators" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements collaborators.Collaborators that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next collaborators.Collaborators -} - -// LoggingMiddleware instruments an implementation of the collaborators.Collaborators with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next collaborators.Collaborators) collaborators.Collaborators { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, subject string) (role string, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "subject": subject} { - 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...) - - role, err = m.next.Get(ctx, spaceId, subject) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "role": role, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return role, err -} - -func (m *loggingMiddleware) ListCollaborators(ctx context.Context, spaceId string) (collaborators []*collaborators.Collaborator, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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("ListCollaborators.Request", fields...) - - collaborators, err = m.next.ListCollaborators(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "collaborators": collaborators, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListCollaborators.Response", fields...) - - return collaborators, err -} - -func (m *loggingMiddleware) ListSpaces(ctx context.Context, subject string) (spaces []*collaborators.Collaborator, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "subject": subject} { - 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("ListSpaces.Request", fields...) - - spaces, err = m.next.ListSpaces(ctx, subject) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "spaces": spaces, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListSpaces.Response", fields...) - - return spaces, err -} - -func (m *loggingMiddleware) Remove(ctx context.Context, spaceId string, subject string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "subject": subject} { - 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("Remove.Request", fields...) - - err = m.next.Remove(ctx, spaceId, subject) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Remove.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Set(ctx context.Context, spaceId string, subject string, role string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "subject": subject, - "role": role} { - 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("Set.Request", fields...) - - err = m.next.Set(ctx, spaceId, subject, role) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Set.Response", fields...) - - return err -} diff --git a/pkg/collaborators/middleware/middleware.go b/pkg/collaborators/middleware/middleware.go index 60931c8494b76be2fe0657ec0d204377e58e0c11..28f0bc687c5ee66f2395303efa502149f8394644 100644 --- a/pkg/collaborators/middleware/middleware.go +++ b/pkg/collaborators/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/collaborators" @@ -17,12 +17,12 @@ func WithLog(s collaborators.Collaborators, logger *zap.Logger, log_access bool) if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Collaborators") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/collaborators/middleware/recovering_middleware.go b/pkg/collaborators/middleware/recovering_middleware.go index 0521cce7a30c9b86cb0fe0a04d058c70a9c48cf4..2217ca1f5827cf228c537223c3181701948b50a5 100644 --- a/pkg/collaborators/middleware/recovering_middleware.go +++ b/pkg/collaborators/middleware/recovering_middleware.go @@ -1,5 +1,5 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../../assets/templates/middleware/recovery +// template: ../../../assets/templates/middleware/recovery // gowrap: http://github.com/hexdigest/gowrap package middleware diff --git a/pkg/collections/events.go b/pkg/collections/events.go new file mode 100644 index 0000000000000000000000000000000000000000..bdc92e7769a7cd7ffc880825caaf3098fb5495fb --- /dev/null +++ b/pkg/collections/events.go @@ -0,0 +1,8 @@ +package collections + +const ( + EventCollectionCreate = "collection_create" + EventCollectionUpdate = "collection_update" + EventCollectionDelete = "collection_delete" + EventCollectionSetSchema = "collection_set_schema" +) diff --git a/pkg/collections/middleware/access_logging_middleware.go b/pkg/collections/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..3624955b5d3ef6201704932e623b4e8e00cc6192 --- /dev/null +++ b/pkg/collections/middleware/access_logging_middleware.go @@ -0,0 +1,175 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/collections" + "git.perx.ru/perxis/perxis-go/pkg/schema" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements collections.Collections that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next collections.Collections +} + +// AccessLoggingMiddleware instruments an implementation of the collections.Collections with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next collections.Collections) collections.Collections { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, collection *collections.Collection) (created *collections.Collection, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("collection", collection), + ) + + created, err = m.next.Create(ctx, collection) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, spaceId string, envId string, collectionId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + ) + + err = m.next.Delete(ctx, spaceId, envId, collectionId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, options ...*collections.GetOptions) (collection *collections.Collection, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("options", options), + ) + + collection, err = m.next.Get(ctx, spaceId, envId, collectionId, options...) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("collection", collection), + zap.Error(err), + ) + + return collection, err +} + +func (m *accessLoggingMiddleware) List(ctx context.Context, spaceId string, envId string, filter *collections.Filter) (collections []*collections.Collection, err error) { + begin := time.Now() + + m.logger.Debug("List.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("filter", filter), + ) + + collections, err = m.next.List(ctx, spaceId, envId, filter) + + m.logger.Debug("List.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("collections", collections), + zap.Error(err), + ) + + return collections, err +} + +func (m *accessLoggingMiddleware) SetSchema(ctx context.Context, spaceId string, envId string, collectionId string, schema *schema.Schema) (err error) { + begin := time.Now() + + m.logger.Debug("SetSchema.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("schema", schema), + ) + + err = m.next.SetSchema(ctx, spaceId, envId, collectionId, schema) + + m.logger.Debug("SetSchema.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) SetState(ctx context.Context, spaceId string, envId string, collectionId string, state *collections.StateInfo) (err error) { + begin := time.Now() + + m.logger.Debug("SetState.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("state", state), + ) + + err = m.next.SetState(ctx, spaceId, envId, collectionId, state) + + m.logger.Debug("SetState.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, coll *collections.Collection) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("coll", coll), + ) + + err = m.next.Update(ctx, coll) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/collections/middleware/error_logging_middleware.go b/pkg/collections/middleware/error_logging_middleware.go deleted file mode 100644 index 0491250639063a0e4d229c711c19b36223b9b2e4..0000000000000000000000000000000000000000 --- a/pkg/collections/middleware/error_logging_middleware.go +++ /dev/null @@ -1,101 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/error_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" - -import ( - "context" - - "git.perx.ru/perxis/perxis-go/pkg/collections" - "git.perx.ru/perxis/perxis-go/pkg/schema" - "go.uber.org/zap" -) - -// errorLoggingMiddleware implements collections.Collections that is instrumented with logging -type errorLoggingMiddleware struct { - logger *zap.Logger - next collections.Collections -} - -// ErrorLoggingMiddleware instruments an implementation of the collections.Collections with simple logging -func ErrorLoggingMiddleware(logger *zap.Logger) Middleware { - return func(next collections.Collections) collections.Collections { - return &errorLoggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *errorLoggingMiddleware) Create(ctx context.Context, collection *collections.Collection) (created *collections.Collection, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Create(ctx, collection) -} - -func (m *errorLoggingMiddleware) Delete(ctx context.Context, spaceId string, envId string, collectionId string) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Delete(ctx, spaceId, envId, collectionId) -} - -func (m *errorLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, options ...*collections.GetOptions) (collection *collections.Collection, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Get(ctx, spaceId, envId, collectionId, options...) -} - -func (m *errorLoggingMiddleware) List(ctx context.Context, spaceId string, envId string, filter *collections.Filter) (collections []*collections.Collection, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.List(ctx, spaceId, envId, filter) -} - -func (m *errorLoggingMiddleware) SetSchema(ctx context.Context, spaceId string, envId string, collectionId string, schema *schema.Schema) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.SetSchema(ctx, spaceId, envId, collectionId, schema) -} - -func (m *errorLoggingMiddleware) SetState(ctx context.Context, spaceId string, envId string, collectionId string, state *collections.StateInfo) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.SetState(ctx, spaceId, envId, collectionId, state) -} - -func (m *errorLoggingMiddleware) Update(ctx context.Context, coll *collections.Collection) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Update(ctx, coll) -} diff --git a/pkg/collections/middleware/logging_middleware.go b/pkg/collections/middleware/logging_middleware.go index bc3e41070fc56e0a4ec2a75f073f9696a88560fb..bf04a4aac6e1f5304e982dac0b6c77662715a1cc 100644 --- a/pkg/collections/middleware/logging_middleware.go +++ b/pkg/collections/middleware/logging_middleware.go @@ -1,303 +1,135 @@ package middleware -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -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/id" "git.perx.ru/perxis/perxis-go/pkg/collections" "git.perx.ru/perxis/perxis-go/pkg/schema" + logzap "git.perx.ru/perxis/perxis-go/zap" "go.uber.org/zap" - "go.uber.org/zap/zapcore" ) -// loggingMiddleware implements collections.Collections that is instrumented with logging type loggingMiddleware struct { logger *zap.Logger next collections.Collections } -// LoggingMiddleware instruments an implementation of the collections.Collections with simple logging func LoggingMiddleware(logger *zap.Logger) Middleware { return func(next collections.Collections) collections.Collections { return &loggingMiddleware{ next: next, - logger: logger, + logger: logger.With(logzap.Component("collections")), } } } func (m *loggingMiddleware) Create(ctx context.Context, collection *collections.Collection) (created *collections.Collection, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "collection": collection} { - 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("Create.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(collections.EventCollectionCreate), + ) created, err = m.next.Create(ctx, collection) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to create", zap.Error(err), logzap.Object(collection), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - + logger.Info("Successfully created", logzap.Object(created), logzap.Channels(logzap.Userlog)) return created, err } func (m *loggingMiddleware) Delete(ctx context.Context, spaceId string, envId string, collectionId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId} { - 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("Delete.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(collections.EventCollectionDelete), + logzap.Object(id.NewCollectionId(spaceId, envId, collectionId)), + ) err = m.next.Delete(ctx, spaceId, envId, collectionId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to delete", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - + logger.Info("Successfully deleted", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, options ...*collections.GetOptions) (collection *collections.Collection, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "options": options} { - 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...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) collection, err = m.next.Get(ctx, spaceId, envId, collectionId, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to get", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "collection": collection, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - return collection, err } func (m *loggingMiddleware) List(ctx context.Context, spaceId string, envId string, filter *collections.Filter) (collections []*collections.Collection, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "filter": filter} { - 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("List.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) collections, err = m.next.List(ctx, spaceId, envId, filter) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "collections": collections, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to list", zap.Error(err)) + return } - m.logger.Debug("List.Response", fields...) - return collections, err } func (m *loggingMiddleware) SetSchema(ctx context.Context, spaceId string, envId string, collectionId string, schema *schema.Schema) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "schema": schema} { - 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("SetSchema.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(collections.EventCollectionSetSchema), + logzap.Object(id.NewCollectionId(spaceId, envId, collectionId)), + ) err = m.next.SetSchema(ctx, spaceId, envId, collectionId, schema) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to set schema", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - m.logger.Debug("SetSchema.Response", fields...) - + logger.Info("Successfully set schema", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) SetState(ctx context.Context, spaceId string, envId string, collectionId string, state *collections.StateInfo) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "state": state} { - 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("SetState.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) err = m.next.SetState(ctx, spaceId, envId, collectionId, state) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to set state", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("SetState.Response", fields...) - + logger.Info("Successfully set state", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Update(ctx context.Context, coll *collections.Collection) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "coll": coll} { - 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("Update.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(collections.EventCollectionUpdate), + logzap.Object(coll), + ) err = m.next.Update(ctx, coll) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to update", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - + logger.Info("Successfully updated", logzap.Channels(logzap.Userlog)) return err } diff --git a/pkg/collections/middleware/middleware.go b/pkg/collections/middleware/middleware.go index b581ce74b6071c707cc96fe9f11656bece37eb99..22514e7c93ec032847590821bfb2ba7467462f63 100644 --- a/pkg/collections/middleware/middleware.go +++ b/pkg/collections/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/collections" @@ -17,12 +17,11 @@ func WithLog(s collections.Collections, logger *zap.Logger, log_access bool) col if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Collections") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = LoggingMiddleware(logger)(s) s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/delivery/transport/grpc/protobuf_type_converters.microgen.go b/pkg/delivery/transport/grpc/protobuf_type_converters.microgen.go index 187f256c9617d39dd2f157a18c2fd43498dadf36..6961c709da405a34710e76ff6c1ad6f34c218f1b 100644 --- a/pkg/delivery/transport/grpc/protobuf_type_converters.microgen.go +++ b/pkg/delivery/transport/grpc/protobuf_type_converters.microgen.go @@ -302,35 +302,11 @@ func ProtoToPtrItemsFilter(protoFilter *itemspb.Filter) (*items.Filter, error) { } func PtrServicesFindOptionsToProto(options *services.FindOptions) (*common.FindOptions, error) { - if options == nil { - return nil, nil - } - return &common.FindOptions{ - Sort: options.Sort, - PageNum: int32(options.PageNum), - PageSize: int32(options.PageSize), - Fields: options.Fields, - ExcludeFields: options.ExcludeFields, - }, nil + return services.FindOptionsToPB(options), nil } func ProtoToPtrServicesFindOptions(protoOptions *common.FindOptions) (*services.FindOptions, error) { - if protoOptions == nil { - return nil, nil - } - return &services.FindOptions{ - SortOptions: services.SortOptions{ - Sort: protoOptions.Sort, - }, - PaginationOptions: services.PaginationOptions{ - PageNum: int(protoOptions.PageNum), - PageSize: int(protoOptions.PageSize), - }, - FieldOptions: services.FieldOptions{ - Fields: protoOptions.Fields, - ExcludeFields: protoOptions.ExcludeFields, - }, - }, nil + return services.FindOptionsFromPB(protoOptions), nil } func ListPtrItemsItemToProto(itms []*items.Item) ([]*itemspb.Item, error) { diff --git a/pkg/environments/middleware/access_logging_middleware.go b/pkg/environments/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..e357e2ec9786edb9f67a7b14445558f86938e924 --- /dev/null +++ b/pkg/environments/middleware/access_logging_middleware.go @@ -0,0 +1,187 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/environments" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements environments.Environments that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next environments.Environments +} + +// AccessLoggingMiddleware instruments an implementation of the environments.Environments with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next environments.Environments) environments.Environments { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, env *environments.Environment) (created *environments.Environment, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("env", env), + ) + + created, err = m.next.Create(ctx, env) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, spaceId string, envId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + ) + + err = m.next.Delete(ctx, spaceId, envId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string) (env *environments.Environment, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + ) + + env, err = m.next.Get(ctx, spaceId, envId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("env", env), + zap.Error(err), + ) + + return env, err +} + +func (m *accessLoggingMiddleware) List(ctx context.Context, spaceId string) (envs []*environments.Environment, err error) { + begin := time.Now() + + m.logger.Debug("List.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + envs, err = m.next.List(ctx, spaceId) + + m.logger.Debug("List.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("envs", envs), + zap.Error(err), + ) + + return envs, err +} + +func (m *accessLoggingMiddleware) Migrate(ctx context.Context, spaceId string, envId string, options ...*environments.MigrateOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Migrate.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("options", options), + ) + + err = m.next.Migrate(ctx, spaceId, envId, options...) + + m.logger.Debug("Migrate.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) RemoveAlias(ctx context.Context, spaceId string, envId string, alias string) (err error) { + begin := time.Now() + + m.logger.Debug("RemoveAlias.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("alias", alias), + ) + + err = m.next.RemoveAlias(ctx, spaceId, envId, alias) + + m.logger.Debug("RemoveAlias.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) SetAlias(ctx context.Context, spaceId string, envId string, alias string) (err error) { + begin := time.Now() + + m.logger.Debug("SetAlias.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("alias", alias), + ) + + err = m.next.SetAlias(ctx, spaceId, envId, alias) + + m.logger.Debug("SetAlias.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, env *environments.Environment) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("env", env), + ) + + err = m.next.Update(ctx, env) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/environments/middleware/error_logging_middleware.go b/pkg/environments/middleware/error_logging_middleware.go index 91ff984763f696cde9f8c152f96842ae995a411e..812de4033878fe1c6d774730c68d2e6e00489751 100644 --- a/pkg/environments/middleware/error_logging_middleware.go +++ b/pkg/environments/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/environments/middleware/logging_middleware.go b/pkg/environments/middleware/logging_middleware.go deleted file mode 100644 index 74692e333c12a3230a03b0cf584010745fb52329..0000000000000000000000000000000000000000 --- a/pkg/environments/middleware/logging_middleware.go +++ /dev/null @@ -1,333 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -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/environments" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements environments.Environments that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next environments.Environments -} - -// LoggingMiddleware instruments an implementation of the environments.Environments with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next environments.Environments) environments.Environments { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Create(ctx context.Context, env *environments.Environment) (created *environments.Environment, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "env": env} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, env) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, spaceId string, envId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, spaceId, envId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, envId string) (env *environments.Environment, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId} { - 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...) - - env, err = m.next.Get(ctx, spaceId, envId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "env": env, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return env, err -} - -func (m *loggingMiddleware) List(ctx context.Context, spaceId string) (envs []*environments.Environment, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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("List.Request", fields...) - - envs, err = m.next.List(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "envs": envs, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("List.Response", fields...) - - return envs, err -} - -func (m *loggingMiddleware) Migrate(ctx context.Context, spaceId string, envId string, options ...*environments.MigrateOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "options": options} { - 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("Migrate.Request", fields...) - - err = m.next.Migrate(ctx, spaceId, envId, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Migrate.Response", fields...) - - return err -} - -func (m *loggingMiddleware) RemoveAlias(ctx context.Context, spaceId string, envId string, alias string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "alias": alias} { - 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("RemoveAlias.Request", fields...) - - err = m.next.RemoveAlias(ctx, spaceId, envId, alias) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("RemoveAlias.Response", fields...) - - return err -} - -func (m *loggingMiddleware) SetAlias(ctx context.Context, spaceId string, envId string, alias string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "alias": alias} { - 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("SetAlias.Request", fields...) - - err = m.next.SetAlias(ctx, spaceId, envId, alias) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("SetAlias.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Update(ctx context.Context, env *environments.Environment) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "env": env} { - 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("Update.Request", fields...) - - err = m.next.Update(ctx, env) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - - return err -} diff --git a/pkg/environments/middleware/middleware.go b/pkg/environments/middleware/middleware.go index cfc89b98b7b17b5335afb81ea3dc5d686a9c892b..7c887417848d7cdea79681b73d7c1954318ad009 100644 --- a/pkg/environments/middleware/middleware.go +++ b/pkg/environments/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/environments" @@ -17,12 +17,12 @@ func WithLog(s environments.Environments, logger *zap.Logger, log_access bool) e if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Environments") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/extension/middleware/access_logging_middleware.go b/pkg/extension/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..0fbd63de8991c449fc96ad49527f5e079bd88773 --- /dev/null +++ b/pkg/extension/middleware/access_logging_middleware.go @@ -0,0 +1,196 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/extension" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements extension.Manager that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next extension.Manager +} + +// AccessLoggingMiddleware instruments an implementation of the extension.Manager with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next extension.Manager) extension.Manager { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Action(ctx context.Context, in *extension.ActionRequest) (ap1 *extension.ActionResponse, err error) { + begin := time.Now() + + m.logger.Debug("Action.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("in", in), + ) + + ap1, err = m.next.Action(ctx, in) + + m.logger.Debug("Action.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("ap1", ap1), + zap.Error(err), + ) + + return ap1, err +} + +func (m *accessLoggingMiddleware) Check(ctx context.Context, in *extension.CheckRequest) (err error) { + begin := time.Now() + + m.logger.Debug("Check.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("in", in), + ) + + err = m.next.Check(ctx, in) + + m.logger.Debug("Check.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) GetDescriptor() (ep1 *extension.ExtensionDescriptor) { + begin := time.Now() + + m.logger.Debug("GetDescriptor.Request") + + ep1 = m.next.GetDescriptor() + + m.logger.Debug("GetDescriptor.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("ep1", ep1), + ) + + return ep1 +} + +func (m *accessLoggingMiddleware) Install(ctx context.Context, in *extension.InstallRequest) (err error) { + begin := time.Now() + + m.logger.Debug("Install.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("in", in), + ) + + err = m.next.Install(ctx, in) + + m.logger.Debug("Install.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) ListExtensions(ctx context.Context, space string, env string, filter *extension.ListExtensionsFilter) (ipa1 []*extension.Info, err error) { + begin := time.Now() + + m.logger.Debug("ListExtensions.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("space", space), + zap.Reflect("env", env), + zap.Reflect("filter", filter), + ) + + ipa1, err = m.next.ListExtensions(ctx, space, env, filter) + + m.logger.Debug("ListExtensions.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("ipa1", ipa1), + zap.Error(err), + ) + + return ipa1, err +} + +func (m *accessLoggingMiddleware) ListRegisteredExtensions(ctx context.Context, extensions ...string) (epa1 []*extension.ExtensionConnector, err error) { + begin := time.Now() + + m.logger.Debug("ListRegisteredExtensions.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("extensions", extensions), + ) + + epa1, err = m.next.ListRegisteredExtensions(ctx, extensions...) + + m.logger.Debug("ListRegisteredExtensions.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("epa1", epa1), + zap.Error(err), + ) + + return epa1, err +} + +func (m *accessLoggingMiddleware) RegisterExtensions(ctx context.Context, ext ...*extension.ExtensionConnector) (err error) { + begin := time.Now() + + m.logger.Debug("RegisterExtensions.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("ext", ext), + ) + + err = m.next.RegisterExtensions(ctx, ext...) + + m.logger.Debug("RegisterExtensions.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Uninstall(ctx context.Context, in *extension.UninstallRequest) (err error) { + begin := time.Now() + + m.logger.Debug("Uninstall.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("in", in), + ) + + err = m.next.Uninstall(ctx, in) + + m.logger.Debug("Uninstall.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) UnregisterExtensions(ctx context.Context, ext ...*extension.ExtensionConnector) (err error) { + begin := time.Now() + + m.logger.Debug("UnregisterExtensions.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("ext", ext), + ) + + err = m.next.UnregisterExtensions(ctx, ext...) + + m.logger.Debug("UnregisterExtensions.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/extension/middleware/error_logging_middleware.go b/pkg/extension/middleware/error_logging_middleware.go index e7dec72ba015ffe7e75a7bf0736f3a20cd7f4204..474003790010e858eed9fb9ac2af71f17fb35094 100644 --- a/pkg/extension/middleware/error_logging_middleware.go +++ b/pkg/extension/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/extension/middleware/logging_middleware.go b/pkg/extension/middleware/logging_middleware.go deleted file mode 100644 index 8ae37929d26a9dbccf40ab1030d73b708d3d96ba..0000000000000000000000000000000000000000 --- a/pkg/extension/middleware/logging_middleware.go +++ /dev/null @@ -1,354 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -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/extension" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements extension.Manager that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next extension.Manager -} - -// LoggingMiddleware instruments an implementation of the extension.Manager with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next extension.Manager) extension.Manager { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Action(ctx context.Context, in *extension.ActionRequest) (ap1 *extension.ActionResponse, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "in": in} { - 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("Action.Request", fields...) - - ap1, err = m.next.Action(ctx, in) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "ap1": ap1, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Action.Response", fields...) - - return ap1, err -} - -func (m *loggingMiddleware) Check(ctx context.Context, in *extension.CheckRequest) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "in": in} { - 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("Check.Request", fields...) - - err = m.next.Check(ctx, in) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Check.Response", fields...) - - return err -} - -func (m *loggingMiddleware) GetDescriptor() (ep1 *extension.ExtensionDescriptor) { - begin := time.Now() - var fields []zapcore.Field - - m.logger.Debug("GetDescriptor.Request", fields...) - - ep1 = m.next.GetDescriptor() - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "ep1": ep1} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("GetDescriptor.Response", fields...) - - return ep1 -} - -func (m *loggingMiddleware) Install(ctx context.Context, in *extension.InstallRequest) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "in": in} { - 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("Install.Request", fields...) - - err = m.next.Install(ctx, in) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Install.Response", fields...) - - return err -} - -func (m *loggingMiddleware) ListExtensions(ctx context.Context, space string, env string, filter *extension.ListExtensionsFilter) (ipa1 []*extension.Info, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "space": space, - "env": env, - "filter": filter} { - 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("ListExtensions.Request", fields...) - - ipa1, err = m.next.ListExtensions(ctx, space, env, filter) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "ipa1": ipa1, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListExtensions.Response", fields...) - - return ipa1, err -} - -func (m *loggingMiddleware) ListRegisteredExtensions(ctx context.Context, extensions ...string) (epa1 []*extension.ExtensionConnector, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "extensions": extensions} { - 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("ListRegisteredExtensions.Request", fields...) - - epa1, err = m.next.ListRegisteredExtensions(ctx, extensions...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "epa1": epa1, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListRegisteredExtensions.Response", fields...) - - return epa1, err -} - -func (m *loggingMiddleware) RegisterExtensions(ctx context.Context, ext ...*extension.ExtensionConnector) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "ext": ext} { - 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("RegisterExtensions.Request", fields...) - - err = m.next.RegisterExtensions(ctx, ext...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("RegisterExtensions.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Uninstall(ctx context.Context, in *extension.UninstallRequest) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "in": in} { - 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("Uninstall.Request", fields...) - - err = m.next.Uninstall(ctx, in) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Uninstall.Response", fields...) - - return err -} - -func (m *loggingMiddleware) UnregisterExtensions(ctx context.Context, ext ...*extension.ExtensionConnector) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "ext": ext} { - 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("UnregisterExtensions.Request", fields...) - - err = m.next.UnregisterExtensions(ctx, ext...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("UnregisterExtensions.Response", fields...) - - return err -} diff --git a/pkg/extension/middleware/middleware.go b/pkg/extension/middleware/middleware.go index 52b8bff724419d007ece694ade348182a738ce82..f308b6a1d0af97853b6105788cd28977f6c637ac 100644 --- a/pkg/extension/middleware/middleware.go +++ b/pkg/extension/middleware/middleware.go @@ -1,10 +1,10 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/extension" @@ -17,12 +17,12 @@ func WithLog(s extension.Manager, logger *zap.Logger, log_access bool) extension if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Manager") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/extension/middleware/recovering_middleware.go b/pkg/extension/middleware/recovering_middleware.go index d75af3364a31dd2e0961166a3a7dca573079f4e1..54b78da481917fda0d5614f6d9158c455d4d03e6 100644 --- a/pkg/extension/middleware/recovering_middleware.go +++ b/pkg/extension/middleware/recovering_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/recovery // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -t ../../../assets/templates/middleware/recovery -o recovering_middleware.go -l "" import ( diff --git a/pkg/files/middleware/access_logging_middleware.go b/pkg/files/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..df932a8282989e17936438b66b714dd9b4b14df6 --- /dev/null +++ b/pkg/files/middleware/access_logging_middleware.go @@ -0,0 +1,163 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/files -i Files -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/files" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements files.Files that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next files.Files +} + +// AccessLoggingMiddleware instruments an implementation of the files.Files with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next files.Files) files.Files { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) AbortUpload(ctx context.Context, upload *files.MultipartUpload) (err error) { + begin := time.Now() + + m.logger.Debug("AbortUpload.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("upload", upload), + ) + + err = m.next.AbortUpload(ctx, upload) + + m.logger.Debug("AbortUpload.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) CompleteUpload(ctx context.Context, upload *files.MultipartUpload) (u *files.MultipartUpload, err error) { + begin := time.Now() + + m.logger.Debug("CompleteUpload.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("upload", upload), + ) + + u, err = m.next.CompleteUpload(ctx, upload) + + m.logger.Debug("CompleteUpload.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("u", u), + zap.Error(err), + ) + + return u, err +} + +func (m *accessLoggingMiddleware) DeleteFile(ctx context.Context, file *files.File) (err error) { + begin := time.Now() + + m.logger.Debug("DeleteFile.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("file", file), + ) + + err = m.next.DeleteFile(ctx, file) + + m.logger.Debug("DeleteFile.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) GetFile(ctx context.Context, file *files.File) (f *files.File, err error) { + begin := time.Now() + + m.logger.Debug("GetFile.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("file", file), + ) + + f, err = m.next.GetFile(ctx, file) + + m.logger.Debug("GetFile.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("f", f), + zap.Error(err), + ) + + return f, err +} + +func (m *accessLoggingMiddleware) MoveUpload(ctx context.Context, upload *files.MultipartUpload) (file *files.File, err error) { + begin := time.Now() + + m.logger.Debug("MoveUpload.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("upload", upload), + ) + + file, err = m.next.MoveUpload(ctx, upload) + + m.logger.Debug("MoveUpload.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("file", file), + zap.Error(err), + ) + + return file, err +} + +func (m *accessLoggingMiddleware) StartUpload(ctx context.Context, upload *files.MultipartUpload) (u *files.MultipartUpload, err error) { + begin := time.Now() + + m.logger.Debug("StartUpload.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("upload", upload), + ) + + u, err = m.next.StartUpload(ctx, upload) + + m.logger.Debug("StartUpload.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("u", u), + zap.Error(err), + ) + + return u, err +} + +func (m *accessLoggingMiddleware) Upload(ctx context.Context, file *files.File) (u *files.Upload, err error) { + begin := time.Now() + + m.logger.Debug("Upload.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("file", file), + ) + + u, err = m.next.Upload(ctx, file) + + m.logger.Debug("Upload.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("u", u), + zap.Error(err), + ) + + return u, err +} diff --git a/pkg/files/middleware/logging_middleware.go b/pkg/files/middleware/logging_middleware.go deleted file mode 100644 index b295fa68cc8367021d5fa5e00a0c850cc27c7cee..0000000000000000000000000000000000000000 --- a/pkg/files/middleware/logging_middleware.go +++ /dev/null @@ -1,291 +0,0 @@ -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -package middleware - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/files -i Files -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/files" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements files.Files that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next files.Files -} - -// LoggingMiddleware instruments an implementation of the files.Files with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next files.Files) files.Files { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) AbortUpload(ctx context.Context, upload *files.MultipartUpload) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "upload": upload} { - 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("AbortUpload.Request", fields...) - - err = m.next.AbortUpload(ctx, upload) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("AbortUpload.Response", fields...) - - return err -} - -func (m *loggingMiddleware) CompleteUpload(ctx context.Context, upload *files.MultipartUpload) (u *files.MultipartUpload, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "upload": upload} { - 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("CompleteUpload.Request", fields...) - - u, err = m.next.CompleteUpload(ctx, upload) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "u": u, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("CompleteUpload.Response", fields...) - - return u, err -} - -func (m *loggingMiddleware) DeleteFile(ctx context.Context, file *files.File) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "file": file} { - 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("DeleteFile.Request", fields...) - - err = m.next.DeleteFile(ctx, file) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("DeleteFile.Response", fields...) - - return err -} - -func (m *loggingMiddleware) GetFile(ctx context.Context, file *files.File) (f *files.File, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "file": file} { - 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("GetFile.Request", fields...) - - f, err = m.next.GetFile(ctx, file) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "f": f, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("GetFile.Response", fields...) - - return f, err -} - -func (m *loggingMiddleware) MoveUpload(ctx context.Context, upload *files.MultipartUpload) (file *files.File, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "upload": upload} { - 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("MoveUpload.Request", fields...) - - file, err = m.next.MoveUpload(ctx, upload) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "file": file, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("MoveUpload.Response", fields...) - - return file, err -} - -func (m *loggingMiddleware) StartUpload(ctx context.Context, upload *files.MultipartUpload) (u *files.MultipartUpload, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "upload": upload} { - 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("StartUpload.Request", fields...) - - u, err = m.next.StartUpload(ctx, upload) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "u": u, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("StartUpload.Response", fields...) - - return u, err -} - -func (m *loggingMiddleware) Upload(ctx context.Context, file *files.File) (u *files.Upload, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "file": file} { - 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("Upload.Request", fields...) - - u, err = m.next.Upload(ctx, file) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "u": u, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Upload.Response", fields...) - - return u, err -} diff --git a/pkg/files/middleware/middleware.go b/pkg/files/middleware/middleware.go index 39c64f8764e904b53fcce18bf8b990424ad03149..68d4c21f67b202f8639963930c71dcd6ab1cc3f9 100644 --- a/pkg/files/middleware/middleware.go +++ b/pkg/files/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/files -i Files -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/files -i Files -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/files" @@ -17,12 +17,12 @@ func WithLog(s files.Files, logger *zap.Logger, log_access bool) files.Files { if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Files") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/invitations/middleware/access_logging_middleware.go b/pkg/invitations/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..24a854995bed29e849ccf873f41ccd1af073cb69 --- /dev/null +++ b/pkg/invitations/middleware/access_logging_middleware.go @@ -0,0 +1,129 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/invitations" + "git.perx.ru/perxis/perxis-go/pkg/options" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements invitations.Invitations that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next invitations.Invitations +} + +// AccessLoggingMiddleware instruments an implementation of the invitations.Invitations with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next invitations.Invitations) invitations.Invitations { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Accept(ctx context.Context, invitationId string, userId string) (err error) { + begin := time.Now() + + m.logger.Debug("Accept.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("invitationId", invitationId), + zap.Reflect("userId", userId), + ) + + err = m.next.Accept(ctx, invitationId, userId) + + m.logger.Debug("Accept.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, invitation *invitations.Invitation) (created *invitations.Invitation, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("invitation", invitation), + ) + + created, err = m.next.Create(ctx, invitation) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, invitationId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("invitationId", invitationId), + ) + + err = m.next.Delete(ctx, invitationId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Find(ctx context.Context, filter *invitations.Filter, opts *options.FindOptions) (invitations []*invitations.Invitation, total int, err error) { + begin := time.Now() + + m.logger.Debug("Find.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("filter", filter), + zap.Reflect("opts", opts), + ) + + invitations, total, err = m.next.Find(ctx, filter, opts) + + m.logger.Debug("Find.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("invitations", invitations), + zap.Reflect("total", total), + zap.Error(err), + ) + + return invitations, total, err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, invitationId string) (invitation *invitations.Invitation, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("invitationId", invitationId), + ) + + invitation, err = m.next.Get(ctx, invitationId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("invitation", invitation), + zap.Error(err), + ) + + return invitation, err +} diff --git a/pkg/invitations/middleware/error_logging_middleware.go b/pkg/invitations/middleware/error_logging_middleware.go index ab0a2122f23c660281716d5dbc697cc6e13de3fe..da6603acdda802808abac634896ceb7d3b92cd1b 100644 --- a/pkg/invitations/middleware/error_logging_middleware.go +++ b/pkg/invitations/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/invitations/middleware/logging_middleware.go b/pkg/invitations/middleware/logging_middleware.go deleted file mode 100644 index ac358b3e1e635bc7f410d5b6a318b4eddc231d38..0000000000000000000000000000000000000000 --- a/pkg/invitations/middleware/logging_middleware.go +++ /dev/null @@ -1,221 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -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/invitations" - "git.perx.ru/perxis/perxis-go/pkg/options" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements invitations.Invitations that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next invitations.Invitations -} - -// LoggingMiddleware instruments an implementation of the invitations.Invitations with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next invitations.Invitations) invitations.Invitations { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Accept(ctx context.Context, invitationId string, userId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "invitationId": invitationId, - "userId": userId} { - 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("Accept.Request", fields...) - - err = m.next.Accept(ctx, invitationId, userId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Accept.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Create(ctx context.Context, invitation *invitations.Invitation) (created *invitations.Invitation, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "invitation": invitation} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, invitation) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, invitationId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "invitationId": invitationId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, invitationId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Find(ctx context.Context, filter *invitations.Filter, opts *options.FindOptions) (invitations []*invitations.Invitation, total int, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "filter": filter, - "opts": opts} { - 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("Find.Request", fields...) - - invitations, total, err = m.next.Find(ctx, filter, opts) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "invitations": invitations, - "total": total, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Find.Response", fields...) - - return invitations, total, err -} - -func (m *loggingMiddleware) Get(ctx context.Context, invitationId string) (invitation *invitations.Invitation, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "invitationId": invitationId} { - 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...) - - invitation, err = m.next.Get(ctx, invitationId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "invitation": invitation, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return invitation, err -} diff --git a/pkg/invitations/middleware/middleware.go b/pkg/invitations/middleware/middleware.go index d4a336ba62cdbef2da5a06e4d71ecdf20491fe49..f59604ba948ade1b4fe03bc3e3cadd8de6f7cfcd 100644 --- a/pkg/invitations/middleware/middleware.go +++ b/pkg/invitations/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/invitations" @@ -17,12 +17,12 @@ func WithLog(s invitations.Invitations, logger *zap.Logger, log_access bool) inv if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Invitations") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go b/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go index ee7b788e2bf670b9f885c0fa3d9a52cbff30502e..1b222519b0aacc35feb180e0273ac9758394aefe 100644 --- a/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go +++ b/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go @@ -104,11 +104,18 @@ func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*pb.FindOptions, if opts == nil { return nil, nil } - return &pb.FindOptions{ + + fo := &pb.FindOptions{ Sort: opts.Sort, - PageNum: int32(opts.PageNum), - PageSize: int32(opts.PageSize), - }, nil + PageSize: int32(opts.Limit), + } + + if opts.Limit != 0 { + // Потенциальная ошибка если offset РЅРµ кратен limit + fo.PageNum = int32(opts.Offset / opts.Limit) + } + + return fo, nil } func ProtoToPtrServicesFindOptions(protoOpts *pb.FindOptions) (*options.FindOptions, error) { @@ -120,8 +127,8 @@ func ProtoToPtrServicesFindOptions(protoOpts *pb.FindOptions) (*options.FindOpti Sort: protoOpts.Sort, }, PaginationOptions: options.PaginationOptions{ - PageNum: int(protoOpts.PageNum), - PageSize: int(protoOpts.PageSize), + Limit: int(protoOpts.PageSize), + Offset: int(protoOpts.PageNum * protoOpts.PageSize), }, }, nil } diff --git a/pkg/items/dummy.go b/pkg/items/dummy.go deleted file mode 100644 index fc1f725abc3e5f9c16164daca30f3334c16f9f86..0000000000000000000000000000000000000000 --- a/pkg/items/dummy.go +++ /dev/null @@ -1,17 +0,0 @@ -package items - -import "context" - -type FindResultDummy struct { - Items []*Item - Total int - Error error -} -type Dummy struct { - Items - FindResult *FindResultDummy -} - -func (d *Dummy) Find(_ context.Context, _, _, _ string, _ *Filter, _ ...*FindOptions) ([]*Item, int, error) { - return d.FindResult.Items, d.FindResult.Total, d.FindResult.Error -} diff --git a/pkg/items/events.go b/pkg/items/events.go index b697d60733031bc259ce0d5b2efc24f2bb63bc94..d97fe63c69fbc02a946bb03c665d61836368c6dc 100644 --- a/pkg/items/events.go +++ b/pkg/items/events.go @@ -12,6 +12,9 @@ const ( EventPublishItem = "publish_item" EventUnpublishItem = "unpublish_item" EventDeleteItem = "delete_item" + EventUndeleteItem = "item_undelete" + EventArchiveItem = "item_archive" + EventUnarchiveItem = "item_unarchive" DefaultEventSubject = "content.{{.EventType}}.{{.SpaceID}}.{{.EnvID}}.{{.CollectionID}}.{{.ItemID}}" ) diff --git a/pkg/items/middleware/access_logging_middleware.go b/pkg/items/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..2342a6d99249f427aa0f4ad6b4220a43ba872a4f --- /dev/null +++ b/pkg/items/middleware/access_logging_middleware.go @@ -0,0 +1,418 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/schema" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements items.Items that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next items.Items +} + +// AccessLoggingMiddleware instruments an implementation of the items.Items with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next items.Items) items.Items { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Aggregate(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregateOptions) (result map[string]interface{}, err error) { + begin := time.Now() + + m.logger.Debug("Aggregate.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + result, err = m.next.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) + + m.logger.Debug("Aggregate.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("result", result), + zap.Error(err), + ) + + return result, err +} + +func (m *accessLoggingMiddleware) AggregatePublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregatePublishedOptions) (result map[string]interface{}, err error) { + begin := time.Now() + + m.logger.Debug("AggregatePublished.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + result, err = m.next.AggregatePublished(ctx, spaceId, envId, collectionId, filter, options...) + + m.logger.Debug("AggregatePublished.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("result", result), + zap.Error(err), + ) + + return result, err +} + +func (m *accessLoggingMiddleware) Archive(ctx context.Context, item *items.Item, options ...*items.ArchiveOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Archive.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Archive(ctx, item, options...) + + m.logger.Debug("Archive.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, item *items.Item, opts ...*items.CreateOptions) (created *items.Item, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("opts", opts), + ) + + created, err = m.next.Create(ctx, item, opts...) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, item *items.Item, options ...*items.DeleteOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Delete(ctx, item, options...) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Find(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindOptions) (items []*items.Item, total int, err error) { + begin := time.Now() + + m.logger.Debug("Find.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + items, total, err = m.next.Find(ctx, spaceId, envId, collectionId, filter, options...) + + m.logger.Debug("Find.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("items", items), + zap.Reflect("total", total), + zap.Error(err), + ) + + return items, total, err +} + +func (m *accessLoggingMiddleware) FindArchived(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindArchivedOptions) (items []*items.Item, total int, err error) { + begin := time.Now() + + m.logger.Debug("FindArchived.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + items, total, err = m.next.FindArchived(ctx, spaceId, envId, collectionId, filter, options...) + + m.logger.Debug("FindArchived.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("items", items), + zap.Reflect("total", total), + zap.Error(err), + ) + + return items, total, err +} + +func (m *accessLoggingMiddleware) FindPublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindPublishedOptions) (items []*items.Item, total int, err error) { + begin := time.Now() + + m.logger.Debug("FindPublished.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + items, total, err = m.next.FindPublished(ctx, spaceId, envId, collectionId, filter, options...) + + m.logger.Debug("FindPublished.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("items", items), + zap.Reflect("total", total), + zap.Error(err), + ) + + return items, total, err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetOptions) (item *items.Item, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("itemId", itemId), + zap.Reflect("options", options), + ) + + item, err = m.next.Get(ctx, spaceId, envId, collectionId, itemId, options...) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("item", item), + zap.Error(err), + ) + + return item, err +} + +func (m *accessLoggingMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetPublishedOptions) (item *items.Item, err error) { + begin := time.Now() + + m.logger.Debug("GetPublished.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("itemId", itemId), + zap.Reflect("options", options), + ) + + item, err = m.next.GetPublished(ctx, spaceId, envId, collectionId, itemId, options...) + + m.logger.Debug("GetPublished.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("item", item), + zap.Error(err), + ) + + return item, err +} + +func (m *accessLoggingMiddleware) GetRevision(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, revisionId string, options ...*items.GetRevisionOptions) (item *items.Item, err error) { + begin := time.Now() + + m.logger.Debug("GetRevision.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("itemId", itemId), + zap.Reflect("revisionId", revisionId), + zap.Reflect("options", options), + ) + + item, err = m.next.GetRevision(ctx, spaceId, envId, collectionId, itemId, revisionId, options...) + + m.logger.Debug("GetRevision.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("item", item), + zap.Error(err), + ) + + return item, err +} + +func (m *accessLoggingMiddleware) Introspect(ctx context.Context, item *items.Item, opts ...*items.IntrospectOptions) (itm *items.Item, sch *schema.Schema, err error) { + begin := time.Now() + + m.logger.Debug("Introspect.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("opts", opts), + ) + + itm, sch, err = m.next.Introspect(ctx, item, opts...) + + m.logger.Debug("Introspect.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("itm", itm), + zap.Reflect("sch", sch), + zap.Error(err), + ) + + return itm, sch, err +} + +func (m *accessLoggingMiddleware) ListRevisions(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.ListRevisionsOptions) (items []*items.Item, err error) { + begin := time.Now() + + m.logger.Debug("ListRevisions.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("collectionId", collectionId), + zap.Reflect("itemId", itemId), + zap.Reflect("options", options), + ) + + items, err = m.next.ListRevisions(ctx, spaceId, envId, collectionId, itemId, options...) + + m.logger.Debug("ListRevisions.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("items", items), + zap.Error(err), + ) + + return items, err +} + +func (m *accessLoggingMiddleware) Publish(ctx context.Context, item *items.Item, options ...*items.PublishOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Publish.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Publish(ctx, item, options...) + + m.logger.Debug("Publish.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Unarchive(ctx context.Context, item *items.Item, options ...*items.UnarchiveOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Unarchive.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Unarchive(ctx, item, options...) + + m.logger.Debug("Unarchive.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Undelete(ctx context.Context, item *items.Item, options ...*items.UndeleteOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Undelete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Undelete(ctx, item, options...) + + m.logger.Debug("Undelete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Unpublish(ctx context.Context, item *items.Item, options ...*items.UnpublishOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Unpublish.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Unpublish(ctx, item, options...) + + m.logger.Debug("Unpublish.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, item *items.Item, options ...*items.UpdateOptions) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("item", item), + zap.Reflect("options", options), + ) + + err = m.next.Update(ctx, item, options...) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/items/middleware/error_logging_middleware.go b/pkg/items/middleware/error_logging_middleware.go deleted file mode 100644 index 345d22ca2727d1516e4a7176e885195ab38f1d20..0000000000000000000000000000000000000000 --- a/pkg/items/middleware/error_logging_middleware.go +++ /dev/null @@ -1,211 +0,0 @@ -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/error_log -// gowrap: http://github.com/hexdigest/gowrap - -package middleware - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -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/schema" - "go.uber.org/zap" -) - -// errorLoggingMiddleware implements items.Items that is instrumented with logging -type errorLoggingMiddleware struct { - logger *zap.Logger - next items.Items -} - -// ErrorLoggingMiddleware instruments an implementation of the items.Items with simple logging -func ErrorLoggingMiddleware(logger *zap.Logger) Middleware { - return func(next items.Items) items.Items { - return &errorLoggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *errorLoggingMiddleware) Aggregate(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregateOptions) (result map[string]interface{}, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) -} - -func (m *errorLoggingMiddleware) AggregatePublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregatePublishedOptions) (result map[string]interface{}, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.AggregatePublished(ctx, spaceId, envId, collectionId, filter, options...) -} - -func (m *errorLoggingMiddleware) Archive(ctx context.Context, item *items.Item, options ...*items.ArchiveOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Archive(ctx, item, options...) -} - -func (m *errorLoggingMiddleware) Create(ctx context.Context, item *items.Item, opts ...*items.CreateOptions) (created *items.Item, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Create(ctx, item, opts...) -} - -func (m *errorLoggingMiddleware) Delete(ctx context.Context, item *items.Item, options ...*items.DeleteOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Delete(ctx, item, options...) -} - -func (m *errorLoggingMiddleware) Find(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindOptions) (items []*items.Item, total int, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Find(ctx, spaceId, envId, collectionId, filter, options...) -} - -func (m *errorLoggingMiddleware) FindArchived(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindArchivedOptions) (items []*items.Item, total int, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.FindArchived(ctx, spaceId, envId, collectionId, filter, options...) -} - -func (m *errorLoggingMiddleware) FindPublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindPublishedOptions) (items []*items.Item, total int, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.FindPublished(ctx, spaceId, envId, collectionId, filter, options...) -} - -func (m *errorLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetOptions) (item *items.Item, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Get(ctx, spaceId, envId, collectionId, itemId, options...) -} - -func (m *errorLoggingMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetPublishedOptions) (item *items.Item, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.GetPublished(ctx, spaceId, envId, collectionId, itemId, options...) -} - -func (m *errorLoggingMiddleware) GetRevision(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, revisionId string, options ...*items.GetRevisionOptions) (item *items.Item, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.GetRevision(ctx, spaceId, envId, collectionId, itemId, revisionId, options...) -} - -func (m *errorLoggingMiddleware) Introspect(ctx context.Context, item *items.Item, opts ...*items.IntrospectOptions) (itm *items.Item, sch *schema.Schema, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Introspect(ctx, item, opts...) -} - -func (m *errorLoggingMiddleware) ListRevisions(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.ListRevisionsOptions) (items []*items.Item, err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.ListRevisions(ctx, spaceId, envId, collectionId, itemId, options...) -} - -func (m *errorLoggingMiddleware) Publish(ctx context.Context, item *items.Item, options ...*items.PublishOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Publish(ctx, item, options...) -} - -func (m *errorLoggingMiddleware) Unarchive(ctx context.Context, item *items.Item, options ...*items.UnarchiveOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Unarchive(ctx, item, options...) -} - -func (m *errorLoggingMiddleware) Undelete(ctx context.Context, item *items.Item, options ...*items.UndeleteOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Undelete(ctx, item, options...) -} - -func (m *errorLoggingMiddleware) Unpublish(ctx context.Context, item *items.Item, options ...*items.UnpublishOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Unpublish(ctx, item, options...) -} - -func (m *errorLoggingMiddleware) Update(ctx context.Context, item *items.Item, options ...*items.UpdateOptions) (err error) { - logger := m.logger - defer func() { - if err != nil { - logger.Warn("response error", zap.Error(err)) - } - }() - return m.next.Update(ctx, item, options...) -} diff --git a/pkg/items/middleware/logging_middleware.go b/pkg/items/middleware/logging_middleware.go index 6ed28f90053eab68a44b1e5ac79d5228d7bfe9be..fe7870a831d9b90a6145ad20f4c55cb602e8ed98 100644 --- a/pkg/items/middleware/logging_middleware.go +++ b/pkg/items/middleware/logging_middleware.go @@ -1,744 +1,306 @@ -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -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/id" "git.perx.ru/perxis/perxis-go/pkg/items" "git.perx.ru/perxis/perxis-go/pkg/schema" + logzap "git.perx.ru/perxis/perxis-go/zap" "go.uber.org/zap" - "go.uber.org/zap/zapcore" ) -// loggingMiddleware implements items.Items that is instrumented with logging type loggingMiddleware struct { logger *zap.Logger next items.Items } -// LoggingMiddleware instruments an implementation of the items.Items with simple logging func LoggingMiddleware(logger *zap.Logger) Middleware { return func(next items.Items) items.Items { return &loggingMiddleware{ next: next, - logger: logger, + logger: logger.With(logzap.Component("items")), } } } func (m *loggingMiddleware) Aggregate(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregateOptions) (result map[string]interface{}, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options} { - 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("Aggregate.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) result, err = m.next.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to aggregate", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "result": result, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Aggregate.Response", fields...) - return result, err } func (m *loggingMiddleware) AggregatePublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregatePublishedOptions) (result map[string]interface{}, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options} { - 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("AggregatePublished.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) result, err = m.next.AggregatePublished(ctx, spaceId, envId, collectionId, filter, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to aggregate published", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "result": result, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("AggregatePublished.Response", fields...) - return result, err } func (m *loggingMiddleware) Archive(ctx context.Context, item *items.Item, options ...*items.ArchiveOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Archive.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventArchiveItem), + logzap.Object(item), + ) err = m.next.Archive(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to archive", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Archive.Response", fields...) - + logger.Info("Successfully archived", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Create(ctx context.Context, item *items.Item, opts ...*items.CreateOptions) (created *items.Item, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "opts": opts} { - 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("Create.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventCreateItem), + ) created, err = m.next.Create(ctx, item, opts...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to create", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog), logzap.Object(item)) + return } - m.logger.Debug("Create.Response", fields...) - + logger.Info("Successfully created", logzap.Channels(logzap.Userlog), logzap.Object(created)) return created, err } func (m *loggingMiddleware) Delete(ctx context.Context, item *items.Item, options ...*items.DeleteOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Delete.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventDeleteItem), + logzap.Object(item), + ) err = m.next.Delete(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to delete", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - + logger.Info("Successfully deleted", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Find(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindOptions) (items []*items.Item, total int, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options} { - 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("Find.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) items, total, err = m.next.Find(ctx, spaceId, envId, collectionId, filter, options...) - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "items": items, - "total": total, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to find", zap.Error(err)) + return } - m.logger.Debug("Find.Response", fields...) - return items, total, err } func (m *loggingMiddleware) FindArchived(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindArchivedOptions) (items []*items.Item, total int, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options} { - 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("FindArchived.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) items, total, err = m.next.FindArchived(ctx, spaceId, envId, collectionId, filter, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "items": items, - "total": total, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to find archived", zap.Error(err)) + return } - m.logger.Debug("FindArchived.Response", fields...) - return items, total, err } func (m *loggingMiddleware) FindPublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindPublishedOptions) (items []*items.Item, total int, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options} { - 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("FindPublished.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + ) items, total, err = m.next.FindPublished(ctx, spaceId, envId, collectionId, filter, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "items": items, - "total": total, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to find published", zap.Error(err)) + return } - m.logger.Debug("FindPublished.Response", fields...) - return items, total, err } func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetOptions) (item *items.Item, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options} { - 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...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Object(id.NewItemId(spaceId, envId, collectionId, itemId)), + ) item, err = m.next.Get(ctx, spaceId, envId, collectionId, itemId, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to get", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "item": item, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - return item, err } func (m *loggingMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetPublishedOptions) (item *items.Item, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options} { - 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("GetPublished.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Object(id.NewItemId(spaceId, envId, collectionId, itemId)), + ) item, err = m.next.GetPublished(ctx, spaceId, envId, collectionId, itemId, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to get published", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "item": item, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("GetPublished.Response", fields...) - return item, err } func (m *loggingMiddleware) GetRevision(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, revisionId string, options ...*items.GetRevisionOptions) (item *items.Item, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "revisionId": revisionId, - "options": options} { - 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("GetRevision.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Object(id.NewItemId(spaceId, envId, collectionId, itemId)), + ) item, err = m.next.GetRevision(ctx, spaceId, envId, collectionId, itemId, revisionId, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to get revision", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "item": item, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("GetRevision.Response", fields...) - return item, err } func (m *loggingMiddleware) Introspect(ctx context.Context, item *items.Item, opts ...*items.IntrospectOptions) (itm *items.Item, sch *schema.Schema, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "opts": opts} { - 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("Introspect.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Object(item), + ) itm, sch, err = m.next.Introspect(ctx, item, opts...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "itm": itm, - "sch": sch, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to introspect", zap.Error(err)) + return } - m.logger.Debug("Introspect.Response", fields...) - return itm, sch, err } func (m *loggingMiddleware) ListRevisions(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.ListRevisionsOptions) (items []*items.Item, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options} { - 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("ListRevisions.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Object(id.NewItemId(spaceId, envId, collectionId, itemId)), + ) items, err = m.next.ListRevisions(ctx, spaceId, envId, collectionId, itemId, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to list revisions", zap.Error(err)) + return } - for k, v := range map[string]interface{}{ - "items": items, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListRevisions.Response", fields...) - return items, err } func (m *loggingMiddleware) Publish(ctx context.Context, item *items.Item, options ...*items.PublishOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Publish.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventPublishItem), + logzap.Object(item), + ) err = m.next.Publish(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to publish", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Publish.Response", fields...) - + logger.Info("Successfully published", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Unarchive(ctx context.Context, item *items.Item, options ...*items.UnarchiveOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Unarchive.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventUnarchiveItem), + logzap.Object(item), + ) err = m.next.Unarchive(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to unarchive", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - m.logger.Debug("Unarchive.Response", fields...) - + logger.Info("Successfully unarchived", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Undelete(ctx context.Context, item *items.Item, options ...*items.UndeleteOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Undelete.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventUndeleteItem), + logzap.Object(item), + ) err = m.next.Undelete(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to undelete", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - m.logger.Debug("Undelete.Response", fields...) - + logger.Info("Successfully undeleted", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Unpublish(ctx context.Context, item *items.Item, options ...*items.UnpublishOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Unpublish.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventUnpublishItem), + logzap.Object(item), + ) err = m.next.Unpublish(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) + if err != nil { + logger.Error("Failed to unpublish", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - m.logger.Debug("Unpublish.Response", fields...) - + logger.Info("Successfully unpublished", logzap.Channels(logzap.Userlog)) return err } func (m *loggingMiddleware) Update(ctx context.Context, item *items.Item, options ...*items.UpdateOptions) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options} { - 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("Update.Request", fields...) + logger := m.logger.With( + logzap.CallerFromContext(ctx), + logzap.Event(items.EventUpdateItem), + logzap.Object(item), + ) err = m.next.Update(ctx, item, options...) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), + if err != nil { + logger.Error("Failed to update", zap.Error(err), logzap.Channels(logzap.Userlog, logzap.Syslog)) + return } - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - + logger.Info("Successfully updated", logzap.Channels(logzap.Userlog)) return err } diff --git a/pkg/items/middleware/middleware.go b/pkg/items/middleware/middleware.go index 52a1c1218d1605dc52ae80342684bb0339e63103..4ef6a1fd2a0e2aec25d759d75d2e40d699ad7e06 100644 --- a/pkg/items/middleware/middleware.go +++ b/pkg/items/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/items" @@ -17,12 +17,12 @@ func WithLog(s items.Items, logger *zap.Logger, log_access bool) items.Items { if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Items") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = LoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/items/pagination.go b/pkg/items/pagination.go index 84fac6da574895acf26075dd14ddd1f051c55bb3..c8c4bb16d2da0d2d10e3d98422aaf345ffbf7c21 100644 --- a/pkg/items/pagination.go +++ b/pkg/items/pagination.go @@ -16,9 +16,9 @@ type BatchProcessor struct { FindPublishedOptions *FindPublishedOptions Filter *Filter - pageSize, pageNum int - sort []string - processed int + limit int + sort []string + processed int } func (b *BatchProcessor) getBatch(ctx context.Context) ([]*Item, bool, error) { @@ -37,7 +37,7 @@ func (b *BatchProcessor) getBatch(ctx context.Context) ([]*Item, bool, error) { Regular: b.FindPublishedOptions.Regular, Hidden: b.FindPublishedOptions.Hidden, Templates: b.FindPublishedOptions.Templates, - FindOptions: *options.NewFindOptions(b.pageNum, b.pageSize, b.sort...), + FindOptions: *options.New(b.processed, b.limit, b.sort...), }, ) } else { @@ -52,14 +52,13 @@ func (b *BatchProcessor) getBatch(ctx context.Context) ([]*Item, bool, error) { Regular: b.FindOptions.Regular, Hidden: b.FindOptions.Hidden, Templates: b.FindOptions.Templates, - FindOptions: *options.NewFindOptions(b.pageNum, b.pageSize, b.sort...), + FindOptions: *options.New(b.processed, b.limit, b.sort...), }, ) } if err == nil { b.processed += len(res) - b.pageNum++ } return res, b.processed != total, err @@ -84,32 +83,29 @@ func (b *BatchProcessor) next(ctx context.Context) (res []*Item, next bool, err } func (b *BatchProcessor) reducePageSize() bool { - if b.pageSize == 1 { + if b.limit == 1 { return false } - b.pageNum = 2 * b.pageNum - b.pageSize = b.pageSize / 2 - + b.limit /= 2 return true } func (b *BatchProcessor) Do(ctx context.Context, f func(batch []*Item) error) (int, error) { - if b.FindOptions == nil && b.FindPublishedOptions == nil { b.FindOptions = new(FindOptions) } if b.FindOptions != nil { - b.pageSize = b.FindOptions.PageSize + b.limit = b.FindOptions.Limit b.sort = b.FindOptions.Sort } if b.FindPublishedOptions != nil { - b.pageSize = b.FindPublishedOptions.PageSize + b.limit = b.FindPublishedOptions.Limit b.sort = b.FindPublishedOptions.Sort } - if b.pageSize == 0 { - b.pageSize = 128 + if b.limit == 0 { + b.limit = 128 } if b.Filter != nil && (len(b.Filter.ID) > 0 || len(b.Filter.Q) > 0) && !data.Contains("_id", b.sort) { diff --git a/pkg/items/pagination_test.go b/pkg/items/pagination_test.go index bf13af39e00bd19550ddd49bae3e165b5cfa9fff..008b17795cc1c57d4e2dcf6bb3507bee8b3f1646 100644 --- a/pkg/items/pagination_test.go +++ b/pkg/items/pagination_test.go @@ -11,25 +11,51 @@ import ( ) func TestBatchProcessor(t *testing.T) { + t.Run("EmptyResults", func(t *testing.T) { + itemssvc := &Stub{ + FindResult: func(req StubFindRequest) StubFindResult { + return StubFindResult{Items: nil, Total: 0, Error: nil} + }, + } - itemssvc := &Dummy{FindResult: &FindResultDummy{Items: nil, Total: 0, Error: nil}} + b := &BatchProcessor{ + Items: itemssvc, + SpaceID: "sp", + EnvID: environments.DefaultEnvironment, + CollectionID: "col", + FindOptions: &FindOptions{ + Regular: true, + Hidden: true, + Templates: true, + FindOptions: *options.NewFindOptions(0, 10), + }, + Filter: NewFilter("a > 5"), + } - b := &BatchProcessor{ - Items: itemssvc, - SpaceID: "sp", - EnvID: environments.DefaultEnvironment, - CollectionID: "col", - FindOptions: &FindOptions{ - Regular: true, - Hidden: true, - Templates: true, - FindOptions: *options.NewFindOptions(0, 10), - }, - Filter: NewFilter("a > 5"), - } + var counter int + _, err := b.Do(context.Background(), func(batch []*Item) error { counter++; return nil }) + require.NoError(t, err) + assert.Equal(t, 0, counter) + }) - var counter int - _, err := b.Do(context.Background(), func(batch []*Item) error { counter++; return nil }) - require.NoError(t, err) - assert.Equal(t, 0, counter) + t.Run("With FindOptions", func(t *testing.T) { + itemssvc := &Stub{ + FindResult: func(req StubFindRequest) StubFindResult { + fo := MergeFindOptions(req.Options...) + return StubFindResult{Items: make([]*Item, fo.Limit), Total: 1000, Error: nil} + }, + } + b := &BatchProcessor{ + Items: itemssvc, + SpaceID: "sp", + EnvID: environments.DefaultEnvironment, + CollectionID: "col", + FindOptions: &FindOptions{FindOptions: *options.New(0, 25)}, + } + + var counter int + _, err := b.Do(context.Background(), func(batch []*Item) error { counter++; return nil }) + require.NoError(t, err) + assert.Equal(t, 1000/25, counter) + }) } diff --git a/pkg/items/stub.go b/pkg/items/stub.go new file mode 100644 index 0000000000000000000000000000000000000000..33573514b655a6084f636403a581bad46b130172 --- /dev/null +++ b/pkg/items/stub.go @@ -0,0 +1,35 @@ +package items + +import ( + "context" +) + +type StubFindRequest struct { + Context context.Context + SpaceID, EnvID, CollID string + Filter *Filter + Options []*FindOptions +} + +type StubFindResult struct { + Items []*Item + Total int + Error error +} + +type Stub struct { + Items + FindResult func(req StubFindRequest) StubFindResult +} + +func (d *Stub) Find(ctx context.Context, spaceID, envID, collID string, filter *Filter, opts ...*FindOptions) ([]*Item, int, error) { + res := d.FindResult(StubFindRequest{ + Context: ctx, + SpaceID: spaceID, + EnvID: envID, + CollID: collID, + Filter: filter, + Options: opts, + }) + return res.Items, res.Total, res.Error +} diff --git a/pkg/items/transport/grpc/protobuf_type_converters.microgen.go b/pkg/items/transport/grpc/protobuf_type_converters.microgen.go index 212b1ecd2bfb27db8b49d0f965b484226265f189..ade05bfffeb4a1c745f80338e7faac2287b067a2 100644 --- a/pkg/items/transport/grpc/protobuf_type_converters.microgen.go +++ b/pkg/items/transport/grpc/protobuf_type_converters.microgen.go @@ -144,35 +144,11 @@ func ProtoToPtrFilter(protoFilter *pb.Filter) (*service.Filter, error) { } func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*pbcommon.FindOptions, error) { - if opts == nil { - return nil, nil - } - return &pbcommon.FindOptions{ - Sort: opts.Sort, - PageNum: int32(opts.PageNum), - PageSize: int32(opts.PageSize), - Fields: opts.Fields, - ExcludeFields: opts.ExcludeFields, - }, nil + return options.FindOptionsToPB(opts), nil } func ProtoToPtrServicesFindOptions(protoOpts *pbcommon.FindOptions) (*options.FindOptions, error) { - if protoOpts == nil { - return nil, nil - } - return &options.FindOptions{ - SortOptions: options.SortOptions{ - Sort: protoOpts.Sort, - }, - PaginationOptions: options.PaginationOptions{ - PageNum: int(protoOpts.PageNum), - PageSize: int(protoOpts.PageSize), - }, - FieldOptions: options.FieldOptions{ - Fields: protoOpts.Fields, - ExcludeFields: protoOpts.ExcludeFields, - }, - }, nil + return options.FindOptionsFromPB(protoOpts), nil } func ListPtrItemToProto(items []*service.Item) ([]*pb.Item, error) { diff --git a/pkg/locales/middleware/access_logging_middleware.go b/pkg/locales/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..eabb71c37756d0a7d39d6abe217f394036a69922 --- /dev/null +++ b/pkg/locales/middleware/access_logging_middleware.go @@ -0,0 +1,89 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/locales" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements locales.Locales that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next locales.Locales +} + +// AccessLoggingMiddleware instruments an implementation of the locales.Locales with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next locales.Locales) locales.Locales { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, locale *locales.Locale) (created *locales.Locale, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("locale", locale), + ) + + created, err = m.next.Create(ctx, locale) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, spaceId string, localeId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("localeId", localeId), + ) + + err = m.next.Delete(ctx, spaceId, localeId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) List(ctx context.Context, spaceId string) (locales []*locales.Locale, err error) { + begin := time.Now() + + m.logger.Debug("List.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + locales, err = m.next.List(ctx, spaceId) + + m.logger.Debug("List.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("locales", locales), + zap.Error(err), + ) + + return locales, err +} diff --git a/pkg/locales/middleware/error_logging_middleware.go b/pkg/locales/middleware/error_logging_middleware.go index 3251fc7c972217ca4480ecbc26cb65cc055504ea..a00f23a29aa8b5330e1097c670e6cc0edf5b9983 100644 --- a/pkg/locales/middleware/error_logging_middleware.go +++ b/pkg/locales/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/locales/middleware/logging_middleware.go b/pkg/locales/middleware/logging_middleware.go deleted file mode 100644 index 2db3ef39beb37cabf73adbfb9a3e1122f9e85387..0000000000000000000000000000000000000000 --- a/pkg/locales/middleware/logging_middleware.go +++ /dev/null @@ -1,145 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -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/locales" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements locales.Locales that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next locales.Locales -} - -// LoggingMiddleware instruments an implementation of the locales.Locales with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next locales.Locales) locales.Locales { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Create(ctx context.Context, locale *locales.Locale) (created *locales.Locale, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "locale": locale} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, locale) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, spaceId string, localeId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "localeId": localeId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, spaceId, localeId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) List(ctx context.Context, spaceId string) (locales []*locales.Locale, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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("List.Request", fields...) - - locales, err = m.next.List(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "locales": locales, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("List.Response", fields...) - - return locales, err -} diff --git a/pkg/locales/middleware/middleware.go b/pkg/locales/middleware/middleware.go index 721829405e98efc0c47e75f8670f4e74b784998d..2598e397afafb552c16be249cfcf1ed62149339b 100644 --- a/pkg/locales/middleware/middleware.go +++ b/pkg/locales/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/locales" @@ -17,12 +17,12 @@ func WithLog(s locales.Locales, logger *zap.Logger, log_access bool) locales.Loc if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Locales") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/members/middleware/access_logging_middleware.go b/pkg/members/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..0a062331a51f9f93d0d7c877637636d3640ef8a7 --- /dev/null +++ b/pkg/members/middleware/access_logging_middleware.go @@ -0,0 +1,147 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/members" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements members.Members that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next members.Members +} + +// AccessLoggingMiddleware instruments an implementation of the members.Members with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next members.Members) members.Members { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, orgId string, userId string) (role members.Role, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + zap.Reflect("userId", userId), + ) + + role, err = m.next.Get(ctx, orgId, userId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("role", role), + zap.Error(err), + ) + + return role, err +} + +func (m *accessLoggingMiddleware) ListMembers(ctx context.Context, orgId string) (members []*members.Member, err error) { + begin := time.Now() + + m.logger.Debug("ListMembers.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + ) + + members, err = m.next.ListMembers(ctx, orgId) + + m.logger.Debug("ListMembers.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("members", members), + zap.Error(err), + ) + + return members, err +} + +func (m *accessLoggingMiddleware) ListOrganizations(ctx context.Context, userId string) (organizations []*members.Member, err error) { + begin := time.Now() + + m.logger.Debug("ListOrganizations.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("userId", userId), + ) + + organizations, err = m.next.ListOrganizations(ctx, userId) + + m.logger.Debug("ListOrganizations.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("organizations", organizations), + zap.Error(err), + ) + + return organizations, err +} + +func (m *accessLoggingMiddleware) Remove(ctx context.Context, orgId string, userId string) (err error) { + begin := time.Now() + + m.logger.Debug("Remove.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + zap.Reflect("userId", userId), + ) + + err = m.next.Remove(ctx, orgId, userId) + + m.logger.Debug("Remove.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) RemoveAll(ctx context.Context, orgId string) (err error) { + begin := time.Now() + + m.logger.Debug("RemoveAll.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + ) + + err = m.next.RemoveAll(ctx, orgId) + + m.logger.Debug("RemoveAll.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Set(ctx context.Context, orgId string, userId string, role members.Role) (err error) { + begin := time.Now() + + m.logger.Debug("Set.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + zap.Reflect("userId", userId), + zap.Reflect("role", role), + ) + + err = m.next.Set(ctx, orgId, userId, role) + + m.logger.Debug("Set.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/members/middleware/error_logging_middleware.go b/pkg/members/middleware/error_logging_middleware.go index 79a92a1f2ac6f3d5854fcdf6c1f709e21ee160a7..d3c1a594983ac1bf25a8a397c12580d445b063b6 100644 --- a/pkg/members/middleware/error_logging_middleware.go +++ b/pkg/members/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/members/middleware/logging_middleware.go b/pkg/members/middleware/logging_middleware.go deleted file mode 100644 index 3136597a451cc8938c4dc326b01b9e022658293e..0000000000000000000000000000000000000000 --- a/pkg/members/middleware/logging_middleware.go +++ /dev/null @@ -1,257 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -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/members" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements members.Members that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next members.Members -} - -// LoggingMiddleware instruments an implementation of the members.Members with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next members.Members) members.Members { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Get(ctx context.Context, orgId string, userId string) (role members.Role, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId, - "userId": userId} { - 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...) - - role, err = m.next.Get(ctx, orgId, userId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "role": role, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return role, err -} - -func (m *loggingMiddleware) ListMembers(ctx context.Context, orgId string) (members []*members.Member, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId} { - 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("ListMembers.Request", fields...) - - members, err = m.next.ListMembers(ctx, orgId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "members": members, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListMembers.Response", fields...) - - return members, err -} - -func (m *loggingMiddleware) ListOrganizations(ctx context.Context, userId string) (organizations []*members.Member, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "userId": userId} { - 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("ListOrganizations.Request", fields...) - - organizations, err = m.next.ListOrganizations(ctx, userId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "organizations": organizations, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListOrganizations.Response", fields...) - - return organizations, err -} - -func (m *loggingMiddleware) Remove(ctx context.Context, orgId string, userId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId, - "userId": userId} { - 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("Remove.Request", fields...) - - err = m.next.Remove(ctx, orgId, userId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Remove.Response", fields...) - - return err -} - -func (m *loggingMiddleware) RemoveAll(ctx context.Context, orgId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId} { - 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("RemoveAll.Request", fields...) - - err = m.next.RemoveAll(ctx, orgId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("RemoveAll.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Set(ctx context.Context, orgId string, userId string, role members.Role) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId, - "userId": userId, - "role": role} { - 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("Set.Request", fields...) - - err = m.next.Set(ctx, orgId, userId, role) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Set.Response", fields...) - - return err -} diff --git a/pkg/members/middleware/middleware.go b/pkg/members/middleware/middleware.go index 517bfa624a35e247d1e93f44db75a5eccaf0c721..bb491623865e21496adedb1e91987bc2205a3ce4 100644 --- a/pkg/members/middleware/middleware.go +++ b/pkg/members/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/members" @@ -17,12 +17,12 @@ func WithLog(s members.Members, logger *zap.Logger, log_access bool) members.Mem if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Members") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/members/observer/middleware/access_logging_middleware.go b/pkg/members/observer/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..48e9da969978baf7abdad1ae3c9a92582f56d299 --- /dev/null +++ b/pkg/members/observer/middleware/access_logging_middleware.go @@ -0,0 +1,52 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/collaborators" + "git.perx.ru/perxis/perxis-go/pkg/members/observer" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements observer.Observer that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next observer.Observer +} + +// AccessLoggingMiddleware instruments an implementation of the observer.Observer with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next observer.Observer) observer.Observer { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error) { + begin := time.Now() + + m.logger.Debug("OnCollaboratorSet.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("collaborator", collaborator), + ) + + delayedTaskID, err = m.next.OnCollaboratorSet(ctx, collaborator) + + m.logger.Debug("OnCollaboratorSet.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("delayedTaskID", delayedTaskID), + zap.Error(err), + ) + + return delayedTaskID, err +} diff --git a/pkg/members/observer/middleware/error_logging_middleware.go b/pkg/members/observer/middleware/error_logging_middleware.go index b7184b475d626a0f4a2a53cd427a672841b38249..462eff251d5aec0648d4ef7e8d60e200896cbe6e 100644 --- a/pkg/members/observer/middleware/error_logging_middleware.go +++ b/pkg/members/observer/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/members/observer/middleware/logging_middleware.go b/pkg/members/observer/middleware/logging_middleware.go deleted file mode 100644 index 09f203fd21f3a3d2ecabd3279c3d1ca2a323194d..0000000000000000000000000000000000000000 --- a/pkg/members/observer/middleware/logging_middleware.go +++ /dev/null @@ -1,72 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -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/collaborators" - "git.perx.ru/perxis/perxis-go/pkg/members/observer" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements observer.Observer that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next observer.Observer -} - -// LoggingMiddleware instruments an implementation of the observer.Observer with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next observer.Observer) observer.Observer { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "collaborator": collaborator} { - 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("OnCollaboratorSet.Request", fields...) - - delayedTaskID, err = m.next.OnCollaboratorSet(ctx, collaborator) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "delayedTaskID": delayedTaskID, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("OnCollaboratorSet.Response", fields...) - - return delayedTaskID, err -} diff --git a/pkg/members/observer/middleware/middleware.go b/pkg/members/observer/middleware/middleware.go index f68b58c7398b341f8f3850ddb96538027a58d354..ba2dff4fee8f9ad426d951d518c18e07dc05134e 100644 --- a/pkg/members/observer/middleware/middleware.go +++ b/pkg/members/observer/middleware/middleware.go @@ -1,10 +1,10 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. -// template: ../../../../assets/templates/middleware/middleware +// template: ../../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/middleware -o middleware.go -l "" +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/members/observer" @@ -17,12 +17,12 @@ func WithLog(s observer.Observer, logger *zap.Logger, log_access bool) observer. if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Observer") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/members/observer/middleware/recovering_middleware.go b/pkg/members/observer/middleware/recovering_middleware.go index bd576ecd2699dea927925b935bc024630420f997..f4d96995ded61101fde4a8faabf21da84000f1fb 100644 --- a/pkg/members/observer/middleware/recovering_middleware.go +++ b/pkg/members/observer/middleware/recovering_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../../assets/templates/middleware/recovery // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/recovery -o recovering_middleware.go -l "" import ( diff --git a/pkg/options/options.go b/pkg/options/options.go index 7f8b0cd624db7e6c4c35fe62333a67ba633fbe7e..d18ca338c01a7d0e2117a0e09f47d1a21421bdd1 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -1,6 +1,10 @@ package options -import "time" +import ( + "time" + + commonpb "git.perx.ru/perxis/perxis-go/proto/common" +) // SortOptions настройки сортировки результатов type SortOptions struct { @@ -9,8 +13,8 @@ type SortOptions struct { // PaginationOptions настройки возвращаемых страниц результатов type PaginationOptions struct { - PageNum int - PageSize int + Limit int + Offset int } // FieldOptions настройки включения/исключения полей РёР· результатов запроса @@ -31,12 +35,18 @@ type FindOptions struct { FieldOptions } +// Deprecated использовать New // NewFindOptions создает новые результаты РїРѕРёСЃРєР° func NewFindOptions(pageNum, pageSize int, sort ...string) *FindOptions { + return New(pageNum*pageSize, pageSize, sort...) +} + +// New создает новые параметры РїРѕРёСЃРєР° +func New(offset, limit int, sort ...string) *FindOptions { return &FindOptions{ PaginationOptions: PaginationOptions{ - PageNum: pageNum, - PageSize: pageSize, + Offset: offset, + Limit: limit, }, SortOptions: SortOptions{ Sort: sort, @@ -78,6 +88,46 @@ func MergeFindOptions(opts ...interface{}) *FindOptions { return fo } +func FindOptionsFromPB(protoOpts *commonpb.FindOptions) *FindOptions { + if protoOpts == nil { + return nil + } + fo := &FindOptions{ + SortOptions: SortOptions{ + Sort: protoOpts.Sort, + }, + PaginationOptions: PaginationOptions{ + Limit: int(protoOpts.Limit), + Offset: int(protoOpts.Offset), + }, + FieldOptions: FieldOptions{ + Fields: protoOpts.Fields, + ExcludeFields: protoOpts.ExcludeFields, + }, + } + + if fo.Offset == 0 && fo.Limit == 0 { + fo.Offset = int(protoOpts.PageSize * protoOpts.PageNum) + fo.Limit = int(protoOpts.PageSize) + } + + return fo +} + +func FindOptionsToPB(opts *FindOptions) *commonpb.FindOptions { + if opts == nil { + return nil + } + fo := &commonpb.FindOptions{ + Sort: opts.Sort, + Offset: int32(opts.Offset), + Limit: int32(opts.Limit), + Fields: opts.Fields, + ExcludeFields: opts.ExcludeFields, + } + return fo +} + type TimeFilter struct { Before, After time.Time } @@ -98,11 +148,11 @@ func MergeSortOptions(options ...SortOptions) SortOptions { func MergePaginationOptions(options ...PaginationOptions) PaginationOptions { fo := PaginationOptions{} for _, opt := range options { - if opt.PageSize == 0 && opt.PageNum == 0 { + if opt.Offset == 0 && opt.Limit == 0 { continue } - fo.PageNum = opt.PageNum - fo.PageSize = opt.PageSize + fo.Offset = opt.Offset + fo.Limit = opt.Limit } return fo } diff --git a/pkg/options/options_test.go b/pkg/options/options_test.go index 981849a0e2625a8bd7e796a22eaa8529d606ef01..d2227a875a837c67006eab028f235afcbd1efe5e 100644 --- a/pkg/options/options_test.go +++ b/pkg/options/options_test.go @@ -7,7 +7,6 @@ import ( ) func TestOptions_MergePaginationOptions(t *testing.T) { - var tt = []struct { name string options []PaginationOptions @@ -24,29 +23,29 @@ func TestOptions_MergePaginationOptions(t *testing.T) { expected: PaginationOptions{}, }, { - name: "One option", - options: []PaginationOptions{{PageNum: 10, PageSize: 100}}, - expected: PaginationOptions{PageNum: 10, PageSize: 100}, + name: "One limit/offset option", + options: []PaginationOptions{{Limit: 10, Offset: 100}}, + expected: PaginationOptions{Limit: 10, Offset: 100}, }, { - name: "Merge #1", - options: []PaginationOptions{{PageNum: 0, PageSize: 0}, {PageNum: 10, PageSize: 100}}, - expected: PaginationOptions{PageNum: 10, PageSize: 100}, + name: "Merge limit/offset #1", + options: []PaginationOptions{{Limit: 0, Offset: 0}, {Limit: 10, Offset: 100}}, + expected: PaginationOptions{Limit: 10, Offset: 100}, }, { - name: "Merge #2", - options: []PaginationOptions{{PageNum: 10, PageSize: 100}, {PageNum: 0, PageSize: 0}}, - expected: PaginationOptions{PageNum: 10, PageSize: 100}, + name: "Merge limit/offset #2", + options: []PaginationOptions{{Limit: 10, Offset: 100}, {Limit: 0, Offset: 0}}, + expected: PaginationOptions{Limit: 10, Offset: 100}, }, { - name: "Merge #3", - options: []PaginationOptions{{PageNum: 0, PageSize: 0}, {PageNum: 10, PageSize: 100}, {PageNum: 0, PageSize: 0}}, - expected: PaginationOptions{PageNum: 10, PageSize: 100}, + name: "Merge limit/offset #3", + options: []PaginationOptions{{Limit: 0, Offset: 0}, {Limit: 10, Offset: 100}, {Limit: 0, Offset: 0}}, + expected: PaginationOptions{Limit: 10, Offset: 100}, }, { - name: "Merge #4", - options: []PaginationOptions{{PageNum: 10, PageSize: 100}, {}}, - expected: PaginationOptions{PageNum: 10, PageSize: 100}, + name: "Merge limit/offset #4", + options: []PaginationOptions{{Limit: 10, Offset: 100}, {}}, + expected: PaginationOptions{Limit: 10, Offset: 100}, }, } diff --git a/pkg/organizations/middleware/access_logging_middleware.go b/pkg/organizations/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..be6e937d1dc76ba9a6d4d80acd5c6343e35eacd7 --- /dev/null +++ b/pkg/organizations/middleware/access_logging_middleware.go @@ -0,0 +1,128 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/options" + "git.perx.ru/perxis/perxis-go/pkg/organizations" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements organizations.Organizations that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next organizations.Organizations +} + +// AccessLoggingMiddleware instruments an implementation of the organizations.Organizations with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next organizations.Organizations) organizations.Organizations { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, org *organizations.Organization) (created *organizations.Organization, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("org", org), + ) + + created, err = m.next.Create(ctx, org) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, orgId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + ) + + err = m.next.Delete(ctx, orgId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Find(ctx context.Context, filter *organizations.Filter, opts *options.FindOptions) (orgs []*organizations.Organization, total int, err error) { + begin := time.Now() + + m.logger.Debug("Find.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("filter", filter), + zap.Reflect("opts", opts), + ) + + orgs, total, err = m.next.Find(ctx, filter, opts) + + m.logger.Debug("Find.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("orgs", orgs), + zap.Reflect("total", total), + zap.Error(err), + ) + + return orgs, total, err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, orgId string) (org *organizations.Organization, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + ) + + org, err = m.next.Get(ctx, orgId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("org", org), + zap.Error(err), + ) + + return org, err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, org *organizations.Organization) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("org", org), + ) + + err = m.next.Update(ctx, org) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/organizations/middleware/error_logging_middleware.go b/pkg/organizations/middleware/error_logging_middleware.go index 1ededdd2a8f391c56909cc33ec799175380a939a..2d6db8198b885e157ba8ebcc855bb6d9dadb519c 100644 --- a/pkg/organizations/middleware/error_logging_middleware.go +++ b/pkg/organizations/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/organizations/middleware/logging_middleware.go b/pkg/organizations/middleware/logging_middleware.go deleted file mode 100644 index b1e6bc3b914ea49d0781d7ae39ddcc5c795fff45..0000000000000000000000000000000000000000 --- a/pkg/organizations/middleware/logging_middleware.go +++ /dev/null @@ -1,220 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -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/options" - "git.perx.ru/perxis/perxis-go/pkg/organizations" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements organizations.Organizations that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next organizations.Organizations -} - -// LoggingMiddleware instruments an implementation of the organizations.Organizations with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next organizations.Organizations) organizations.Organizations { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Create(ctx context.Context, org *organizations.Organization) (created *organizations.Organization, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "org": org} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, org) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, orgId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, orgId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Find(ctx context.Context, filter *organizations.Filter, opts *options.FindOptions) (orgs []*organizations.Organization, total int, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "filter": filter, - "opts": opts} { - 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("Find.Request", fields...) - - orgs, total, err = m.next.Find(ctx, filter, opts) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "orgs": orgs, - "total": total, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Find.Response", fields...) - - return orgs, total, err -} - -func (m *loggingMiddleware) Get(ctx context.Context, orgId string) (org *organizations.Organization, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId} { - 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...) - - org, err = m.next.Get(ctx, orgId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "org": org, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return org, err -} - -func (m *loggingMiddleware) Update(ctx context.Context, org *organizations.Organization) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "org": org} { - 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("Update.Request", fields...) - - err = m.next.Update(ctx, org) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - - return err -} diff --git a/pkg/organizations/middleware/middleware.go b/pkg/organizations/middleware/middleware.go index f6cf5c5527ede8c7d285cc280642ca6aa420970c..906a4c356b434fa2926a3e970bf0f32d0c0fa936 100644 --- a/pkg/organizations/middleware/middleware.go +++ b/pkg/organizations/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/organizations" @@ -17,12 +17,12 @@ func WithLog(s organizations.Organizations, logger *zap.Logger, log_access bool) if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Organizations") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/organizations/transport/grpc/protobuf_type_converters.microgen.go b/pkg/organizations/transport/grpc/protobuf_type_converters.microgen.go index 15fce8f5a7966f8fa2958fef30f62805923f512b..9a35f86e871d4e9b7792aa31590fd8f1b1fd0e12 100644 --- a/pkg/organizations/transport/grpc/protobuf_type_converters.microgen.go +++ b/pkg/organizations/transport/grpc/protobuf_type_converters.microgen.go @@ -61,29 +61,11 @@ func ProtoToPtrFilter(protoFilter *pb.Filter) (*organizations.Filter, error) { } func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*common.FindOptions, error) { - if opts == nil { - return nil, nil - } - return &common.FindOptions{ - Sort: opts.Sort, - PageNum: int32(opts.PageNum), - PageSize: int32(opts.PageSize), - }, nil + return options.FindOptionsToPB(opts), nil } func ProtoToPtrServicesFindOptions(protoOpts *common.FindOptions) (*options.FindOptions, error) { - if protoOpts == nil { - return nil, nil - } - return &options.FindOptions{ - SortOptions: options.SortOptions{ - Sort: protoOpts.Sort, - }, - PaginationOptions: options.PaginationOptions{ - PageNum: int(protoOpts.PageNum), - PageSize: int(protoOpts.PageSize), - }, - }, nil + return options.FindOptionsFromPB(protoOpts), nil } func ListPtrOrganizationToProto(orgs []*organizations.Organization) ([]*pb.Organization, error) { diff --git a/pkg/references/middleware/access_logging_middleware.go b/pkg/references/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..c628dc11fccc175b91f0ed7fdc7f180e3a91bfb4 --- /dev/null +++ b/pkg/references/middleware/access_logging_middleware.go @@ -0,0 +1,80 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "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" +) + +// accessLoggingMiddleware implements references.References that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next references.References +} + +// AccessLoggingMiddleware instruments an implementation of the references.References with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next references.References) references.References { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, envId string, references []*references.Reference) (items []*items.Item, notfound []*references.Reference, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("references", references), + ) + + items, notfound, err = m.next.Get(ctx, spaceId, envId, references) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("items", items), + zap.Reflect("notfound", notfound), + zap.Error(err), + ) + + return items, notfound, err +} + +func (m *accessLoggingMiddleware) Publish(ctx context.Context, spaceId string, envId string, references []*references.Reference, recursive bool, force bool) (published []*references.Reference, notfound []*references.Reference, unpublished []*references.Reference, err error) { + begin := time.Now() + + m.logger.Debug("Publish.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("envId", envId), + zap.Reflect("references", references), + zap.Reflect("recursive", recursive), + zap.Reflect("force", force), + ) + + published, notfound, unpublished, err = m.next.Publish(ctx, spaceId, envId, references, recursive, force) + + m.logger.Debug("Publish.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("published", published), + zap.Reflect("notfound", notfound), + zap.Reflect("unpublished", unpublished), + zap.Error(err), + ) + + return published, notfound, unpublished, err +} diff --git a/pkg/references/middleware/error_logging_middleware.go b/pkg/references/middleware/error_logging_middleware.go index 0cfbf919e5acd70dc453494d15e9e8778afcca85..b55b11679d819e42f30234d27f6f140b2d024aa8 100644 --- a/pkg/references/middleware/error_logging_middleware.go +++ b/pkg/references/middleware/error_logging_middleware.go @@ -1,10 +1,10 @@ -package middleware +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/error_log +// gowrap: http://github.com/hexdigest/gowrap -// DO NOT EDIT! -// This code is generated with http://github.com/hexdigest/gowrap tool -// using ../../../assets/templates/middleware/error_log template +package middleware -//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 +//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" diff --git a/pkg/references/middleware/logging_middleware.go b/pkg/references/middleware/logging_middleware.go deleted file mode 100644 index a0f010ae99c2f9ce1eb726e5caba316379328a42..0000000000000000000000000000000000000000 --- a/pkg/references/middleware/logging_middleware.go +++ /dev/null @@ -1,118 +0,0 @@ -package middleware - -// DO NOT EDIT! -// This code is generated with http://github.com/hexdigest/gowrap tool -// using ../../../assets/templates/middleware/access_log template - -//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 - -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)), - } - - for k, v := range map[string]interface{}{ - "items": items, - "notfound": notfound, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return items, notfound, err -} - -func (m *loggingMiddleware) Publish(ctx context.Context, spaceId string, envId string, references []*references.Reference, recursive bool, force bool) (published []*references.Reference, notfound []*references.Reference, unpublished []*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, - "recursive": recursive, - "force": force} { - 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("Publish.Request", fields...) - - published, notfound, unpublished, err = m.next.Publish(ctx, spaceId, envId, references, recursive, force) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "published": published, - "notfound": notfound, - "unpublished": unpublished, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Publish.Response", fields...) - - return published, notfound, unpublished, err -} diff --git a/pkg/references/middleware/middleware.go b/pkg/references/middleware/middleware.go index 6bd830146952e16ccabf780230d03dc6b9473a74..529a61b60265f0f77bc0a4a3be38151f7ba5334e 100644 --- a/pkg/references/middleware/middleware.go +++ b/pkg/references/middleware/middleware.go @@ -1,10 +1,10 @@ -package middleware +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/middleware.tmpl +// gowrap: http://github.com/hexdigest/gowrap -// DO NOT EDIT! -// This code is generated with http://github.com/hexdigest/gowrap tool -// using ../../../assets/templates/middleware/middleware template +package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/middleware -o middleware.go +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/references" @@ -17,12 +17,12 @@ func WithLog(s references.References, logger *zap.Logger, log_access bool) refer if logger == nil { logger = zap.NewNop() } - logger = logger.Named("References") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/references/middleware/recovering_middleware.go b/pkg/references/middleware/recovering_middleware.go index 070d9d22fca08a8394362b8eea6a31628d56902c..1331a96787b8ba98322ab2e4ee5764d296504066 100644 --- a/pkg/references/middleware/recovering_middleware.go +++ b/pkg/references/middleware/recovering_middleware.go @@ -1,10 +1,10 @@ -package middleware +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/recovery +// gowrap: http://github.com/hexdigest/gowrap -// DO NOT EDIT! -// This code is generated with http://github.com/hexdigest/gowrap tool -// using ../../../assets/templates/middleware/recovery template +package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/recovery -o recovering_middleware.go +//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" diff --git a/pkg/roles/middleware/access_logging_middleware.go b/pkg/roles/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..310cdeda7c585c571263bebb6c42739a8d3074de --- /dev/null +++ b/pkg/roles/middleware/access_logging_middleware.go @@ -0,0 +1,127 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/roles" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements roles.Roles that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next roles.Roles +} + +// AccessLoggingMiddleware instruments an implementation of the roles.Roles with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next roles.Roles) roles.Roles { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, role *roles.Role) (created *roles.Role, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("role", role), + ) + + created, err = m.next.Create(ctx, role) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, spaceId string, roleId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("roleId", roleId), + ) + + err = m.next.Delete(ctx, spaceId, roleId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, roleId string) (role *roles.Role, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("roleId", roleId), + ) + + role, err = m.next.Get(ctx, spaceId, roleId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("role", role), + zap.Error(err), + ) + + return role, err +} + +func (m *accessLoggingMiddleware) List(ctx context.Context, spaceId string) (roles []*roles.Role, err error) { + begin := time.Now() + + m.logger.Debug("List.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + roles, err = m.next.List(ctx, spaceId) + + m.logger.Debug("List.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("roles", roles), + zap.Error(err), + ) + + return roles, err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, role *roles.Role) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("role", role), + ) + + err = m.next.Update(ctx, role) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/roles/middleware/error_logging_middleware.go b/pkg/roles/middleware/error_logging_middleware.go index 48f12c3d6416ade72e1567c976e78b6237a3d323..bb6073d11fef1d2763ca85855274edf4a8c71839 100644 --- a/pkg/roles/middleware/error_logging_middleware.go +++ b/pkg/roles/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/roles/middleware/logging_middleware.go b/pkg/roles/middleware/logging_middleware.go deleted file mode 100644 index 31d9d49245bd64eb0e2ba542e54e32f01805d007..0000000000000000000000000000000000000000 --- a/pkg/roles/middleware/logging_middleware.go +++ /dev/null @@ -1,219 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -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/roles" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements roles.Roles that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next roles.Roles -} - -// LoggingMiddleware instruments an implementation of the roles.Roles with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next roles.Roles) roles.Roles { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Create(ctx context.Context, role *roles.Role) (created *roles.Role, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "role": role} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, role) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, spaceId string, roleId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "roleId": roleId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, spaceId, roleId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Get(ctx context.Context, spaceId string, roleId string) (role *roles.Role, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "roleId": roleId} { - 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...) - - role, err = m.next.Get(ctx, spaceId, roleId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "role": role, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return role, err -} - -func (m *loggingMiddleware) List(ctx context.Context, spaceId string) (roles []*roles.Role, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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("List.Request", fields...) - - roles, err = m.next.List(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "roles": roles, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("List.Response", fields...) - - return roles, err -} - -func (m *loggingMiddleware) Update(ctx context.Context, role *roles.Role) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "role": role} { - 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("Update.Request", fields...) - - err = m.next.Update(ctx, role) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - - return err -} diff --git a/pkg/roles/middleware/middleware.go b/pkg/roles/middleware/middleware.go index 6b1a8b16e0178a22a57a6f44226aa32c6dacf4eb..aaeb2da895d5aa71768e577315e549daa6a247c4 100644 --- a/pkg/roles/middleware/middleware.go +++ b/pkg/roles/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/roles" @@ -17,12 +17,12 @@ func WithLog(s roles.Roles, logger *zap.Logger, log_access bool) roles.Roles { if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Roles") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/spaces/middleware/access_logging_middleware.go b/pkg/spaces/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..7fca51ede8a87ba31ceb7293537e32c2db4c08d7 --- /dev/null +++ b/pkg/spaces/middleware/access_logging_middleware.go @@ -0,0 +1,219 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/spaces" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements spaces.Spaces that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next spaces.Spaces +} + +// AccessLoggingMiddleware instruments an implementation of the spaces.Spaces with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next spaces.Spaces) spaces.Spaces { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) { + begin := time.Now() + + m.logger.Debug("AbortTransfer.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceID", spaceID), + ) + + err = m.next.AbortTransfer(ctx, spaceID) + + m.logger.Debug("AbortTransfer.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("space", space), + ) + + created, err = m.next.Create(ctx, space) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("created", created), + zap.Error(err), + ) + + return created, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, spaceId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + err = m.next.Delete(ctx, spaceId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string) (space *spaces.Space, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + ) + + space, err = m.next.Get(ctx, spaceId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("space", space), + zap.Error(err), + ) + + return space, err +} + +func (m *accessLoggingMiddleware) List(ctx context.Context, orgId string) (spaces []*spaces.Space, err error) { + begin := time.Now() + + m.logger.Debug("List.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgId", orgId), + ) + + spaces, err = m.next.List(ctx, orgId) + + m.logger.Debug("List.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("spaces", spaces), + zap.Error(err), + ) + + return spaces, err +} + +func (m *accessLoggingMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) { + begin := time.Now() + + m.logger.Debug("ListTransfers.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("orgID", orgID), + ) + + spaces, err = m.next.ListTransfers(ctx, orgID) + + m.logger.Debug("ListTransfers.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("spaces", spaces), + zap.Error(err), + ) + + return spaces, err +} + +func (m *accessLoggingMiddleware) Move(ctx context.Context, spaceID string, orgID string) (err error) { + begin := time.Now() + + m.logger.Debug("Move.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceID", spaceID), + zap.Reflect("orgID", orgID), + ) + + err = m.next.Move(ctx, spaceID, orgID) + + m.logger.Debug("Move.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) { + begin := time.Now() + + m.logger.Debug("Transfer.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceID", spaceID), + zap.Reflect("transferToOrg", transferToOrg), + ) + + err = m.next.Transfer(ctx, spaceID, transferToOrg) + + m.logger.Debug("Transfer.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("space", space), + ) + + err = m.next.Update(ctx, space) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) UpdateConfig(ctx context.Context, spaceId string, config *spaces.Config) (err error) { + begin := time.Now() + + m.logger.Debug("UpdateConfig.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceId", spaceId), + zap.Reflect("config", config), + ) + + err = m.next.UpdateConfig(ctx, spaceId, config) + + m.logger.Debug("UpdateConfig.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/spaces/middleware/error_logging_middleware.go b/pkg/spaces/middleware/error_logging_middleware.go index b82cc16f7b7652dcec33bb262346d727c719d390..2b11838b51f1a033e9963a729c6378401e193d0c 100644 --- a/pkg/spaces/middleware/error_logging_middleware.go +++ b/pkg/spaces/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/spaces/middleware/logging_middleware.go b/pkg/spaces/middleware/logging_middleware.go deleted file mode 100644 index 499ed2d23d12737be2af49ec02835956d4b6eb83..0000000000000000000000000000000000000000 --- a/pkg/spaces/middleware/logging_middleware.go +++ /dev/null @@ -1,401 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -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/spaces" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements spaces.Spaces that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next spaces.Spaces -} - -// LoggingMiddleware instruments an implementation of the spaces.Spaces with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next spaces.Spaces) spaces.Spaces { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID} { - 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("AbortTransfer.Request", fields...) - - err = m.next.AbortTransfer(ctx, spaceID) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("AbortTransfer.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "space": space} { - 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("Create.Request", fields...) - - created, err = m.next.Create(ctx, space) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "created": created, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return created, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, spaceId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Get(ctx context.Context, spaceId string) (space *spaces.Space, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId} { - 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...) - - space, err = m.next.Get(ctx, spaceId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "space": space, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return space, err -} - -func (m *loggingMiddleware) List(ctx context.Context, orgId string) (spaces []*spaces.Space, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgId": orgId} { - 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("List.Request", fields...) - - spaces, err = m.next.List(ctx, orgId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "spaces": spaces, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("List.Response", fields...) - - return spaces, err -} - -func (m *loggingMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "orgID": orgID} { - 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("ListTransfers.Request", fields...) - - spaces, err = m.next.ListTransfers(ctx, orgID) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "spaces": spaces, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("ListTransfers.Response", fields...) - - return spaces, err -} - -func (m *loggingMiddleware) Move(ctx context.Context, spaceID string, orgID string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID, - "orgID": orgID} { - 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("Move.Request", fields...) - - err = m.next.Move(ctx, spaceID, orgID) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Move.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID, - "transferToOrg": transferToOrg} { - 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("Transfer.Request", fields...) - - err = m.next.Transfer(ctx, spaceID, transferToOrg) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Transfer.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "space": space} { - 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("Update.Request", fields...) - - err = m.next.Update(ctx, space) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - - return err -} - -func (m *loggingMiddleware) UpdateConfig(ctx context.Context, spaceId string, config *spaces.Config) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "config": config} { - 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("UpdateConfig.Request", fields...) - - err = m.next.UpdateConfig(ctx, spaceId, config) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("UpdateConfig.Response", fields...) - - return err -} diff --git a/pkg/spaces/middleware/middleware.go b/pkg/spaces/middleware/middleware.go index 7379b4ae182293f7750504663e59005551e3a63d..73c3b8c3538e6bf9a6457617afc35f68f429aaf3 100644 --- a/pkg/spaces/middleware/middleware.go +++ b/pkg/spaces/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/spaces" @@ -17,12 +17,12 @@ func WithLog(s spaces.Spaces, logger *zap.Logger, log_access bool) spaces.Spaces if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Spaces") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/spaces/middleware/recovering_middleware.go b/pkg/spaces/middleware/recovering_middleware.go index ad13a929c8c1ebd9a6132043a00617352af7e6d8..7b9b64ed276aa9a91dd9e07ee1b463ff8bb06003 100644 --- a/pkg/spaces/middleware/recovering_middleware.go +++ b/pkg/spaces/middleware/recovering_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/recovery // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/recovery -o recovering_middleware.go -l "" import ( diff --git a/pkg/users/middleware/access_logging_middleware.go b/pkg/users/middleware/access_logging_middleware.go new file mode 100644 index 0000000000000000000000000000000000000000..dd8d4a14c73915d553381b239770fcf05c02aca5 --- /dev/null +++ b/pkg/users/middleware/access_logging_middleware.go @@ -0,0 +1,147 @@ +// Code generated by gowrap. DO NOT EDIT. +// template: ../../../assets/templates/middleware/access_log.tmpl +// gowrap: http://github.com/hexdigest/gowrap + +package middleware + +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/access_log.tmpl -o access_logging_middleware.go -l "" + +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/options" + "git.perx.ru/perxis/perxis-go/pkg/users" + "go.uber.org/zap" +) + +// accessLoggingMiddleware implements users.Users that is instrumented with logging +type accessLoggingMiddleware struct { + logger *zap.Logger + next users.Users +} + +// AccessLoggingMiddleware instruments an implementation of the users.Users with simple logging +func AccessLoggingMiddleware(logger *zap.Logger) Middleware { + return func(next users.Users) users.Users { + return &accessLoggingMiddleware{ + next: next, + logger: logger, + } + } +} + +func (m *accessLoggingMiddleware) Create(ctx context.Context, create *users.User) (user *users.User, err error) { + begin := time.Now() + + m.logger.Debug("Create.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("create", create), + ) + + user, err = m.next.Create(ctx, create) + + m.logger.Debug("Create.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("user", user), + zap.Error(err), + ) + + return user, err +} + +func (m *accessLoggingMiddleware) Delete(ctx context.Context, userId string) (err error) { + begin := time.Now() + + m.logger.Debug("Delete.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("userId", userId), + ) + + err = m.next.Delete(ctx, userId) + + m.logger.Debug("Delete.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} + +func (m *accessLoggingMiddleware) Find(ctx context.Context, filter *users.Filter, options *options.FindOptions) (users []*users.User, total int, err error) { + begin := time.Now() + + m.logger.Debug("Find.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("filter", filter), + zap.Reflect("options", options), + ) + + users, total, err = m.next.Find(ctx, filter, options) + + m.logger.Debug("Find.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("users", users), + zap.Reflect("total", total), + zap.Error(err), + ) + + return users, total, err +} + +func (m *accessLoggingMiddleware) Get(ctx context.Context, userId string) (user *users.User, err error) { + begin := time.Now() + + m.logger.Debug("Get.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("userId", userId), + ) + + user, err = m.next.Get(ctx, userId) + + m.logger.Debug("Get.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("user", user), + zap.Error(err), + ) + + return user, err +} + +func (m *accessLoggingMiddleware) GetByIdentity(ctx context.Context, identity string) (user *users.User, err error) { + begin := time.Now() + + m.logger.Debug("GetByIdentity.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("identity", identity), + ) + + user, err = m.next.GetByIdentity(ctx, identity) + + m.logger.Debug("GetByIdentity.Response", + zap.Duration("time", time.Since(begin)), + zap.Reflect("user", user), + zap.Error(err), + ) + + return user, err +} + +func (m *accessLoggingMiddleware) Update(ctx context.Context, update *users.User) (err error) { + begin := time.Now() + + m.logger.Debug("Update.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("update", update), + ) + + err = m.next.Update(ctx, update) + + m.logger.Debug("Update.Response", + zap.Duration("time", time.Since(begin)), + zap.Error(err), + ) + + return err +} diff --git a/pkg/users/middleware/error_logging_middleware.go b/pkg/users/middleware/error_logging_middleware.go index 688083dac93de779db6cdabd02002836901a0883..c499b9f3bf60726a10d30ced82e24bced6702236 100644 --- a/pkg/users/middleware/error_logging_middleware.go +++ b/pkg/users/middleware/error_logging_middleware.go @@ -1,9 +1,9 @@ -package middleware - // Code generated by gowrap. DO NOT EDIT. // template: ../../../assets/templates/middleware/error_log // gowrap: http://github.com/hexdigest/gowrap +package middleware + //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l "" import ( diff --git a/pkg/users/middleware/logging_middleware.go b/pkg/users/middleware/logging_middleware.go deleted file mode 100644 index 0b9438ed939131c97679c5a3364a1e715be63b75..0000000000000000000000000000000000000000 --- a/pkg/users/middleware/logging_middleware.go +++ /dev/null @@ -1,257 +0,0 @@ -package middleware - -// Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/access_log -// gowrap: http://github.com/hexdigest/gowrap - -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -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/options" - "git.perx.ru/perxis/perxis-go/pkg/users" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -// loggingMiddleware implements users.Users that is instrumented with logging -type loggingMiddleware struct { - logger *zap.Logger - next users.Users -} - -// LoggingMiddleware instruments an implementation of the users.Users with simple logging -func LoggingMiddleware(logger *zap.Logger) Middleware { - return func(next users.Users) users.Users { - return &loggingMiddleware{ - next: next, - logger: logger, - } - } -} - -func (m *loggingMiddleware) Create(ctx context.Context, create *users.User) (user *users.User, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "create": create} { - 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("Create.Request", fields...) - - user, err = m.next.Create(ctx, create) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "user": user, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Create.Response", fields...) - - return user, err -} - -func (m *loggingMiddleware) Delete(ctx context.Context, userId string) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "userId": userId} { - 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("Delete.Request", fields...) - - err = m.next.Delete(ctx, userId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Delete.Response", fields...) - - return err -} - -func (m *loggingMiddleware) Find(ctx context.Context, filter *users.Filter, options *options.FindOptions) (users []*users.User, total int, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "filter": filter, - "options": options} { - 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("Find.Request", fields...) - - users, total, err = m.next.Find(ctx, filter, options) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "users": users, - "total": total, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Find.Response", fields...) - - return users, total, err -} - -func (m *loggingMiddleware) Get(ctx context.Context, userId string) (user *users.User, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "userId": userId} { - 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...) - - user, err = m.next.Get(ctx, userId) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "user": user, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Get.Response", fields...) - - return user, err -} - -func (m *loggingMiddleware) GetByIdentity(ctx context.Context, identity string) (user *users.User, err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "identity": identity} { - 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("GetByIdentity.Request", fields...) - - user, err = m.next.GetByIdentity(ctx, identity) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "user": user, - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("GetByIdentity.Response", fields...) - - return user, err -} - -func (m *loggingMiddleware) Update(ctx context.Context, update *users.User) (err error) { - begin := time.Now() - var fields []zapcore.Field - for k, v := range map[string]interface{}{ - "ctx": ctx, - "update": update} { - 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("Update.Request", fields...) - - err = m.next.Update(ctx, update) - - fields = []zapcore.Field{ - zap.Duration("time", time.Since(begin)), - } - - for k, v := range map[string]interface{}{ - "err": err} { - if k == "err" { - err, _ := v.(error) - fields = append(fields, zap.Error(err)) - continue - } - fields = append(fields, zap.Reflect(k, v)) - } - - m.logger.Debug("Update.Response", fields...) - - return err -} diff --git a/pkg/users/middleware/middleware.go b/pkg/users/middleware/middleware.go index 63bc862271dc6d7002ea2db479aa359885ad5ebd..d94190827de3028c96000df15bf06c719e30cf92 100644 --- a/pkg/users/middleware/middleware.go +++ b/pkg/users/middleware/middleware.go @@ -1,10 +1,10 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/middleware +// template: ../../../assets/templates/middleware/middleware.tmpl // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/middleware -o middleware.go -l "" +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l "" import ( "git.perx.ru/perxis/perxis-go/pkg/users" @@ -17,12 +17,12 @@ func WithLog(s users.Users, logger *zap.Logger, log_access bool) users.Users { if logger == nil { logger = zap.NewNop() } - logger = logger.Named("Users") - s = ErrorLoggingMiddleware(logger)(s) if log_access { - s = LoggingMiddleware(logger)(s) + s = AccessLoggingMiddleware(logger)(s) } + s = ErrorLoggingMiddleware(logger)(s) + s = RecoveringMiddleware(logger)(s) return s } diff --git a/pkg/users/transport/grpc/protobuf_type_converters.microgen.go b/pkg/users/transport/grpc/protobuf_type_converters.microgen.go index 3a73ddd7680439be98f1e8ca6ec0f4dbb70b076a..5f98e2486e50a16049db5ee136cc4d2c943264d7 100644 --- a/pkg/users/transport/grpc/protobuf_type_converters.microgen.go +++ b/pkg/users/transport/grpc/protobuf_type_converters.microgen.go @@ -127,27 +127,9 @@ func ProtoToListPtrUser(protoCreates []*pb.User) ([]*service.User, error) { } func PtrServicesFindOptionsToProto(opts *options.FindOptions) (*common.FindOptions, error) { - if opts == nil { - return nil, nil - } - return &common.FindOptions{ - Sort: opts.Sort, - PageNum: int32(opts.PageNum), - PageSize: int32(opts.PageSize), - }, nil + return options.FindOptionsToPB(opts), nil } func ProtoToPtrServicesFindOptions(protoOpts *common.FindOptions) (*options.FindOptions, error) { - if protoOpts == nil { - return nil, nil - } - return &options.FindOptions{ - SortOptions: options.SortOptions{ - Sort: protoOpts.Sort, - }, - PaginationOptions: options.PaginationOptions{ - PageNum: int(protoOpts.PageNum), - PageSize: int(protoOpts.PageSize), - }, - }, nil + return options.FindOptionsFromPB(protoOpts), nil } diff --git a/proto/common/common.pb.go b/proto/common/common.pb.go index 31926abe8e19b189bc87a67684e2476a43898811..ea585fe3435096d877fa4bbc3649fe96a4b0649f 100644 --- a/proto/common/common.pb.go +++ b/proto/common/common.pb.go @@ -194,10 +194,12 @@ type FindOptions struct { unknownFields protoimpl.UnknownFields Sort []string `protobuf:"bytes,1,rep,name=sort,proto3" json:"sort,omitempty"` - PageNum int32 `protobuf:"varint,2,opt,name=page_num,json=pageNum,proto3" json:"page_num,omitempty"` - PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + PageNum int32 `protobuf:"varint,2,opt,name=page_num,json=pageNum,proto3" json:"page_num,omitempty"` // Deprecated + PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // Deprecated Fields []string `protobuf:"bytes,4,rep,name=fields,proto3" json:"fields,omitempty"` ExcludeFields bool `protobuf:"varint,5,opt,name=exclude_fields,json=excludeFields,proto3" json:"exclude_fields,omitempty"` + Offset int32 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"` + Limit int32 `protobuf:"varint,7,opt,name=limit,proto3" json:"limit,omitempty"` } func (x *FindOptions) Reset() { @@ -267,6 +269,20 @@ func (x *FindOptions) GetExcludeFields() bool { return false } +func (x *FindOptions) GetOffset() int32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *FindOptions) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + type Rule struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -541,7 +557,7 @@ var file_common_common_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x0b, 0x46, 0x69, + 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc6, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, @@ -551,59 +567,62 @@ var file_common_common_proto_rawDesc = []byte{ 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x73, 0x22, 0x90, 0x03, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x06, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x68, 0x69, 0x64, - 0x64, 0x65, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x61, - 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x6f, 0x6e, 0x6c, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1f, 0x0a, - 0x0b, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x21, - 0x0a, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x65, 0x6e, - 0x79, 0x52, 0x65, 0x61, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x64, - 0x65, 0x6e, 0x79, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, - 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x57, 0x72, 0x69, 0x74, - 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x57, 0x0a, 0x0c, 0x43, 0x6f, 0x6c, 0x6c, 0x61, - 0x62, 0x6f, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, - 0x22, 0xab, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, - 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2a, 0x25, - 0x0a, 0x06, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, - 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, - 0x4f, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x43, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, - 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, - 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, - 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, - 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, - 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6c, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x22, 0x90, 0x03, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x6f, + 0x6e, 0x6c, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0e, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x29, 0x0a, 0x10, 0x77, 0x72, 0x69, 0x74, 0x65, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x6f, 0x6e, 0x6c, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x65, 0x61, 0x64, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x72, 0x65, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x77, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x28, 0x0a, 0x10, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x65, 0x6e, 0x79, 0x52, + 0x65, 0x61, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x6e, + 0x79, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0b, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x57, 0x0a, 0x0c, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x62, 0x6f, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, + 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0xab, + 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2a, 0x25, 0x0a, 0x06, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x00, 0x12, + 0x08, 0x0a, 0x04, 0x4d, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x4f, 0x4c, + 0x45, 0x10, 0x02, 0x2a, 0x43, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x52, + 0x45, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, 0x44, 0x10, 0x02, + 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, + 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x2e, + 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, + 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/logs/log.pb.go b/proto/logs/log.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..8beabf96d64b409bc99ebf0b6e6ecb64b1ae4aa6 --- /dev/null +++ b/proto/logs/log.pb.go @@ -0,0 +1,371 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: logs/log.proto + +package logs + +import ( + _ "git.perx.ru/perxis/perxis-go/proto/common" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// LogLevel задает уровень журналирования. +type LogLevel int32 + +const ( + // INFO - обозначает сообщения СЃ нормальным, операционным уровнем журналирования. + LogLevel_INFO LogLevel = 0 + // WARNING - обозначает сообщения, которые содержат потенциально вредные ситуации. + LogLevel_WARNING LogLevel = 1 + // ERROR - обозначает РґСЂСѓРіРёРµ ошибки РІ работе. + LogLevel_ERROR LogLevel = 2 + // CRITICAL - обозначает серьезные ошибки, РёР·-Р·Р° которых программа может РЅРµ выполнять некоторые функции. + LogLevel_CRITICAL LogLevel = 3 + // FATAL - обозначает очень серьезные ошибки, которые РјРѕРіСѓС‚ привести Рє остановке приложения. + LogLevel_FATAL LogLevel = 4 +) + +// Enum value maps for LogLevel. +var ( + LogLevel_name = map[int32]string{ + 0: "INFO", + 1: "WARNING", + 2: "ERROR", + 3: "CRITICAL", + 4: "FATAL", + } + LogLevel_value = map[string]int32{ + "INFO": 0, + "WARNING": 1, + "ERROR": 2, + "CRITICAL": 3, + "FATAL": 4, + } +) + +func (x LogLevel) Enum() *LogLevel { + p := new(LogLevel) + *p = x + return p +} + +func (x LogLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (LogLevel) Descriptor() protoreflect.EnumDescriptor { + return file_logs_log_proto_enumTypes[0].Descriptor() +} + +func (LogLevel) Type() protoreflect.EnumType { + return &file_logs_log_proto_enumTypes[0] +} + +func (x LogLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use LogLevel.Descriptor instead. +func (LogLevel) EnumDescriptor() ([]byte, []int) { + return file_logs_log_proto_rawDescGZIP(), []int{0} +} + +// LogEntry представляет СЃРѕР±РѕР№ структуру данных для хранения информации Рѕ журнале. +type LogEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // id является уникальным идентификатором каждой записи РІ журнале. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // timestamp указывает РЅР° временную метку, указывающую РєРѕРіРґР° было создано данное сообщение. + Timestamp *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Level LogLevel `protobuf:"varint,3,opt,name=level,proto3,enum=logs.LogLevel" json:"level,omitempty"` // message это РѕСЃРЅРѕРІРЅРѕРµ сообщение, которое требуется записать РІ лог. + Message string `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` + // category указывает РЅР° категорию события. + // Примеры: + // - + Category string `protobuf:"bytes,5,opt,name=category,proto3" json:"category,omitempty"` + Component string `protobuf:"bytes,6,opt,name=component,proto3" json:"component,omitempty"` + // action описывает действие, которое было произведено. Рто поле может принимать разные значения РІ зависимости РѕС‚ сервиса. + // Примеры: + // - item.create + // - item.update + // - organization.create + // - action.run + // - reference.create + Event string `protobuf:"bytes,7,opt,name=event,proto3" json:"event,omitempty"` + // object это идентификатор объекта связанного СЃ событием + // Рдентификатор объекта должен быть РІ формате GlobalID: + // <контекст>/<тип объекта>/<идентификатор объекта> + // РіРґРµ: + // - <контекст> - представляет СЃРѕР±РѕР№ иднетификатор родительского объекта, если таковой имеется + // - <тип объекта> - представляет СЃРѕР±РѕР№ тип объекта, например: + // spaces, envs, cols, items, revs, fields, clients, roles, orgs, users + // - <идентификатор объекта> - представляет СЃРѕР±РѕР№ идентификатор объекта + // + // Примеры: + // /spaces/<space_id> - пространство + // /spaces/<space_id>/envs/<env_id> - окружение + // /spaces/<space_id>/envs/<env_id>/cols/<collection_id> - коллекция + // /spaces/<space_id>/cols/<collection_id> - коллекция РІ окружении "master" + // /spaces/<space_id>/envs/<env_id>/schema/<collection_id> - схема коллекции + // /spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id> - элемент коллекции + // /spaces/<space_id>/cols/<collection_id>/items/<item_id> - элемент коллекции РІ окружении "master" + // /spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/fields/<field_name> - поле элемента коллекции + // /spaces/<space_id>/envs/<env_id>/cols/<collection_id>/items/<item_id>/revs/<rev_id> - ревизия элемента коллекции + // /spaces/<space_id>/clients/<client_id> - клиент + // /spaces/<space_id>/roles/<role_id> - роль + // /orgs/<org_id> - организация + // /users/<user_id> - пользователь + // /services/<service_id> - сервис + ObjectId string `protobuf:"bytes,8,opt,name=object_id,json=objectId,proto3" json:"object_id,omitempty"` + // caller содержит идентификатор сущности вызвавшей событиe, аналогично полю object + // + // Примеры: + // /users/<user_id> - пользователь + // /spaces/<space_id>/clients/<client_id> - клиент + // /services/<service_id> - сервис + CallerId string `protobuf:"bytes,9,opt,name=caller_id,json=callerId,proto3" json:"caller_id,omitempty"` + // attr содержит дополнительные связанные СЃ событием атрибуты РІ формате Any + // позволяет добавить дополнительные данные РІ событие + Attr *anypb.Any `protobuf:"bytes,10,opt,name=attr,proto3" json:"attr,omitempty"` + // tags содержит теги связанные СЃ событием, РЅР° усмотрение сервиса + Tags []string `protobuf:"bytes,11,rep,name=tags,proto3" json:"tags,omitempty"` +} + +func (x *LogEntry) Reset() { + *x = LogEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogEntry) ProtoMessage() {} + +func (x *LogEntry) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogEntry.ProtoReflect.Descriptor instead. +func (*LogEntry) Descriptor() ([]byte, []int) { + return file_logs_log_proto_rawDescGZIP(), []int{0} +} + +func (x *LogEntry) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *LogEntry) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *LogEntry) GetLevel() LogLevel { + if x != nil { + return x.Level + } + return LogLevel_INFO +} + +func (x *LogEntry) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *LogEntry) GetCategory() string { + if x != nil { + return x.Category + } + return "" +} + +func (x *LogEntry) GetComponent() string { + if x != nil { + return x.Component + } + return "" +} + +func (x *LogEntry) GetEvent() string { + if x != nil { + return x.Event + } + return "" +} + +func (x *LogEntry) GetObjectId() string { + if x != nil { + return x.ObjectId + } + return "" +} + +func (x *LogEntry) GetCallerId() string { + if x != nil { + return x.CallerId + } + return "" +} + +func (x *LogEntry) GetAttr() *anypb.Any { + if x != nil { + return x.Attr + } + return nil +} + +func (x *LogEntry) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +var File_logs_log_proto protoreflect.FileDescriptor + +var file_logs_log_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdc, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, + 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x6c, + 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, + 0x76, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, + 0x09, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x61, 0x74, 0x74, 0x72, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x61, 0x74, 0x74, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x61, 0x67, 0x73, 0x2a, 0x45, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x57, + 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, + 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x04, 0x42, 0x2e, 0x5a, 0x2c, + 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, + 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x3b, 0x6c, 0x6f, 0x67, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_logs_log_proto_rawDescOnce sync.Once + file_logs_log_proto_rawDescData = file_logs_log_proto_rawDesc +) + +func file_logs_log_proto_rawDescGZIP() []byte { + file_logs_log_proto_rawDescOnce.Do(func() { + file_logs_log_proto_rawDescData = protoimpl.X.CompressGZIP(file_logs_log_proto_rawDescData) + }) + return file_logs_log_proto_rawDescData +} + +var file_logs_log_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_logs_log_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_logs_log_proto_goTypes = []interface{}{ + (LogLevel)(0), // 0: logs.LogLevel + (*LogEntry)(nil), // 1: logs.LogEntry + (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp + (*anypb.Any)(nil), // 3: google.protobuf.Any +} +var file_logs_log_proto_depIdxs = []int32{ + 2, // 0: logs.LogEntry.timestamp:type_name -> google.protobuf.Timestamp + 0, // 1: logs.LogEntry.level:type_name -> logs.LogLevel + 3, // 2: logs.LogEntry.attr:type_name -> google.protobuf.Any + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_logs_log_proto_init() } +func file_logs_log_proto_init() { + if File_logs_log_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_logs_log_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_logs_log_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_logs_log_proto_goTypes, + DependencyIndexes: file_logs_log_proto_depIdxs, + EnumInfos: file_logs_log_proto_enumTypes, + MessageInfos: file_logs_log_proto_msgTypes, + }.Build() + File_logs_log_proto = out.File + file_logs_log_proto_rawDesc = nil + file_logs_log_proto_goTypes = nil + file_logs_log_proto_depIdxs = nil +} diff --git a/proto/logs/log_service.pb.go b/proto/logs/log_service.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..7036778591e3e51156c67eccffb05976fea10d38 --- /dev/null +++ b/proto/logs/log_service.pb.go @@ -0,0 +1,735 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.25.1 +// source: logs/log_service.proto + +package logs + +import ( + common "git.perx.ru/perxis/perxis-go/proto/common" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Запрос для лога +type LogRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Запись лога + Entries []*LogEntry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` +} + +func (x *LogRequest) Reset() { + *x = LogRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogRequest) ProtoMessage() {} + +func (x *LogRequest) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogRequest.ProtoReflect.Descriptor instead. +func (*LogRequest) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{0} +} + +func (x *LogRequest) GetEntries() []*LogEntry { + if x != nil { + return x.Entries + } + return nil +} + +// Ответ сервера РЅР° запрос лога +type LogResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Содержит информацию РѕР± ошибке, если таковая имеется + Error *common.Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *LogResponse) Reset() { + *x = LogResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogResponse) ProtoMessage() {} + +func (x *LogResponse) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogResponse.ProtoReflect.Descriptor instead. +func (*LogResponse) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{1} +} + +func (x *LogResponse) GetError() *common.Error { + if x != nil { + return x.Error + } + return nil +} + +type Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Запрос РЅР° РїРѕРёСЃРє логов + // Примеры: + // 1. `timestamp > '2019-01-01' AND timestamp < '2019-01-02'` + // 2. `timestamp > '2019-01-01' AND timestamp < '2019-01-02' AND level = 'error'` + // 3. `component = 'api' AND object_id = '123' AND object_type = 'item' AND space = 'spc1'` + // 4. `id in ['1', '2', '3']` + Q []string `protobuf:"bytes,3,rep,name=q,proto3" json:"q,omitempty"` // РЎРїРёСЃРѕРє выражений для фильтрации +} + +func (x *Filter) Reset() { + *x = Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Filter) ProtoMessage() {} + +func (x *Filter) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Filter.ProtoReflect.Descriptor instead. +func (*Filter) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{2} +} + +func (x *Filter) GetQ() []string { + if x != nil { + return x.Q + } + return nil +} + +// Запрос РЅР° РїРѕРёСЃРє логов +type FindRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Фильтры для РїРѕРёСЃРєР° + Filter *Filter `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + // Опции РїРѕРёСЃРєР° + Options *common.FindOptions `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *FindRequest) Reset() { + *x = FindRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindRequest) ProtoMessage() {} + +func (x *FindRequest) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindRequest.ProtoReflect.Descriptor instead. +func (*FindRequest) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{3} +} + +func (x *FindRequest) GetFilter() *Filter { + if x != nil { + return x.Filter + } + return nil +} + +func (x *FindRequest) GetOptions() *common.FindOptions { + if x != nil { + return x.Options + } + return nil +} + +// Результат РїРѕРёСЃРєР° +type FindResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Найденные записи лога + Entries []*LogEntry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + // Рспользовавшийся для РїРѕРёСЃРєР° фильтр + // Для + Filter *Filter `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + // Рспользовавшиеся для РїРѕРёСЃРєР° опции + Options *common.FindOptions `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` + // Общее количество найденных записей + Total uint32 `protobuf:"varint,4,opt,name=total,proto3" json:"total,omitempty"` +} + +func (x *FindResult) Reset() { + *x = FindResult{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindResult) ProtoMessage() {} + +func (x *FindResult) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindResult.ProtoReflect.Descriptor instead. +func (*FindResult) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{4} +} + +func (x *FindResult) GetEntries() []*LogEntry { + if x != nil { + return x.Entries + } + return nil +} + +func (x *FindResult) GetFilter() *Filter { + if x != nil { + return x.Filter + } + return nil +} + +func (x *FindResult) GetOptions() *common.FindOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *FindResult) GetTotal() uint32 { + if x != nil { + return x.Total + } + return 0 +} + +// Ответ сервера РЅР° запрос РїРѕРёСЃРєР° +type FindResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Response: + // + // *FindResponse_Result + // *FindResponse_Error + Response isFindResponse_Response `protobuf_oneof:"response"` +} + +func (x *FindResponse) Reset() { + *x = FindResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindResponse) ProtoMessage() {} + +func (x *FindResponse) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindResponse.ProtoReflect.Descriptor instead. +func (*FindResponse) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{5} +} + +func (m *FindResponse) GetResponse() isFindResponse_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *FindResponse) GetResult() *FindResult { + if x, ok := x.GetResponse().(*FindResponse_Result); ok { + return x.Result + } + return nil +} + +func (x *FindResponse) GetError() *common.Error { + if x, ok := x.GetResponse().(*FindResponse_Error); ok { + return x.Error + } + return nil +} + +type isFindResponse_Response interface { + isFindResponse_Response() +} + +type FindResponse_Result struct { + // Результаты РїРѕРёСЃРєР° + Result *FindResult `protobuf:"bytes,1,opt,name=result,proto3,oneof"` +} + +type FindResponse_Error struct { + // Рнформация РѕР± ошибке, если таковая имеется + Error *common.Error `protobuf:"bytes,2,opt,name=error,proto3,oneof"` +} + +func (*FindResponse_Result) isFindResponse_Response() {} + +func (*FindResponse_Error) isFindResponse_Response() {} + +// Запрос РЅР° удаление логов +type DeleteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Фильтры для удаления + Filter *Filter `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *DeleteRequest) Reset() { + *x = DeleteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRequest) ProtoMessage() {} + +func (x *DeleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead. +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{6} +} + +func (x *DeleteRequest) GetFilter() *Filter { + if x != nil { + return x.Filter + } + return nil +} + +// Ответ сервера РЅР° запрос удаления +type DeleteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Рнформация РѕР± ошибке, если таковая имеется + Error *common.Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *DeleteResponse) Reset() { + *x = DeleteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_logs_log_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteResponse) ProtoMessage() {} + +func (x *DeleteResponse) ProtoReflect() protoreflect.Message { + mi := &file_logs_log_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead. +func (*DeleteResponse) Descriptor() ([]byte, []int) { + return file_logs_log_service_proto_rawDescGZIP(), []int{7} +} + +func (x *DeleteResponse) GetError() *common.Error { + if x != nil { + return x.Error + } + return nil +} + +var File_logs_log_service_proto protoreflect.FileDescriptor + +var file_logs_log_service_proto_rawDesc = []byte{ + 0x0a, 0x16, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x6c, 0x6f, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x1a, 0x13, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0e, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x6c, 0x6f, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, + 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x22, 0x32, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x23, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x22, 0x16, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x0c, + 0x0a, 0x01, 0x71, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x01, 0x71, 0x22, 0x62, 0x0a, 0x0b, + 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, + 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6e, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0xa1, 0x01, 0x0a, 0x0a, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, + 0x28, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x67, 0x73, + 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x6d, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x0e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x10, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, + 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x6c, 0x6f, 0x67, + 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x2f, 0x0a, 0x04, 0x46, 0x69, 0x6e, 0x64, 0x12, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6f, 0x67, + 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x35, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x6c, 0x6f, 0x67, + 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x70, + 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, + 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x6f, + 0x67, 0x73, 0x3b, 0x6c, 0x6f, 0x67, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_logs_log_service_proto_rawDescOnce sync.Once + file_logs_log_service_proto_rawDescData = file_logs_log_service_proto_rawDesc +) + +func file_logs_log_service_proto_rawDescGZIP() []byte { + file_logs_log_service_proto_rawDescOnce.Do(func() { + file_logs_log_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_logs_log_service_proto_rawDescData) + }) + return file_logs_log_service_proto_rawDescData +} + +var file_logs_log_service_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_logs_log_service_proto_goTypes = []interface{}{ + (*LogRequest)(nil), // 0: logs.LogRequest + (*LogResponse)(nil), // 1: logs.LogResponse + (*Filter)(nil), // 2: logs.Filter + (*FindRequest)(nil), // 3: logs.FindRequest + (*FindResult)(nil), // 4: logs.FindResult + (*FindResponse)(nil), // 5: logs.FindResponse + (*DeleteRequest)(nil), // 6: logs.DeleteRequest + (*DeleteResponse)(nil), // 7: logs.DeleteResponse + (*LogEntry)(nil), // 8: logs.LogEntry + (*common.Error)(nil), // 9: common.Error + (*common.FindOptions)(nil), // 10: common.FindOptions +} +var file_logs_log_service_proto_depIdxs = []int32{ + 8, // 0: logs.LogRequest.entries:type_name -> logs.LogEntry + 9, // 1: logs.LogResponse.error:type_name -> common.Error + 2, // 2: logs.FindRequest.filter:type_name -> logs.Filter + 10, // 3: logs.FindRequest.options:type_name -> common.FindOptions + 8, // 4: logs.FindResult.entries:type_name -> logs.LogEntry + 2, // 5: logs.FindResult.filter:type_name -> logs.Filter + 10, // 6: logs.FindResult.options:type_name -> common.FindOptions + 4, // 7: logs.FindResponse.result:type_name -> logs.FindResult + 9, // 8: logs.FindResponse.error:type_name -> common.Error + 2, // 9: logs.DeleteRequest.filter:type_name -> logs.Filter + 9, // 10: logs.DeleteResponse.error:type_name -> common.Error + 0, // 11: logs.LogsService.Log:input_type -> logs.LogRequest + 3, // 12: logs.LogsService.Find:input_type -> logs.FindRequest + 6, // 13: logs.LogsService.Delete:input_type -> logs.DeleteRequest + 1, // 14: logs.LogsService.Log:output_type -> logs.LogResponse + 5, // 15: logs.LogsService.Find:output_type -> logs.FindResponse + 7, // 16: logs.LogsService.Delete:output_type -> logs.DeleteResponse + 14, // [14:17] is the sub-list for method output_type + 11, // [11:14] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name +} + +func init() { file_logs_log_service_proto_init() } +func file_logs_log_service_proto_init() { + if File_logs_log_service_proto != nil { + return + } + file_logs_log_proto_init() + if !protoimpl.UnsafeEnabled { + file_logs_log_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Filter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_logs_log_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_logs_log_service_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*FindResponse_Result)(nil), + (*FindResponse_Error)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_logs_log_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_logs_log_service_proto_goTypes, + DependencyIndexes: file_logs_log_service_proto_depIdxs, + MessageInfos: file_logs_log_service_proto_msgTypes, + }.Build() + File_logs_log_service_proto = out.File + file_logs_log_service_proto_rawDesc = nil + file_logs_log_service_proto_goTypes = nil + file_logs_log_service_proto_depIdxs = nil +} diff --git a/proto/logs/log_service_grpc.pb.go b/proto/logs/log_service_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..ad55cee20f51d0135ab737a566f405696fe693fa --- /dev/null +++ b/proto/logs/log_service_grpc.pb.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v4.25.1 +// source: logs/log_service.proto + +package logs + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + LogsService_Log_FullMethodName = "/logs.LogsService/Log" + LogsService_Find_FullMethodName = "/logs.LogsService/Find" + LogsService_Delete_FullMethodName = "/logs.LogsService/Delete" +) + +// LogsServiceClient is the client API for LogsService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type LogsServiceClient interface { + // Метод для записи логов + Log(ctx context.Context, in *LogRequest, opts ...grpc.CallOption) (*LogResponse, error) + // Метод для РїРѕРёСЃРєР° логов РїРѕ заданным параметрам + Find(ctx context.Context, in *FindRequest, opts ...grpc.CallOption) (*FindResponse, error) + // Метод для удаления логов РїРѕ заданным параметрам + Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) +} + +type logsServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewLogsServiceClient(cc grpc.ClientConnInterface) LogsServiceClient { + return &logsServiceClient{cc} +} + +func (c *logsServiceClient) Log(ctx context.Context, in *LogRequest, opts ...grpc.CallOption) (*LogResponse, error) { + out := new(LogResponse) + err := c.cc.Invoke(ctx, LogsService_Log_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *logsServiceClient) Find(ctx context.Context, in *FindRequest, opts ...grpc.CallOption) (*FindResponse, error) { + out := new(FindResponse) + err := c.cc.Invoke(ctx, LogsService_Find_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *logsServiceClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) { + out := new(DeleteResponse) + err := c.cc.Invoke(ctx, LogsService_Delete_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// LogsServiceServer is the server API for LogsService service. +// All implementations must embed UnimplementedLogsServiceServer +// for forward compatibility +type LogsServiceServer interface { + // Метод для записи логов + Log(context.Context, *LogRequest) (*LogResponse, error) + // Метод для РїРѕРёСЃРєР° логов РїРѕ заданным параметрам + Find(context.Context, *FindRequest) (*FindResponse, error) + // Метод для удаления логов РїРѕ заданным параметрам + Delete(context.Context, *DeleteRequest) (*DeleteResponse, error) + mustEmbedUnimplementedLogsServiceServer() +} + +// UnimplementedLogsServiceServer must be embedded to have forward compatible implementations. +type UnimplementedLogsServiceServer struct { +} + +func (UnimplementedLogsServiceServer) Log(context.Context, *LogRequest) (*LogResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Log not implemented") +} +func (UnimplementedLogsServiceServer) Find(context.Context, *FindRequest) (*FindResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Find not implemented") +} +func (UnimplementedLogsServiceServer) Delete(context.Context, *DeleteRequest) (*DeleteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (UnimplementedLogsServiceServer) mustEmbedUnimplementedLogsServiceServer() {} + +// UnsafeLogsServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to LogsServiceServer will +// result in compilation errors. +type UnsafeLogsServiceServer interface { + mustEmbedUnimplementedLogsServiceServer() +} + +func RegisterLogsServiceServer(s grpc.ServiceRegistrar, srv LogsServiceServer) { + s.RegisterService(&LogsService_ServiceDesc, srv) +} + +func _LogsService_Log_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LogRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogsServiceServer).Log(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: LogsService_Log_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogsServiceServer).Log(ctx, req.(*LogRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _LogsService_Find_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogsServiceServer).Find(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: LogsService_Find_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogsServiceServer).Find(ctx, req.(*FindRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _LogsService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LogsServiceServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: LogsService_Delete_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LogsServiceServer).Delete(ctx, req.(*DeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// LogsService_ServiceDesc is the grpc.ServiceDesc for LogsService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var LogsService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "logs.LogsService", + HandlerType: (*LogsServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Log", + Handler: _LogsService_Log_Handler, + }, + { + MethodName: "Find", + Handler: _LogsService_Find_Handler, + }, + { + MethodName: "Delete", + Handler: _LogsService_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "logs/log_service.proto", +} diff --git a/zap/channels.go b/zap/channels.go new file mode 100644 index 0000000000000000000000000000000000000000..5753163514b1a91605e54e41adfdac711a2518b4 --- /dev/null +++ b/zap/channels.go @@ -0,0 +1,51 @@ +package zap + +import ( + "git.perx.ru/perxis/perxis-go/pkg/data" + "go.uber.org/zap/zapcore" +) + +const ( + channelKey = "channel" + + Syslog = "syslog" + Userlog = "userlog" + // ChannelsAll = "*" +) + +func ContainsChannels(channels ...string) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + for _, f := range fields { + if f.Key == channelKey && f.Type == zapcore.SkipType { + for _, v := range f.Interface.(stringArray) { + if data.Contains(v, channels) { + return true + } + } + } + } + return false + } +} + +// WithDefaultChannel аналогичен WithChannel, РЅРѕ также устанавливает переданный канал РІ качестве канала РїРѕ умолчанию. +// Рто означает, что если поле Channels РІ записи РЅРµ указано, запись РІСЃРµ равно будет передана РІ zapcore.Core. +func WithDefaultChannel(core zapcore.Core, channel string) zapcore.Core { + return WithChannel(core, channel, true) +} + +// WithChannel добавляет Рє переданному zapcore.Core фильтрацию записей РїРѕ каналам. +// Рто означает, что если запись содержит поле Channels Рё значение соответствует +// переданному каналу, то запись будет передана РІ zapcore.Core. +func WithChannel(core zapcore.Core, channel string, isDefault ...bool) zapcore.Core { + filterFn := ContainsChannels(channel) + if len(isDefault) > 0 && isDefault[0] { + filterFn = Or(filterFn, Not(ContainsKey(channelKey))) + } + return WithFilters(core, filterFn) +} + +func WithChannels(core zapcore.Core, channels ...string) zapcore.Core { + filterFn := ContainsChannels(channels...) + return WithFilters(core, filterFn) +} diff --git a/zap/channels_test.go b/zap/channels_test.go new file mode 100644 index 0000000000000000000000000000000000000000..ac4c5c9a33797413a7744e439a9d31f38191540e --- /dev/null +++ b/zap/channels_test.go @@ -0,0 +1,58 @@ +package zap + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" +) + +func TestWithChannel_WriteSingleChannel(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + core = WithChannel(core, "test") + + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("test")})) + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("empty")})) // запись РЅРµ попадет РІ лог + + require.Equal(t, 1, logs.Len()) +} + +func TestWithChannel_WriteMultiplyChannels(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + + core = zapcore.NewTee( + WithChannel(core, "test1"), + WithChannel(core, "test2"), + ) + + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("test1", "test2")})) // запись попадет сразу РІ 2 core + + require.Equal(t, 2, logs.Len()) +} + +func TestWithDefaultChannels(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + + core = zapcore.NewTee( + WithChannel(core, "test1", true), + WithChannel(core, "test2"), + ) + + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("test1")})) + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("test3")})) // эта запись РЅРµ попадет РІ лог + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{})) + + require.Equal(t, 2, logs.Len()) +} + +func TestWithChannels(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + + core = WithChannels(core, "test1", "test2") + + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("test1")})) + require.NoError(t, core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{Channels("test2")})) + + require.Equal(t, 2, logs.Len()) +} diff --git a/zap/field.go b/zap/field.go new file mode 100644 index 0000000000000000000000000000000000000000..308c21d6e83a4a80c35ab9866cb757e65c4b7a24 --- /dev/null +++ b/zap/field.go @@ -0,0 +1,68 @@ +package zap + +import ( + "context" + + "git.perx.ru/perxis/perxis-go/id" + _ "git.perx.ru/perxis/perxis-go/id/system" // регистрируем обработчики для системных объектов + "git.perx.ru/perxis/perxis-go/pkg/auth" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type stringArray []string + +func (ss stringArray) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for i := range ss { + arr.AppendString(ss[i]) + } + return nil +} + +// Channels возвращает поле, содержащее СЃРїРёСЃРѕРє каналов, РІ которые должна быть передана запись. +func Channels(channels ...string) zap.Field { + return zap.Field{ + Key: channelKey, + Type: zapcore.SkipType, // используем тип zapcore.SkipType, чтобы РїСЂРё кодировании поле игнорировалось + Interface: stringArray(channels), + } +} + +func Category(category string) zap.Field { + return zap.String("category", category) +} + +func Component(component string) zap.Field { + return zap.String("component", component) +} + +func Event(event string) zap.Field { + return zap.String("event", event) +} + +// Object возвращает поле Рё устанавливает передаваемый аргумент РІ качестве идентификатора объекта РІ формате ObjectId. +// Поддерживает типы РІ формате ObjectId: id.Descriptor, string, map[string]any, системные объекты. +func Object(v any) zap.Field { + oid, _ := id.NewObjectId(v) + return zap.Reflect("object", oid) +} + +// Caller возвращает поле Рё устанавливает передаваемый аргумент РІ качестве "вызывающего" РІ формате ObjectId. +// Поддерживает типы РІ формате ObjectId: id.Descriptor, string, map[string]any, системные объекты. +func Caller(v any) zap.Field { + oid, _ := id.NewObjectId(v) + return zap.Reflect("caller", oid) +} + +// CallerFromContext извлекает auth.Principal РёР· контекста Рё устанавливает его РІ качестве "вызывающего" РІ формате Object. +func CallerFromContext(ctx context.Context) zap.Field { + return Caller(auth.GetPrincipal(ctx)) +} + +func Attr(attr any) zap.Field { + return zap.Any("attr", attr) +} + +func Tags(tags ...string) zap.Field { + return zap.Strings("tags", tags) +} diff --git a/zap/field_test.go b/zap/field_test.go new file mode 100644 index 0000000000000000000000000000000000000000..84efa584f85a66468e160334510e39ddee0246b0 --- /dev/null +++ b/zap/field_test.go @@ -0,0 +1,220 @@ +package zap + +import ( + "context" + "testing" + + "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" + "git.perx.ru/perxis/perxis-go/pkg/items" + "git.perx.ru/perxis/perxis-go/pkg/users" + "github.com/stretchr/testify/assert" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func TestChannels(t *testing.T) { + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: Channels("master"), want: zap.Field{Key: channelKey, Type: zapcore.SkipType, Interface: stringArray{"master"}}}, + {name: "invalid", field: Channels(), want: zap.Field{Key: channelKey, Type: zapcore.SkipType, Interface: stringArray(nil)}}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.want, tc.field) + }) + } +} + +func TestChannelsEncode(t *testing.T) { + enc := zapcore.NewMapObjectEncoder() + field := Channels("master") + field.AddTo(enc) + + assert.Empty(t, enc.Fields) +} + +func TestCategory(t *testing.T) { + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: Category("update"), want: zap.String("category", "update")}, + {name: "invalid", field: Category(""), want: zap.String("category", "")}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.True(t, tc.want.Equals(tc.field)) + }) + } +} + +func TestComponent(t *testing.T) { + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: Component("Items"), want: zap.String("component", "Items")}, + {name: "invalid", field: Component(""), want: zap.String("component", "")}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.True(t, tc.want.Equals(tc.field)) + }) + } +} + +func TestEvent(t *testing.T) { + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: Event("items.create"), want: zap.String("event", "items.create")}, + {name: "invalid", field: Event(""), want: zap.String("event", "")}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.True(t, tc.want.Equals(tc.field)) + }) + } +} + +func TestObject(t *testing.T) { + item := &items.Item{ + ID: "c4ca4238a0b923820dcc509a6f75849b", + SpaceID: "c81e728d9d4c2f636f067f89cc14862c", + EnvID: "eccbc87e4b5ce2fe28308fd9f2a7baf3", + CollectionID: "a87ff679a2f3e71d9181a67b7542122c", + } + + oid := id.MustObjectId(item) + itemId := id.NewItemId(item.SpaceID, item.EnvID, item.CollectionID, item.ID) + + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "system object", field: Object(item), want: zap.Reflect("object", oid)}, + {name: "object id", field: Object(itemId), want: zap.Reflect("object", oid)}, + {name: "string", field: Object(oid.String()), want: zap.Reflect("object", oid)}, + {name: "invalid", field: Object(nil), want: zap.Reflect("object", (*id.ObjectId)(nil))}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + wantObjectId, ok1 := tc.want.Interface.(*id.ObjectId) + fieldObjectId, ok2 := tc.field.Interface.(*id.ObjectId) + + if ok1 && ok2 && wantObjectId != nil && fieldObjectId != nil { + assert.Equal(t, wantObjectId.String(), fieldObjectId.String()) + } else { + assert.Equal(t, tc.want.Interface, tc.field.Interface) + } + }) + } +} + +func TestCaller(t *testing.T) { + user := &users.User{ + ID: "c4ca4238a0b923820dcc509a6f75849b", + } + + oid := id.MustObjectId(user) + userId := id.NewUserId(user.ID) + + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "system object", field: Caller(user), want: zap.Reflect("caller", oid)}, + {name: "object id", field: Caller(userId), want: zap.Reflect("caller", oid)}, + {name: "string", field: Caller(oid.String()), want: zap.Reflect("caller", oid)}, + {name: "invalid", field: Caller(nil), want: zap.Reflect("caller", (*id.ObjectId)(nil))}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + wantObjectId, ok1 := tc.want.Interface.(*id.ObjectId) + fieldObjectId, ok2 := tc.field.Interface.(*id.ObjectId) + + if ok1 && ok2 && wantObjectId != nil && fieldObjectId != nil { + assert.Equal(t, wantObjectId.String(), fieldObjectId.String()) + } else { + assert.Equal(t, tc.want.Interface, tc.field.Interface) + } + }) + } +} + +func TestCallerFromContext(t *testing.T) { + ctx := auth.WithSystem(context.Background()) + oid := id.MustObjectId(auth.GetPrincipal(ctx)) + + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: CallerFromContext(ctx), want: zap.Reflect("caller", oid)}, + {name: "invalid", field: CallerFromContext(context.TODO()), want: zap.Reflect("caller", (*id.ObjectId)(nil))}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + wantObjectId, ok1 := tc.want.Interface.(*id.ObjectId) + fieldObjectId, ok2 := tc.field.Interface.(*id.ObjectId) + + if ok1 && ok2 && wantObjectId != nil && fieldObjectId != nil { + assert.Equal(t, wantObjectId.String(), fieldObjectId.String()) + } else { + assert.Equal(t, tc.want.Interface, tc.field.Interface) + } + }) + } +} + +func TestAttr(t *testing.T) { + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: Attr(map[string]string{"a": "b"}), want: zap.Reflect("attr", map[string]string{"a": "b"})}, + {name: "invalid", field: Attr(nil), want: zap.Reflect("attr", nil)}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.True(t, tc.want.Equals(tc.field)) + }) + } +} + +func TestTags(t *testing.T) { + tests := []struct { + name string + field zap.Field + want zap.Field + }{ + {name: "ok", field: Tags("a", "b", "c"), want: zap.Strings("tags", []string{"a", "b", "c"})}, + {name: "invalid", field: Tags(nil...), want: zap.Strings("tags", nil)}, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + assert.True(t, tc.want.Equals(tc.field)) + }) + } +} diff --git a/zap/filter_core.go b/zap/filter_core.go new file mode 100644 index 0000000000000000000000000000000000000000..7e99d942e439afc8a05faaf55be29b8cb604b7fc --- /dev/null +++ b/zap/filter_core.go @@ -0,0 +1,106 @@ +package zap + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type FilterFunc func(entry zapcore.Entry, fields []zapcore.Field) bool + +func ContainsField(field zapcore.Field) FilterFunc { + return func(_ zapcore.Entry, fields []zapcore.Field) bool { + for _, f := range fields { + if f.Equals(field) { + return true + } + } + return false + } +} + +func ContainsKey(key string) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + for _, f := range fields { + if f.Key == key { + return true + } + } + return false + } +} + +func Or(filters ...FilterFunc) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + for _, f := range filters { + if f(entry, fields) { + return true + } + } + return false + } +} + +func Not(filter FilterFunc) FilterFunc { + return func(entry zapcore.Entry, fields []zapcore.Field) bool { + return !filter(entry, fields) + } +} + +type filterCore struct { + zapcore.Core + + filters []FilterFunc + + // fields хранит контекст записей СЏРґСЂР°, передаваемых РїСЂРё вызове With. + // Р’ методе Write передаются только поля конкретной записи, РЅРѕ РјС‹ также хотим учитывать поля контекста СЏРґСЂР°. + fields []zap.Field +} + +// WithFilters - добавить фильтры, которые Р±СѓРґСѓС‚ применяться РїСЂРё записи лога (вызове `core.Write`) +// Метод `core.Write` будет вызван только РІ случае, РєРѕРіРґР° результат всех фильтров `true` +// +// Обратить внимание, фильтр РЅРµ применяется Рє полям, которые были добавлены РІ `core` через вызов `core.With` +// РґРѕ вызова WithFilters. Пример: +// +// l, _ := zap.NewDevelopment() +// core := l.Core().With([]zapcore.Field{zap.Int("a", 5)}) +// core = WithFilters(core, ContainsField(zap.Int("a", 5))) +// +// logger := zap.New(core) +// logger.Info("Test log") // РќР• будет записан +// logger.Info("Test log", zap.Int("a", 5)) // будет записан +func WithFilters(core zapcore.Core, filters ...FilterFunc) zapcore.Core { + return &filterCore{ + Core: core, + filters: filters, + } +} + +func (core *filterCore) With(fields []zapcore.Field) zapcore.Core { + return &filterCore{ + Core: core.Core.With(fields), + filters: core.filters, + fields: append(core.fields, fields...), + } +} + +func (core *filterCore) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry { + if core.Core.Enabled(entry.Level) { + return checkedEntry.AddCore(entry, core) + } + return checkedEntry +} + +func (core *filterCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { + if len(core.fields) > 0 { + fields = append(core.fields, fields...) + } + + for _, filter := range core.filters { + if !filter(entry, fields) { + return nil + } + } + + return core.Core.Write(entry, fields) +} diff --git a/zap/filter_core_test.go b/zap/filter_core_test.go new file mode 100644 index 0000000000000000000000000000000000000000..21c906f24f5b7458c7628985871f1480564a3164 --- /dev/null +++ b/zap/filter_core_test.go @@ -0,0 +1,48 @@ +package zap + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" +) + +func TestFilterCore_Write(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + core = WithFilters(core, ContainsField(zap.Bool("check", true))) + + err := core.With([]zapcore.Field{zap.Bool("check", true)}).Write(zapcore.Entry{Message: "msg"}, nil) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{zap.Bool("check", true)}) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, nil) + require.NoError(t, err) + + require.Equal(t, 2, logs.Len()) +} + +func TestNotContainsField(t *testing.T) { + core, logs := observer.New(zapcore.InfoLevel) + core = WithFilters(core, Not(ContainsField(zap.Int("b", 2)))) + + err := core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 1), + zap.Int("b", 2), + }) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{ + zap.Int("a", 1), + zap.Int("b", 3), + }) + require.NoError(t, err) + + err = core.Write(zapcore.Entry{Message: "msg"}, []zapcore.Field{}) + require.NoError(t, err) + + require.Equal(t, 2, logs.Len()) +}