From 13aff35a832508293a2cf91e8fac667c96837d40 Mon Sep 17 00:00:00 2001 From: "cai.zhang" Date: Fri, 28 Feb 2025 10:07:58 +0800 Subject: [PATCH] enhance: Add metrics for parse expression (#39654) Signed-off-by: Cai Zhang --- internal/proxy/task_delete.go | 5 +++++ internal/proxy/task_query.go | 8 +++++++- internal/proxy/task_search.go | 4 ++++ pkg/metrics/proxy_metrics.go | 11 +++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/internal/proxy/task_delete.go b/internal/proxy/task_delete.go index 3969ab553a..07e628ef7f 100644 --- a/internal/proxy/task_delete.go +++ b/internal/proxy/task_delete.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "io" + "strconv" + "time" "github.com/cockroachdb/errors" "go.opentelemetry.io/otel" @@ -347,10 +349,13 @@ func (dr *deleteRunner) Init(ctx context.Context) error { return ErrWithLog(log, "Failed to get collection schema", err) } + start := time.Now() dr.plan, err = planparserv2.CreateRetrievePlan(dr.schema.schemaHelper, dr.req.GetExpr(), dr.req.GetExprTemplateValues()) if err != nil { + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "delete", metrics.FailLabel).Observe(float64(time.Since(start).Milliseconds())) return merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg("failed to create delete plan: %v", err)) } + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "delete", metrics.SuccessLabel).Observe(float64(time.Since(start).Milliseconds())) if planparserv2.IsAlwaysTruePlan(dr.plan) { return merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg("delete plan can't be empty or always true : %s", dr.req.GetExpr())) diff --git a/internal/proxy/task_query.go b/internal/proxy/task_query.go index 9905c5440a..474a313ffc 100644 --- a/internal/proxy/task_query.go +++ b/internal/proxy/task_query.go @@ -5,6 +5,7 @@ import ( "fmt" "strconv" "strings" + "time" "github.com/cockroachdb/errors" "github.com/samber/lo" @@ -235,11 +236,13 @@ func createCntPlan(expr string, schemaHelper *typeutil.SchemaHelper, exprTemplat }, }, nil } + start := time.Now() plan, err := planparserv2.CreateRetrievePlan(schemaHelper, expr, exprTemplateValues) if err != nil { + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "query", metrics.FailLabel).Observe(float64(time.Since(start).Milliseconds())) return nil, merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg("failed to create query plan: %v", err)) } - + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "query", metrics.SuccessLabel).Observe(float64(time.Since(start).Milliseconds())) plan.Node.(*planpb.PlanNode_Query).Query.IsCount = true return plan, nil @@ -258,10 +261,13 @@ func (t *queryTask) createPlan(ctx context.Context) error { var err error if t.plan == nil { + start := time.Now() t.plan, err = planparserv2.CreateRetrievePlan(schema.schemaHelper, t.request.Expr, t.request.GetExprTemplateValues()) if err != nil { + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "query", metrics.FailLabel).Observe(float64(time.Since(start).Milliseconds())) return merr.WrapErrAsInputError(merr.WrapErrParameterInvalidMsg("failed to create query plan: %v", err)) } + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "query", metrics.SuccessLabel).Observe(float64(time.Since(start).Milliseconds())) } t.request.OutputFields, t.userOutputFields, t.userDynamicFields, err = translateOutputFields(t.request.OutputFields, t.schema, true) diff --git a/internal/proxy/task_search.go b/internal/proxy/task_search.go index 809cdbe968..f60cdaf35b 100644 --- a/internal/proxy/task_search.go +++ b/internal/proxy/task_search.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "strconv" + "time" "github.com/cockroachdb/errors" "github.com/samber/lo" @@ -558,13 +559,16 @@ func (t *searchTask) tryGeneratePlan(params []*commonpb.KeyValuePair, dsl string } searchInfo.planInfo.QueryFieldId = annField.GetFieldID() + start := time.Now() plan, planErr := planparserv2.CreateSearchPlan(t.schema.schemaHelper, dsl, annsFieldName, searchInfo.planInfo, exprTemplateValues) if planErr != nil { log.Ctx(t.ctx).Warn("failed to create query plan", zap.Error(planErr), zap.String("dsl", dsl), // may be very large if large term passed. zap.String("anns field", annsFieldName), zap.Any("query info", searchInfo.planInfo)) + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "search", metrics.FailLabel).Observe(float64(time.Since(start).Milliseconds())) return nil, nil, 0, false, merr.WrapErrParameterInvalidMsg("failed to create query plan: %v", planErr) } + metrics.ProxyParseExpressionLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), "search", metrics.SuccessLabel).Observe(float64(time.Since(start).Milliseconds())) log.Ctx(t.ctx).Debug("create query plan", zap.String("dsl", t.request.Dsl), // may be very large if large term passed. zap.String("anns field", annsFieldName), zap.Any("query info", searchInfo.planInfo)) diff --git a/pkg/metrics/proxy_metrics.go b/pkg/metrics/proxy_metrics.go index 2af25c89ac..24e6688196 100644 --- a/pkg/metrics/proxy_metrics.go +++ b/pkg/metrics/proxy_metrics.go @@ -436,6 +436,15 @@ var ( Name: "queue_task_num", Help: "", }, []string{nodeIDLabelName, queueTypeLabelName, taskStateLabel}) + + ProxyParseExpressionLatency = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: milvusNamespace, + Subsystem: typeutil.ProxyRole, + Name: "parse_expr_latency", + Help: "the latency of parse expression", + Buckets: buckets, + }, []string{nodeIDLabelName, functionLabelName, statusLabelName}) ) // RegisterProxy registers Proxy metrics @@ -501,6 +510,8 @@ func RegisterProxy(registry *prometheus.Registry) { registry.MustRegister(ProxySearchSparseNumNonZeros) registry.MustRegister(ProxyQueueTaskNum) + registry.MustRegister(ProxyParseExpressionLatency) + RegisterStreamingServiceClient(registry) }