diff --git a/docs/generated/eventlog.md b/docs/generated/eventlog.md index 9d681e97ddc9..b2264fe3d05d 100644 --- a/docs/generated/eventlog.md +++ b/docs/generated/eventlog.md @@ -2435,6 +2435,7 @@ contains common SQL event/execution details. | `SkippedQueries` | skipped_queries indicate how many SQL statements were not considered for sampling prior to this one. If the field is omitted, or its value is zero, this indicates that no statement was omitted since the last event. | no | | `CostEstimate` | Cost of the query as estimated by the optimizer. | no | | `Distribution` | The distribution of the DistSQL query plan (local, full, or partial). | no | +| `PlanGist` | The query's plan gist bytes as a base64 encoded string. | no | #### Common fields diff --git a/pkg/sql/exec_log.go b/pkg/sql/exec_log.go index 38e6aff1afcc..82628bc7c8f8 100644 --- a/pkg/sql/exec_log.go +++ b/pkg/sql/exec_log.go @@ -389,6 +389,7 @@ func (p *planner) maybeLogStatementInternal( SkippedQueries: skippedQueries, CostEstimate: p.curPlan.instrumentation.costEstimate, Distribution: p.curPlan.instrumentation.distribution.String(), + PlanGist: p.curPlan.instrumentation.planGist.String(), }}) } else { telemetryMetrics.incSkippedQueryCount() diff --git a/pkg/sql/telemetry_logging_test.go b/pkg/sql/telemetry_logging_test.go index 39d8b5d3c560..2bae4296dd28 100644 --- a/pkg/sql/telemetry_logging_test.go +++ b/pkg/sql/telemetry_logging_test.go @@ -231,6 +231,11 @@ func TestTelemetryLogging(t *testing.T) { if !distRe.MatchString(e.Message) { t.Errorf("expected to find Distribution but none was found") } + // Match plan gist on any non-empty string value. + planGist := regexp.MustCompile("\"PlanGist\":(\"\\S+\")") + if !planGist.MatchString(e.Message) { + t.Errorf("expected to find PlanGist but none was found in: %s", e.Message) + } for _, eTag := range tc.expectedUnredactedTags { for _, tag := range strings.Split(e.Tags, ",") { kv := strings.Split(tag, "=") diff --git a/pkg/util/log/eventpb/json_encode_generated.go b/pkg/util/log/eventpb/json_encode_generated.go index c52665378545..7063af584d22 100644 --- a/pkg/util/log/eventpb/json_encode_generated.go +++ b/pkg/util/log/eventpb/json_encode_generated.go @@ -3226,6 +3226,16 @@ func (m *SampledQuery) AppendJSONFields(printComma bool, b redact.RedactableByte b = append(b, '"') } + if m.PlanGist != "" { + if printComma { + b = append(b, ',') + } + printComma = true + b = append(b, "\"PlanGist\":\""...) + b = redact.RedactableBytes(jsonbytes.EncodeString([]byte(b), string(m.PlanGist))) + b = append(b, '"') + } + return printComma, b } diff --git a/pkg/util/log/eventpb/telemetry.proto b/pkg/util/log/eventpb/telemetry.proto index c8256a73c9d0..186dd8e0de7f 100644 --- a/pkg/util/log/eventpb/telemetry.proto +++ b/pkg/util/log/eventpb/telemetry.proto @@ -43,6 +43,9 @@ message SampledQuery { // The distribution of the DistSQL query plan (local, full, or partial). string distribution = 6 [(gogoproto.jsontag) = ",omitempty", (gogoproto.moretags) = "redact:\"nonsensitive\""]; + + // The query's plan gist bytes as a base64 encoded string. + string plan_gist = 7 [(gogoproto.jsontag) = ',omitempty', (gogoproto.moretags) = "redact:\"nonsensitive\""]; } // CapturedIndexUsageStats