diff --git a/api/auth/center.go b/api/auth/center.go index adb998a5..c1b7c57b 100644 --- a/api/auth/center.go +++ b/api/auth/center.go @@ -160,7 +160,7 @@ func IsStandardContentSHA256(key string) bool { return ok } -func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) { +func (c *Center) Authenticate(ctx context.Context, r *http.Request) (*middleware.Box, error) { var ( err error authHdr *AuthHeader @@ -215,7 +215,7 @@ func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) { authHeaderField := r.Header[AuthorizationHdr] if len(authHeaderField) != 1 { if strings.HasPrefix(r.Header.Get(ContentTypeHdr), "multipart/form-data") { - return c.checkFormData(r) + return c.checkFormData(ctx, r) } return nil, fmt.Errorf("%w: %v", middleware.ErrNoAuthorizationHeader, authHeaderField) } @@ -241,7 +241,7 @@ func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) { return nil, err } - box, attrs, err := c.cli.GetBox(r.Context(), cnrID, authHdr.AccessKeyID) + box, attrs, err := c.cli.GetBox(ctx, cnrID, authHdr.AccessKeyID) if err != nil { return nil, fmt.Errorf("get box by access key '%s': %w", authHdr.AccessKeyID, err) } @@ -314,7 +314,7 @@ func (c Center) checkAccessKeyID(accessKeyID string) error { return fmt.Errorf("%w: accesskeyID prefix isn't allowed", apierr.GetAPIError(apierr.ErrAccessDenied)) } -func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) { +func (c *Center) checkFormData(ctx context.Context, r *http.Request) (*middleware.Box, error) { if err := r.ParseMultipartForm(maxFormSizeMemory); err != nil { return nil, fmt.Errorf("%w: parse multipart form with max size %d", apierr.GetAPIError(apierr.ErrInvalidArgument), maxFormSizeMemory) } @@ -346,7 +346,7 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) { return nil, err } - box, attrs, err := c.cli.GetBox(r.Context(), cnrID, accessKeyID) + box, attrs, err := c.cli.GetBox(ctx, cnrID, accessKeyID) if err != nil { return nil, fmt.Errorf("get box by accessKeyID '%s': %w", accessKeyID, err) } diff --git a/api/auth/center_test.go b/api/auth/center_test.go index c4756466..d4fca86e 100644 --- a/api/auth/center_test.go +++ b/api/auth/center_test.go @@ -484,7 +484,7 @@ func TestAuthenticate(t *testing.T) { t.Run(tc.name, func(t *testing.T) { creds := tokens.New(bigConfig) cntr := New(creds, tc.prefixes, ¢erSettingsMock{}) - box, err := cntr.Authenticate(tc.request) + box, err := cntr.Authenticate(ctx, tc.request) if tc.err { require.Error(t, err) @@ -511,6 +511,7 @@ func TestHTTPPostAuthenticate(t *testing.T) { region = "default" ) + ctx := context.Background() key, err := keys.NewPrivateKey() require.NoError(t, err) @@ -662,7 +663,7 @@ func TestHTTPPostAuthenticate(t *testing.T) { t.Run(tc.name, func(t *testing.T) { creds := tokens.New(bigConfig) cntr := New(creds, tc.prefixes, ¢erSettingsMock{}) - box, err := cntr.Authenticate(tc.request) + box, err := cntr.Authenticate(ctx, tc.request) if tc.err { require.Error(t, err) diff --git a/api/auth/presign_test.go b/api/auth/presign_test.go index 7b70dbf4..545edc62 100644 --- a/api/auth/presign_test.go +++ b/api/auth/presign_test.go @@ -100,12 +100,14 @@ func TestCheckSign(t *testing.T) { postReg: NewRegexpMatcher(postPolicyCredentialRegexp), settings: ¢erSettingsMock{}, } - box, err := c.Authenticate(req) + box, err := c.Authenticate(ctx, req) require.NoError(t, err) require.EqualValues(t, expBox, box.AccessBox) } func TestCheckSignV4a(t *testing.T) { + ctx := context.Background() + var accessKeyAddr oid.Address err := accessKeyAddr.DecodeString("8N7CYBY74kxZXoyvA5UNdmovaXqFpwNfvEPsqaN81es2/3tDwq5tR8fByrJcyJwyiuYX7Dae8tyDT7pd8oaL1MBto") require.NoError(t, err) @@ -149,7 +151,7 @@ func TestCheckSignV4a(t *testing.T) { regV4a: NewRegexpMatcher(authorizationFieldV4aRegexp), postReg: NewRegexpMatcher(postPolicyCredentialRegexp), } - box, err := c.Authenticate(req) + box, err := c.Authenticate(ctx, req) require.NoError(t, err) require.EqualValues(t, expBox, box.AccessBox) } diff --git a/api/handler/acl.go b/api/handler/acl.go index ff2c1b6c..a10fb0a4 100644 --- a/api/handler/acl.go +++ b/api/handler/acl.go @@ -11,6 +11,7 @@ import ( "net/http" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -47,7 +48,9 @@ const ( ) func (h *handler) GetBucketACLHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketACL") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -127,7 +130,9 @@ func getTokenIssuerKey(box *accessbox.Box) (*keys.PublicKey, error) { } func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketACL") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -194,7 +199,9 @@ func (h *handler) putBucketACLAPEHandler(w http.ResponseWriter, r *http.Request, } func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectACL") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -216,7 +223,9 @@ func (h *handler) GetObjectACLHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectACL") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) if _, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName); err != nil { @@ -228,7 +237,9 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketPolicyStatus") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -271,7 +282,9 @@ func (h *handler) GetBucketPolicyStatusHandler(w http.ResponseWriter, r *http.Re } func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketPolicy") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -298,7 +311,9 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) } func (h *handler) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketPolicy") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -328,7 +343,9 @@ func checkOwner(info *data.BucketInfo, owner string) error { } func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketPolicy") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/attributes.go b/api/handler/attributes.go index 4e4a9132..ea83a394 100644 --- a/api/handler/attributes.go +++ b/api/handler/attributes.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -70,7 +71,9 @@ var validAttributes = map[string]struct{}{ } func (h *handler) GetObjectAttributesHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectAttributes") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) params, err := parseGetObjectAttributeArgs(r, h.reqLogger(ctx)) diff --git a/api/handler/copy.go b/api/handler/copy.go index f4c8c783..9bf5181b 100644 --- a/api/handler/copy.go +++ b/api/handler/copy.go @@ -6,6 +6,7 @@ import ( "regexp" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" @@ -40,18 +41,19 @@ func path2BucketObject(path string) (string, string, error) { } func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) { + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CopyObject") + defer span.End() + var ( err error versionID string metadata map[string]string tagSet map[string]string - - ctx = r.Context() - reqInfo = middleware.GetReqInfo(ctx) - - cannedACLStatus = aclHeadersStatus(r) ) + reqInfo := middleware.GetReqInfo(ctx) + cannedACLStatus := aclHeadersStatus(r) + src := r.Header.Get(api.AmzCopySource) // Check https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectVersioning.html // Regardless of whether you have enabled versioning, each object in your bucket diff --git a/api/handler/cors.go b/api/handler/cors.go index dcdaa521..f4611401 100644 --- a/api/handler/cors.go +++ b/api/handler/cors.go @@ -5,6 +5,7 @@ import ( "strconv" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" @@ -20,7 +21,9 @@ const ( ) func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketCors") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -42,7 +45,9 @@ func (h *handler) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketCors") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -76,7 +81,9 @@ func (h *handler) PutBucketCorsHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketCors") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -93,6 +100,9 @@ func (h *handler) DeleteBucketCorsHandler(w http.ResponseWriter, r *http.Request } func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) { + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.AppendCORSHeaders") + defer span.End() + if r.Method == http.MethodOptions { return } @@ -101,7 +111,6 @@ func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) { return } - ctx := r.Context() reqInfo := middleware.GetReqInfo(ctx) if reqInfo.BucketName == "" { return @@ -153,7 +162,9 @@ func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) { } func (h *handler) Preflight(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.Preflight") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketInfo(ctx, reqInfo.BucketName) if err != nil { diff --git a/api/handler/delete.go b/api/handler/delete.go index 67b025d5..3c2a895e 100644 --- a/api/handler/delete.go +++ b/api/handler/delete.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" @@ -61,7 +62,9 @@ type DeleteObjectsResponse struct { } func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteObject") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) versionID := reqInfo.URL.Query().Get(api.QueryVersionID) versionedObject := []*layer.VersionedObject{{ @@ -128,7 +131,9 @@ func isErrObjectLocked(err error) bool { // DeleteMultipleObjectsHandler handles multiple delete requests. func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteMultipleObjects") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) // Content-Md5 is required and should be set @@ -237,7 +242,9 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re } func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucket") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) if err != nil { diff --git a/api/handler/get.go b/api/handler/get.go index 3403ac7d..4cc97989 100644 --- a/api/handler/get.go +++ b/api/handler/get.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -148,12 +149,11 @@ func writeHeaders(h http.Header, requestHeader http.Header, extendedInfo *data.E } func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) { - var ( - params *layer.RangeParams + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObject") + defer span.End() - ctx = r.Context() - reqInfo = middleware.GetReqInfo(ctx) - ) + var params *layer.RangeParams + reqInfo := middleware.GetReqInfo(ctx) conditional := parseConditionalHeaders(r.Header, h.reqLogger(ctx)) diff --git a/api/handler/head.go b/api/handler/head.go index 8556e4b7..95048922 100644 --- a/api/handler/head.go +++ b/api/handler/head.go @@ -4,6 +4,7 @@ import ( "io" "net/http" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -27,7 +28,9 @@ func getRangeToDetectContentType(maxSize uint64) *layer.RangeParams { } func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.HeadObject") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -123,7 +126,9 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.HeadBucket") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/info.go b/api/handler/info.go index d526b812..f50d576e 100644 --- a/api/handler/info.go +++ b/api/handler/info.go @@ -3,11 +3,14 @@ package handler import ( "net/http" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" ) func (h *handler) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketLocation") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/lifecycle.go b/api/handler/lifecycle.go index 4ebdb2ed..03e8a338 100644 --- a/api/handler/lifecycle.go +++ b/api/handler/lifecycle.go @@ -10,6 +10,7 @@ import ( "net/http" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -27,7 +28,9 @@ const ( ) func (h *handler) GetBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketLifecycle") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -49,10 +52,12 @@ func (h *handler) GetBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque } func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) { + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketLifecycle") + defer span.End() + var buf bytes.Buffer tee := io.TeeReader(r.Body, &buf) - ctx := r.Context() reqInfo := middleware.GetReqInfo(ctx) // Content-Md5 is required and should be set @@ -120,7 +125,9 @@ func (h *handler) PutBucketLifecycleHandler(w http.ResponseWriter, r *http.Reque } func (h *handler) DeleteBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketLifecycle") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/list.go b/api/handler/list.go index f6bfae3a..f2bfd92e 100644 --- a/api/handler/list.go +++ b/api/handler/list.go @@ -4,6 +4,7 @@ import ( "net/http" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" ) @@ -12,13 +13,16 @@ const maxObjectList = 1000 // Limit number of objects in a listObjectsResponse/l // ListBucketsHandler handles bucket listing requests. func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) { + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListBuckets") + defer span.End() + var ( - own user.ID - res *ListBucketsResponse - ctx = r.Context() - reqInfo = middleware.GetReqInfo(ctx) + own user.ID + res *ListBucketsResponse ) + reqInfo := middleware.GetReqInfo(ctx) + list, err := h.obj.ListBuckets(ctx) if err != nil { h.logAndSendError(ctx, w, "something went wrong", reqInfo, err) diff --git a/api/handler/locking.go b/api/handler/locking.go index e9a0a23b..57b8fe06 100644 --- a/api/handler/locking.go +++ b/api/handler/locking.go @@ -7,6 +7,7 @@ import ( "strconv" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -26,7 +27,9 @@ const ( ) func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketObjectLockConfig") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -74,7 +77,9 @@ func (h *handler) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt } func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketObjectLockConfig") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -108,7 +113,9 @@ func (h *handler) GetBucketObjectLockConfigHandler(w http.ResponseWriter, r *htt } func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectLegalHold") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -161,7 +168,9 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque } func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectLegalHold") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -199,7 +208,9 @@ func (h *handler) GetObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque } func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectRetention") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -247,7 +258,9 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque } func (h *handler) GetObjectRetentionHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectRetention") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/multipart_upload.go b/api/handler/multipart_upload.go index da3fef3d..734f804b 100644 --- a/api/handler/multipart_upload.go +++ b/api/handler/multipart_upload.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -104,7 +105,9 @@ const ( ) func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CreateMultipartUpload") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) uploadID := uuid.New() cannedACLStatus := aclHeadersStatus(r) @@ -180,7 +183,9 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re } func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.UploadPart") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -247,15 +252,16 @@ func (h *handler) UploadPartHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) { - var ( - versionID string - ctx = r.Context() - reqInfo = middleware.GetReqInfo(ctx) - queryValues = reqInfo.URL.Query() - uploadID = queryValues.Get(uploadIDHeaderName) - partNumStr = queryValues.Get(partNumberHeaderName) - additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("partNumber", partNumStr)} - ) + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.UploadPartCopy") + defer span.End() + + var versionID string + + reqInfo := middleware.GetReqInfo(ctx) + queryValues := reqInfo.URL.Query() + uploadID := queryValues.Get(uploadIDHeaderName) + partNumStr := queryValues.Get(partNumberHeaderName) + additional := []zap.Field{zap.String("uploadID", uploadID), zap.String("partNumber", partNumStr)} partNumber, err := strconv.Atoi(partNumStr) if err != nil || partNumber < layer.UploadMinPartNumber || partNumber > layer.UploadMaxPartNumber { @@ -375,7 +381,9 @@ func (h *handler) UploadPartCopy(w http.ResponseWriter, r *http.Request) { } func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CompleteMultipartUpload") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -496,7 +504,9 @@ func (h *handler) completeMultipartUpload(r *http.Request, c *layer.CompleteMult } func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListMultipartUploads") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -547,7 +557,9 @@ func (h *handler) ListMultipartUploadsHandler(w http.ResponseWriter, r *http.Req } func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListParts") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -611,7 +623,9 @@ func (h *handler) ListPartsHandler(w http.ResponseWriter, r *http.Request) { } func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.AbortMultipartUpload") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/object_list.go b/api/handler/object_list.go index 7c20f37d..3921ccd2 100644 --- a/api/handler/object_list.go +++ b/api/handler/object_list.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -17,7 +18,9 @@ import ( // ListObjectsV1Handler handles objects listing requests for API version 1. func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListObjectsV1") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) params, err := parseListObjectsArgsV1(reqInfo) if err != nil { @@ -62,7 +65,9 @@ func (h *handler) encodeV1(p *layer.ListObjectsParamsV1, list *layer.ListObjects // ListObjectsV2Handler handles objects listing requests for API version 2. func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListObjectsV2") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) params, err := parseListObjectsArgsV2(reqInfo) if err != nil { @@ -221,7 +226,9 @@ func fillContents(src []*data.ExtendedNodeVersion, encode string, fetchOwner, md } func (h *handler) ListBucketObjectVersionsHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.ListBucketObjectVersions") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) p, err := parseListObjectVersionsRequest(reqInfo) if err != nil { diff --git a/api/handler/patch.go b/api/handler/patch.go index 60efe3d2..18a82776 100644 --- a/api/handler/patch.go +++ b/api/handler/patch.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -19,7 +20,9 @@ import ( const maxPatchSize = 5 * 1024 * 1024 * 1024 // 5GB func (h *handler) PatchObjectHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PatchObject") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) if _, ok := r.Header[api.ContentRange]; !ok { diff --git a/api/handler/put.go b/api/handler/put.go index c3776f79..9f74f7ea 100644 --- a/api/handler/put.go +++ b/api/handler/put.go @@ -18,6 +18,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" @@ -184,12 +185,13 @@ type createBucketParams struct { } func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) { - var ( - err error - cannedACLStatus = aclHeadersStatus(r) - ctx = r.Context() - reqInfo = middleware.GetReqInfo(ctx) - ) + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObject") + defer span.End() + + var err error + + cannedACLStatus := aclHeadersStatus(r) + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) if err != nil { @@ -458,12 +460,13 @@ func (h *handler) isTLSCheckRequired(r *http.Request) bool { } func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) { - var ( - tagSet map[string]string - ctx = r.Context() - reqInfo = middleware.GetReqInfo(ctx) - metadata = make(map[string]string) - ) + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PostObject") + defer span.End() + + var tagSet map[string]string + + reqInfo := middleware.GetReqInfo(ctx) + metadata := make(map[string]string) policy, err := checkPostPolicy(r, reqInfo, metadata) if err != nil { @@ -748,7 +751,10 @@ func parseCannedACL(header http.Header) (string, error) { } func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) { - h.createBucketHandlerPolicy(w, r) + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.CreateBucket") + defer span.End() + + h.createBucketHandlerPolicy(w, r.WithContext(ctx)) } func (h *handler) parseCommonCreateBucketParams(reqInfo *middleware.ReqInfo, boxData *accessbox.Box, r *http.Request) (*keys.PublicKey, *layer.CreateBucketParams, error) { diff --git a/api/handler/tagging.go b/api/handler/tagging.go index ac20828a..9dd7c369 100644 --- a/api/handler/tagging.go +++ b/api/handler/tagging.go @@ -6,6 +6,7 @@ import ( "strings" "unicode" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -21,7 +22,9 @@ const ( ) func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutObjectTagging") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) tagSet, err := h.readTagSet(reqInfo.Tagging) @@ -54,7 +57,9 @@ func (h *handler) PutObjectTaggingHandler(w http.ResponseWriter, r *http.Request } func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetObjectTagging") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -92,7 +97,9 @@ func (h *handler) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request } func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteObjectTagging") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -116,7 +123,9 @@ func (h *handler) DeleteObjectTaggingHandler(w http.ResponseWriter, r *http.Requ } func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketTagging") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) tagSet, err := h.readTagSet(reqInfo.Tagging) @@ -138,7 +147,9 @@ func (h *handler) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request } func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketTagging") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) @@ -160,7 +171,9 @@ func (h *handler) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request } func (h *handler) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.DeleteBucketTagging") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/handler/versioning.go b/api/handler/versioning.go index bf9c895c..5a3c0eae 100644 --- a/api/handler/versioning.go +++ b/api/handler/versioning.go @@ -3,6 +3,7 @@ package handler import ( "net/http" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" @@ -10,7 +11,9 @@ import ( ) func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.PutBucketVersioning") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) configuration := new(VersioningConfiguration) @@ -57,7 +60,9 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ // GetBucketVersioningHandler implements bucket versioning getter handler. func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "handler.GetBucketVersioning") + defer span.End() + reqInfo := middleware.GetReqInfo(ctx) bktInfo, err := h.getBucketAndCheckOwner(r, reqInfo.BucketName) diff --git a/api/layer/compound.go b/api/layer/compound.go index 83f38051..ba59e70f 100644 --- a/api/layer/compound.go +++ b/api/layer/compound.go @@ -5,12 +5,16 @@ import ( "errors" "fmt" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" ) func (n *Layer) GetObjectTaggingAndLock(ctx context.Context, objVersion *data.ObjectVersion, nodeVersion *data.NodeVersion) (map[string]string, data.LockInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObjectTaggingAndLock") + defer span.End() + var err error owner := n.BearerOwner(ctx) diff --git a/api/layer/cors.go b/api/layer/cors.go index 925f8ed2..3eb2fe62 100644 --- a/api/layer/cors.go +++ b/api/layer/cors.go @@ -8,6 +8,7 @@ import ( "fmt" "io" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" @@ -23,6 +24,9 @@ const wildcard = "*" var supportedMethods = map[string]struct{}{"GET": {}, "HEAD": {}, "POST": {}, "PUT": {}, "DELETE": {}} func (n *Layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketCORS") + defer span.End() + var ( buf bytes.Buffer tee = io.TeeReader(p.Reader, &buf) @@ -97,6 +101,9 @@ func (n *Layer) deleteCORSObject(ctx context.Context, bktInfo *data.BucketInfo, } func (n *Layer) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, decoder func(io.Reader, string) *xml.Decoder) (*data.CORSConfiguration, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketCORS") + defer span.End() + cors, err := n.getCORS(ctx, bktInfo, decoder) if err != nil { return nil, err @@ -106,6 +113,9 @@ func (n *Layer) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, dec } func (n *Layer) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucketCORS") + defer span.End() + objs, err := n.treeService.DeleteBucketCORS(ctx, bktInfo) objNotFound := errors.Is(err, tree.ErrNoNodeToRemove) if err != nil && !objNotFound { diff --git a/api/layer/layer.go b/api/layer/layer.go index bd7e7d8c..ff80d772 100644 --- a/api/layer/layer.go +++ b/api/layer/layer.go @@ -15,6 +15,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -324,6 +325,9 @@ func (n *Layer) prepareAuthParameters(ctx context.Context, prm *frostfs.PrmAuth, // GetBucketInfo returns bucket info by name. func (n *Layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketInfo") + defer span.End() + name, err := url.QueryUnescape(name) if err != nil { return nil, fmt.Errorf("unescape bucket name: %w", err) @@ -372,11 +376,17 @@ func (n *Layer) ResolveCID(ctx context.Context, name string) (cid.ID, error) { // ListBuckets returns all user containers. The name of the bucket is a container // id. Timestamp is omitted since it is not saved in frostfs container. func (n *Layer) ListBuckets(ctx context.Context) ([]*data.BucketInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListBuckets") + defer span.End() + return n.containerList(ctx) } // GetObject from storage. func (n *Layer) GetObject(ctx context.Context, p *GetObjectParams) (*ObjectPayload, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObject") + defer span.End() + var params getParams params.objInfo = p.ObjectInfo @@ -491,6 +501,9 @@ func getDecrypter(p *GetObjectParams) (*encryption.Decrypter, error) { // GetObjectInfo returns meta information about the object. func (n *Layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ObjectInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObjectInfo") + defer span.End() + extendedObjectInfo, err := n.GetExtendedObjectInfo(ctx, p) if err != nil { return nil, err @@ -501,8 +514,13 @@ func (n *Layer) GetObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.O // GetExtendedObjectInfo returns meta information and corresponding info from the tree service about the object. func (n *Layer) GetExtendedObjectInfo(ctx context.Context, p *HeadObjectParams) (*data.ExtendedObjectInfo, error) { - var objInfo *data.ExtendedObjectInfo - var err error + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetExtendedObjectInfo") + defer span.End() + + var ( + objInfo *data.ExtendedObjectInfo + err error + ) if p.Versioned() { objInfo, err = n.headVersion(ctx, p.BktInfo, p) @@ -522,6 +540,9 @@ func (n *Layer) GetExtendedObjectInfo(ctx context.Context, p *HeadObjectParams) // CopyObject from one bucket into another bucket. func (n *Layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*data.ExtendedObjectInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.CopyObject") + defer span.End() + objPayload, err := n.GetObject(ctx, &GetObjectParams{ ObjectInfo: p.SrcObject, Versioned: p.SrcVersioned, @@ -790,6 +811,9 @@ func (n *Layer) removeCombinedObject(ctx context.Context, bkt *data.BucketInfo, // DeleteObjects from the storage. func (n *Layer) DeleteObjects(ctx context.Context, p *DeleteObjectParams) []*VersionedObject { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteObjects") + defer span.End() + for i, obj := range p.Objects { p.Objects[i] = n.deleteObject(ctx, p.BktInfo, p.Settings, obj, p.NetworkInfo) if p.IsMultiple && p.Objects[i].Error != nil { @@ -801,6 +825,9 @@ func (n *Layer) DeleteObjects(ctx context.Context, p *DeleteObjectParams) []*Ver } func (n *Layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.CreateBucket") + defer span.End() + bktInfo, err := n.GetBucketInfo(ctx, p.Name) if err != nil { if apierr.IsS3Error(err, apierr.ErrNoSuchBucket) { @@ -830,6 +857,9 @@ func (n *Layer) ResolveBucket(ctx context.Context, zone, name string) (cid.ID, e } func (n *Layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucket") + defer span.End() + if !p.SkipCheck { res, _, err := n.getAllObjectsVersions(ctx, commonVersionsListingParams{ BktInfo: p.BktInfo, @@ -873,6 +903,9 @@ func (n *Layer) DeleteBucket(ctx context.Context, p *DeleteBucketParams) error { } func (n *Layer) DeleteContainer(ctx context.Context, p *DeleteBucketParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteContainer") + defer span.End() + n.cache.DeleteBucket(p.BktInfo) if err := n.frostFS.DeleteContainer(ctx, p.BktInfo.CID, p.SessionToken); err != nil { return fmt.Errorf("delete container: %w", err) @@ -881,6 +914,9 @@ func (n *Layer) DeleteContainer(ctx context.Context, p *DeleteBucketParams) erro } func (n *Layer) GetNetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetNetworkInfo") + defer span.End() + cachedInfo := n.cache.GetNetworkInfo() if cachedInfo != nil { return *cachedInfo, nil diff --git a/api/layer/lifecycle.go b/api/layer/lifecycle.go index f16aded3..93b57a04 100644 --- a/api/layer/lifecycle.go +++ b/api/layer/lifecycle.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" @@ -23,6 +24,9 @@ type PutBucketLifecycleParams struct { } func (n *Layer) PutBucketLifecycleConfiguration(ctx context.Context, p *PutBucketLifecycleParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketLifecycleConfiguration") + defer span.End() + cfgBytes, err := xml.Marshal(p.LifecycleCfg) if err != nil { return fmt.Errorf("marshal lifecycle configuration: %w", err) @@ -84,6 +88,9 @@ func (n *Layer) deleteLifecycleObject(ctx context.Context, bktInfo *data.BucketI } func (n *Layer) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) (*data.LifecycleConfiguration, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketLifecycleConfiguration") + defer span.End() + owner := n.BearerOwner(ctx) if cfg := n.cache.GetLifecycleConfiguration(owner, bktInfo); cfg != nil { return cfg, nil @@ -129,6 +136,9 @@ func (n *Layer) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *da } func (n *Layer) DeleteBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucketLifecycleConfiguration") + defer span.End() + objs, err := n.treeService.DeleteBucketLifecycleConfiguration(ctx, bktInfo) objsNotFound := errors.Is(err, tree.ErrNoNodeToRemove) if err != nil && !objsNotFound { diff --git a/api/layer/listing.go b/api/layer/listing.go index 790243b8..e8354e0f 100644 --- a/api/layer/listing.go +++ b/api/layer/listing.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -97,6 +98,9 @@ const ( // ListObjectsV1 returns objects in a bucket for requests of Version 1. func (n *Layer) ListObjectsV1(ctx context.Context, p *ListObjectsParamsV1) (*ListObjectsInfoV1, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListObjectsV1") + defer span.End() + var result ListObjectsInfoV1 prm := commonLatestVersionsListingParams{ @@ -128,6 +132,9 @@ func (n *Layer) ListObjectsV1(ctx context.Context, p *ListObjectsParamsV1) (*Lis // ListObjectsV2 returns objects in a bucket for requests of Version 2. func (n *Layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*ListObjectsInfoV2, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListObjectsV2") + defer span.End() + var result ListObjectsInfoV2 prm := commonLatestVersionsListingParams{ @@ -158,6 +165,9 @@ func (n *Layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*Lis } func (n *Layer) ListObjectVersions(ctx context.Context, p *ListObjectVersionsParams) (*ListObjectVersionsInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListObjectVersions") + defer span.End() + prm := commonVersionsListingParams{ BktInfo: p.BktInfo, Delimiter: p.Delimiter, diff --git a/api/layer/multipart_upload.go b/api/layer/multipart_upload.go index 134b54f9..544fdcf5 100644 --- a/api/layer/multipart_upload.go +++ b/api/layer/multipart_upload.go @@ -15,6 +15,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" @@ -149,6 +150,9 @@ type ( ) func (n *Layer) CreateMultipartUpload(ctx context.Context, p *CreateMultipartParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.CreateMultipartUpload") + defer span.End() + metaSize := len(p.Header) if p.Data != nil { metaSize += len(p.Data.TagSet) @@ -189,6 +193,9 @@ func (n *Layer) CreateMultipartUpload(ctx context.Context, p *CreateMultipartPar } func (n *Layer) UploadPart(ctx context.Context, p *UploadPartParams) (string, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.UploadPart") + defer span.End() + multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID) if err != nil { if errors.Is(err, tree.ErrNodeNotFound) { @@ -334,6 +341,9 @@ func (n *Layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf } func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data.ObjectInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.UploadPartCopy") + defer span.End() + multipartInfo, err := n.treeService.GetMultipartUpload(ctx, p.Info.Bkt, p.Info.Key, p.Info.UploadID) if err != nil { if errors.Is(err, tree.ErrNodeNotFound) { @@ -382,6 +392,9 @@ func (n *Layer) UploadPartCopy(ctx context.Context, p *UploadCopyParams) (*data. } func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipartParams) (*UploadData, *data.ExtendedObjectInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.CompleteMultipartUpload") + defer span.End() + for i := 1; i < len(p.Parts); i++ { if p.Parts[i].PartNumber <= p.Parts[i-1].PartNumber { return nil, nil, apierr.GetAPIError(apierr.ErrInvalidPartOrder) @@ -502,6 +515,9 @@ func (n *Layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar } func (n *Layer) ListMultipartUploads(ctx context.Context, p *ListMultipartUploadsParams) (*ListMultipartUploadsInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListMultipartUploads") + defer span.End() + var result ListMultipartUploadsInfo if p.MaxUploads == 0 { return &result, nil @@ -562,6 +578,9 @@ func (n *Layer) ListMultipartUploads(ctx context.Context, p *ListMultipartUpload } func (n *Layer) AbortMultipartUpload(ctx context.Context, p *UploadInfoParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.AbortMultipartUpload") + defer span.End() + multipartInfo, parts, err := n.getUploadParts(ctx, p) if err != nil { return err @@ -599,6 +618,9 @@ func (n *Layer) deleteUploadedParts(ctx context.Context, bkt *data.BucketInfo, p } func (n *Layer) ListParts(ctx context.Context, p *ListPartsParams) (*ListPartsInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.ListParts") + defer span.End() + var res ListPartsInfo multipartInfo, partsInfo, err := n.getUploadParts(ctx, p.Info) if err != nil { diff --git a/api/layer/object.go b/api/layer/object.go index 571a120e..f22a5e07 100644 --- a/api/layer/object.go +++ b/api/layer/object.go @@ -17,6 +17,7 @@ import ( "strconv" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" @@ -227,6 +228,9 @@ func ParseCompletedPartHeader(hdr string) (*Part, error) { // PutObject stores object into FrostFS, took payload from io.Reader. func (n *Layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.ExtendedObjectInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutObject") + defer span.End() + bktSettings, err := n.GetBucketSettings(ctx, p.BktInfo) if err != nil { return nil, fmt.Errorf("couldn't get versioning settings object: %w", err) diff --git a/api/layer/patch.go b/api/layer/patch.go index fca21427..def74c1c 100644 --- a/api/layer/patch.go +++ b/api/layer/patch.go @@ -10,6 +10,7 @@ import ( "strconv" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" @@ -25,6 +26,9 @@ type PatchObjectParams struct { } func (n *Layer) PatchObject(ctx context.Context, p *PatchObjectParams) (*data.ExtendedObjectInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PatchObject") + defer span.End() + if p.Object.ObjectInfo.Headers[AttributeDecryptedSize] != "" { return nil, fmt.Errorf("patch encrypted object") } diff --git a/api/layer/system_object.go b/api/layer/system_object.go index 4f7f40ec..0e44ca7a 100644 --- a/api/layer/system_object.go +++ b/api/layer/system_object.go @@ -10,6 +10,7 @@ import ( "strconv" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" @@ -32,6 +33,9 @@ type PutLockInfoParams struct { } func (n *Layer) PutLockInfo(ctx context.Context, p *PutLockInfoParams) (err error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutLockInfo") + defer span.End() + newLock := p.NewLock versionNode := p.NodeVersion // sometimes node version can be provided from executing context @@ -139,6 +143,9 @@ func (n *Layer) putLockObject(ctx context.Context, bktInfo *data.BucketInfo, obj } func (n *Layer) GetLockInfo(ctx context.Context, objVersion *data.ObjectVersion) (*data.LockInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetLockInfo") + defer span.End() + owner := n.BearerOwner(ctx) if lockInfo := n.cache.GetLockInfo(owner, lockObjectKey(objVersion)); lockInfo != nil { return lockInfo, nil @@ -206,6 +213,9 @@ func lockObjectKey(objVersion *data.ObjectVersion) string { } func (n *Layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketSettings") + defer span.End() + owner := n.BearerOwner(ctx) if settings := n.cache.GetSettings(owner, bktInfo); settings != nil { return settings, nil @@ -226,6 +236,9 @@ func (n *Layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo) } func (n *Layer) PutBucketSettings(ctx context.Context, p *PutSettingsParams) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketSettings") + defer span.End() + if err := n.treeService.PutSettingsNode(ctx, p.BktInfo, p.Settings); err != nil { return fmt.Errorf("failed to get settings node: %w", err) } diff --git a/api/layer/tagging.go b/api/layer/tagging.go index a80e72b4..a8eaed33 100644 --- a/api/layer/tagging.go +++ b/api/layer/tagging.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" @@ -16,6 +17,9 @@ import ( ) func (n *Layer) GetObjectTagging(ctx context.Context, p *data.GetObjectTaggingParams) (string, map[string]string, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetObjectTagging") + defer span.End() + var err error owner := n.BearerOwner(ctx) @@ -52,6 +56,9 @@ func (n *Layer) GetObjectTagging(ctx context.Context, p *data.GetObjectTaggingPa } func (n *Layer) PutObjectTagging(ctx context.Context, p *data.PutObjectTaggingParams) (err error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutObjectTagging") + defer span.End() + nodeVersion := p.NodeVersion if nodeVersion == nil { nodeVersion, err = n.getNodeVersionFromCacheOrFrostfs(ctx, p.ObjectVersion) @@ -75,6 +82,9 @@ func (n *Layer) PutObjectTagging(ctx context.Context, p *data.PutObjectTaggingPa } func (n *Layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectVersion) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteObjectTagging") + defer span.End() + version, err := n.getNodeVersion(ctx, p) if err != nil { return err @@ -96,6 +106,9 @@ func (n *Layer) DeleteObjectTagging(ctx context.Context, p *data.ObjectVersion) } func (n *Layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.GetBucketTagging") + defer span.End() + owner := n.BearerOwner(ctx) if tags := n.cache.GetTagging(owner, bucketTaggingCacheKey(bktInfo.CID)); tags != nil { @@ -113,6 +126,9 @@ func (n *Layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) } func (n *Layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.PutBucketTagging") + defer span.End() + if err := n.treeService.PutBucketTagging(ctx, bktInfo, tagSet); err != nil { return err } @@ -123,6 +139,9 @@ func (n *Layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, } func (n *Layer) DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "layer.DeleteBucketTagging") + defer span.End() + n.cache.DeleteTagging(bucketTaggingCacheKey(bktInfo.CID)) return n.treeService.DeleteBucketTagging(ctx, bktInfo) diff --git a/api/middleware/auth.go b/api/middleware/auth.go index 2d9a91f5..833f3792 100644 --- a/api/middleware/auth.go +++ b/api/middleware/auth.go @@ -1,12 +1,14 @@ package middleware import ( + "context" "crypto/elliptic" "errors" "fmt" "net/http" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" @@ -30,7 +32,9 @@ type ( Center interface { // Authenticate validate and authenticate request. // Must return ErrNoAuthorizationHeader if auth header is missed. - Authenticate(request *http.Request) (*Box, error) + // Authenticate uses a separate context so that the authorization + // span middleware does not contain all subsequent spans. + Authenticate(ctx context.Context, request *http.Request) (*Box, error) } //nolint:revive @@ -47,34 +51,38 @@ var ErrNoAuthorizationHeader = errors.New("no authorization header") func Auth(center Center, log *zap.Logger) Func { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - reqInfo := GetReqInfo(ctx) + reqCtx := r.Context() + ctx, span := tracing.StartSpanFromContext(reqCtx, "middleware.Auth") + + reqInfo := GetReqInfo(reqCtx) reqInfo.User = "anon" - box, err := center.Authenticate(r) + box, err := center.Authenticate(ctx, r) if err != nil { if errors.Is(err, ErrNoAuthorizationHeader) { - reqLogOrDefault(ctx, log).Debug(logs.CouldntReceiveAccessBoxForGateKeyRandomKeyWillBeUsed, zap.Error(err)) + reqLogOrDefault(reqCtx, log).Debug(logs.CouldntReceiveAccessBoxForGateKeyRandomKeyWillBeUsed, zap.Error(err)) } else { - reqLogOrDefault(ctx, log).Error(logs.FailedToPassAuthentication, zap.Error(err)) + reqLogOrDefault(reqCtx, log).Error(logs.FailedToPassAuthentication, zap.Error(err)) err = apierr.TransformToS3Error(err) if err.(apierr.Error).ErrCode == apierr.ErrInternalError { err = apierr.GetAPIError(apierr.ErrAccessDenied) } if _, wrErr := WriteErrorResponse(w, GetReqInfo(r.Context()), err); wrErr != nil { - reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr)) + reqLogOrDefault(reqCtx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr)) } + span.End() return } } else { - ctx = SetBox(ctx, box) + reqCtx = SetBox(reqCtx, box) if box.AccessBox.Gate.BearerToken != nil { reqInfo.User = bearer.ResolveIssuer(*box.AccessBox.Gate.BearerToken).String() } - reqLogOrDefault(ctx, log).Debug(logs.SuccessfulAuth, zap.String("accessKeyID", box.AuthHeaders.AccessKeyID)) + reqLogOrDefault(reqCtx, log).Debug(logs.SuccessfulAuth, zap.String("accessKeyID", box.AuthHeaders.AccessKeyID)) } - h.ServeHTTP(w, r.WithContext(ctx)) + span.End() + h.ServeHTTP(w, r.WithContext(reqCtx)) }) } } @@ -86,22 +94,26 @@ type FrostFSIDValidator interface { func FrostfsIDValidation(frostfsID FrostFSIDValidator, log *zap.Logger) Func { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + ctx, span := tracing.StartSpanFromContext(r.Context(), "middleware.FrostfsIDValidation") + bd, err := GetBoxData(ctx) if err != nil || bd.Gate.BearerToken == nil { reqLogOrDefault(ctx, log).Debug(logs.AnonRequestSkipFrostfsIDValidation) + span.End() h.ServeHTTP(w, r) return } if err = validateBearerToken(frostfsID, bd.Gate.BearerToken); err != nil { reqLogOrDefault(ctx, log).Error(logs.FrostfsIDValidationFailed, zap.Error(err)) - if _, wrErr := WriteErrorResponse(w, GetReqInfo(r.Context()), err); wrErr != nil { + if _, wrErr := WriteErrorResponse(w, GetReqInfo(ctx), err); wrErr != nil { reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr)) } + span.End() return } + span.End() h.ServeHTTP(w, r) }) } diff --git a/api/middleware/policy.go b/api/middleware/policy.go index 07340833..612a7d9e 100644 --- a/api/middleware/policy.go +++ b/api/middleware/policy.go @@ -10,6 +10,7 @@ import ( "net/url" "strings" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" apierr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" @@ -88,32 +89,35 @@ type PolicyConfig struct { func PolicyCheck(cfg PolicyConfig) Func { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - if err := policyCheck(r, cfg); err != nil { + ctx, span := tracing.StartSpanFromContext(r.Context(), "middleware.PolicyCheck") + + if err := policyCheck(ctx, r, cfg); err != nil { reqLogOrDefault(ctx, cfg.Log).Error(logs.PolicyValidationFailed, zap.Error(err)) err = apierr.TransformToS3Error(err) if _, wrErr := WriteErrorResponse(w, GetReqInfo(ctx), err); wrErr != nil { reqLogOrDefault(ctx, cfg.Log).Error(logs.FailedToWriteResponse, zap.Error(wrErr)) } + span.End() return } + span.End() h.ServeHTTP(w, r) }) } } -func policyCheck(r *http.Request, cfg PolicyConfig) error { - reqInfo := GetReqInfo(r.Context()) +func policyCheck(ctx context.Context, r *http.Request, cfg PolicyConfig) error { + reqInfo := GetReqInfo(ctx) - req, userKey, userGroups, err := getPolicyRequest(r, cfg, reqInfo.RequestType, reqInfo.BucketName, reqInfo.ObjectName) + req, userKey, userGroups, err := getPolicyRequest(ctx, r, cfg, reqInfo.RequestType, reqInfo.BucketName, reqInfo.ObjectName) if err != nil { return err } var bktInfo *data.BucketInfo if reqInfo.RequestType != noneType && !strings.HasSuffix(req.Operation(), CreateBucketOperation) { - bktInfo, err = cfg.BucketResolver(r.Context(), reqInfo.BucketName) + bktInfo, err = cfg.BucketResolver(ctx, reqInfo.BucketName) if err != nil { return err } @@ -161,7 +165,7 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error { return nil } -func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktName string, objName string) (*testutil.Request, *keys.PublicKey, []string, error) { +func getPolicyRequest(ctx context.Context, r *http.Request, cfg PolicyConfig, reqType ReqType, bktName string, objName string) (*testutil.Request, *keys.PublicKey, []string, error) { var ( owner string groups []string @@ -169,8 +173,8 @@ func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktNam pk *keys.PublicKey ) - ctx := r.Context() - bd, err := GetBoxData(ctx) + reqCtx := r.Context() + bd, err := GetBoxData(reqCtx) if err == nil && bd.Gate.BearerToken != nil { pk, err = keys.NewPublicKeyFromBytes(bd.Gate.BearerToken.SigningKeyBytes(), elliptic.P256()) if err != nil { @@ -193,7 +197,7 @@ func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktNam res = fmt.Sprintf(s3.ResourceFormatS3Bucket, bktName) } - requestProps, resourceProps, err := determineProperties(r, cfg.Decoder, cfg.BucketResolver, cfg.Tagging, reqType, op, bktName, objName, owner, groups, tags) + requestProps, resourceProps, err := determineProperties(ctx, r, cfg.Decoder, cfg.BucketResolver, cfg.Tagging, reqType, op, bktName, objName, owner, groups, tags) if err != nil { return nil, nil, nil, fmt.Errorf("determine properties: %w", err) } @@ -418,7 +422,7 @@ func determineGeneralOperation(r *http.Request) string { return "UnmatchedOperation" } -func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketResolveFunc, tagging ResourceTagging, reqType ReqType, +func determineProperties(ctx context.Context, r *http.Request, decoder XMLDecoder, resolver BucketResolveFunc, tagging ResourceTagging, reqType ReqType, op, bktName, objName, owner string, groups []string, userClaims map[string]string) (requestProperties map[string]string, resourceProperties map[string]string, err error) { requestProperties = map[string]string{ s3.PropertyKeyOwner: owner, @@ -466,7 +470,7 @@ func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketRes requestProperties[k] = v } - resourceProperties, err = determineResourceTags(r.Context(), reqType, op, bktName, objName, queries.Get(QueryVersionID), resolver, tagging) + resourceProperties, err = determineResourceTags(ctx, reqType, op, bktName, objName, queries.Get(QueryVersionID), resolver, tagging) if err != nil { return nil, nil, fmt.Errorf("determine resource tags: %w", err) } diff --git a/api/router_mock_test.go b/api/router_mock_test.go index 4c4bb828..5d1320ec 100644 --- a/api/router_mock_test.go +++ b/api/router_mock_test.go @@ -45,7 +45,7 @@ type centerMock struct { key *keys.PrivateKey } -func (c *centerMock) Authenticate(*http.Request) (*middleware.Box, error) { +func (c *centerMock) Authenticate(context.Context, *http.Request) (*middleware.Box, error) { if c.noAuthHeader { return nil, middleware.ErrNoAuthorizationHeader } diff --git a/go.mod b/go.mod index e44194fb..b7f9daf3 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22 require ( git.frostfs.info/TrueCloudLab/frostfs-contract v0.20.1-0.20241022094040-5f956751d48b - git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88 + git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241125133852-37bd75821121 git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20241218062344-42a0fc8c13ae git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972 git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240822104152-a3bc3099bd5b diff --git a/go.sum b/go.sum index 7fb8068a..21cf4b7d 100644 --- a/go.sum +++ b/go.sum @@ -40,10 +40,10 @@ git.frostfs.info/TrueCloudLab/frostfs-contract v0.20.1-0.20241022094040-5f956751 git.frostfs.info/TrueCloudLab/frostfs-contract v0.20.1-0.20241022094040-5f956751d48b/go.mod h1:5fSm/l5xSjGWqsPUffSdboiGFUHa7y/1S0fvxzQowN8= git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 h1:FxqFDhQYYgpe41qsIHVOcdzSVCB8JNSfPG7Uk4r2oSk= git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0/go.mod h1:RUIKZATQLJ+TaYQa60X2fTDwfuhMfm8Ar60bQ5fr+vU= -git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88 h1:9bvBDLApbbO5sXBKdODpE9tzy3HV99nXxkDWNn22rdI= -git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241112082307-f17779933e88/go.mod h1:kbwB4v2o6RyOfCo9kEFeUDZIX3LKhmS0yXPrtvzkQ1g= git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20241218062344-42a0fc8c13ae h1:7gvuOTmS3oaOM79JkHWWlsvGqIRqsum5KnOI1TYqfn0= git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20241218062344-42a0fc8c13ae/go.mod h1:dbWUc5jOBTXVvssCLCYxkkSTL9jgLr1KruGP2FMAfiM= +git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241125133852-37bd75821121 h1:/Z8DfbLZXp7exUQWUKoG/9tbFdI9d5lV1qSReaYoG8I= +git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20241125133852-37bd75821121/go.mod h1:kbwB4v2o6RyOfCo9kEFeUDZIX3LKhmS0yXPrtvzkQ1g= git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc= git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM= git.frostfs.info/TrueCloudLab/multinet v0.0.0-20241015075604-6cb0d80e0972 h1:/960fWeyn2AFHwQUwDsWB3sbP6lTEnFnMzLMM6tx6N8= diff --git a/internal/frostfs/frostfs.go b/internal/frostfs/frostfs.go index ffe75299..6dea51cf 100644 --- a/internal/frostfs/frostfs.go +++ b/internal/frostfs/frostfs.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" frosterr "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util" @@ -57,6 +58,9 @@ func NewFrostFS(p *pool.Pool, key *keys.PrivateKey) *FrostFS { // TimeToEpoch implements layer.FrostFS interface method. func (x *FrostFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (uint64, uint64, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.TimeToEpoch") + defer span.End() + if futureTime.Before(now) { return 0, 0, fmt.Errorf("time '%s' must be in the future (after %s)", futureTime.Format(time.RFC3339), now.Format(time.RFC3339)) @@ -77,6 +81,9 @@ func (x *FrostFS) TimeToEpoch(ctx context.Context, now, futureTime time.Time) (u // Container implements layer.FrostFS interface method. func (x *FrostFS) Container(ctx context.Context, layerPrm frostfs.PrmContainer) (*container.Container, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.Container") + defer span.End() + prm := pool.PrmContainerGet{ ContainerID: layerPrm.ContainerID, Session: layerPrm.SessionToken, @@ -92,6 +99,9 @@ func (x *FrostFS) Container(ctx context.Context, layerPrm frostfs.PrmContainer) // CreateContainer implements layer.FrostFS interface method. func (x *FrostFS) CreateContainer(ctx context.Context, prm frostfs.PrmContainerCreate) (*frostfs.ContainerCreateResult, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.CreateContainer") + defer span.End() + var cnr container.Container cnr.Init() cnr.SetPlacementPolicy(prm.Policy) @@ -139,6 +149,9 @@ func (x *FrostFS) CreateContainer(ctx context.Context, prm frostfs.PrmContainerC // AddContainerPolicyChain implements frostfs.FrostFS interface method. func (x *FrostFS) AddContainerPolicyChain(ctx context.Context, prm frostfs.PrmAddContainerPolicyChain) error { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.AddContainerPolicyChain") + defer span.End() + data, err := prm.Chain.MarshalBinary() if err != nil { return err @@ -158,6 +171,9 @@ func (x *FrostFS) AddContainerPolicyChain(ctx context.Context, prm frostfs.PrmAd // UserContainers implements layer.FrostFS interface method. func (x *FrostFS) UserContainers(ctx context.Context, layerPrm frostfs.PrmUserContainers) ([]cid.ID, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.UserContainers") + defer span.End() + prm := pool.PrmContainerList{ OwnerID: layerPrm.UserID, Session: layerPrm.SessionToken, @@ -169,6 +185,9 @@ func (x *FrostFS) UserContainers(ctx context.Context, layerPrm frostfs.PrmUserCo // DeleteContainer implements layer.FrostFS interface method. func (x *FrostFS) DeleteContainer(ctx context.Context, id cid.ID, token *session.Container) error { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.DeleteContainer") + defer span.End() + prm := pool.PrmContainerDelete{ContainerID: id, Session: token, WaitParams: &x.await} err := x.pool.DeleteContainer(ctx, prm) @@ -177,6 +196,9 @@ func (x *FrostFS) DeleteContainer(ctx context.Context, id cid.ID, token *session // CreateObject implements layer.FrostFS interface method. func (x *FrostFS) CreateObject(ctx context.Context, prm frostfs.PrmObjectCreate) (*frostfs.CreateObjectResult, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.CreateObject") + defer span.End() + attrNum := len(prm.Attributes) + 1 // + creation time if prm.Filepath != "" { @@ -271,6 +293,9 @@ func (x payloadReader) Read(p []byte) (int, error) { // HeadObject implements layer.FrostFS interface method. func (x *FrostFS) HeadObject(ctx context.Context, prm frostfs.PrmObjectHead) (*object.Object, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.HeadObject") + defer span.End() + var addr oid.Address addr.SetContainer(prm.Container) addr.SetObject(prm.Object) @@ -294,6 +319,9 @@ func (x *FrostFS) HeadObject(ctx context.Context, prm frostfs.PrmObjectHead) (*o // GetObject implements layer.FrostFS interface method. func (x *FrostFS) GetObject(ctx context.Context, prm frostfs.PrmObjectGet) (*frostfs.Object, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.GetObject") + defer span.End() + var addr oid.Address addr.SetContainer(prm.Container) addr.SetObject(prm.Object) @@ -320,6 +348,9 @@ func (x *FrostFS) GetObject(ctx context.Context, prm frostfs.PrmObjectGet) (*fro // RangeObject implements layer.FrostFS interface method. func (x *FrostFS) RangeObject(ctx context.Context, prm frostfs.PrmObjectRange) (io.ReadCloser, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.RangeObject") + defer span.End() + var addr oid.Address addr.SetContainer(prm.Container) addr.SetObject(prm.Object) @@ -345,6 +376,9 @@ func (x *FrostFS) RangeObject(ctx context.Context, prm frostfs.PrmObjectRange) ( // DeleteObject implements layer.FrostFS interface method. func (x *FrostFS) DeleteObject(ctx context.Context, prm frostfs.PrmObjectDelete) error { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.DeleteObject") + defer span.End() + var addr oid.Address addr.SetContainer(prm.Container) addr.SetObject(prm.Object) @@ -364,6 +398,9 @@ func (x *FrostFS) DeleteObject(ctx context.Context, prm frostfs.PrmObjectDelete) // SearchObjects implements layer.FrostFS interface method. func (x *FrostFS) SearchObjects(ctx context.Context, prm frostfs.PrmObjectSearch) ([]oid.ID, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.SearchObjects") + defer span.End() + filters := object.NewSearchFilters() filters.AddRootFilter() @@ -401,6 +438,9 @@ func (x *FrostFS) SearchObjects(ctx context.Context, prm frostfs.PrmObjectSearch // NetworkInfo implements layer.FrostFS interface method. func (x *FrostFS) NetworkInfo(ctx context.Context) (netmap.NetworkInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.NetworkInfo") + defer span.End() + ni, err := x.pool.NetworkInfo(ctx) if err != nil { return ni, handleObjectError("get network info via connection pool", err) @@ -419,6 +459,9 @@ func (x *FrostFS) NetmapSnapshot(ctx context.Context) (netmap.NetMap, error) { } func (x *FrostFS) PatchObject(ctx context.Context, prm frostfs.PrmObjectPatch) (oid.ID, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.PatchObject") + defer span.End() + var addr oid.Address addr.SetContainer(prm.Container) addr.SetObject(prm.Object) @@ -467,6 +510,9 @@ func NewResolverFrostFS(p *pool.Pool) *ResolverFrostFS { // SystemDNS implements resolver.FrostFS interface method. func (x *ResolverFrostFS) SystemDNS(ctx context.Context) (string, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "frostfs.SystemDNS") + defer span.End() + networkInfo, err := x.pool.NetworkInfo(ctx) if err != nil { return "", handleObjectError("read network info via client", err) diff --git a/pkg/service/tree/tree.go b/pkg/service/tree/tree.go index 862c0a3c..2979dade 100644 --- a/pkg/service/tree/tree.go +++ b/pkg/service/tree/tree.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/frostfs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer/tree" @@ -493,6 +494,9 @@ func newPartInfo(node NodeResponse) (*data.PartInfoExtended, error) { } func (c *Tree) GetSettingsNode(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetSettingsNode") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, settingsFileName) if err != nil { return nil, fmt.Errorf("couldn't get node: %w", err) @@ -523,6 +527,9 @@ func (c *Tree) GetSettingsNode(ctx context.Context, bktInfo *data.BucketInfo) (* } func (c *Tree) PutSettingsNode(ctx context.Context, bktInfo *data.BucketInfo, settings *data.BucketSettings) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutSettingsNode") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, settingsFileName) isErrNotFound := errors.Is(err, tree.ErrNodeNotFound) if err != nil && !isErrNotFound { @@ -552,6 +559,9 @@ func (c *Tree) PutSettingsNode(ctx context.Context, bktInfo *data.BucketInfo, se } func (c *Tree) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid.Address, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetBucketCORS") + defer span.End() + node, err := c.getSystemNode(ctx, bktInfo, corsFilename) if err != nil { return oid.Address{}, err @@ -561,6 +571,9 @@ func (c *Tree) GetBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) (oid } func (c *Tree) PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, addr oid.Address) ([]oid.Address, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutBucketCORS") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, corsFilename) isErrNotFound := errors.Is(err, tree.ErrNodeNotFound) if err != nil && !isErrNotFound { @@ -601,6 +614,9 @@ func (c *Tree) PutBucketCORS(ctx context.Context, bktInfo *data.BucketInfo, addr } func (c *Tree) DeleteBucketCORS(ctx context.Context, bktInfo *data.BucketInfo) ([]oid.Address, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteBucketCORS") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, corsFilename) isErrNotFound := errors.Is(err, tree.ErrNodeNotFound) if err != nil && !isErrNotFound { @@ -658,6 +674,9 @@ func (c *Tree) cleanOldNodes(ctx context.Context, nodes []*treeNode, bktInfo *da } func (c *Tree) GetObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion) (map[string]string, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetObjectTagging") + defer span.End() + tagNode, err := c.getTreeNode(ctx, bktInfo, objVersion.ID, isTagKV) if err != nil { return nil, err @@ -683,6 +702,9 @@ func getObjectTagging(tagNode *treeNode) map[string]string { } func (c *Tree) PutObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion, tagSet map[string]string) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutObjectTagging") + defer span.End() + tagNode, err := c.getTreeNode(ctx, bktInfo, objVersion.ID, isTagKV) if err != nil { return err @@ -709,10 +731,16 @@ func (c *Tree) PutObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, o } func (c *Tree) DeleteObjectTagging(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteObjectTagging") + defer span.End() + return c.PutObjectTagging(ctx, bktInfo, objVersion, nil) } func (c *Tree) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetBucketTagging") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, bucketTaggingFilename) if err != nil { return nil, err @@ -730,6 +758,9 @@ func (c *Tree) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) ( } func (c *Tree) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, tagSet map[string]string) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutBucketTagging") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, bucketTaggingFilename) isErrNotFound := errors.Is(err, tree.ErrNodeNotFound) if err != nil && !isErrNotFound { @@ -764,6 +795,9 @@ func (c *Tree) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo, t } func (c *Tree) DeleteBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteBucketTagging") + defer span.End() + return c.PutBucketTagging(ctx, bktInfo, nil) } @@ -807,10 +841,16 @@ func (c *Tree) getTreeNodes(ctx context.Context, bktInfo *data.BucketInfo, nodeI } func (c *Tree) GetVersions(ctx context.Context, bktInfo *data.BucketInfo, filepath string) ([]*data.NodeVersion, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetVersions") + defer span.End() + return c.getVersions(ctx, bktInfo, versionTree, filepath, false) } func (c *Tree) GetLatestVersion(ctx context.Context, bktInfo *data.BucketInfo, objectName string) (*data.NodeVersion, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetLatestVersion") + defer span.End() + meta := []string{oidKV, isCombinedKV, isUnversionedKV, isDeleteMarkerKV, etagKV, sizeKV, md5KV, creationEpochKV} path := pathFromName(objectName) @@ -1080,6 +1120,9 @@ func (s *VersionsByPrefixStreamImpl) parseNodeResponse(node NodeResponse) (res * } func (c *Tree) InitVersionsByPrefixStream(ctx context.Context, bktInfo *data.BucketInfo, prefix string, latestOnly bool) (data.VersionsStream, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.InitVersionsByPrefixStream") + defer span.End() + mainStream, tailPrefix, rootID, err := c.getSubTreeByPrefixMainStream(ctx, bktInfo, versionTree, prefix) if err != nil { if errors.Is(err, io.EOF) { @@ -1272,6 +1315,9 @@ func formLatestNodeKey(parentID uint64, fileName string) string { } func (c *Tree) GetUnversioned(ctx context.Context, bktInfo *data.BucketInfo, filepath string) (*data.NodeVersion, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetUnversioned") + defer span.End() + return c.getUnversioned(ctx, bktInfo, versionTree, filepath) } @@ -1298,14 +1344,23 @@ func (c *Tree) getUnversioned(ctx context.Context, bktInfo *data.BucketInfo, tre } func (c *Tree) AddVersion(ctx context.Context, bktInfo *data.BucketInfo, version *data.NodeVersion) (uint64, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.AddVersion") + defer span.End() + return c.addVersion(ctx, bktInfo, versionTree, version) } func (c *Tree) RemoveVersion(ctx context.Context, bktInfo *data.BucketInfo, id uint64) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.RemoveVersion") + defer span.End() + return c.service.RemoveNode(ctx, bktInfo, versionTree, id) } func (c *Tree) CreateMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, info *data.MultipartInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.CreateMultipartUpload") + defer span.End() + path := pathFromName(info.Key) meta := metaFromMultipart(info, path[len(path)-1]) _, err := c.service.AddNodeByPath(ctx, bktInfo, systemTree, path[:len(path)-1], meta) @@ -1314,6 +1369,9 @@ func (c *Tree) CreateMultipartUpload(ctx context.Context, bktInfo *data.BucketIn } func (c *Tree) GetMultipartUploadsByPrefix(ctx context.Context, bktInfo *data.BucketInfo, prefix string) ([]*data.MultipartInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetMultipartUploadsByPrefix") + defer span.End() + subTreeNodes, headPrefix, err := c.getSubTreeByPrefix(ctx, bktInfo, systemTree, prefix, false) if err != nil { return nil, err @@ -1394,6 +1452,9 @@ func (c *Tree) getSubTreeMultipartUploads(ctx context.Context, bktInfo *data.Buc } func (c *Tree) GetMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, objectName, uploadID string) (*data.MultipartInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetMultipartUpload") + defer span.End() + path := pathFromName(objectName) p := &GetNodesParams{ BktInfo: bktInfo, @@ -1425,6 +1486,9 @@ func (c *Tree) GetMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, } func (c *Tree) AddPart(ctx context.Context, bktInfo *data.BucketInfo, multipartNodeID uint64, info *data.PartInfo) (oldObjIDsToDelete []oid.ID, err error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.AddPart") + defer span.End() + parts, err := c.service.GetSubTree(ctx, bktInfo, systemTree, []uint64{multipartNodeID}, 2, false) if err != nil { return nil, err @@ -1503,6 +1567,9 @@ func (c *Tree) AddPart(ctx context.Context, bktInfo *data.BucketInfo, multipartN } func (c *Tree) GetParts(ctx context.Context, bktInfo *data.BucketInfo, multipartNodeID uint64) ([]*data.PartInfoExtended, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetParts") + defer span.End() + parts, err := c.service.GetSubTree(ctx, bktInfo, systemTree, []uint64{multipartNodeID}, 2, false) if err != nil { return nil, err @@ -1535,6 +1602,9 @@ func (c *Tree) GetParts(ctx context.Context, bktInfo *data.BucketInfo, multipart } func (c *Tree) PutBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo, addr oid.Address) ([]oid.Address, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutBucketLifecycleConfiguration") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, bucketLifecycleFilename) isErrNotFound := errors.Is(err, tree.ErrNodeNotFound) if err != nil && !isErrNotFound { @@ -1575,6 +1645,9 @@ func (c *Tree) PutBucketLifecycleConfiguration(ctx context.Context, bktInfo *dat } func (c *Tree) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) (oid.Address, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetBucketLifecycleConfiguration") + defer span.End() + node, err := c.getSystemNode(ctx, bktInfo, bucketLifecycleFilename) if err != nil { return oid.Address{}, fmt.Errorf("get lifecycle node: %w", err) @@ -1584,6 +1657,9 @@ func (c *Tree) GetBucketLifecycleConfiguration(ctx context.Context, bktInfo *dat } func (c *Tree) DeleteBucketLifecycleConfiguration(ctx context.Context, bktInfo *data.BucketInfo) ([]oid.Address, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteBucketLifecycleConfiguration") + defer span.End() + multiNode, err := c.getSystemNode(ctx, bktInfo, bucketLifecycleFilename) isErrNotFound := errors.Is(err, tree.ErrNodeNotFound) if err != nil && !isErrNotFound { @@ -1603,6 +1679,9 @@ func (c *Tree) DeleteBucketLifecycleConfiguration(ctx context.Context, bktInfo * } func (c *Tree) DeleteMultipartUpload(ctx context.Context, bktInfo *data.BucketInfo, multipartInfo *data.MultipartInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.DeleteMultipartUpload") + defer span.End() + err := c.service.RemoveNode(ctx, bktInfo, systemTree, multipartInfo.ID) if err != nil { return err @@ -1614,6 +1693,9 @@ func (c *Tree) DeleteMultipartUpload(ctx context.Context, bktInfo *data.BucketIn } func (c *Tree) PutLock(ctx context.Context, bktInfo *data.BucketInfo, nodeID uint64, lock *data.LockInfo) error { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.PutLock") + defer span.End() + meta := map[string]string{isLockKV: "true"} if lock.IsLegalHoldSet() { @@ -1636,6 +1718,9 @@ func (c *Tree) PutLock(ctx context.Context, bktInfo *data.BucketInfo, nodeID uin } func (c *Tree) GetLock(ctx context.Context, bktInfo *data.BucketInfo, nodeID uint64) (*data.LockInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetLock") + defer span.End() + lockNode, err := c.getTreeNode(ctx, bktInfo, nodeID, isLockKV) if err != nil { return nil, err @@ -1675,6 +1760,9 @@ func getLock(lockNode *treeNode) (*data.LockInfo, error) { } func (c *Tree) GetObjectTaggingAndLock(ctx context.Context, bktInfo *data.BucketInfo, objVersion *data.NodeVersion) (map[string]string, *data.LockInfo, error) { + ctx, span := tracing.StartSpanFromContext(ctx, "tree.GetObjectTaggingAndLock") + defer span.End() + nodes, err := c.getTreeNodes(ctx, bktInfo, objVersion.ID, isTagKV, isLockKV) if err != nil { return nil, nil, err