diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 83f34df990ff1e4a1a128755bcfe548b02aa41ec..e4f5e9be9098cd25885506576ca5ddcc317041d6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: golang:1.22 +image: golang:1.23.2 stages: - test @@ -18,7 +18,7 @@ run_tests: junit: report.xml lint: - image: golangci/golangci-lint:v1.56-alpine + image: golangci/golangci-lint:v1.61-alpine rules: - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' stage: test diff --git a/assets/templates/middleware/telemetry_content b/assets/templates/middleware/telemetry_content new file mode 100644 index 0000000000000000000000000000000000000000..7adcd36c4aef3ea9f3077fcd0771d50c34d406fb --- /dev/null +++ b/assets/templates/middleware/telemetry_content @@ -0,0 +1,121 @@ +import ( + "context" + "time" + + "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + oid "git.perx.ru/perxis/perxis-go/id" + otelmetric "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" +) + +type spaceGetter interface { + GetSpaceID() string +} + +{{ $decorator := (or .Vars.DecoratorName "telemetryMiddleware") }} +{{ $funcName := (or .Vars.FuncName ("TelemetryMiddleware")) }} + +// {{$decorator}} implements {{.Interface.Type}} interface instrumented with opentracing spans +type {{$decorator}} struct { + {{.Interface.Type}} + _instance string + requestMetrics *metrics.RequestMetrics + _spanDecorator func(span trace.Span, params, results map[string]interface{}) +} + +// {{$funcName}} returns {{$decorator}} +func {{$funcName}} (base {{.Interface.Type}}, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) {{$decorator}} { + requestMetrics, err := metrics.GetRequestMetrics() + if err != nil { + panic(err) + } + + d := {{$decorator}} { + {{.Interface.Name}}: base, + _instance: instance, + requestMetrics: requestMetrics, + } + + if len(spanDecorator) > 0 && spanDecorator[0] != nil { + d._spanDecorator = spanDecorator[0] + } + + return d +} +{{range $method := .Interface.Methods}} + {{if $method.AcceptsContext}} + +// {{$method.Name}} implements {{$.Interface.Type}} +func (_d {{$decorator}}) {{$method.Declaration}} { + var att = []attribute.KeyValue{ + attribute.String("service", "{{ $.Interface.Name }}"), + attribute.String("method", "{{ $method.Name }}"), + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) + + start := time.Now() + ctx, _span := otel.Tracer(_d._instance).Start(ctx, "{{$.Interface.Name}}.{{$method.Name}}") + defer _span.End() + + {{ $method.ResultsNames }} = {{ (printf "_d.%s." $.Interface.Name) }}{{ $method.Call }} + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + {{- $spaceID := "" -}} + {{- range $param := $method.Params -}} + {{- if (eq $param.Name "spaceId") -}} + {{- $spaceID = "spaceId" -}} + {{- end -}} + {{- end -}} + {{- if (eq $spaceID "") -}} + {{- $params := list -}} + {{- $params = append $params $method.ParamsNames -}} + {{- $params = append $params $method.ResultsNames -}} + + {{- $length := len $params }} + params := []interface{}{ + {{- range $index, $paramName := $params | toStrings }} + {{- $paramName }}{{- if (ne $index $length) }},{{- end -}} + {{- end -}} + } + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + {{- else }} + spID = spaceId + {{- end }} + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, {{$method.ParamsMap}}, {{$method.ResultsMap}}) + }{{- if $method.ReturnsError}} 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())) + } + {{end}} + return {{$method.ResultsNames }} +} + {{end}} +{{end}} \ No newline at end of file diff --git a/assets/templates/middleware/telemetry b/assets/templates/middleware/telemetry_default similarity index 67% rename from assets/templates/middleware/telemetry rename to assets/templates/middleware/telemetry_default index f35cde213c9523050d863351757fb0ee560c73fe..6616504f1f5db9bd0126eba40dd5b7f8f4d718a0 100644 --- a/assets/templates/middleware/telemetry +++ b/assets/templates/middleware/telemetry_default @@ -1,5 +1,3 @@ -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry - import ( "context" "time" @@ -7,10 +5,15 @@ import ( "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + oid "git.perx.ru/perxis/perxis-go/id" otelmetric "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + {{ $decorator := (or .Vars.DecoratorName "telemetryMiddleware") }} {{ $funcName := (or .Vars.FuncName ("TelemetryMiddleware")) }} @@ -41,25 +44,33 @@ func {{$funcName}} (base {{.Interface.Type}}, instance string, spanDecorator ... return d } - {{range $method := .Interface.Methods}} {{if $method.AcceptsContext}} - // {{$method.Name}} implements {{$.Interface.Type}} -func (_d {{$decorator}}) {{$method.Declaration}} { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( - attribute.String("service", "{{ $.Interface.Name }}"), - attribute.String("method", "{{ $method.Name }}"), - )) - _d.requestMetrics.Total.Add(ctx, 1, attributes) +// {{$method.Name}} implements {{$.Interface.Type}} +func (_d {{$decorator}}) {{$method.Declaration}} { + var att = []attribute.KeyValue{ + attribute.String("service", "{{ $.Interface.Name }}"), + attribute.String("method", "{{ $method.Name }}"), + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "{{$.Interface.Name}}.{{$method.Name}}") + defer _span.End() + + {{ $method.ResultsNames }} = {{ (printf "_d.%s." $.Interface.Name) }}{{ $method.Call }} + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - if _d._spanDecorator != nil { + if _d._spanDecorator != nil { _d._spanDecorator(_span, {{$method.ParamsMap}}, {{$method.ResultsMap}}) }{{- if $method.ReturnsError}} else if err != nil { _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) @@ -69,9 +80,7 @@ func (_d {{$decorator}}) {{$method.Declaration}} { _span.SetAttributes(attribute.String("message", err.Error())) } {{end}} - _span.End() - }() - {{$method.Pass (printf "_d.%s." $.Interface.Name) }} + return {{$method.ResultsNames }} } {{end}} {{end}} \ No newline at end of file diff --git a/go.mod b/go.mod index 372a5f1f61d2f523d327d630e73fa21f0aad2eac..1f94424c686dc81bb80569395734cae6eeddfb2b 100644 --- a/go.mod +++ b/go.mod @@ -1,31 +1,31 @@ module git.perx.ru/perxis/perxis-go -go 1.22 +go 1.23.2 require ( - github.com/avast/retry-go/v4 v4.5.1 - github.com/bep/gowebp v0.2.0 - github.com/expr-lang/expr v1.15.8 + github.com/avast/retry-go/v4 v4.6.0 + github.com/bep/gowebp v0.4.0 + github.com/expr-lang/expr v1.16.9 github.com/go-kit/kit v0.13.0 - github.com/gosimple/slug v1.13.1 + github.com/gosimple/slug v1.14.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/json-iterator/go v1.1.12 github.com/mitchellh/mapstructure v1.5.0 - github.com/nats-io/nats.go v1.31.0 + github.com/nats-io/nats.go v1.37.0 github.com/pkg/errors v0.9.1 - github.com/rs/xid v1.5.0 - github.com/stretchr/testify v1.8.4 - go.mongodb.org/mongo-driver v1.13.0 - go.opentelemetry.io/otel v1.24.0 - go.opentelemetry.io/otel/trace v1.24.0 - go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.23.0 - golang.org/x/image v0.14.0 - golang.org/x/net v0.25.0 - golang.org/x/oauth2 v0.18.0 - google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 + github.com/rs/xid v1.6.0 + github.com/stretchr/testify v1.9.0 + go.mongodb.org/mongo-driver v1.17.1 + go.opentelemetry.io/otel v1.30.0 + go.opentelemetry.io/otel/trace v1.30.0 + go.uber.org/zap v1.27.0 + golang.org/x/crypto v0.27.0 + golang.org/x/image v0.20.0 + golang.org/x/net v0.29.0 + golang.org/x/oauth2 v0.23.0 + google.golang.org/grpc v1.67.1 + google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 ) @@ -35,36 +35,33 @@ require ( ) require ( - cloud.google.com/go/compute v1.25.1 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - github.com/brianvoe/gofakeit/v6 v6.26.3 + cloud.google.com/go/compute/metadata v0.5.2 // indirect + github.com/brianvoe/gofakeit/v6 v6.28.0 github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/gosimple/unidecode v1.0.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.10 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/montanaflynn/stats v0.7.1 // indirect - github.com/nats-io/nkeys v0.4.6 // indirect + github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.5.1 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect - go.opentelemetry.io/otel/metric v1.24.0 + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.opentelemetry.io/otel/metric v1.30.0 go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.15.0 - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index 7f00103fa5b26228e50be943d05c23325cbdc38c..4b2f278b81ef6999417ee78fb77df8203b8073db 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,17 @@ -cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= -cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= -github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= -github.com/bep/gowebp v0.2.0 h1:ZVfK8i9PpZqKHEmthQSt3qCnnHycbLzBPEsVtk2ch2Q= -github.com/bep/gowebp v0.2.0/go.mod h1:ZhFodwdiFp8ehGJpF4LdPl6unxZm9lLFjxD3z2h2AgI= -github.com/brianvoe/gofakeit/v6 v6.26.3 h1:3ljYrjPwsUNAUFdUIr2jVg5EhKdcke/ZLop7uVg1Er8= -github.com/brianvoe/gofakeit/v6 v6.26.3/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= +cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= +cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= +github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/bep/gowebp v0.4.0 h1:QihuVnvIKbRoeBNQkN0JPMM8ClLmD6V2jMftTFwSK3Q= +github.com/bep/gowebp v0.4.0/go.mod h1:95gtYkAA8iIn1t3HkAPurRCVGV/6NhgaHJ1urz0iIwc= +github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4= +github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/expr-lang/expr v1.15.8 h1:FL8+d3rSSP4tmK9o+vKfSMqqpGL8n15pEPiHcnBpxoI= -github.com/expr-lang/expr v1.15.8/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= +github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI= +github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= @@ -21,24 +19,17 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gosimple/slug v1.13.1 h1:bQ+kpX9Qa6tHRaK+fZR0A0M2Kd7Pa5eHPPsb1JpHD+Q= -github.com/gosimple/slug v1.13.1/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= +github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= +github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -50,9 +41,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -67,13 +57,12 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/nats-io/nats.go v1.31.0 h1:/WFBHEc/dOKBF6qf1TZhrdEfTmOZ5JzdJ+Y3m6Y/p7E= -github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8= -github.com/nats-io/nkeys v0.4.6 h1:IzVe95ru2CT6ta874rt9saQRkWfe2nFj1NtvYSLqMzY= -github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts= +github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE= +github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= +github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= +github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -84,103 +73,82 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= -github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= -github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY= -go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM= +go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= -golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw= +golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/id/object_id.go b/id/object_id.go index e84ea1c0fff9960bfef7584fbd68699509cfa2a6..3a3ff12641fd9dfee4ac458a3677fad3a4f0a501 100644 --- a/id/object_id.go +++ b/id/object_id.go @@ -1,11 +1,12 @@ package id import ( + "strings" + 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 = '/' diff --git a/images/middleware/telemetry_middleware.go b/images/middleware/telemetry_middleware.go index 72d38c2e1d91813383116398e5c41b9bb93004f4..36d09a320a2bd7fa92ceaa341fad44c89989942b 100644 --- a/images/middleware/telemetry_middleware.go +++ b/images/middleware/telemetry_middleware.go @@ -1,18 +1,18 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\assets\templates\middleware\telemetry +// template: ../../assets/templates/middleware/telemetry_default // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/images -i Images -t ../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" "git.perx.ru/perxis/perxis-go/images" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/files" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements images.Images interface instrumented with opentracing spans type telemetryMiddleware struct { images.Images @@ -51,35 +55,41 @@ func TelemetryMiddleware(base images.Images, instance string, spanDecorator ...f // Get implements images.Images func (_d telemetryMiddleware) Get(ctx context.Context, source *files.File, opts *images.GetOptions) (result *files.File, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Images"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Images.Get") + defer _span.End() + + result, err = _d.Images.Get(ctx, source, opts) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "source": source, + "opts": opts}, map[string]interface{}{ + "result": result, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "source": source, - "opts": opts}, map[string]interface{}{ - "result": result, - "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.Images.Get(ctx, source, opts) + return result, err } diff --git a/logs/middleware/telemetry_middleware.go b/logs/middleware/telemetry_middleware.go index 2aebc795b22d770c369f0445bfa543bde6828ac2..3731386368aeb9cdd4678a1e3bd65d892798c610 100644 --- a/logs/middleware/telemetry_middleware.go +++ b/logs/middleware/telemetry_middleware.go @@ -1,18 +1,18 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../assets/templates/middleware/telemetry +// template: ../../assets/templates/middleware/telemetry_default // 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 +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/logs -i Service -t ../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" "git.perx.ru/perxis/perxis-go/logs" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/options" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements logs.Service interface instrumented with opentracing spans type telemetryMiddleware struct { logs.Service @@ -51,101 +55,119 @@ func TelemetryMiddleware(base logs.Service, instance string, spanDecorator ...fu // Delete implements logs.Service func (_d telemetryMiddleware) Delete(ctx context.Context, filter *logs.Filter) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Service"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Service.Delete") + defer _span.End() + + err = _d.Service.Delete(ctx, filter) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + 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())) + } - 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) + return err } // 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( + var att = []attribute.KeyValue{ attribute.String("service", "Service"), attribute.String("method", "Find"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Service.Find") + defer _span.End() + + fp1, err = _d.Service.Find(ctx, filter, options) - 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) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + 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())) + } + + return fp1, err } // Log implements logs.Service func (_d telemetryMiddleware) Log(ctx context.Context, entries []*logs.Entry) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Service"), attribute.String("method", "Log"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Service.Log") + defer _span.End() + + err = _d.Service.Log(ctx, entries) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + 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())) + } - 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) + return err } diff --git a/pkg/clients/client.go b/pkg/clients/client.go index 6c4c6735b8ec91f226ba5306b2649252390ffc67..447c523aaf5ae8692421e85567973f407007561a 100644 --- a/pkg/clients/client.go +++ b/pkg/clients/client.go @@ -50,6 +50,10 @@ func (c Client) GetID() string { return c.ID } +func (c Client) GetSpaceID() string { + return c.SpaceID +} + func (c *Client) SetDisabled(b bool) *Client { c.Disabled = &b return c diff --git a/pkg/clients/middleware/telemetry_middleware.go b/pkg/clients/middleware/telemetry_middleware.go index 22c604f2d5be413681ccdb933eb5c33a61517cc6..cbb217153db160631a1e71ebf9d48d68cd787ebc 100644 --- a/pkg/clients/middleware/telemetry_middleware.go +++ b/pkg/clients/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/clients -i Clients -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "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/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements clients.Clients interface instrumented with opentracing spans type telemetryMiddleware struct { clients.Clients @@ -50,240 +54,339 @@ func TelemetryMiddleware(base clients.Clients, instance string, spanDecorator .. // Create implements clients.Clients func (_d telemetryMiddleware) Create(ctx context.Context, client *clients.Client) (created *clients.Client, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.Create") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "client": client}, map[string]interface{}{ - "created": created, - "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())) + created, err = _d.Clients.Create(ctx, client) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, client, created, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "client": client}, map[string]interface{}{ + "created": created, + "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.Clients.Create(ctx, client) + return created, err } // Delete implements clients.Clients func (_d telemetryMiddleware) Delete(ctx context.Context, spaceId string, id string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "id": id}, 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())) - } + err = _d.Clients.Delete(ctx, spaceId, id) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.End() - }() - return _d.Clients.Delete(ctx, spaceId, id) + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "id": id}, 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())) + } + + return err } // Enable implements clients.Clients func (_d telemetryMiddleware) Enable(ctx context.Context, spaceId string, id string, enable bool) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "Enable"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.Enable") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "id": id, - "enable": enable}, 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())) - } + err = _d.Clients.Enable(ctx, spaceId, id, enable) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Clients.Enable(ctx, spaceId, id, enable) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "id": id, + "enable": enable}, 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())) + } + + return err } // Get implements clients.Clients func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, id string) (client *clients.Client, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "id": id}, map[string]interface{}{ - "client": client, - "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())) - } + client, err = _d.Clients.Get(ctx, spaceId, id) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Clients.Get(ctx, spaceId, id) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "id": id}, map[string]interface{}{ + "client": client, + "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())) + } + + return client, err } // GetBy implements clients.Clients func (_d telemetryMiddleware) GetBy(ctx context.Context, spaceId string, params *clients.GetByParams) (client *clients.Client, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "GetBy"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.GetBy") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "params": params}, map[string]interface{}{ - "client": client, - "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())) - } + client, err = _d.Clients.GetBy(ctx, spaceId, params) - _span.End() - }() - return _d.Clients.GetBy(ctx, spaceId, params) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "params": params}, map[string]interface{}{ + "client": client, + "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())) + } + + return client, err } // List implements clients.Clients func (_d telemetryMiddleware) List(ctx context.Context, spaceId string) (clients []*clients.Client, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "List"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.List") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "clients": clients, - "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())) - } + clients, err = _d.Clients.List(ctx, spaceId) - _span.End() - }() - return _d.Clients.List(ctx, spaceId) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "clients": clients, + "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())) + } + + return clients, err } // Update implements clients.Clients func (_d telemetryMiddleware) Update(ctx context.Context, client *clients.Client) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Clients"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Clients.Update") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Clients.Update(ctx, client) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "client": client}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, client, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "client": client}, 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.Clients.Update(ctx, client) + return err } diff --git a/pkg/collaborators/collaborator.go b/pkg/collaborators/collaborator.go index 5fe1b481c231568af13b9c9e827eede723312576..b3406960b899f66ce498358d8a3199eb223e9de0 100644 --- a/pkg/collaborators/collaborator.go +++ b/pkg/collaborators/collaborator.go @@ -13,3 +13,7 @@ func (c Collaborator) Clone() *Collaborator { Role: c.Role, } } + +func (c *Collaborator) GetSpaceID() string { + return c.SpaceID +} diff --git a/pkg/collaborators/middleware/telemetry_middleware.go b/pkg/collaborators/middleware/telemetry_middleware.go index cd95016628ed34da1c6fdd5c951a14c766a8cabc..d4a6f56ccbc0d2b5334d596c8ca88932d677017b 100644 --- a/pkg/collaborators/middleware/telemetry_middleware.go +++ b/pkg/collaborators/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collaborators -i Collaborators -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/collaborators" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements collaborators.Collaborators interface instrumented with opentracing spans type telemetryMiddleware struct { collaborators.Collaborators @@ -50,172 +54,238 @@ func TelemetryMiddleware(base collaborators.Collaborators, instance string, span // Get implements collaborators.Collaborators func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, subject string) (role string, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collaborators"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collaborators.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "subject": subject}, map[string]interface{}{ - "role": role, - "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())) - } + role, err = _d.Collaborators.Get(ctx, spaceId, subject) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.End() - }() - return _d.Collaborators.Get(ctx, spaceId, subject) + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "subject": subject}, map[string]interface{}{ + "role": role, + "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())) + } + + return role, err } // ListCollaborators implements collaborators.Collaborators func (_d telemetryMiddleware) ListCollaborators(ctx context.Context, spaceId string) (collaborators []*collaborators.Collaborator, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collaborators"), attribute.String("method", "ListCollaborators"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collaborators.ListCollaborators") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "collaborators": collaborators, - "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())) - } + collaborators, err = _d.Collaborators.ListCollaborators(ctx, spaceId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "collaborators": collaborators, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Collaborators.ListCollaborators(ctx, spaceId) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return collaborators, err } // ListSpaces implements collaborators.Collaborators func (_d telemetryMiddleware) ListSpaces(ctx context.Context, subject string) (spaces []*collaborators.Collaborator, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collaborators"), attribute.String("method", "ListSpaces"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collaborators.ListSpaces") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "subject": subject}, map[string]interface{}{ - "spaces": spaces, - "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())) + spaces, err = _d.Collaborators.ListSpaces(ctx, subject) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, subject, spaces, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "subject": subject}, map[string]interface{}{ + "spaces": spaces, + "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.Collaborators.ListSpaces(ctx, subject) + return spaces, err } // Remove implements collaborators.Collaborators func (_d telemetryMiddleware) Remove(ctx context.Context, spaceId string, subject string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collaborators"), attribute.String("method", "Remove"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collaborators.Remove") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "subject": subject}, 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())) - } + err = _d.Collaborators.Remove(ctx, spaceId, subject) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Collaborators.Remove(ctx, spaceId, subject) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "subject": subject}, 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())) + } + + return err } // Set implements collaborators.Collaborators func (_d telemetryMiddleware) Set(ctx context.Context, spaceId string, subject string, role string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collaborators"), attribute.String("method", "Set"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collaborators.Set") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "subject": subject, - "role": role}, 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())) - } + err = _d.Collaborators.Set(ctx, spaceId, subject, role) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "subject": subject, + "role": role}, 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.Collaborators.Set(ctx, spaceId, subject, role) + return err } diff --git a/pkg/collections/collection.go b/pkg/collections/collection.go index b5d2418aac40332c99b08b31a5df128007e1b7a6..2baeffc6b3f87b90c281aebd5dae85c57d93a5cd 100644 --- a/pkg/collections/collection.go +++ b/pkg/collections/collection.go @@ -97,6 +97,10 @@ func (c Collection) GetID() string { return c.ID } +func (c Collection) GetSpaceID() string { + return c.SpaceID +} + // Equal Ñравнивает две коллекции, за иÑключением Schema, Access, StateInfo и Config func (c Collection) Equal(other *Collection) bool { if c.ID != other.ID || diff --git a/pkg/collections/middleware/telemetry_middleware.go b/pkg/collections/middleware/telemetry_middleware.go index 306570dba01ac1d7faaf193d92f97820369a6ad2..c189a7bebaf727b818aa3f37ecb828ff89de6391 100644 --- a/pkg/collections/middleware/telemetry_middleware.go +++ b/pkg/collections/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/collections -i Collections -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/collections" "git.perx.ru/perxis/perxis-go/pkg/schema" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements collections.Collections interface instrumented with opentracing spans type telemetryMiddleware struct { collections.Collections @@ -51,247 +55,346 @@ func TelemetryMiddleware(base collections.Collections, instance string, spanDeco // Create implements collections.Collections func (_d telemetryMiddleware) Create(ctx context.Context, collection *collections.Collection) (created *collections.Collection, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.Create") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "collection": collection}, map[string]interface{}{ - "created": created, - "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())) + created, err = _d.Collections.Create(ctx, collection) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, collection, created, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Collections.Create(ctx, collection) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "collection": collection}, map[string]interface{}{ + "created": created, + "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())) + } + + return created, err } // Delete implements collections.Collections func (_d telemetryMiddleware) Delete(ctx context.Context, spaceId string, envId string, collectionId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId}, 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())) - } + err = _d.Collections.Delete(ctx, spaceId, envId, collectionId) - _span.End() - }() - return _d.Collections.Delete(ctx, spaceId, envId, collectionId) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId}, 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())) + } + + return err } // Get implements collections.Collections func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, options ...*collections.GetOptions) (collection *collections.Collection, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "options": options}, map[string]interface{}{ - "collection": collection, - "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())) - } + collection, err = _d.Collections.Get(ctx, spaceId, envId, collectionId, options...) - _span.End() - }() - return _d.Collections.Get(ctx, spaceId, envId, collectionId, options...) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "options": options}, map[string]interface{}{ + "collection": collection, + "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())) + } + + return collection, err } // List implements collections.Collections func (_d telemetryMiddleware) List(ctx context.Context, spaceId string, envId string, filter *collections.Filter) (collections []*collections.Collection, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "List"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.List") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "filter": filter}, map[string]interface{}{ - "collections": collections, - "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())) - } + collections, err = _d.Collections.List(ctx, spaceId, envId, filter) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Collections.List(ctx, spaceId, envId, filter) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "filter": filter}, map[string]interface{}{ + "collections": collections, + "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())) + } + + return collections, err } // SetSchema implements collections.Collections func (_d telemetryMiddleware) SetSchema(ctx context.Context, spaceId string, envId string, collectionId string, schema *schema.Schema) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "SetSchema"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.SetSchema") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "schema": schema}, 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())) - } + err = _d.Collections.SetSchema(ctx, spaceId, envId, collectionId, schema) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Collections.SetSchema(ctx, spaceId, envId, collectionId, schema) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "schema": schema}, 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())) + } + + return err } // SetState implements collections.Collections func (_d telemetryMiddleware) SetState(ctx context.Context, spaceId string, envId string, collectionId string, state *collections.StateInfo) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "SetState"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.SetState") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "state": state}, 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())) - } + err = _d.Collections.SetState(ctx, spaceId, envId, collectionId, state) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Collections.SetState(ctx, spaceId, envId, collectionId, state) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "state": state}, 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())) + } + + return err } // Update implements collections.Collections func (_d telemetryMiddleware) Update(ctx context.Context, coll *collections.Collection) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Collections"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Collections.Update") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Collections.Update(ctx, coll) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "coll": coll}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, coll, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "coll": coll}, 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.Collections.Update(ctx, coll) + return err } diff --git a/pkg/delivery/middleware/telemetry_middleware.go b/pkg/delivery/middleware/telemetry_middleware.go index 05a017300c0b2d60c0cc03df333c62365babffa6..600b6a61caec8391507735e01d12d82ee822c8e3 100644 --- a/pkg/delivery/middleware/telemetry_middleware.go +++ b/pkg/delivery/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // gowrap: http://github.com/hexdigest/gowrap package middleware -//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/delivery -i Delivery -t ..\..\..\assets\templates\middleware\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/delivery -i Delivery -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/collections" "git.perx.ru/perxis/perxis-go/pkg/delivery" "git.perx.ru/perxis/perxis-go/pkg/environments" @@ -24,6 +24,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements delivery.Delivery interface instrumented with opentracing spans type telemetryMiddleware struct { delivery.Delivery @@ -54,289 +58,377 @@ func TelemetryMiddleware(base delivery.Delivery, instance string, spanDecorator // Aggregate implements delivery.Delivery func (_d telemetryMiddleware) Aggregate(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregatePublishedOptions) (result map[string]interface{}, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "Aggregate"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.Aggregate") + defer _span.End() + + result, err = _d.Delivery.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "result": result, - "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.Delivery.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "result": result, + "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())) + } + + return result, err } // FindItems implements delivery.Delivery func (_d telemetryMiddleware) FindItems(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindPublishedOptions) (items []*items.Item, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "FindItems"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.FindItems") + defer _span.End() + + items, total, err = _d.Delivery.FindItems(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "items": items, + "total": total, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "items": items, - "total": total, - "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.Delivery.FindItems(ctx, spaceId, envId, collectionId, filter, options...) + return items, total, err } // GetCollection implements delivery.Delivery func (_d telemetryMiddleware) GetCollection(ctx context.Context, spaceId string, envId string, collectionId string) (collection *collections.Collection, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "GetCollection"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.GetCollection") + defer _span.End() + + collection, err = _d.Delivery.GetCollection(ctx, spaceId, envId, collectionId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId}, map[string]interface{}{ + "collection": collection, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId}, map[string]interface{}{ - "collection": collection, - "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.Delivery.GetCollection(ctx, spaceId, envId, collectionId) + return collection, err } // GetEnvironment implements delivery.Delivery func (_d telemetryMiddleware) GetEnvironment(ctx context.Context, spaceId string, envId string) (env *environments.Environment, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "GetEnvironment"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.GetEnvironment") + defer _span.End() + + env, err = _d.Delivery.GetEnvironment(ctx, spaceId, envId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId}, map[string]interface{}{ - "env": env, - "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.Delivery.GetEnvironment(ctx, spaceId, envId) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId}, map[string]interface{}{ + "env": env, + "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())) + } + + return env, err } // GetItem implements delivery.Delivery func (_d telemetryMiddleware) GetItem(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetPublishedOptions) (item *items.Item, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "GetItem"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.GetItem") + defer _span.End() + + item, err = _d.Delivery.GetItem(ctx, spaceId, envId, collectionId, itemId, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "itemId": itemId, + "options": options}, map[string]interface{}{ + "item": item, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options}, map[string]interface{}{ - "item": item, - "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.Delivery.GetItem(ctx, spaceId, envId, collectionId, itemId, options...) + return item, err } // ListCollections implements delivery.Delivery func (_d telemetryMiddleware) ListCollections(ctx context.Context, spaceId string, envId string) (collections []*collections.Collection, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "ListCollections"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.ListCollections") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId}, map[string]interface{}{ - "collections": collections, - "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.Delivery.ListCollections(ctx, spaceId, envId) + collections, err = _d.Delivery.ListCollections(ctx, spaceId, envId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId}, map[string]interface{}{ + "collections": collections, + "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())) + } + + return collections, err } // ListEnvironments implements delivery.Delivery func (_d telemetryMiddleware) ListEnvironments(ctx context.Context, spaceId string) (envs []*environments.Environment, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "ListEnvironments"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.ListEnvironments") + defer _span.End() + + envs, err = _d.Delivery.ListEnvironments(ctx, spaceId) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "envs": envs, - "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.Delivery.ListEnvironments(ctx, spaceId) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "envs": envs, + "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())) + } + + return envs, err } // ListLocales implements delivery.Delivery func (_d telemetryMiddleware) ListLocales(ctx context.Context, spaceId string) (locales []*locales.Locale, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Delivery"), attribute.String("method", "ListLocales"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Delivery.ListLocales") + defer _span.End() + + locales, err = _d.Delivery.ListLocales(ctx, spaceId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "locales": locales, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "locales": locales, - "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.Delivery.ListLocales(ctx, spaceId) + return locales, err } diff --git a/pkg/environments/environment.go b/pkg/environments/environment.go index 3e0f7bb62a0be1d2fbef334322a6cb315060af8a..6ccfc2558e90e14c94925bdd29f56df71aac22b9 100644 --- a/pkg/environments/environment.go +++ b/pkg/environments/environment.go @@ -104,3 +104,7 @@ func (e Environment) Clone() *Environment { return clone } + +func (e Environment) GetSpaceID() string { + return e.SpaceID +} diff --git a/pkg/environments/middleware/telemetry_middleware.go b/pkg/environments/middleware/telemetry_middleware.go index 95b50dbc590f134386747a2fb4810455e7f2a800..f1fb94c767248ac3db42617e9f8c0475ddcece64 100644 --- a/pkg/environments/middleware/telemetry_middleware.go +++ b/pkg/environments/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/environments -i Environments -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/environments" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements environments.Environments interface instrumented with opentracing spans type telemetryMiddleware struct { environments.Environments @@ -50,275 +54,385 @@ func TelemetryMiddleware(base environments.Environments, instance string, spanDe // Create implements environments.Environments func (_d telemetryMiddleware) Create(ctx context.Context, env *environments.Environment) (created *environments.Environment, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.Create") + defer _span.End() + + created, err = _d.Environments.Create(ctx, env) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "env": env}, map[string]interface{}{ - "created": created, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, env, created, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Environments.Create(ctx, env) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "env": env}, map[string]interface{}{ + "created": created, + "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())) + } + + return created, err } // Delete implements environments.Environments func (_d telemetryMiddleware) Delete(ctx context.Context, spaceId string, envId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId}, 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())) - } + err = _d.Environments.Delete(ctx, spaceId, envId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Environments.Delete(ctx, spaceId, envId) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // Get implements environments.Environments func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, envId string) (env *environments.Environment, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId}, map[string]interface{}{ - "env": env, - "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())) - } + env, err = _d.Environments.Get(ctx, spaceId, envId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.End() - }() - return _d.Environments.Get(ctx, spaceId, envId) + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId}, map[string]interface{}{ + "env": env, + "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())) + } + + return env, err } // List implements environments.Environments func (_d telemetryMiddleware) List(ctx context.Context, spaceId string) (envs []*environments.Environment, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "List"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.List") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "envs": envs, - "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())) - } + envs, err = _d.Environments.List(ctx, spaceId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Environments.List(ctx, spaceId) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "envs": envs, + "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())) + } + + return envs, err } // Migrate implements environments.Environments func (_d telemetryMiddleware) Migrate(ctx context.Context, spaceId string, envId string, options ...*environments.MigrateOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "Migrate"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.Migrate") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "options": options}, 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())) - } + err = _d.Environments.Migrate(ctx, spaceId, envId, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Environments.Migrate(ctx, spaceId, envId, options...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "options": options}, 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())) + } + + return err } // RemoveAlias implements environments.Environments func (_d telemetryMiddleware) RemoveAlias(ctx context.Context, spaceId string, envId string, alias string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "RemoveAlias"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.RemoveAlias") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "alias": alias}, 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())) - } + err = _d.Environments.RemoveAlias(ctx, spaceId, envId, alias) - _span.End() - }() - return _d.Environments.RemoveAlias(ctx, spaceId, envId, alias) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "alias": alias}, 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())) + } + + return err } // SetAlias implements environments.Environments func (_d telemetryMiddleware) SetAlias(ctx context.Context, spaceId string, envId string, alias string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "SetAlias"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.SetAlias") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "alias": alias}, 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())) - } + err = _d.Environments.SetAlias(ctx, spaceId, envId, alias) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "alias": alias}, 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.Environments.SetAlias(ctx, spaceId, envId, alias) + return err } // Update implements environments.Environments func (_d telemetryMiddleware) Update(ctx context.Context, env *environments.Environment) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Environments"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Environments.Update") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Environments.Update(ctx, env) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "env": env}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, env, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "env": env}, 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.Environments.Update(ctx, env) + return err } diff --git a/pkg/expr/config.go b/pkg/expr/config.go index e6ba9d90b4f4e04c56c17b8591d4a92e30984e6c..130342b812b8798bd5d94b564fd5f27296facff5 100644 --- a/pkg/expr/config.go +++ b/pkg/expr/config.go @@ -16,7 +16,6 @@ func (c *ExprConfig) RegisterOption(opt ...expr.Option) { func (c *ExprConfig) GetConfig(e map[string]interface{}) *conf.Config { cfg := conf.New(e) - cfg.Operators = make(map[string][]string) for _, opt := range c.options { opt(cfg) } @@ -38,9 +37,9 @@ func GetDefaultConfig(e map[string]interface{}) *conf.Config { return defaultConfig.GetConfig(e) } -//func GetDefaultEnv(e map[string]interface{}) map[string]interface{} { +// func GetDefaultEnv(e map[string]interface{}) map[string]interface{} { // return defaultConfig.GetEnv(e) -//} +// } func Extend(kv ...interface{}) expr.Option { e := make(map[string]interface{}) diff --git a/pkg/extension/middleware/telemetry_middleware.go b/pkg/extension/middleware/telemetry_middleware.go index 764e7cbd2de929e5550b8175a5ec7713b361f3cb..7302cab3b4ecf364f475b0dbe7d77a37c96cd784 100644 --- a/pkg/extension/middleware/telemetry_middleware.go +++ b/pkg/extension/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/telemetry +// template: ../../../assets/templates/middleware/telemetry_default // 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/telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/extension -i Manager -t ../../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/extension" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements extension.Manager interface instrumented with opentracing spans type telemetryMiddleware struct { extension.Manager @@ -50,269 +54,317 @@ func TelemetryMiddleware(base extension.Manager, instance string, spanDecorator // Action implements extension.Manager func (_d telemetryMiddleware) Action(ctx context.Context, in *extension.ActionRequest) (ap1 *extension.ActionResponse, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "Action"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.Action") + defer _span.End() + + ap1, err = _d.Manager.Action(ctx, in) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "in": in}, map[string]interface{}{ + "ap1": ap1, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "in": in}, map[string]interface{}{ - "ap1": ap1, - "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.Manager.Action(ctx, in) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return ap1, err } // Check implements extension.Manager func (_d telemetryMiddleware) Check(ctx context.Context, in *extension.CheckRequest) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "Check"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.Check") + defer _span.End() + + err = _d.Manager.Check(ctx, in) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "in": in}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "in": in}, 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.Manager.Check(ctx, in) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // Install implements extension.Manager func (_d telemetryMiddleware) Install(ctx context.Context, in *extension.InstallRequest) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "Install"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.Install") + defer _span.End() + + err = _d.Manager.Install(ctx, in) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "in": in}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "in": in}, 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.Manager.Install(ctx, in) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // ListExtensions implements extension.Manager func (_d telemetryMiddleware) ListExtensions(ctx context.Context, space string, env string, filter *extension.ListExtensionsFilter) (ipa1 []*extension.Info, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "ListExtensions"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.ListExtensions") + defer _span.End() + + ipa1, err = _d.Manager.ListExtensions(ctx, space, env, filter) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "space": space, + "env": env, + "filter": filter}, map[string]interface{}{ + "ipa1": ipa1, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "space": space, - "env": env, - "filter": filter}, map[string]interface{}{ - "ipa1": ipa1, - "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.Manager.ListExtensions(ctx, space, env, filter) + return ipa1, err } // ListRegisteredExtensions implements extension.Manager func (_d telemetryMiddleware) ListRegisteredExtensions(ctx context.Context, extensions ...string) (epa1 []*extension.ExtensionConnector, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "ListRegisteredExtensions"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.ListRegisteredExtensions") + defer _span.End() + + epa1, err = _d.Manager.ListRegisteredExtensions(ctx, extensions...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "extensions": extensions}, map[string]interface{}{ + "epa1": epa1, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "extensions": extensions}, map[string]interface{}{ - "epa1": epa1, - "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.Manager.ListRegisteredExtensions(ctx, extensions...) + return epa1, err } // RegisterExtensions implements extension.Manager func (_d telemetryMiddleware) RegisterExtensions(ctx context.Context, ext ...*extension.ExtensionConnector) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "RegisterExtensions"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.RegisterExtensions") + defer _span.End() + + err = _d.Manager.RegisterExtensions(ctx, ext...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "ext": ext}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "ext": ext}, 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.Manager.RegisterExtensions(ctx, ext...) + return err } // Uninstall implements extension.Manager func (_d telemetryMiddleware) Uninstall(ctx context.Context, in *extension.UninstallRequest) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "Uninstall"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.Uninstall") + defer _span.End() + + err = _d.Manager.Uninstall(ctx, in) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "in": in}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "in": in}, 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.Manager.Uninstall(ctx, in) + return err } // UnregisterExtensions implements extension.Manager func (_d telemetryMiddleware) UnregisterExtensions(ctx context.Context, ext ...*extension.ExtensionConnector) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Manager"), attribute.String("method", "UnregisterExtensions"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Manager.UnregisterExtensions") + defer _span.End() + + err = _d.Manager.UnregisterExtensions(ctx, ext...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "ext": ext}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "ext": ext}, 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.Manager.UnregisterExtensions(ctx, ext...) + return err } diff --git a/pkg/files/middleware/telemetry_middleware.go b/pkg/files/middleware/telemetry_middleware.go index bed97ea15eba2acd026249d698195835ee6a9db1..e2e482a6af8f4ffde281120f35c17fae425202f6 100644 --- a/pkg/files/middleware/telemetry_middleware.go +++ b/pkg/files/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_default // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/files -i Files -t ../../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/files" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements files.Files interface instrumented with opentracing spans type telemetryMiddleware struct { files.Files @@ -50,236 +54,278 @@ func TelemetryMiddleware(base files.Files, instance string, spanDecorator ...fun // AbortUpload implements files.Files func (_d telemetryMiddleware) AbortUpload(ctx context.Context, upload *files.MultipartUpload) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "AbortUpload"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.AbortUpload") + defer _span.End() + + err = _d.Files.AbortUpload(ctx, upload) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "upload": upload}, 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.Files.AbortUpload(ctx, upload) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "upload": upload}, 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())) + } + + return err } // CompleteUpload implements files.Files func (_d telemetryMiddleware) CompleteUpload(ctx context.Context, upload *files.MultipartUpload) (u *files.MultipartUpload, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "CompleteUpload"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.CompleteUpload") + defer _span.End() + + u, err = _d.Files.CompleteUpload(ctx, upload) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "upload": upload}, map[string]interface{}{ - "u": u, - "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.Files.CompleteUpload(ctx, upload) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "upload": upload}, map[string]interface{}{ + "u": u, + "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())) + } + + return u, err } // DeleteFile implements files.Files func (_d telemetryMiddleware) DeleteFile(ctx context.Context, file *files.File) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "DeleteFile"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.DeleteFile") + defer _span.End() + + err = _d.Files.DeleteFile(ctx, file) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "file": file}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "file": file}, 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.Files.DeleteFile(ctx, file) + return err } // GetFile implements files.Files func (_d telemetryMiddleware) GetFile(ctx context.Context, file *files.File) (f *files.File, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "GetFile"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.GetFile") + defer _span.End() + + f, err = _d.Files.GetFile(ctx, file) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "file": file}, map[string]interface{}{ - "f": f, - "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.Files.GetFile(ctx, file) + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "file": file}, map[string]interface{}{ + "f": f, + "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())) + } + + return f, err } // MoveUpload implements files.Files func (_d telemetryMiddleware) MoveUpload(ctx context.Context, upload *files.MultipartUpload) (file *files.File, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "MoveUpload"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.MoveUpload") + defer _span.End() + + file, err = _d.Files.MoveUpload(ctx, upload) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "upload": upload}, map[string]interface{}{ - "file": file, - "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.Files.MoveUpload(ctx, upload) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "upload": upload}, map[string]interface{}{ + "file": file, + "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())) + } + + return file, err } // StartUpload implements files.Files func (_d telemetryMiddleware) StartUpload(ctx context.Context, upload *files.MultipartUpload) (u *files.MultipartUpload, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "StartUpload"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.StartUpload") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "upload": upload}, map[string]interface{}{ - "u": u, - "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.Files.StartUpload(ctx, upload) + u, err = _d.Files.StartUpload(ctx, upload) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "upload": upload}, map[string]interface{}{ + "u": u, + "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())) + } + + return u, err } // Upload implements files.Files func (_d telemetryMiddleware) Upload(ctx context.Context, file *files.File) (u *files.Upload, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Files"), attribute.String("method", "Upload"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Files.Upload") + defer _span.End() + + u, err = _d.Files.Upload(ctx, file) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "file": file}, map[string]interface{}{ + "u": u, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "file": file}, map[string]interface{}{ - "u": u, - "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.Files.Upload(ctx, file) + return u, err } diff --git a/pkg/invitations/invitation.go b/pkg/invitations/invitation.go index a5b91ed006693748deb71877b8e555e485b0c6c8..86d0db29a4d77b0eb7e7533b706d4a299fbed388 100644 --- a/pkg/invitations/invitation.go +++ b/pkg/invitations/invitation.go @@ -27,3 +27,7 @@ func (i Invitation) Clone() *Invitation { ValidUntil: i.ValidUntil, } } + +func (i Invitation) GetSpaceID() string { + return i.SpaceID +} diff --git a/pkg/invitations/middleware/telemetry_middleware.go b/pkg/invitations/middleware/telemetry_middleware.go index 44b7d2683137884f330946cce8d39a0eb3617d15..1696f81a9ada1457336e928ebb44c79aa6852bcd 100644 --- a/pkg/invitations/middleware/telemetry_middleware.go +++ b/pkg/invitations/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/invitations -i Invitations -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/invitations" "git.perx.ru/perxis/perxis-go/pkg/options" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements invitations.Invitations interface instrumented with opentracing spans type telemetryMiddleware struct { invitations.Invitations @@ -51,171 +55,281 @@ func TelemetryMiddleware(base invitations.Invitations, instance string, spanDeco // Accept implements invitations.Invitations func (_d telemetryMiddleware) Accept(ctx context.Context, invitationId string, userId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Invitations"), attribute.String("method", "Accept"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Invitations.Accept") + defer _span.End() + + err = _d.Invitations.Accept(ctx, invitationId, userId) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "invitationId": invitationId, - "userId": userId}, 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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, invitationId, userId, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "invitationId": invitationId, + "userId": userId}, 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.Invitations.Accept(ctx, invitationId, userId) + return err } // Create implements invitations.Invitations func (_d telemetryMiddleware) Create(ctx context.Context, invitation *invitations.Invitation) (created *invitations.Invitation, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Invitations"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Invitations.Create") + defer _span.End() + + created, err = _d.Invitations.Create(ctx, invitation) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "invitation": invitation}, map[string]interface{}{ - "created": created, - "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())) + var spID string + params := []interface{}{ctx, invitation, created, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Invitations.Create(ctx, invitation) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "invitation": invitation}, map[string]interface{}{ + "created": created, + "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())) + } + + return created, err } // Delete implements invitations.Invitations func (_d telemetryMiddleware) Delete(ctx context.Context, invitationId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Invitations"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Invitations.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Invitations.Delete(ctx, invitationId) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "invitationId": invitationId}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, invitationId, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Invitations.Delete(ctx, invitationId) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "invitationId": invitationId}, 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())) + } + + return err } // Find implements invitations.Invitations func (_d telemetryMiddleware) Find(ctx context.Context, filter *invitations.Filter, opts *options.FindOptions) (invitations []*invitations.Invitation, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Invitations"), attribute.String("method", "Find"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Invitations.Find") + defer _span.End() + + invitations, total, err = _d.Invitations.Find(ctx, filter, opts) - 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, - "opts": opts}, map[string]interface{}{ - "invitations": invitations, - "total": total, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, filter, opts, invitations, total, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Invitations.Find(ctx, filter, opts) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "filter": filter, + "opts": opts}, map[string]interface{}{ + "invitations": invitations, + "total": total, + "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())) + } + + return invitations, total, err } // Get implements invitations.Invitations func (_d telemetryMiddleware) Get(ctx context.Context, invitationId string) (invitation *invitations.Invitation, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Invitations"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Invitations.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "invitationId": invitationId}, map[string]interface{}{ - "invitation": invitation, - "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())) + invitation, err = _d.Invitations.Get(ctx, invitationId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, invitationId, invitation, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "invitationId": invitationId}, map[string]interface{}{ + "invitation": invitation, + "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.Invitations.Get(ctx, invitationId) + return invitation, err } diff --git a/pkg/items/item.go b/pkg/items/item.go index c37c4fc69c2829d511764afdb89b4db8fb8f7137..dc56fe63284be6885cf4560578df0bf77729e359 100644 --- a/pkg/items/item.go +++ b/pkg/items/item.go @@ -150,6 +150,10 @@ func (i *Item) GetID() string { return i.ID } +func (i *Item) GetSpaceID() string { + return i.SpaceID +} + func (i *Item) Clone() *Item { itm := *i itm.Data = data.CloneMap(i.Data) diff --git a/pkg/items/middleware/telemetry_middleware.go b/pkg/items/middleware/telemetry_middleware.go index 98891f9f4f957ffe12626150c58e8bb7df67389a..da626aa53ea846ce5747bd0deded09d300d48d95 100644 --- a/pkg/items/middleware/telemetry_middleware.go +++ b/pkg/items/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "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/schema" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements items.Items interface instrumented with opentracing spans type telemetryMiddleware struct { items.Items @@ -51,655 +55,952 @@ func TelemetryMiddleware(base items.Items, instance string, spanDecorator ...fun // Aggregate implements items.Items func (_d telemetryMiddleware) Aggregate(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregateOptions) (result map[string]interface{}, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Aggregate"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Aggregate") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "result": result, - "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())) - } + result, err = _d.Items.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "result": result, + "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.Items.Aggregate(ctx, spaceId, envId, collectionId, filter, options...) + return result, err } // AggregatePublished implements items.Items func (_d telemetryMiddleware) AggregatePublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregatePublishedOptions) (result map[string]interface{}, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "AggregatePublished"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.AggregatePublished") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "result": result, - "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())) - } + result, err = _d.Items.AggregatePublished(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "result": result, + "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.Items.AggregatePublished(ctx, spaceId, envId, collectionId, filter, options...) + return result, err } // Archive implements items.Items func (_d telemetryMiddleware) Archive(ctx context.Context, item *items.Item, options ...*items.ArchiveOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Archive"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Archive") + defer _span.End() + + err = _d.Items.Archive(ctx, item, options...) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Items.Archive(ctx, item, options...) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, 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())) + } + + return err } // Create implements items.Items func (_d telemetryMiddleware) Create(ctx context.Context, item *items.Item, opts ...*items.CreateOptions) (created *items.Item, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Create") + defer _span.End() + + created, err = _d.Items.Create(ctx, item, opts...) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "opts": opts}, map[string]interface{}{ - "created": created, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, item, opts, created, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Items.Create(ctx, item, opts...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "opts": opts}, map[string]interface{}{ + "created": created, + "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())) + } + + return created, err } // Delete implements items.Items func (_d telemetryMiddleware) Delete(ctx context.Context, item *items.Item, options ...*items.DeleteOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Delete") + defer _span.End() + + err = _d.Items.Delete(ctx, item, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Items.Delete(ctx, item, options...) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // Find implements items.Items func (_d telemetryMiddleware) Find(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindOptions) (items []*items.Item, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Find"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Find") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "items": items, - "total": total, - "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())) - } + items, total, err = _d.Items.Find(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.End() - }() - return _d.Items.Find(ctx, spaceId, envId, collectionId, filter, options...) + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "items": items, + "total": total, + "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())) + } + + return items, total, err } // FindArchived implements items.Items func (_d telemetryMiddleware) FindArchived(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindArchivedOptions) (items []*items.Item, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "FindArchived"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.FindArchived") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "items": items, - "total": total, - "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())) - } + items, total, err = _d.Items.FindArchived(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Items.FindArchived(ctx, spaceId, envId, collectionId, filter, options...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "items": items, + "total": total, + "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())) + } + + return items, total, err } // FindPublished implements items.Items func (_d telemetryMiddleware) FindPublished(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindPublishedOptions) (items []*items.Item, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "FindPublished"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.FindPublished") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "filter": filter, - "options": options}, map[string]interface{}{ - "items": items, - "total": total, - "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())) - } + items, total, err = _d.Items.FindPublished(ctx, spaceId, envId, collectionId, filter, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.End() - }() - return _d.Items.FindPublished(ctx, spaceId, envId, collectionId, filter, options...) + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "filter": filter, + "options": options}, map[string]interface{}{ + "items": items, + "total": total, + "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())) + } + + return items, total, err } // Get implements items.Items func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetOptions) (item *items.Item, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options}, map[string]interface{}{ - "item": item, - "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())) - } + item, err = _d.Items.Get(ctx, spaceId, envId, collectionId, itemId, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Items.Get(ctx, spaceId, envId, collectionId, itemId, options...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "itemId": itemId, + "options": options}, map[string]interface{}{ + "item": item, + "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())) + } + + return item, err } // GetPublished implements items.Items func (_d telemetryMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.GetPublishedOptions) (item *items.Item, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "GetPublished"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.GetPublished") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options}, map[string]interface{}{ - "item": item, - "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())) - } + item, err = _d.Items.GetPublished(ctx, spaceId, envId, collectionId, itemId, options...) - _span.End() - }() - return _d.Items.GetPublished(ctx, spaceId, envId, collectionId, itemId, options...) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "itemId": itemId, + "options": options}, map[string]interface{}{ + "item": item, + "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())) + } + + return item, err } // GetRevision implements items.Items func (_d telemetryMiddleware) GetRevision(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, revisionId string, options ...*items.GetRevisionOptions) (item *items.Item, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "GetRevision"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.GetRevision") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "revisionId": revisionId, - "options": options}, map[string]interface{}{ - "item": item, - "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())) - } + item, err = _d.Items.GetRevision(ctx, spaceId, envId, collectionId, itemId, revisionId, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "itemId": itemId, + "revisionId": revisionId, + "options": options}, map[string]interface{}{ + "item": item, + "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.Items.GetRevision(ctx, spaceId, envId, collectionId, itemId, revisionId, options...) + return item, err } // Introspect implements items.Items func (_d telemetryMiddleware) Introspect(ctx context.Context, item *items.Item, opts ...*items.IntrospectOptions) (itm *items.Item, sch *schema.Schema, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Introspect"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Introspect") + defer _span.End() + + itm, sch, err = _d.Items.Introspect(ctx, item, opts...) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "opts": opts}, map[string]interface{}{ - "itm": itm, - "sch": sch, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, item, opts, itm, sch, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Items.Introspect(ctx, item, opts...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "opts": opts}, map[string]interface{}{ + "itm": itm, + "sch": sch, + "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())) + } + + return itm, sch, err } // ListRevisions implements items.Items func (_d telemetryMiddleware) ListRevisions(ctx context.Context, spaceId string, envId string, collectionId string, itemId string, options ...*items.ListRevisionsOptions) (items []*items.Item, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "ListRevisions"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.ListRevisions") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "collectionId": collectionId, - "itemId": itemId, - "options": options}, map[string]interface{}{ - "items": items, - "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())) - } + items, err = _d.Items.ListRevisions(ctx, spaceId, envId, collectionId, itemId, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "collectionId": collectionId, + "itemId": itemId, + "options": options}, map[string]interface{}{ + "items": items, + "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.Items.ListRevisions(ctx, spaceId, envId, collectionId, itemId, options...) + return items, err } // Publish implements items.Items func (_d telemetryMiddleware) Publish(ctx context.Context, item *items.Item, options ...*items.PublishOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Publish"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Publish") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + err = _d.Items.Publish(ctx, item, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Items.Publish(ctx, item, options...) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, 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())) + } + + return err } // Unarchive implements items.Items func (_d telemetryMiddleware) Unarchive(ctx context.Context, item *items.Item, options ...*items.UnarchiveOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Unarchive"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Unarchive") + defer _span.End() + + err = _d.Items.Unarchive(ctx, item, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Items.Unarchive(ctx, item, options...) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // Undelete implements items.Items func (_d telemetryMiddleware) Undelete(ctx context.Context, item *items.Item, options ...*items.UndeleteOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Undelete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Undelete") + defer _span.End() + + err = _d.Items.Undelete(ctx, item, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Items.Undelete(ctx, item, options...) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // Unpublish implements items.Items func (_d telemetryMiddleware) Unpublish(ctx context.Context, item *items.Item, options ...*items.UnpublishOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Unpublish"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Unpublish") + defer _span.End() + + err = _d.Items.Unpublish(ctx, item, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Items.Unpublish(ctx, item, options...) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // Update implements items.Items func (_d telemetryMiddleware) Update(ctx context.Context, item *items.Item, options ...*items.UpdateOptions) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Items"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.Update") + defer _span.End() + + err = _d.Items.Update(ctx, item, options...) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "item": item, - "options": options}, 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())) + var spID string + params := []interface{}{ctx, item, options, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "item": item, + "options": options}, 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.Items.Update(ctx, item, options...) + return err } diff --git a/pkg/locales/locale.go b/pkg/locales/locale.go index e0e32616ee4bd526c7d25c9cbab740e196529328..80cd2d60c884951206ccb3aad5113f0a369b68bf 100644 --- a/pkg/locales/locale.go +++ b/pkg/locales/locale.go @@ -55,6 +55,10 @@ func (locale *Locale) Key() string { return locale.ID } +func (locale *Locale) GetSpaceID() string { + return locale.SpaceID +} + // Возвращает Ñзык локали, например "en", "ru" func (locale *Locale) GetLanguage() string { lang, err := language.Parse(locale.Code) diff --git a/pkg/locales/middleware/telemetry_middleware.go b/pkg/locales/middleware/telemetry_middleware.go index 98fe346ea000409be27bfd21fccc6723ed09851b..709a6bab9a23210954ae0c756e6c10ac7fa2bd05 100644 --- a/pkg/locales/middleware/telemetry_middleware.go +++ b/pkg/locales/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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/telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/locales -i Locales -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/locales" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements locales.Locales interface instrumented with opentracing spans type telemetryMiddleware struct { locales.Locales @@ -50,135 +54,201 @@ func TelemetryMiddleware(base locales.Locales, instance string, spanDecorator .. // Create implements locales.Locales func (_d telemetryMiddleware) Create(ctx context.Context, locale *locales.Locale) (created *locales.Locale, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Locales"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Locales.Create") + defer _span.End() + + created, err = _d.Locales.Create(ctx, locale) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "locale": locale}, map[string]interface{}{ - "created": created, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, locale, created, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Locales.Create(ctx, locale) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "locale": locale}, map[string]interface{}{ + "created": created, + "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())) + } + + return created, err } // Delete implements locales.Locales func (_d telemetryMiddleware) Delete(ctx context.Context, spaceId string, localeId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Locales"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Locales.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "localeId": localeId}, 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())) - } + err = _d.Locales.Delete(ctx, spaceId, localeId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "localeId": localeId}, map[string]interface{}{ + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Locales.Delete(ctx, spaceId, localeId) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return err } // List implements locales.Locales func (_d telemetryMiddleware) List(ctx context.Context, spaceId string) (locales []*locales.Locale, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Locales"), attribute.String("method", "List"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Locales.List") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "locales": locales, - "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())) - } + locales, err = _d.Locales.List(ctx, spaceId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.End() - }() - return _d.Locales.List(ctx, spaceId) + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "locales": locales, + "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())) + } + + return locales, err } // Update implements locales.Locales func (_d telemetryMiddleware) Update(ctx context.Context, locale *locales.Locale) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Locales"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Locales.Update") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Locales.Update(ctx, locale) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "locale": locale}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, locale, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "locale": locale}, 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.Locales.Update(ctx, locale) + return err } diff --git a/pkg/members/middleware/middleware.go b/pkg/members/middleware/middleware.go index 04626790010ac2da99f00e8501d1c4186683e6b7..bb491623865e21496adedb1e91987bc2205a3ce4 100644 --- a/pkg/members/middleware/middleware.go +++ b/pkg/members/middleware/middleware.go @@ -21,7 +21,7 @@ func WithLog(s members.Members, logger *zap.Logger, log_access bool) members.Mem if log_access { s = AccessLoggingMiddleware(logger)(s) } - s = LoggingMiddleware(logger)(s) + s = ErrorLoggingMiddleware(logger)(s) s = RecoveringMiddleware(logger)(s) return s diff --git a/pkg/members/middleware/telemetry_middleware.go b/pkg/members/middleware/telemetry_middleware.go index 6193a4bacb41dcea61a1384e939bcdb2785f5e8a..bf339f3fd998e3e49d842a6b99612759743aced5 100644 --- a/pkg/members/middleware/telemetry_middleware.go +++ b/pkg/members/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_default // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members -i Members -t ../../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/members" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements members.Members interface instrumented with opentracing spans type telemetryMiddleware struct { members.Members @@ -50,205 +54,241 @@ func TelemetryMiddleware(base members.Members, instance string, spanDecorator .. // Get implements members.Members func (_d telemetryMiddleware) Get(ctx context.Context, orgId string, userId string) (role members.Role, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Members"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Members.Get") + defer _span.End() + + role, err = _d.Members.Get(ctx, orgId, userId) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId, - "userId": userId}, map[string]interface{}{ - "role": role, - "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.Members.Get(ctx, orgId, userId) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId, + "userId": userId}, map[string]interface{}{ + "role": role, + "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())) + } + + return role, err } // ListMembers implements members.Members func (_d telemetryMiddleware) ListMembers(ctx context.Context, orgId string) (members []*members.Member, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Members"), attribute.String("method", "ListMembers"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Members.ListMembers") + defer _span.End() + + members, err = _d.Members.ListMembers(ctx, orgId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId}, map[string]interface{}{ - "members": members, - "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.Members.ListMembers(ctx, orgId) + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId}, map[string]interface{}{ + "members": members, + "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())) + } + + return members, err } // ListOrganizations implements members.Members func (_d telemetryMiddleware) ListOrganizations(ctx context.Context, userId string) (organizations []*members.Member, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Members"), attribute.String("method", "ListOrganizations"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Members.ListOrganizations") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "userId": userId}, map[string]interface{}{ - "organizations": organizations, - "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.Members.ListOrganizations(ctx, userId) + organizations, err = _d.Members.ListOrganizations(ctx, userId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "userId": userId}, map[string]interface{}{ + "organizations": organizations, + "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())) + } + + return organizations, err } // Remove implements members.Members func (_d telemetryMiddleware) Remove(ctx context.Context, orgId string, userId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Members"), attribute.String("method", "Remove"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Members.Remove") + defer _span.End() + + err = _d.Members.Remove(ctx, orgId, userId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId, - "userId": userId}, 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.Members.Remove(ctx, orgId, userId) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId, + "userId": userId}, 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())) + } + + return err } // RemoveAll implements members.Members func (_d telemetryMiddleware) RemoveAll(ctx context.Context, orgId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Members"), attribute.String("method", "RemoveAll"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Members.RemoveAll") + defer _span.End() + + err = _d.Members.RemoveAll(ctx, orgId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId}, 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.Members.RemoveAll(ctx, orgId) + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId}, 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())) + } + + return err } // Set implements members.Members func (_d telemetryMiddleware) Set(ctx context.Context, orgId string, userId string, role members.Role) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Members"), attribute.String("method", "Set"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Members.Set") + defer _span.End() + + err = _d.Members.Set(ctx, orgId, userId, role) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId, + "userId": userId, + "role": role}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId, - "userId": userId, - "role": role}, 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.Members.Set(ctx, orgId, userId, role) + return err } diff --git a/pkg/organizations/middleware/telemetry_middleware.go b/pkg/organizations/middleware/telemetry_middleware.go index d728b1f10f4ba303b6469d3a1b8bf63cb24a7283..1cb7932880080c617db6ccbf2f3d204682ca7c11 100644 --- a/pkg/organizations/middleware/telemetry_middleware.go +++ b/pkg/organizations/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_default // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/organizations -i Organizations -t ../../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/options" "git.perx.ru/perxis/perxis-go/pkg/organizations" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements organizations.Organizations interface instrumented with opentracing spans type telemetryMiddleware struct { organizations.Organizations @@ -51,170 +55,200 @@ func TelemetryMiddleware(base organizations.Organizations, instance string, span // Create implements organizations.Organizations func (_d telemetryMiddleware) Create(ctx context.Context, org *organizations.Organization) (created *organizations.Organization, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Organizations"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Organizations.Create") + defer _span.End() + + created, err = _d.Organizations.Create(ctx, org) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "org": org}, map[string]interface{}{ + "created": created, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "org": org}, map[string]interface{}{ - "created": created, - "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.Organizations.Create(ctx, org) + return created, err } // Delete implements organizations.Organizations func (_d telemetryMiddleware) Delete(ctx context.Context, orgId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Organizations"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Organizations.Delete") + defer _span.End() + + err = _d.Organizations.Delete(ctx, orgId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId}, 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.Organizations.Delete(ctx, orgId) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId}, 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())) + } + + return err } // Find implements organizations.Organizations func (_d telemetryMiddleware) Find(ctx context.Context, filter *organizations.Filter, opts *options.FindOptions) (orgs []*organizations.Organization, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Organizations"), attribute.String("method", "Find"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Organizations.Find") + defer _span.End() + + orgs, total, err = _d.Organizations.Find(ctx, filter, opts) - 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, - "opts": opts}, map[string]interface{}{ - "orgs": orgs, - "total": total, - "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.Organizations.Find(ctx, filter, opts) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "filter": filter, + "opts": opts}, map[string]interface{}{ + "orgs": orgs, + "total": total, + "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())) + } + + return orgs, total, err } // Get implements organizations.Organizations func (_d telemetryMiddleware) Get(ctx context.Context, orgId string) (org *organizations.Organization, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Organizations"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Organizations.Get") + defer _span.End() + + org, err = _d.Organizations.Get(ctx, orgId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId}, map[string]interface{}{ + "org": org, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId}, map[string]interface{}{ - "org": org, - "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.Organizations.Get(ctx, orgId) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return org, err } // Update implements organizations.Organizations func (_d telemetryMiddleware) Update(ctx context.Context, org *organizations.Organization) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Organizations"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Organizations.Update") + defer _span.End() + + err = _d.Organizations.Update(ctx, org) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "org": org}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "org": org}, 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.Organizations.Update(ctx, org) + return err } diff --git a/pkg/references/middleware/telemetry_middleware.go b/pkg/references/middleware/telemetry_middleware.go index 71c51698bd9c015fdefd24e79b41ddcacda09eb2..3e8fbb773fd9bc548eed3f34f78a4f5adcbe1128 100644 --- a/pkg/references/middleware/telemetry_middleware.go +++ b/pkg/references/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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/telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/references -i References -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "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/references" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements references.References interface instrumented with opentracing spans type telemetryMiddleware struct { references.References @@ -51,78 +55,100 @@ func TelemetryMiddleware(base references.References, instance string, spanDecora // Get implements references.References func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, envId string, references []*references.Reference, options ...*references.GetOptions) (items []*items.Item, notfound []*references.Reference, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "References"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "References.Get") + defer _span.End() + + items, notfound, err = _d.References.Get(ctx, spaceId, envId, references, options...) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "references": references, - "options": options}, map[string]interface{}{ - "items": items, - "notfound": notfound, - "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.References.Get(ctx, spaceId, envId, references, options...) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "references": references, + "options": options}, map[string]interface{}{ + "items": items, + "notfound": notfound, + "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())) + } + + return items, notfound, err } // Publish implements references.References func (_d telemetryMiddleware) 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) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "References"), attribute.String("method", "Publish"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "References.Publish") + defer _span.End() + + published, notfound, unpublished, err = _d.References.Publish(ctx, spaceId, envId, references, recursive, force) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "envId": envId, + "references": references, + "recursive": recursive, + "force": force}, map[string]interface{}{ + "published": published, + "notfound": notfound, + "unpublished": unpublished, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "envId": envId, - "references": references, - "recursive": recursive, - "force": force}, map[string]interface{}{ - "published": published, - "notfound": notfound, - "unpublished": unpublished, - "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.References.Publish(ctx, spaceId, envId, references, recursive, force) + return published, notfound, unpublished, err } diff --git a/pkg/roles/middleware/middleware.go b/pkg/roles/middleware/middleware.go index 299199a40432f486d1020bb803f5bff18a95428e..aaeb2da895d5aa71768e577315e549daa6a247c4 100644 --- a/pkg/roles/middleware/middleware.go +++ b/pkg/roles/middleware/middleware.go @@ -21,7 +21,7 @@ func WithLog(s roles.Roles, logger *zap.Logger, log_access bool) roles.Roles { if log_access { s = AccessLoggingMiddleware(logger)(s) } - s = LoggingMiddleware(logger)(s) + s = ErrorLoggingMiddleware(logger)(s) s = RecoveringMiddleware(logger)(s) return s diff --git a/pkg/roles/middleware/telemetry_middleware.go b/pkg/roles/middleware/telemetry_middleware.go index 5d9d5e35cee66af5e24fb5888d52907ce35aadde..7403575220d93fe24a00b0a8de749371e57904b0 100644 --- a/pkg/roles/middleware/telemetry_middleware.go +++ b/pkg/roles/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/roles -i Roles -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/roles" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "go.opentelemetry.io/otel" @@ -20,6 +20,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements roles.Roles interface instrumented with opentracing spans type telemetryMiddleware struct { roles.Roles @@ -50,170 +54,247 @@ func TelemetryMiddleware(base roles.Roles, instance string, spanDecorator ...fun // Create implements roles.Roles func (_d telemetryMiddleware) Create(ctx context.Context, role *roles.Role) (created *roles.Role, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Roles"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Roles.Create") + defer _span.End() + + created, err = _d.Roles.Create(ctx, role) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "role": role}, map[string]interface{}{ - "created": created, - "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())) + var spID string + params := []interface{}{ctx, role, created, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "role": role}, map[string]interface{}{ + "created": created, + "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.Roles.Create(ctx, role) + return created, err } // Delete implements roles.Roles func (_d telemetryMiddleware) Delete(ctx context.Context, spaceId string, roleId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Roles"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Roles.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "roleId": roleId}, 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())) - } + err = _d.Roles.Delete(ctx, spaceId, roleId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Roles.Delete(ctx, spaceId, roleId) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "roleId": roleId}, 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())) + } + + return err } // Get implements roles.Roles func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, roleId string) (role *roles.Role, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Roles"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Roles.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "roleId": roleId}, map[string]interface{}{ - "role": role, - "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())) - } + role, err = _d.Roles.Get(ctx, spaceId, roleId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "roleId": roleId}, map[string]interface{}{ + "role": role, + "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.Roles.Get(ctx, spaceId, roleId) + return role, err } // List implements roles.Roles func (_d telemetryMiddleware) List(ctx context.Context, spaceId string) (roles []*roles.Role, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Roles"), attribute.String("method", "List"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Roles.List") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "roles": roles, - "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())) - } + roles, err = _d.Roles.List(ctx, spaceId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Roles.List(ctx, spaceId) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "roles": roles, + "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())) + } + + return roles, err } // Update implements roles.Roles func (_d telemetryMiddleware) Update(ctx context.Context, role *roles.Role) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Roles"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Roles.Update") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Roles.Update(ctx, role) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "role": role}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, role, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "role": role}, 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.Roles.Update(ctx, role) + return err } diff --git a/pkg/roles/role.go b/pkg/roles/role.go index 76520f8fbf353c027ae782efb1bf79a1bfa453f5..81feb1e909f15d40a918309a25add9c420e25b35 100644 --- a/pkg/roles/role.go +++ b/pkg/roles/role.go @@ -40,6 +40,10 @@ func (r Role) GetID() string { return r.ID } +func (r Role) GetSpaceID() string { + return r.SpaceID +} + func (r Role) Clone() *Role { return &Role{ ID: r.ID, diff --git a/pkg/spaces/middleware/access_logging_middleware.go b/pkg/spaces/middleware/access_logging_middleware.go index 9596d7d4fc2daa611a0db631eef56fe6d5531488..d155ee1f0d95daad6b29c5961604cdc8b466fcd9 100644 --- a/pkg/spaces/middleware/access_logging_middleware.go +++ b/pkg/spaces/middleware/access_logging_middleware.go @@ -184,6 +184,25 @@ func (m *accessLoggingMiddleware) Move(ctx context.Context, spaceID string, orgI return err } +func (m *accessLoggingMiddleware) SetState(ctx context.Context, spaceID string, state *spaces.StateInfo) (err error) { + begin := time.Now() + + m.logger.Debug("SetState.Request", + zap.Reflect("principal", auth.GetPrincipal(ctx)), + zap.Reflect("spaceID", spaceID), + zap.Reflect("state", state), + ) + + err = m.next.SetState(ctx, spaceID, state) + + m.logger.Debug("SetState.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() @@ -239,22 +258,3 @@ func (m *accessLoggingMiddleware) UpdateConfig(ctx context.Context, spaceId stri return err } - -func (m *accessLoggingMiddleware) SetState(ctx context.Context, spaceID string, state *spaces.StateInfo) (err error) { - begin := time.Now() - - m.logger.Debug("SetState.Request", - zap.Reflect("principal", auth.GetPrincipal(ctx)), - zap.Reflect("spaceID", spaceID), - zap.Reflect("state", state), - ) - - err = m.next.SetState(ctx, spaceID, state) - - m.logger.Debug("SetState.Response", - zap.Duration("time", time.Since(begin)), - zap.Error(err), - ) - - return err -} diff --git a/pkg/spaces/middleware/telemetry_middleware.go b/pkg/spaces/middleware/telemetry_middleware.go index e9623692afe644e58cb1b406b4b06a3208edc710..84c90bd6a74bd9bdce5479ae6d100e306916355d 100644 --- a/pkg/spaces/middleware/telemetry_middleware.go +++ b/pkg/spaces/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ../../../assets/templates/middleware/telemetry +// template: ../../../assets/templates/middleware/telemetry_content // 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/telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/spaces -i Spaces -t ../../../assets/templates/middleware/telemetry_content -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/options" "git.perx.ru/perxis/perxis-go/pkg/spaces" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements spaces.Spaces interface instrumented with opentracing spans type telemetryMiddleware struct { spaces.Spaces @@ -51,407 +55,638 @@ func TelemetryMiddleware(base spaces.Spaces, instance string, spanDecorator ...f // AbortTransfer implements spaces.Spaces func (_d telemetryMiddleware) AbortTransfer(ctx context.Context, spaceID string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "AbortTransfer"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.AbortTransfer") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Spaces.AbortTransfer(ctx, spaceID) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, spaceID, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Spaces.AbortTransfer(ctx, spaceID) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceID": spaceID}, 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())) + } + + return err } // Create implements spaces.Spaces func (_d telemetryMiddleware) Create(ctx context.Context, space *spaces.Space) (created *spaces.Space, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Create") + defer _span.End() + + created, err = _d.Spaces.Create(ctx, space) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "space": space}, map[string]interface{}{ - "created": created, - "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())) + var spID string + params := []interface{}{ctx, space, created, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Spaces.Create(ctx, space) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "space": space}, map[string]interface{}{ + "created": created, + "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())) + } + + return created, err } // Delete implements spaces.Spaces func (_d telemetryMiddleware) Delete(ctx context.Context, spaceId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Delete") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Spaces.Delete(ctx, spaceId) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) - } + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, 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.Spaces.Delete(ctx, spaceId) + return err } // Find implements spaces.Spaces func (_d telemetryMiddleware) Find(ctx context.Context, filter *spaces.Filter, fo *options.FindOptions) (spaces []*spaces.Space, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Find"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Find") + defer _span.End() + + spaces, total, err = _d.Spaces.Find(ctx, filter, fo) - 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, - "fo": fo}, map[string]interface{}{ - "spaces": spaces, - "total": total, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, filter, fo, spaces, total, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Spaces.Find(ctx, filter, fo) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "filter": filter, + "fo": fo}, map[string]interface{}{ + "spaces": spaces, + "total": total, + "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())) + } + + return spaces, total, err } // Get implements spaces.Spaces func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string) (space *spaces.Space, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Get") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId}, map[string]interface{}{ - "space": space, - "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())) - } + space, err = _d.Spaces.Get(ctx, spaceId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Spaces.Get(ctx, spaceId) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId}, map[string]interface{}{ + "space": space, + "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())) + } + + return space, err } // List implements spaces.Spaces func (_d telemetryMiddleware) List(ctx context.Context, orgId string) (spaces []*spaces.Space, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "List"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.List") + defer _span.End() + + spaces, err = _d.Spaces.List(ctx, orgId) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgId": orgId}, map[string]interface{}{ - "spaces": spaces, - "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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, orgId, spaces, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Spaces.List(ctx, orgId) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgId": orgId}, map[string]interface{}{ + "spaces": spaces, + "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())) + } + + return spaces, err } // ListTransfers implements spaces.Spaces func (_d telemetryMiddleware) ListTransfers(ctx context.Context, orgID string) (spaces []*spaces.Space, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "ListTransfers"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.ListTransfers") + defer _span.End() + + spaces, err = _d.Spaces.ListTransfers(ctx, orgID) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "orgID": orgID}, map[string]interface{}{ - "spaces": spaces, - "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())) + var spID string + params := []interface{}{ctx, orgID, spaces, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "orgID": orgID}, map[string]interface{}{ + "spaces": spaces, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - _span.End() - }() - return _d.Spaces.ListTransfers(ctx, orgID) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return spaces, err } // Move implements spaces.Spaces func (_d telemetryMiddleware) Move(ctx context.Context, spaceID string, orgID string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Move"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Move") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID, - "orgID": orgID}, 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())) + err = _d.Spaces.Move(ctx, spaceID, orgID) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, spaceID, orgID, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Spaces.Move(ctx, spaceID, orgID) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceID": spaceID, + "orgID": orgID}, 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())) + } + + return err } // SetState implements spaces.Spaces func (_d telemetryMiddleware) SetState(ctx context.Context, spaceID string, state *spaces.StateInfo) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "SetState"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.SetState") + defer _span.End() + + err = _d.Spaces.SetState(ctx, spaceID, state) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID, - "state": state}, 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())) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + params := []interface{}{ctx, spaceID, state, err} + for _, p := range params { + if p == nil { + continue + } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceID": spaceID, + "state": state}, 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.Spaces.SetState(ctx, spaceID, state) + return err } // Transfer implements spaces.Spaces func (_d telemetryMiddleware) Transfer(ctx context.Context, spaceID string, transferToOrg string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Transfer"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Transfer") + defer _span.End() + + err = _d.Spaces.Transfer(ctx, spaceID, transferToOrg) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceID": spaceID, - "transferToOrg": transferToOrg}, 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())) + var spID string + params := []interface{}{ctx, spaceID, transferToOrg, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } - _span.End() - }() - return _d.Spaces.Transfer(ctx, spaceID, transferToOrg) + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceID": spaceID, + "transferToOrg": transferToOrg}, 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())) + } + + return err } // Update implements spaces.Spaces func (_d telemetryMiddleware) Update(ctx context.Context, space *spaces.Space) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.Update") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + err = _d.Spaces.Update(ctx, space) - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "space": space}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - _span.RecordError(err) - _span.SetAttributes(attribute.String("event", "error")) - _span.SetAttributes(attribute.String("message", err.Error())) + var spID string + params := []interface{}{ctx, space, err} + for _, p := range params { + if p == nil { + continue } + if sg, ok := p.(spaceGetter); ok { + spID = sg.GetSpaceID() + if spID != "" { + break + } + } + } + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) - _span.End() - }() - return _d.Spaces.Update(ctx, space) + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "space": space}, 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())) + } + + return err } // UpdateConfig implements spaces.Spaces func (_d telemetryMiddleware) UpdateConfig(ctx context.Context, spaceId string, config *spaces.Config) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Spaces"), attribute.String("method", "UpdateConfig"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Spaces.UpdateConfig") + defer _span.End() - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "spaceId": spaceId, - "config": config}, 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())) - } + err = _d.Spaces.UpdateConfig(ctx, spaceId, config) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + var spID string + spID = spaceId + if spID != "" { + att = append(att, attribute.String("spaceID", spID)) + } + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "spaceId": spaceId, + "config": config}, 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.Spaces.UpdateConfig(ctx, spaceId, config) + return err } diff --git a/pkg/spaces/space.go b/pkg/spaces/space.go index baa44124b6830aa8c4f666f0300661952eadbc9d..46edd87af1de695b639759bcddfacc3bb313353e 100644 --- a/pkg/spaces/space.go +++ b/pkg/spaces/space.go @@ -88,3 +88,10 @@ type StateInfo struct { func (s Space) Clone() *Space { return &s } + +func (s *Space) GetSpaceID() string { + if s == nil { + return "" + } + return s.ID +} diff --git a/pkg/users/middleware/telemetry_middleware.go b/pkg/users/middleware/telemetry_middleware.go index 698b4f6b4f2928e5f466e7855defa4c2df96ef36..8ad677e704656503e246943bf12d30e133d4c11f 100644 --- a/pkg/users/middleware/telemetry_middleware.go +++ b/pkg/users/middleware/telemetry_middleware.go @@ -1,17 +1,17 @@ // Code generated by gowrap. DO NOT EDIT. -// template: ..\..\..\assets\templates\middleware\telemetry +// template: ../../../assets/templates/middleware/telemetry_default // 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\telemetry -o telemetry_middleware.go -l "" - -// source template: https://github.com/hexdigest/gowrap/blob/master/templates/opentelemetry +//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/users -i Users -t ../../../assets/templates/middleware/telemetry_default -o telemetry_middleware.go -l "" import ( "context" "time" + oid "git.perx.ru/perxis/perxis-go/id" + "git.perx.ru/perxis/perxis-go/pkg/auth" "git.perx.ru/perxis/perxis-go/pkg/options" "git.perx.ru/perxis/perxis-go/pkg/telemetry/metrics" "git.perx.ru/perxis/perxis-go/pkg/users" @@ -21,6 +21,10 @@ import ( "go.opentelemetry.io/otel/trace" ) +type spaceGetter interface { + GetSpaceID() string +} + // telemetryMiddleware implements users.Users interface instrumented with opentracing spans type telemetryMiddleware struct { users.Users @@ -51,204 +55,240 @@ func TelemetryMiddleware(base users.Users, instance string, spanDecorator ...fun // Create implements users.Users func (_d telemetryMiddleware) Create(ctx context.Context, create *users.User) (user *users.User, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Users"), attribute.String("method", "Create"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.Create") + defer _span.End() + + user, err = _d.Users.Create(ctx, create) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "create": create}, map[string]interface{}{ + "user": user, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "create": create}, map[string]interface{}{ - "user": user, - "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.Users.Create(ctx, create) + return user, err } // Delete implements users.Users func (_d telemetryMiddleware) Delete(ctx context.Context, userId string) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Users"), attribute.String("method", "Delete"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.Delete") + defer _span.End() + + err = _d.Users.Delete(ctx, userId) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "userId": userId}, 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.Users.Delete(ctx, userId) + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "userId": userId}, 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())) + } + + return err } // Find implements users.Users func (_d telemetryMiddleware) Find(ctx context.Context, filter *users.Filter, options *options.FindOptions) (users []*users.User, total int, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Users"), attribute.String("method", "Find"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.Find") + defer _span.End() + + users, total, err = _d.Users.Find(ctx, filter, options) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "filter": filter, + "options": options}, map[string]interface{}{ + "users": users, + "total": total, + "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())) + } - 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{}{ - "users": users, - "total": total, - "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.Users.Find(ctx, filter, options) + return users, total, err } // Get implements users.Users func (_d telemetryMiddleware) Get(ctx context.Context, userId string) (user *users.User, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Users"), attribute.String("method", "Get"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.Get") + defer _span.End() + + user, err = _d.Users.Get(ctx, userId) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "userId": userId}, map[string]interface{}{ + "user": user, + "err": err}) + } else if err != nil { + _d.requestMetrics.FailedTotal.Add(ctx, 1, attributes) - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "userId": userId}, map[string]interface{}{ - "user": user, - "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.Users.Get(ctx, userId) + _span.RecordError(err) + _span.SetAttributes(attribute.String("event", "error")) + _span.SetAttributes(attribute.String("message", err.Error())) + } + + return user, err } // GetByIdentity implements users.Users func (_d telemetryMiddleware) GetByIdentity(ctx context.Context, identity string) (user *users.User, err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Users"), attribute.String("method", "GetByIdentity"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.GetByIdentity") + defer _span.End() + + user, err = _d.Users.GetByIdentity(ctx, identity) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "identity": identity}, map[string]interface{}{ + "user": user, + "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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "identity": identity}, map[string]interface{}{ - "user": user, - "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.Users.GetByIdentity(ctx, identity) + return user, err } // Update implements users.Users func (_d telemetryMiddleware) Update(ctx context.Context, update *users.User) (err error) { - attributes := otelmetric.WithAttributeSet(attribute.NewSet( + var att = []attribute.KeyValue{ attribute.String("service", "Users"), attribute.String("method", "Update"), - )) - - _d.requestMetrics.Total.Add(ctx, 1, attributes) + } + attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...)) start := time.Now() ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Users.Update") + defer _span.End() + + err = _d.Users.Update(ctx, update) + + _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) + + caller, _ := oid.NewObjectId(auth.GetPrincipal(ctx)) + if caller != nil { + att = append(att, attribute.String("caller", caller.String())) + } + + _d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...))) + + if _d._spanDecorator != nil { + _d._spanDecorator(_span, map[string]interface{}{ + "ctx": ctx, + "update": update}, 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())) + } - defer func() { - _d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes) - - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "update": update}, 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.Users.Update(ctx, update) + return err } diff --git a/yaml/file_resolver.go b/yaml/file_resolver.go new file mode 100644 index 0000000000000000000000000000000000000000..03a795d9871571c1c5b640ed9c91877b8918de18 --- /dev/null +++ b/yaml/file_resolver.go @@ -0,0 +1,31 @@ +package yaml + +import ( + "io" + + "git.perx.ru/perxis/perxis-go/pkg/errors" + "gopkg.in/yaml.v3" +) + +// FileResolver подключает Ñодержимое целевого файла в качеÑтве Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ. +func FileResolver(tp TagProcessor, node *yaml.Node) (*yaml.Node, error) { + if node.Kind != yaml.ScalarNode { + return nil, errors.New("!include on a non-scalar node") + } + + file, err := tp.FS().Open(node.Value) + if err != nil { + return nil, err + } + defer func() { _ = file.Close() }() + + bytes, err := io.ReadAll(file) + if err != nil { + return nil, err + } + + out := new(yaml.Node) + out.SetString(string(bytes)) + + return out, err +} diff --git a/yaml/include_resolver.go b/yaml/include_resolver.go new file mode 100644 index 0000000000000000000000000000000000000000..0f459c539ab2a244413eab46f2a67181cfce0a0a --- /dev/null +++ b/yaml/include_resolver.go @@ -0,0 +1,33 @@ +package yaml + +import ( + "path/filepath" + + "git.perx.ru/perxis/perxis-go/pkg/errors" + "gopkg.in/yaml.v3" +) + +// IncludeResolver включает Ñодержимое целевого YAML-файла в поле. +func IncludeResolver(tp TagProcessor, node *yaml.Node) (*yaml.Node, error) { + if node.Kind != yaml.ScalarNode { + return nil, errors.New("!include on a non-scalar node") + } + + if ext := filepath.Ext(node.Value); ext != ".yaml" && ext != ".yml" { + return nil, errors.New("!include on file with unknown extension") + } + + file, err := tp.FS().Open(node.Value) + if err != nil { + return nil, err + } + defer func() { _ = file.Close() }() + + out := new(yaml.Node) + err = yaml.NewDecoder(file).Decode(WithTagProcessor(tp.FS())(out)) + if err != nil { + return nil, err + } + + return out, nil +} diff --git a/yaml/tag_processor.go b/yaml/tag_processor.go new file mode 100644 index 0000000000000000000000000000000000000000..89678b93d8242fb15260193208d8445404570cc4 --- /dev/null +++ b/yaml/tag_processor.go @@ -0,0 +1,61 @@ +package yaml + +import ( + "io/fs" + + "gopkg.in/yaml.v3" +) + +type TagProcessor interface { + yaml.Unmarshaler + FS() fs.FS +} + +// tagProcessor обёртка Ð´Ð»Ñ Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð³Ð¾ значениÑ. +// +// Перед декодированием Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°ÑŽÑ‚ÑÑ Ð²Ñе теги узла. +type tagProcessor struct { + fsys fs.FS + target any +} + +// WithTagProcessor возвращает функцию, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¾Ð±Ð¾Ñ€Ð°Ñ‡Ð¸Ð²Ð°ÐµÑ‚ декодируемые Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ обработки тегов YAML. +// +// Ð”Ð»Ñ Ð¿ÑƒÑ‚ÐµÐ¹ к файлам, иÑпользуемых в качеÑтве значений тегов, пути должны быть указаны отноÑительно переданной файловой ÑиÑтемы. +func WithTagProcessor(fsys fs.FS) func(any) *tagProcessor { + return func(v any) *tagProcessor { + return &tagProcessor{fsys: fsys, target: v} + } +} + +func (tp *tagProcessor) FS() fs.FS { + return tp.fsys +} + +func (tp *tagProcessor) UnmarshalYAML(value *yaml.Node) error { + resolved, err := resolveTags(tp, value) + if err != nil { + return err + } + return resolved.Decode(tp.target) +} + +// resolveTags обрабатывает вÑе теги YAML Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ð½Ð½Ð¾Ð³Ð¾ узла и возвращает иÑправленный узел. +// ЕÑли узел предÑтавлÑет Ñобой поÑледовательноÑть или Ñловарь, то обрабатываютÑÑ Ñ‚ÐµÐ³Ð¸ Ð´Ð»Ñ ÐµÐ³Ð¾ дочерних Ñлементов. +func resolveTags(tp TagProcessor, node *yaml.Node) (*yaml.Node, error) { + switch node.Kind { + case yaml.SequenceNode, yaml.MappingNode: + for i := range node.Content { + var err error + node.Content[i], err = resolveTags(tp, node.Content[i]) + if err != nil { + return nil, err + } + } + default: + if resolver, ok := tagResolvers[node.Tag]; ok { + return resolver.Resolve(tp, node) + } + } + return node, nil +} diff --git a/yaml/tag_processor_test.go b/yaml/tag_processor_test.go new file mode 100644 index 0000000000000000000000000000000000000000..e54ec041180e1fa31975ea9fdd9e789ebcdc2e2a --- /dev/null +++ b/yaml/tag_processor_test.go @@ -0,0 +1,64 @@ +package yaml + +import ( + "testing" + + "git.perx.ru/perxis/perxis-go/yaml/testdata" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestTagProcessor(t *testing.T) { + t.Run("!file", func(t *testing.T) { + file, err := testdata.FS.Open("file/file_simple.yaml") + require.NoError(t, err) + defer file.Close() + + var result any + decoder := yaml.NewDecoder(file) + err = decoder.Decode(WithTagProcessor(testdata.FS)(&result)) + require.NoError(t, err) + assert.Equal(t, map[string]any{"config": `server { + listen 80; + server_name example.com; + + location / { + root /var/www/example.com/html; + index index.html index.htm; + try_files $uri $uri/ =404; + } +}`}, result) + }) + t.Run("!include", func(t *testing.T) { + t.Run("simple", func(t *testing.T) { + file, err := testdata.FS.Open("include/include_simple.yaml") + require.NoError(t, err) + defer file.Close() + + var result any + decoder := yaml.NewDecoder(file) + err = decoder.Decode(WithTagProcessor(testdata.FS)(&result)) + require.NoError(t, err) + assert.Equal(t, map[string]any{"data": map[string]any{"text": "Hello, World!"}}, result) + }) + t.Run("with merge", func(t *testing.T) { + file, err := testdata.FS.Open("include/include_merge.yaml") + require.NoError(t, err) + defer file.Close() + + var result any + decoder := yaml.NewDecoder(file) + err = decoder.Decode(WithTagProcessor(testdata.FS)(&result)) + require.NoError(t, err) + assert.Equal(t, map[string]any{ + "server": map[string]any{ + "host": "dev.perx.ru", + "port": 3000, + "ssl": true, + "tags": []any{"http", "api"}, + }, + }, result) + }) + }) +} diff --git a/yaml/testdata/file/file_simple.yaml b/yaml/testdata/file/file_simple.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6e7181a3eb1ae553aa5a8055c9a95f772cb43e0b --- /dev/null +++ b/yaml/testdata/file/file_simple.yaml @@ -0,0 +1 @@ +config: !file file/nginx.conf \ No newline at end of file diff --git a/yaml/testdata/file/nginx.conf b/yaml/testdata/file/nginx.conf new file mode 100644 index 0000000000000000000000000000000000000000..a9bbbc506ed333d44456d224cecda27d77d65827 --- /dev/null +++ b/yaml/testdata/file/nginx.conf @@ -0,0 +1,10 @@ +server { + listen 80; + server_name example.com; + + location / { + root /var/www/example.com/html; + index index.html index.htm; + try_files $uri $uri/ =404; + } +} \ No newline at end of file diff --git a/yaml/testdata/include/default_server_config.yaml b/yaml/testdata/include/default_server_config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..eff5d022e1e6778243499803d37d589a96b813b9 --- /dev/null +++ b/yaml/testdata/include/default_server_config.yaml @@ -0,0 +1,4 @@ +host: localhost +port: 3000 +ssl: true +<<: !include include/default_server_tags.yaml \ No newline at end of file diff --git a/yaml/testdata/include/default_server_tags.yaml b/yaml/testdata/include/default_server_tags.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1f7c1497f5ea652c94b1e21fc48823147d728105 --- /dev/null +++ b/yaml/testdata/include/default_server_tags.yaml @@ -0,0 +1 @@ +tags: [ http, api ] \ No newline at end of file diff --git a/yaml/testdata/include/include_merge.yaml b/yaml/testdata/include/include_merge.yaml new file mode 100644 index 0000000000000000000000000000000000000000..894a9a91c0491a56663bb1e831ae9e0802727498 --- /dev/null +++ b/yaml/testdata/include/include_merge.yaml @@ -0,0 +1,3 @@ +server: + <<: !include include/default_server_config.yaml + host: dev.perx.ru \ No newline at end of file diff --git a/yaml/testdata/include/include_simple.yaml b/yaml/testdata/include/include_simple.yaml new file mode 100644 index 0000000000000000000000000000000000000000..689f5f9f0cd8e2f5acf9f05eb248bf92e3df168a --- /dev/null +++ b/yaml/testdata/include/include_simple.yaml @@ -0,0 +1 @@ +data: !include include/simple_data.yaml \ No newline at end of file diff --git a/yaml/testdata/include/simple_data.yaml b/yaml/testdata/include/simple_data.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a0bfdf8ea14a5dae1dbe66345309cc67df0b2f4e --- /dev/null +++ b/yaml/testdata/include/simple_data.yaml @@ -0,0 +1 @@ +text: Hello, World! \ No newline at end of file diff --git a/yaml/testdata/testdata.go b/yaml/testdata/testdata.go new file mode 100644 index 0000000000000000000000000000000000000000..f8b469980cf76e31cd31f40dfae6f6cc0f92dcb1 --- /dev/null +++ b/yaml/testdata/testdata.go @@ -0,0 +1,6 @@ +package testdata + +import "embed" + +//go:embed * +var FS embed.FS diff --git a/yaml/yaml.go b/yaml/yaml.go new file mode 100644 index 0000000000000000000000000000000000000000..3830b76d2f606f32013236152479a2eaa2c1609f --- /dev/null +++ b/yaml/yaml.go @@ -0,0 +1,34 @@ +package yaml + +import ( + "gopkg.in/yaml.v3" +) + +var ( + NewDecoder = yaml.NewDecoder + NewEncoder = yaml.NewEncoder + Unmarshal = yaml.Unmarshal + Marshal = yaml.Marshal +) + +var tagResolvers = make(map[string]Resolver) + +func RegisterTagResolver(tag string, resolver Resolver) { + tagResolvers[tag] = resolver +} + +// Resolver обрабатывает тег YAML и возвращает его обработанный вариант +type Resolver interface { + Resolve(tp TagProcessor, node *yaml.Node) (*yaml.Node, error) +} + +type ResolverFunc func(TagProcessor, *yaml.Node) (*yaml.Node, error) + +func (fn ResolverFunc) Resolve(tp TagProcessor, node *yaml.Node) (*yaml.Node, error) { + return fn(tp, node) +} + +func init() { + RegisterTagResolver("!include", ResolverFunc(IncludeResolver)) + RegisterTagResolver("!file", ResolverFunc(FileResolver)) +}