mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 21:15:56 +08:00
fix: update clickhouse quries
Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com>
This commit is contained in:
parent
31cd192f24
commit
7ddf002d46
@ -2,12 +2,21 @@ package tracefunnel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
tracev4 "github.com/SigNoz/signoz/pkg/query-service/app/traces/v4"
|
tracev4 "github.com/SigNoz/signoz/pkg/query-service/app/traces/v4"
|
||||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||||
"github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
"github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// sanitizeClause adds AND prefix to non-empty clauses
|
||||||
|
func sanitizeClause(clause string) string {
|
||||||
|
if clause == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return "AND " + clause
|
||||||
|
}
|
||||||
|
|
||||||
func ValidateTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange) (*v3.ClickHouseQuery, error) {
|
func ValidateTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange) (*v3.ClickHouseQuery, error) {
|
||||||
var query string
|
var query string
|
||||||
var err error
|
var err error
|
||||||
@ -28,22 +37,27 @@ func ValidateTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunn
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build filter clauses for each step
|
// Build filter clauses for each step
|
||||||
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
clauseStep1, err := tracev4.BuildTracesFilter(funnelSteps[0].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
clauseStep2, err := tracev4.BuildTracesFilter(funnelSteps[1].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep3 := ""
|
clauseStep3 := ""
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
clauseStep3, err = tracev4.BuildTracesFilter(funnelSteps[2].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize clauses
|
||||||
|
clauseStep1 = sanitizeClause(clauseStep1)
|
||||||
|
clauseStep2 = sanitizeClause(clauseStep2)
|
||||||
|
clauseStep3 = sanitizeClause(clauseStep3)
|
||||||
|
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
query = BuildThreeStepFunnelValidationQuery(
|
query = BuildThreeStepFunnelValidationQuery(
|
||||||
containsErrorT1,
|
containsErrorT1,
|
||||||
@ -107,22 +121,27 @@ func GetFunnelAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange trace
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build filter clauses for each step
|
// Build filter clauses for each step
|
||||||
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
clauseStep1, err := tracev4.BuildTracesFilter(funnelSteps[0].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
clauseStep2, err := tracev4.BuildTracesFilter(funnelSteps[1].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep3 := ""
|
clauseStep3 := ""
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
clauseStep3, err = tracev4.BuildTracesFilter(funnelSteps[2].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize clauses
|
||||||
|
clauseStep1 = sanitizeClause(clauseStep1)
|
||||||
|
clauseStep2 = sanitizeClause(clauseStep2)
|
||||||
|
clauseStep3 = sanitizeClause(clauseStep3)
|
||||||
|
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
query = BuildThreeStepFunnelOverviewQuery(
|
query = BuildThreeStepFunnelOverviewQuery(
|
||||||
containsErrorT1,
|
containsErrorT1,
|
||||||
@ -215,22 +234,27 @@ func GetFunnelStepAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build filter clauses for each step
|
// Build filter clauses for each step
|
||||||
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
clauseStep1, err := tracev4.BuildTracesFilter(funnelSteps[0].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
clauseStep2, err := tracev4.BuildTracesFilter(funnelSteps[1].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep3 := ""
|
clauseStep3 := ""
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
clauseStep3, err = tracev4.BuildTracesFilter(funnelSteps[2].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize clauses
|
||||||
|
clauseStep1 = sanitizeClause(clauseStep1)
|
||||||
|
clauseStep2 = sanitizeClause(clauseStep2)
|
||||||
|
clauseStep3 = sanitizeClause(clauseStep3)
|
||||||
|
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
query = BuildThreeStepFunnelStepOverviewQuery(
|
query = BuildThreeStepFunnelStepOverviewQuery(
|
||||||
containsErrorT1,
|
containsErrorT1,
|
||||||
@ -294,22 +318,27 @@ func GetStepAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange tracefu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build filter clauses for each step
|
// Build filter clauses for each step
|
||||||
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
clauseStep1, err := tracev4.BuildTracesFilter(funnelSteps[0].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
clauseStep2, err := tracev4.BuildTracesFilter(funnelSteps[1].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep3 := ""
|
clauseStep3 := ""
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
clauseStep3, err = tracev4.BuildTracesFilter(funnelSteps[2].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize clauses
|
||||||
|
clauseStep1 = sanitizeClause(clauseStep1)
|
||||||
|
clauseStep2 = sanitizeClause(clauseStep2)
|
||||||
|
clauseStep3 = sanitizeClause(clauseStep3)
|
||||||
|
|
||||||
if len(funnel.Steps) > 2 {
|
if len(funnel.Steps) > 2 {
|
||||||
query = BuildThreeStepFunnelCountQuery(
|
query = BuildThreeStepFunnelCountQuery(
|
||||||
containsErrorT1,
|
containsErrorT1,
|
||||||
@ -366,15 +395,19 @@ func GetSlowestTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build filter clauses for the steps
|
// Build filter clauses for the steps
|
||||||
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepStartOrder].Filters)
|
clauseStep1, err := tracev4.BuildTracesFilter(funnelSteps[stepStartOrder].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepEndOrder].Filters)
|
clauseStep2, err := tracev4.BuildTracesFilter(funnelSteps[stepEndOrder].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize clauses
|
||||||
|
clauseStep1 = sanitizeClause(clauseStep1)
|
||||||
|
clauseStep2 = sanitizeClause(clauseStep2)
|
||||||
|
|
||||||
query := BuildTwoStepFunnelTopSlowTracesQuery(
|
query := BuildTwoStepFunnelTopSlowTracesQuery(
|
||||||
containsErrorT1,
|
containsErrorT1,
|
||||||
containsErrorT2,
|
containsErrorT2,
|
||||||
@ -409,15 +442,19 @@ func GetErroredTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build filter clauses for the steps
|
// Build filter clauses for the steps
|
||||||
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepStartOrder].Filters)
|
clauseStep1, err := tracev4.BuildTracesFilter(funnelSteps[stepStartOrder].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepEndOrder].Filters)
|
clauseStep2, err := tracev4.BuildTracesFilter(funnelSteps[stepEndOrder].Filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanitize clauses
|
||||||
|
clauseStep1 = sanitizeClause(clauseStep1)
|
||||||
|
clauseStep2 = sanitizeClause(clauseStep2)
|
||||||
|
|
||||||
query := BuildTwoStepFunnelTopSlowErrorTracesQuery(
|
query := BuildTwoStepFunnelTopSlowErrorTracesQuery(
|
||||||
containsErrorT1,
|
containsErrorT1,
|
||||||
containsErrorT2,
|
containsErrorT2,
|
||||||
|
@ -87,6 +87,62 @@ func existsSubQueryForFixedColumn(key v3.AttributeKey, op v3.FilterOperator) (st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BuildTracesFilter(fs *v3.FilterSet) (string, error) {
|
||||||
|
var conditions []string
|
||||||
|
|
||||||
|
if fs != nil && len(fs.Items) != 0 {
|
||||||
|
for _, item := range fs.Items {
|
||||||
|
|
||||||
|
val := item.Value
|
||||||
|
// generate the key
|
||||||
|
columnName := getColumnName(item.Key)
|
||||||
|
var fmtVal string
|
||||||
|
item.Operator = v3.FilterOperator(strings.ToLower(strings.TrimSpace(string(item.Operator))))
|
||||||
|
if item.Operator != v3.FilterOperatorExists && item.Operator != v3.FilterOperatorNotExists {
|
||||||
|
var err error
|
||||||
|
val, err = utils.ValidateAndCastValue(val, item.Key.DataType)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("invalid value for key %s: %v", item.Key.Key, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if val != nil {
|
||||||
|
fmtVal = utils.ClickHouseFormattedValue(val)
|
||||||
|
}
|
||||||
|
if operator, ok := tracesOperatorMappingV3[item.Operator]; ok {
|
||||||
|
switch item.Operator {
|
||||||
|
case v3.FilterOperatorContains, v3.FilterOperatorNotContains:
|
||||||
|
// we also want to treat %, _ as literals for contains
|
||||||
|
val := utils.QuoteEscapedStringForContains(fmt.Sprintf("%s", item.Value), false)
|
||||||
|
conditions = append(conditions, fmt.Sprintf("%s %s '%%%s%%'", columnName, operator, val))
|
||||||
|
case v3.FilterOperatorRegex, v3.FilterOperatorNotRegex:
|
||||||
|
conditions = append(conditions, fmt.Sprintf(operator, columnName, fmtVal))
|
||||||
|
case v3.FilterOperatorExists, v3.FilterOperatorNotExists:
|
||||||
|
if item.Key.IsColumn {
|
||||||
|
subQuery, err := existsSubQueryForFixedColumn(item.Key, item.Operator)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
conditions = append(conditions, subQuery)
|
||||||
|
} else {
|
||||||
|
cType := getClickHouseTracesColumnType(item.Key.Type)
|
||||||
|
cDataType := getClickHouseTracesColumnDataType(item.Key.DataType)
|
||||||
|
col := fmt.Sprintf("%s_%s", cType, cDataType)
|
||||||
|
conditions = append(conditions, fmt.Sprintf(operator, col, item.Key.Key))
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
conditions = append(conditions, fmt.Sprintf("%s %s %s", columnName, operator, fmtVal))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("unsupported operator %s", item.Operator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queryString := strings.Join(conditions, " AND ")
|
||||||
|
|
||||||
|
return queryString, nil
|
||||||
|
}
|
||||||
|
|
||||||
func BuildTracesFilterQuery(fs *v3.FilterSet) (string, error) {
|
func BuildTracesFilterQuery(fs *v3.FilterSet) (string, error) {
|
||||||
var conditions []string
|
var conditions []string
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user