From 2a3649157dc1b6113749aae3cf0ac1cd19344a75 Mon Sep 17 00:00:00 2001 From: Binbin Li Date: Thu, 15 Aug 2024 11:40:53 +0800 Subject: [PATCH] feat: add timestamp and traceId to verification response (#1697) Signed-off-by: Joshua Duffney --- httpserver/handlers.go | 10 +++++----- httpserver/types.go | 10 +++++++++- httpserver/types_test.go | 3 ++- internal/logger/logger.go | 9 +++++++++ internal/logger/logger_test.go | 3 +-- library/default/template.yaml | 2 +- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/httpserver/handlers.go b/httpserver/handlers.go index 13db60f92..7c4596fb1 100644 --- a/httpserver/handlers.go +++ b/httpserver/handlers.go @@ -141,12 +141,12 @@ func (server *Server) verify(ctx context.Context, w http.ResponseWriter, r *http logger.GetLogger(ctx, server.LogOption).Warnf("unable to insert cache entry for subject %v", resolvedSubjectReference) } } - - if res, err := json.MarshalIndent(result, "", " "); err == nil { - logger.GetLogger(ctx, server.LogOption).Infof("verify result for subject %s: %s", resolvedSubjectReference, string(res)) - } } - returnItem.Value = fromVerifyResult(result, server.GetExecutor(ctx).PolicyEnforcer.GetPolicyType(ctx)) + verificationResponse := fromVerifyResult(ctx, result, server.GetExecutor(ctx).PolicyEnforcer.GetPolicyType(ctx)) + returnItem.Value = verificationResponse + if res, err := json.MarshalIndent(verificationResponse, "", " "); err == nil { + logger.GetLogger(ctx, server.LogOption).Infof("verification response for subject %s: \n%s", resolvedSubjectReference, string(res)) + } logger.GetLogger(ctx, server.LogOption).Debugf("verification: execution time for image %s: %dms", resolvedSubjectReference, time.Since(routineStartTime).Milliseconds()) }(utils.SanitizeString(key), ctx) } diff --git a/httpserver/types.go b/httpserver/types.go index 8e3655cb5..dafad6547 100644 --- a/httpserver/types.go +++ b/httpserver/types.go @@ -16,6 +16,10 @@ limitations under the License. package httpserver import ( + "context" + "time" + + "github.com/ratify-project/ratify/internal/logger" "github.com/ratify-project/ratify/pkg/executor/types" pt "github.com/ratify-project/ratify/pkg/policyprovider/types" ) @@ -32,10 +36,12 @@ const ( type VerificationResponse struct { Version string `json:"version"` IsSuccess bool `json:"isSuccess"` + TraceID string `json:"traceID,omitempty"` + Timestamp string `json:"timestamp,omitempty"` VerifierReports []interface{} `json:"verifierReports,omitempty"` } -func fromVerifyResult(res types.VerifyResult, policyType string) VerificationResponse { +func fromVerifyResult(ctx context.Context, res types.VerifyResult, policyType string) VerificationResponse { version := ResultVersion0_2_0 if policyType == pt.RegoPolicy { version = ResultVersion1_1_0 @@ -43,6 +49,8 @@ func fromVerifyResult(res types.VerifyResult, policyType string) VerificationRes return VerificationResponse{ Version: version, IsSuccess: res.IsSuccess, + Timestamp: time.Now().Format(time.RFC3339Nano), + TraceID: logger.GetTraceID(ctx), VerifierReports: res.VerifierReports, } } diff --git a/httpserver/types_test.go b/httpserver/types_test.go index 04ed6da5c..c03d694df 100644 --- a/httpserver/types_test.go +++ b/httpserver/types_test.go @@ -16,6 +16,7 @@ limitations under the License. package httpserver import ( + "context" "testing" "github.com/ratify-project/ratify/pkg/executor/types" @@ -43,7 +44,7 @@ func TestFromVerifyResult(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if res := fromVerifyResult(result, tc.policyType); res.Version != tc.expectedVersion { + if res := fromVerifyResult(context.Background(), result, tc.policyType); res.Version != tc.expectedVersion { t.Fatalf("Expected version to be %s, got %s", tc.expectedVersion, res.Version) } }) diff --git a/internal/logger/logger.go b/internal/logger/logger.go index ff050cef3..3a65de01c 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -101,6 +101,15 @@ func GetLogger(ctx context.Context, opt Option) dcontext.Logger { return dcontext.GetLogger(ctx, ContextKeyComponentType) } +// GetTraceID returns the trace ID from the context. +func GetTraceID(ctx context.Context) string { + traceID := ctx.Value(ContextKeyTraceID) + if traceID == nil { + return "" + } + return traceID.(string) +} + // setTraceID sets the trace ID in the context. If the trace ID is not present in the request headers, a new one is generated. func setTraceID(ctx context.Context, r *http.Request) context.Context { traceID := "" diff --git a/internal/logger/logger_test.go b/internal/logger/logger_test.go index 6024134e7..9aa95d3a6 100644 --- a/internal/logger/logger_test.go +++ b/internal/logger/logger_test.go @@ -23,7 +23,6 @@ import ( "testing" logstash "github.com/bshuster-repo/logrus-logstash-hook" - dcontext "github.com/docker/distribution/context" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) @@ -75,7 +74,7 @@ func TestInitContext(t *testing.T) { t.Run(tc.name, func(t *testing.T) { traceIDHeaderNames = tc.headerNames ctx := InitContext(context.Background(), tc.r) - traceID := dcontext.GetStringValue(ctx, ContextKeyTraceID) + traceID := GetTraceID(ctx) if traceID == "" { t.Fatalf("expected non-empty traceID, but got empty one") } diff --git a/library/default/template.yaml b/library/default/template.yaml index a37192135..6cc46ec3f 100644 --- a/library/default/template.yaml +++ b/library/default/template.yaml @@ -44,5 +44,5 @@ spec: general_violation[{"result": result}] { subject_validation := remote_data.responses[_] subject_validation[1].isSuccess == false - result := sprintf("Failed to verify the artifact: %s", [subject_validation[0]]) + result := sprintf("Time=%s, failed to verify the artifact: %s, trace-id: %s", [subject_validation[1].timestamp, subject_validation[0], subject_validation[1].traceID]) }