diff --git a/pkg/modules/tracefunnel/clickhouse_queries.go b/pkg/modules/tracefunnel/clickhouse_queries.go index b52dd9b7bd58..659c47769896 100644 --- a/pkg/modules/tracefunnel/clickhouse_queries.go +++ b/pkg/modules/tracefunnel/clickhouse_queries.go @@ -2,7 +2,6 @@ package tracefunnel import ( "fmt" - "strings" ) func BuildTwoStepFunnelValidationQuery( @@ -41,7 +40,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[9]s GROUP BY trace_id LIMIT 100000 ) @@ -57,7 +56,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[10]s GROUP BY trace_id LIMIT 100000 ) @@ -88,22 +87,10 @@ LIMIT 5;` spanNameT1, serviceNameT2, spanNameT2, + clauseStep1, + clauseStep2, ) - // Inject clauseStep1 - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - // Inject clauseStep2 - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -150,7 +137,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[12]s GROUP BY trace_id LIMIT 100000 ) @@ -166,7 +153,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[13]s GROUP BY trace_id LIMIT 100000 ) @@ -182,7 +169,7 @@ WITH AND serviceName = service_name_t3 AND name = span_name_t3 AND (contains_error_t3 = 0 OR has_error = true) - -- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>> + %[14]s GROUP BY trace_id LIMIT 100000 ) @@ -218,26 +205,11 @@ LIMIT 5;` spanNameT2, serviceNameT3, spanNameT3, + clauseStep1, + clauseStep2, + clauseStep3, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep3 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "AND "+clauseStep3, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -281,7 +253,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT clause_step1 HERE IN GO IF NOT EMPTY >>> + %[11]s GROUP BY trace_id LIMIT 100000 ) @@ -298,7 +270,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT clause_step2 HERE IN GO IF NOT EMPTY >>> + %[12]s GROUP BY trace_id LIMIT 100000 ) @@ -335,20 +307,10 @@ FROM joined;` spanNameT1, serviceNameT2, spanNameT2, + clauseStep1, + clauseStep2, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT clause_step1 HERE IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT clause_step1 HERE IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT clause_step2 HERE IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT clause_step2 HERE IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -404,7 +366,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[15]s GROUP BY trace_id LIMIT 100000 ) @@ -421,7 +383,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[16]s GROUP BY trace_id LIMIT 100000 ) @@ -438,7 +400,7 @@ WITH AND serviceName = service_name_t3 AND name = span_name_t3 AND (contains_error_t3 = 0 OR has_error = true) - -- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>> + %[17]s GROUP BY trace_id LIMIT 100000 ) @@ -494,26 +456,11 @@ FROM joined_t3;` spanNameT2, serviceNameT3, spanNameT3, + clauseStep1, + clauseStep2, + clauseStep3, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep3 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "AND "+clauseStep3, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -569,7 +516,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[15]s GROUP BY trace_id LIMIT 100000 ) @@ -586,7 +533,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[16]s GROUP BY trace_id LIMIT 100000 ) @@ -603,7 +550,7 @@ WITH AND serviceName = service_name_t3 AND name = span_name_t3 AND (contains_error_t3 = 0 OR has_error = true) - -- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>> + %[17]s GROUP BY trace_id LIMIT 100000 ) @@ -656,26 +603,11 @@ FROM joined_t3;` spanNameT2, serviceNameT3, spanNameT3, + clauseStep1, + clauseStep2, + clauseStep3, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep3 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "AND "+clauseStep3, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -716,7 +648,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[9]s GROUP BY trace_id LIMIT 100000 ) @@ -733,7 +665,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[10]s GROUP BY trace_id LIMIT 100000 ) @@ -768,20 +700,10 @@ FROM joined;` spanNameT1, serviceNameT2, spanNameT2, + clauseStep1, + clauseStep2, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -829,7 +751,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[12]s GROUP BY trace_id LIMIT 100000 ) @@ -846,7 +768,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[13]s GROUP BY trace_id LIMIT 100000 ) @@ -863,7 +785,7 @@ WITH AND serviceName = service_name_t3 AND name = span_name_t3 AND (contains_error_t3 = 0 OR has_error = true) - -- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>> + %[14]s GROUP BY trace_id LIMIT 100000 ) @@ -918,26 +840,11 @@ FROM joined_t3;` spanNameT2, serviceNameT3, spanNameT3, + clauseStep1, + clauseStep2, + clauseStep3, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep3 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "AND "+clauseStep3, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step3 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -975,7 +882,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[9]s GROUP BY trace_id LIMIT 100000 ), step1 AS ( @@ -993,7 +900,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[10]s GROUP BY trace_id LIMIT 100000 ), step2 AS ( @@ -1048,20 +955,10 @@ LIMIT 5;` spanNameT1, serviceNameT2, spanNameT2, + clauseStep1, + clauseStep2, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } @@ -1099,7 +996,7 @@ WITH AND serviceName = service_name_t1 AND name = span_name_t1 AND (contains_error_t1 = 0 OR has_error = true) - -- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>> + %[9]s GROUP BY trace_id LIMIT 100000 ), step1 AS ( @@ -1117,7 +1014,7 @@ WITH AND serviceName = service_name_t2 AND name = span_name_t2 AND (contains_error_t2 = 0 OR has_error = true) - -- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>> + %[10]s GROUP BY trace_id LIMIT 100000 ), step2 AS ( @@ -1177,19 +1074,9 @@ LIMIT 5;` spanNameT1, serviceNameT2, spanNameT2, + clauseStep1, + clauseStep2, ) - if clauseStep1 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "AND "+clauseStep1, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step1 IN GO IF NOT EMPTY >>>", "", 1) - } - - if clauseStep2 != "" { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "AND "+clauseStep2, 1) - } else { - query = strings.Replace(query, "-- <<< INJECT AND clause_step2 IN GO IF NOT EMPTY >>>", "", 1) - } - return query } diff --git a/pkg/modules/tracefunnel/query.go b/pkg/modules/tracefunnel/query.go index 01894a0cc1d1..703e50bceab9 100644 --- a/pkg/modules/tracefunnel/query.go +++ b/pkg/modules/tracefunnel/query.go @@ -1,21 +1,32 @@ package tracefunnel import ( + tracesv3 "github.com/SigNoz/signoz/pkg/query-service/app/traces/v3" v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3" tracefunnel "github.com/SigNoz/signoz/pkg/types/tracefunnel" ) +// buildFilterClause converts a FilterSet into a SQL WHERE clause string +func buildFilterClause(filters *v3.FilterSet) string { + if filters == nil { + return "" + } + + clause, err := tracesv3.BuildTracesFilterQuery(filters) + if err != nil { + return "" + } + return clause +} + func ValidateTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange) (*v3.ClickHouseQuery, error) { var query string - // (todo) sort by order funnelSteps := funnel.Steps containsErrorT1 := 0 containsErrorT2 := 0 containsErrorT3 := 0 - // (todo) prepare funnel step wise whereclause - if funnelSteps[0].HasErrors { containsErrorT1 = 1 } @@ -26,6 +37,14 @@ func ValidateTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange) containsErrorT3 = 1 } + // Build filter clauses for each step + clauseStep1 := buildFilterClause(funnelSteps[0].Filters) + clauseStep2 := buildFilterClause(funnelSteps[1].Filters) + clauseStep3 := "" + if len(funnel.Steps) > 2 { + clauseStep3 = buildFilterClause(funnelSteps[2].Filters) + } + if len(funnel.Steps) > 2 { query = BuildThreeStepFunnelValidationQuery( containsErrorT1, // containsErrorT1 @@ -39,9 +58,9 @@ func ValidateTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange) funnelSteps[1].SpanName, // spanNameT2 funnelSteps[2].ServiceName, // serviceNameT1 funnelSteps[2].SpanName, // spanNameT3 - "", - "", - "", + clauseStep1, + clauseStep2, + clauseStep3, ) } else { query = BuildTwoStepFunnelValidationQuery( @@ -53,8 +72,8 @@ func ValidateTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange) funnelSteps[0].SpanName, // spanNameT1 funnelSteps[1].ServiceName, // serviceNameT1 funnelSteps[1].SpanName, // spanNameT2 - "", - "", + clauseStep1, + clauseStep2, ) } @@ -73,8 +92,6 @@ func GetFunnelAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRa latencyPointerT1 := "start" latencyPointerT2 := "start" latencyPointerT3 := "start" - stepStartOrder := 0 - stepEndOrder := 1 if funnelSteps[0].HasErrors { containsErrorT1 = 1 @@ -90,10 +107,18 @@ func GetFunnelAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRa latencyPointerT1 = "end" } if funnelSteps[1].LatencyPointer != "" { - latencyPointerT1 = "end" + latencyPointerT2 = "end" } if len(funnel.Steps) > 2 && funnelSteps[2].LatencyPointer != "" { - latencyPointerT1 = "end" + latencyPointerT3 = "end" + } + + // Build filter clauses for each step + clauseStep1 := buildFilterClause(funnelSteps[0].Filters) + clauseStep2 := buildFilterClause(funnelSteps[1].Filters) + clauseStep3 := "" + if len(funnel.Steps) > 2 { + clauseStep3 = buildFilterClause(funnelSteps[2].Filters) } if len(funnel.Steps) > 2 { @@ -112,35 +137,24 @@ func GetFunnelAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRa funnelSteps[1].SpanName, // spanNameT2 funnelSteps[2].ServiceName, // serviceNameT1 funnelSteps[2].SpanName, // spanNameT3 - "", - "", - "", - //"http_method = 'POST'", // clauseStep1 - //"response_status_code = '500'", // clauseStep2 - //"db_operation = 'SELECT'", // clauseStep3 + clauseStep1, + clauseStep2, + clauseStep3, ) } else { - - if funnelSteps[stepStartOrder].HasErrors { - containsErrorT1 = 1 - } - if funnelSteps[stepEndOrder].HasErrors { - containsErrorT2 = 1 - } - query = BuildTwoStepFunnelOverviewQuery( containsErrorT1, // containsErrorT1 containsErrorT2, // containsErrorT2 latencyPointerT1, latencyPointerT2, - timeRange.StartTime, // startTs - timeRange.EndTime, // endTs - funnelSteps[stepStartOrder].ServiceName, // serviceNameT1 - funnelSteps[stepStartOrder].SpanName, // spanNameT1 - funnelSteps[stepEndOrder].ServiceName, // serviceNameT1 - funnelSteps[stepEndOrder].SpanName, // spanNameT2 - "", - "", + timeRange.StartTime, // startTs + timeRange.EndTime, // endTs + funnelSteps[0].ServiceName, // serviceNameT1 + funnelSteps[0].SpanName, // spanNameT1 + funnelSteps[1].ServiceName, // serviceNameT1 + funnelSteps[1].SpanName, // spanNameT2 + clauseStep1, + clauseStep2, ) } return &v3.ClickHouseQuery{Query: query}, nil @@ -159,16 +173,6 @@ func GetFunnelStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.Ti stepStartOrder := 0 stepEndOrder := 1 - if funnelSteps[0].HasErrors { - containsErrorT1 = 1 - } - if funnelSteps[1].HasErrors { - containsErrorT2 = 1 - } - if len(funnel.Steps) > 2 && funnelSteps[2].HasErrors { - containsErrorT3 = 1 - } - if stepStart != stepEnd { stepStartOrder = int(stepStart) - 1 stepEndOrder = int(stepEnd) - 1 @@ -178,12 +182,6 @@ func GetFunnelStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.Ti if funnelSteps[stepEndOrder].HasErrors { containsErrorT2 = 1 } - if funnelSteps[stepStartOrder].HasErrors { - containsErrorT1 = 1 - } - if funnelSteps[stepEndOrder].HasErrors { - containsErrorT2 = 1 - } if funnelSteps[stepStartOrder].LatencyPointer != "" { latencyPointerT1 = "end" } @@ -191,6 +189,15 @@ func GetFunnelStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.Ti latencyPointerT2 = "end" } } + + // Build filter clauses for the steps + clauseStep1 := buildFilterClause(funnelSteps[stepStartOrder].Filters) + clauseStep2 := buildFilterClause(funnelSteps[stepEndOrder].Filters) + clauseStep3 := "" + if len(funnel.Steps) > 2 { + clauseStep3 = buildFilterClause(funnelSteps[2].Filters) + } + if stepStart == 2 { query = BuildFunnelStepFunnelOverviewQuery( containsErrorT1, // containsErrorT1 @@ -207,9 +214,9 @@ func GetFunnelStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.Ti funnelSteps[stepStartOrder].SpanName, // spanNameT1 funnelSteps[stepEndOrder].ServiceName, // serviceNameT1 funnelSteps[stepEndOrder].SpanName, // spanNameT2 - "", - "", - "", + clauseStep1, + clauseStep2, + clauseStep3, ) } else { query = BuildTwoStepFunnelOverviewQuery( @@ -223,8 +230,8 @@ func GetFunnelStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.Ti funnelSteps[stepStartOrder].SpanName, // spanNameT1 funnelSteps[stepEndOrder].ServiceName, // serviceNameT1 funnelSteps[stepEndOrder].SpanName, // spanNameT2 - "", - "", + clauseStep1, + clauseStep2, ) } @@ -232,7 +239,6 @@ func GetFunnelStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.Ti } func GetStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange) (*v3.ClickHouseQuery, error) { - var query string funnelSteps := funnel.Steps @@ -250,6 +256,14 @@ func GetStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang containsErrorT3 = 1 } + // Build filter clauses for each step + clauseStep1 := buildFilterClause(funnelSteps[0].Filters) + clauseStep2 := buildFilterClause(funnelSteps[1].Filters) + clauseStep3 := "" + if len(funnel.Steps) > 2 { + clauseStep3 = buildFilterClause(funnelSteps[2].Filters) + } + if len(funnel.Steps) > 2 { query = BuildThreeStepFunnelCountQuery( containsErrorT1, // containsErrorT1 @@ -263,9 +277,9 @@ func GetStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang funnelSteps[1].SpanName, // spanNameT2 funnelSteps[2].ServiceName, // serviceNameT1 funnelSteps[2].SpanName, // spanNameT3 - "", - "", - "", + clauseStep1, + clauseStep2, + clauseStep3, ) } else { query = BuildTwoStepFunnelCountQuery( @@ -277,8 +291,8 @@ func GetStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang funnelSteps[0].SpanName, // spanNameT1 funnelSteps[1].ServiceName, // serviceNameT1 funnelSteps[1].SpanName, // spanNameT2 - "", - "", + clauseStep1, + clauseStep2, ) } @@ -288,7 +302,6 @@ func GetStepAnalytics(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang } func GetSlowestTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange, stepStart, stepEnd int64) (*v3.ClickHouseQuery, error) { - funnelSteps := funnel.Steps containsErrorT1 := 0 containsErrorT2 := 0 @@ -306,6 +319,10 @@ func GetSlowestTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang } } + // Build filter clauses for the steps + clauseStep1 := buildFilterClause(funnelSteps[stepStartOrder].Filters) + clauseStep2 := buildFilterClause(funnelSteps[stepEndOrder].Filters) + query := BuildTwoStepFunnelTopSlowTracesQuery( containsErrorT1, // containsErrorT1 containsErrorT2, // containsErrorT2 @@ -315,21 +332,19 @@ func GetSlowestTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang funnelSteps[stepStartOrder].SpanName, // spanNameT1 funnelSteps[stepEndOrder].ServiceName, // serviceNameT1 funnelSteps[stepEndOrder].SpanName, // spanNameT2 - "", - "", + clauseStep1, + clauseStep2, ) return &v3.ClickHouseQuery{Query: query}, nil } func GetErroredTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRange, stepStart, stepEnd int64) (*v3.ClickHouseQuery, error) { - funnelSteps := funnel.Steps containsErrorT1 := 0 containsErrorT2 := 0 stepStartOrder := 0 stepEndOrder := 1 - // (todo): check the logic if stepStart != stepEnd { stepStartOrder = int(stepStart) - 1 stepEndOrder = int(stepEnd) - 1 @@ -341,6 +356,10 @@ func GetErroredTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang } } + // Build filter clauses for the steps + clauseStep1 := buildFilterClause(funnelSteps[stepStartOrder].Filters) + clauseStep2 := buildFilterClause(funnelSteps[stepEndOrder].Filters) + query := BuildTwoStepFunnelTopSlowErrorTracesQuery( containsErrorT1, // containsErrorT1 containsErrorT2, // containsErrorT2 @@ -350,8 +369,8 @@ func GetErroredTraces(funnel *tracefunnel.Funnel, timeRange tracefunnel.TimeRang funnelSteps[stepStartOrder].SpanName, // spanNameT1 funnelSteps[stepEndOrder].ServiceName, // serviceNameT1 funnelSteps[stepEndOrder].SpanName, // spanNameT2 - "", - "", + clauseStep1, + clauseStep2, ) return &v3.ClickHouseQuery{Query: query}, nil } diff --git a/pkg/query-service/app/traces/v3/query_builder.go b/pkg/query-service/app/traces/v3/query_builder.go index ded13cdafbd6..a7e11c02bae5 100644 --- a/pkg/query-service/app/traces/v3/query_builder.go +++ b/pkg/query-service/app/traces/v3/query_builder.go @@ -144,7 +144,7 @@ func getZerosForEpochNano(epoch int64) int64 { return int64(math.Pow(10, float64(19-count))) } -func buildTracesFilterQuery(fs *v3.FilterSet) (string, error) { +func BuildTracesFilterQuery(fs *v3.FilterSet) (string, error) { var conditions []string if fs != nil && len(fs.Items) != 0 { @@ -228,14 +228,14 @@ func handleEmptyValuesInGroupBy(groupBy []v3.AttributeKey) (string, error) { Operator: "AND", Items: filterItems, } - return buildTracesFilterQuery(&filterSet) + return BuildTracesFilterQuery(&filterSet) } return "", nil } func buildTracesQuery(start, end, step int64, mq *v3.BuilderQuery, _ string, panelType v3.PanelType, options v3.QBOptions) (string, error) { - filterSubQuery, err := buildTracesFilterQuery(mq.Filters) + filterSubQuery, err := BuildTracesFilterQuery(mq.Filters) if err != nil { return "", err } diff --git a/pkg/query-service/app/traces/v3/query_builder_test.go b/pkg/query-service/app/traces/v3/query_builder_test.go index e2d953720ab1..424d57396cd8 100644 --- a/pkg/query-service/app/traces/v3/query_builder_test.go +++ b/pkg/query-service/app/traces/v3/query_builder_test.go @@ -133,7 +133,7 @@ var buildFilterQueryData = []struct { func TestBuildTracesFilterQuery(t *testing.T) { for _, tt := range buildFilterQueryData { Convey("TestBuildTracesFilterQuery", t, func() { - query, err := buildTracesFilterQuery(tt.FilterSet) + query, err := BuildTracesFilterQuery(tt.FilterSet) So(err, ShouldBeNil) So(query, ShouldEqual, tt.ExpectedFilter) })