From 066b9a025097dfb3818e1dd583d5b76c560345e6 Mon Sep 17 00:00:00 2001 From: Marina Biryukova Date: Tue, 29 Aug 2023 12:27:50 +0300 Subject: [PATCH] [#142] Add trace ID into log when tracing is enabled Signed-off-by: Marina Biryukova --- CHANGELOG.md | 1 + api/handler/get_test.go | 10 ++++------ api/handler/util.go | 7 +++++++ api/middleware/reqinfo.go | 1 + api/middleware/response.go | 11 ++++++++--- api/middleware/tracing.go | 2 ++ 6 files changed, 23 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd4b46e..3cb3bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This document outlines major changes between releases. - Use correct keys in `list-multipart-uploads` response (#185) ### Added +- Add `trace_id` value into log record when tracing is enabled (#142) - Add basic error types and exit codes to `frostfs-s3-authmate` (#152) - Add a metric with addresses of nodes of the same and highest priority that are currently healthy (#51) - Support dump metrics descriptions (#80) diff --git a/api/handler/get_test.go b/api/handler/get_test.go index 78c0fbc..2bbaeda 100644 --- a/api/handler/get_test.go +++ b/api/handler/get_test.go @@ -14,8 +14,6 @@ import ( "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" - apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" - s3errors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" "github.com/stretchr/testify/require" @@ -195,8 +193,8 @@ func TestGetObject(t *testing.T) { hc.tp.SetObjectError(addr, &apistatus.ObjectNotFound{}) hc.tp.SetObjectError(objInfo.Address(), &apistatus.ObjectNotFound{}) - getObjectAssertS3Error(hc, bktName, objName, objInfo.VersionID(), s3errors.ErrNoSuchVersion) - getObjectAssertS3Error(hc, bktName, objName, emptyVersion, s3errors.ErrNoSuchKey) + getObjectAssertS3Error(hc, bktName, objName, objInfo.VersionID(), errors.ErrNoSuchVersion) + getObjectAssertS3Error(hc, bktName, objName, emptyVersion, errors.ErrNoSuchKey) } func putObjectContent(hc *handlerContext, bktName, objName, content string) { @@ -216,9 +214,9 @@ func getObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, s return content } -func getObjectAssertS3Error(hc *handlerContext, bktName, objName, version string, code apiErrors.ErrorCode) { +func getObjectAssertS3Error(hc *handlerContext, bktName, objName, version string, code errors.ErrorCode) { w := getObjectBaseResponse(hc, bktName, objName, version) - assertS3Error(hc.t, w, apiErrors.GetAPIError(code)) + assertS3Error(hc.t, w, errors.GetAPIError(code)) } func getObjectBaseResponse(hc *handlerContext, bktName, objName, version string) *httptest.ResponseRecorder { diff --git a/api/handler/util.go b/api/handler/util.go index 3cd91cb..d2a0b78 100644 --- a/api/handler/util.go +++ b/api/handler/util.go @@ -15,6 +15,7 @@ import ( frosterrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" ) @@ -37,6 +38,9 @@ func (h *handler) logAndSendError(w http.ResponseWriter, logText string, reqInfo zap.String("description", logText), zap.Error(err)} fields = append(fields, additional...) + if traceID, err := trace.TraceIDFromHex(reqInfo.TraceID); err == nil && traceID.IsValid() { + fields = append(fields, zap.String("trace_id", reqInfo.TraceID)) + } h.log.Error(logs.RequestFailed, fields...) // consider using h.reqLogger (it requires accept context.Context or http.Request) } @@ -50,6 +54,9 @@ func (h *handler) logAndSendErrorNoHeader(w http.ResponseWriter, logText string, zap.String("description", logText), zap.Error(err)} fields = append(fields, additional...) + if traceID, err := trace.TraceIDFromHex(reqInfo.TraceID); err == nil && traceID.IsValid() { + fields = append(fields, zap.String("trace_id", reqInfo.TraceID)) + } h.log.Error(logs.RequestFailed, fields...) // consider using h.reqLogger (it requires accept context.Context or http.Request) } diff --git a/api/middleware/reqinfo.go b/api/middleware/reqinfo.go index 5cb2dd5..0388dca 100644 --- a/api/middleware/reqinfo.go +++ b/api/middleware/reqinfo.go @@ -34,6 +34,7 @@ type ( API string // API name -- GetObject PutObject NewMultipartUpload etc. BucketName string // Bucket name ObjectName string // Object name + TraceID string // Trace ID URL *url.URL // Request url tags []KeyVal // Any additional info not accommodated by above fields } diff --git a/api/middleware/response.go b/api/middleware/response.go index 68de712..a9e0905 100644 --- a/api/middleware/response.go +++ b/api/middleware/response.go @@ -11,6 +11,7 @@ import ( "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/version" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" ) @@ -320,13 +321,17 @@ func LogSuccessResponse(l *zap.Logger) Func { reqLogger := reqLogOrDefault(ctx, l) reqInfo := GetReqInfo(ctx) - reqLogger.Info(logs.RequestEnd, + fields := []zap.Field{ zap.String("method", reqInfo.API), zap.String("bucket", reqInfo.BucketName), zap.String("object", reqInfo.ObjectName), zap.Int("status", lw.statusCode), - zap.String("description", http.StatusText(lw.statusCode)), - ) + zap.String("description", http.StatusText(lw.statusCode))} + if traceID, err := trace.TraceIDFromHex(reqInfo.TraceID); err == nil && traceID.IsValid() { + fields = append(fields, zap.String("trace_id", reqInfo.TraceID)) + } + + reqLogger.Info(logs.RequestEnd, fields...) }) } } diff --git a/api/middleware/tracing.go b/api/middleware/tracing.go index c6fbd6f..7597700 100644 --- a/api/middleware/tracing.go +++ b/api/middleware/tracing.go @@ -17,6 +17,8 @@ func Tracing() Func { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { appCtx, span := StartHTTPServerSpan(r, "REQUEST S3") + reqInfo := GetReqInfo(r.Context()) + reqInfo.TraceID = span.SpanContext().TraceID().String() lw := &traceResponseWriter{ResponseWriter: w, ctx: appCtx, span: span} h.ServeHTTP(lw, r.WithContext(appCtx)) })