mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 23:05:56 +08:00
chore: tf testing
Signed-off-by: Shivanshu Raj Shrivastava <shivanshu1333@gmail.com>
This commit is contained in:
parent
71b098776b
commit
89de68f987
1160
pkg/modules/tracefunnel/clickhouse_queries.go
Normal file
1160
pkg/modules/tracefunnel/clickhouse_queries.go
Normal file
File diff suppressed because it is too large
Load Diff
420
pkg/modules/tracefunnel/query.go
Normal file
420
pkg/modules/tracefunnel/query.go
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
package tracefunnel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
tracev4 "github.com/SigNoz/signoz/pkg/query-service/app/traces/v4"
|
||||||
|
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||||
|
"github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ValidateTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange) (*v3.ClickHouseQuery, error) {
|
||||||
|
var query string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
funnelSteps := funnel.Steps
|
||||||
|
containsErrorT1 := 0
|
||||||
|
containsErrorT2 := 0
|
||||||
|
containsErrorT3 := 0
|
||||||
|
|
||||||
|
if funnelSteps[0].HasErrors {
|
||||||
|
containsErrorT1 = 1
|
||||||
|
}
|
||||||
|
if funnelSteps[1].HasErrors {
|
||||||
|
containsErrorT2 = 1
|
||||||
|
}
|
||||||
|
if len(funnel.Steps) > 2 && funnelSteps[2].HasErrors {
|
||||||
|
containsErrorT3 = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build filter clauses for each step
|
||||||
|
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep3 := ""
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
query = BuildThreeStepFunnelValidationQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
containsErrorT3,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
funnelSteps[2].ServiceName,
|
||||||
|
funnelSteps[2].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
clauseStep3,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
query = BuildTwoStepFunnelValidationQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &v3.ClickHouseQuery{
|
||||||
|
Query: query,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFunnelAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange) (*v3.ClickHouseQuery, error) {
|
||||||
|
var query string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
funnelSteps := funnel.Steps
|
||||||
|
containsErrorT1 := 0
|
||||||
|
containsErrorT2 := 0
|
||||||
|
containsErrorT3 := 0
|
||||||
|
latencyPointerT1 := funnelSteps[0].LatencyPointer
|
||||||
|
latencyPointerT2 := funnelSteps[1].LatencyPointer
|
||||||
|
latencyPointerT3 := "start"
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
latencyPointerT3 = funnelSteps[2].LatencyPointer
|
||||||
|
}
|
||||||
|
|
||||||
|
if funnelSteps[0].HasErrors {
|
||||||
|
containsErrorT1 = 1
|
||||||
|
}
|
||||||
|
if funnelSteps[1].HasErrors {
|
||||||
|
containsErrorT2 = 1
|
||||||
|
}
|
||||||
|
if len(funnel.Steps) > 2 && funnelSteps[2].HasErrors {
|
||||||
|
containsErrorT3 = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build filter clauses for each step
|
||||||
|
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep3 := ""
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
query = BuildThreeStepFunnelOverviewQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
containsErrorT3,
|
||||||
|
latencyPointerT1,
|
||||||
|
latencyPointerT2,
|
||||||
|
latencyPointerT3,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
funnelSteps[2].ServiceName,
|
||||||
|
funnelSteps[2].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
clauseStep3,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
query = BuildTwoStepFunnelOverviewQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
latencyPointerT1,
|
||||||
|
latencyPointerT2,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return &v3.ClickHouseQuery{Query: query}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFunnelStepAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange, stepStart, stepEnd int64) (*v3.ClickHouseQuery, error) {
|
||||||
|
var query string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
funnelSteps := funnel.Steps
|
||||||
|
containsErrorT1 := 0
|
||||||
|
containsErrorT2 := 0
|
||||||
|
containsErrorT3 := 0
|
||||||
|
latencyPointerT1 := funnelSteps[0].LatencyPointer
|
||||||
|
latencyPointerT2 := funnelSteps[1].LatencyPointer
|
||||||
|
latencyPointerT3 := "start"
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
latencyPointerT3 = funnelSteps[2].LatencyPointer
|
||||||
|
}
|
||||||
|
latencyTypeT2 := "p99"
|
||||||
|
latencyTypeT3 := "p99"
|
||||||
|
|
||||||
|
if stepStart == stepEnd {
|
||||||
|
return nil, fmt.Errorf("step start and end cannot be the same for /step/overview")
|
||||||
|
}
|
||||||
|
|
||||||
|
if funnelSteps[0].HasErrors {
|
||||||
|
containsErrorT1 = 1
|
||||||
|
}
|
||||||
|
if funnelSteps[1].HasErrors {
|
||||||
|
containsErrorT2 = 1
|
||||||
|
}
|
||||||
|
if len(funnel.Steps) > 2 && funnelSteps[2].HasErrors {
|
||||||
|
containsErrorT3 = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if funnelSteps[1].LatencyType != "" {
|
||||||
|
latencyTypeT2 = strings.ToLower(funnelSteps[1].LatencyType)
|
||||||
|
}
|
||||||
|
if len(funnel.Steps) > 2 && funnelSteps[2].LatencyType != "" {
|
||||||
|
latencyTypeT3 = strings.ToLower(funnelSteps[2].LatencyType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build filter clauses for each step
|
||||||
|
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep3 := ""
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
query = BuildThreeStepFunnelStepOverviewQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
containsErrorT3,
|
||||||
|
latencyPointerT1,
|
||||||
|
latencyPointerT2,
|
||||||
|
latencyPointerT3,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
funnelSteps[2].ServiceName,
|
||||||
|
funnelSteps[2].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
clauseStep3,
|
||||||
|
stepStart,
|
||||||
|
stepEnd,
|
||||||
|
latencyTypeT2,
|
||||||
|
latencyTypeT3,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
query = BuildTwoStepFunnelStepOverviewQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
latencyPointerT1,
|
||||||
|
latencyPointerT2,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
latencyTypeT2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return &v3.ClickHouseQuery{Query: query}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStepAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange) (*v3.ClickHouseQuery, error) {
|
||||||
|
var query string
|
||||||
|
|
||||||
|
funnelSteps := funnel.Steps
|
||||||
|
containsErrorT1 := 0
|
||||||
|
containsErrorT2 := 0
|
||||||
|
containsErrorT3 := 0
|
||||||
|
|
||||||
|
if funnelSteps[0].HasErrors {
|
||||||
|
containsErrorT1 = 1
|
||||||
|
}
|
||||||
|
if funnelSteps[1].HasErrors {
|
||||||
|
containsErrorT2 = 1
|
||||||
|
}
|
||||||
|
if len(funnel.Steps) > 2 && funnelSteps[2].HasErrors {
|
||||||
|
containsErrorT3 = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build filter clauses for each step
|
||||||
|
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[0].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[1].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep3 := ""
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
clauseStep3, err = tracev4.BuildTracesFilterQuery(funnelSteps[2].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(funnel.Steps) > 2 {
|
||||||
|
query = BuildThreeStepFunnelCountQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
containsErrorT3,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
funnelSteps[2].ServiceName,
|
||||||
|
funnelSteps[2].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
clauseStep3,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
query = BuildTwoStepFunnelCountQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[0].ServiceName,
|
||||||
|
funnelSteps[0].SpanName,
|
||||||
|
funnelSteps[1].ServiceName,
|
||||||
|
funnelSteps[1].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &v3.ClickHouseQuery{
|
||||||
|
Query: query,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSlowestTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange, stepStart, stepEnd int64) (*v3.ClickHouseQuery, error) {
|
||||||
|
funnelSteps := funnel.Steps
|
||||||
|
containsErrorT1 := 0
|
||||||
|
containsErrorT2 := 0
|
||||||
|
stepStartOrder := 0
|
||||||
|
stepEndOrder := 1
|
||||||
|
|
||||||
|
if stepStart != stepEnd {
|
||||||
|
stepStartOrder = int(stepStart) - 1
|
||||||
|
stepEndOrder = int(stepEnd) - 1
|
||||||
|
if funnelSteps[stepStartOrder].HasErrors {
|
||||||
|
containsErrorT1 = 1
|
||||||
|
}
|
||||||
|
if funnelSteps[stepEndOrder].HasErrors {
|
||||||
|
containsErrorT2 = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build filter clauses for the steps
|
||||||
|
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepStartOrder].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepEndOrder].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
query := BuildTwoStepFunnelTopSlowTracesQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[stepStartOrder].ServiceName,
|
||||||
|
funnelSteps[stepStartOrder].SpanName,
|
||||||
|
funnelSteps[stepEndOrder].ServiceName,
|
||||||
|
funnelSteps[stepEndOrder].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
)
|
||||||
|
return &v3.ClickHouseQuery{Query: query}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetErroredTraces(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange, stepStart, stepEnd int64) (*v3.ClickHouseQuery, error) {
|
||||||
|
funnelSteps := funnel.Steps
|
||||||
|
containsErrorT1 := 0
|
||||||
|
containsErrorT2 := 0
|
||||||
|
stepStartOrder := 0
|
||||||
|
stepEndOrder := 1
|
||||||
|
|
||||||
|
if stepStart != stepEnd {
|
||||||
|
stepStartOrder = int(stepStart) - 1
|
||||||
|
stepEndOrder = int(stepEnd) - 1
|
||||||
|
if funnelSteps[stepStartOrder].HasErrors {
|
||||||
|
containsErrorT1 = 1
|
||||||
|
}
|
||||||
|
if funnelSteps[stepEndOrder].HasErrors {
|
||||||
|
containsErrorT2 = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build filter clauses for the steps
|
||||||
|
clauseStep1, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepStartOrder].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clauseStep2, err := tracev4.BuildTracesFilterQuery(funnelSteps[stepEndOrder].Filters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
query := BuildTwoStepFunnelTopSlowErrorTracesQuery(
|
||||||
|
containsErrorT1,
|
||||||
|
containsErrorT2,
|
||||||
|
timeRange.StartTime,
|
||||||
|
timeRange.EndTime,
|
||||||
|
funnelSteps[stepStartOrder].ServiceName,
|
||||||
|
funnelSteps[stepStartOrder].SpanName,
|
||||||
|
funnelSteps[stepEndOrder].ServiceName,
|
||||||
|
funnelSteps[stepEndOrder].SpanName,
|
||||||
|
clauseStep1,
|
||||||
|
clauseStep2,
|
||||||
|
)
|
||||||
|
return &v3.ClickHouseQuery{Query: query}, nil
|
||||||
|
}
|
@ -40,6 +40,7 @@ import (
|
|||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
|
||||||
"github.com/SigNoz/signoz/pkg/cache"
|
"github.com/SigNoz/signoz/pkg/cache"
|
||||||
|
traceFunnelsModule "github.com/SigNoz/signoz/pkg/modules/tracefunnel"
|
||||||
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
|
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
|
||||||
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
|
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
|
||||||
"github.com/SigNoz/signoz/pkg/query-service/app/inframetrics"
|
"github.com/SigNoz/signoz/pkg/query-service/app/inframetrics"
|
||||||
@ -63,6 +64,7 @@ import (
|
|||||||
"github.com/SigNoz/signoz/pkg/types/featuretypes"
|
"github.com/SigNoz/signoz/pkg/types/featuretypes"
|
||||||
"github.com/SigNoz/signoz/pkg/types/pipelinetypes"
|
"github.com/SigNoz/signoz/pkg/types/pipelinetypes"
|
||||||
ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes"
|
ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes"
|
||||||
|
traceFunnels "github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
@ -5255,4 +5257,240 @@ func (aH *APIHandler) RegisterTraceFunnelsRoutes(router *mux.Router, am *middlew
|
|||||||
traceFunnelsRouter.HandleFunc("/{funnel_id}",
|
traceFunnelsRouter.HandleFunc("/{funnel_id}",
|
||||||
am.ViewAccess(aH.Signoz.Handlers.TraceFunnel.UpdateFunnel)).
|
am.ViewAccess(aH.Signoz.Handlers.TraceFunnel.UpdateFunnel)).
|
||||||
Methods(http.MethodPut)
|
Methods(http.MethodPut)
|
||||||
|
|
||||||
|
// Analytics endpoints
|
||||||
|
traceFunnelsRouter.HandleFunc("/{funnel_id}/analytics/validate", aH.handleValidateTraces).Methods("POST")
|
||||||
|
traceFunnelsRouter.HandleFunc("/{funnel_id}/analytics/overview", aH.handleFunnelAnalytics).Methods("POST")
|
||||||
|
traceFunnelsRouter.HandleFunc("/{funnel_id}/analytics/steps", aH.handleStepAnalytics).Methods("POST")
|
||||||
|
traceFunnelsRouter.HandleFunc("/{funnel_id}/analytics/steps/overview", aH.handleFunnelStepAnalytics).Methods("POST")
|
||||||
|
traceFunnelsRouter.HandleFunc("/{funnel_id}/analytics/slow-traces", aH.handleFunnelSlowTraces).Methods("POST")
|
||||||
|
traceFunnelsRouter.HandleFunc("/{funnel_id}/analytics/error-traces", aH.handleFunnelErrorTraces).Methods("POST")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) handleValidateTraces(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
funnelID := vars["funnel_id"]
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
render.Error(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
funnel, err := aH.Signoz.Modules.TraceFunnel.Get(r.Context(), valuer.MustNewUUID(funnelID), valuer.MustNewUUID(claims.OrgID))
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorNotFound, Err: fmt.Errorf("funnel not found: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeRange traceFunnels.TimeRange
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&timeRange); err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("error decoding time range: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(funnel.Steps) < 2 {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("funnel must have at least 2 steps")}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := traceFunnelsModule.ValidateTraces(funnel, timeRange)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error building clickhouse query: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error converting clickhouse results to list: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.Respond(w, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) handleFunnelAnalytics(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
funnelID := vars["funnel_id"]
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
render.Error(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
funnel, err := aH.Signoz.Modules.TraceFunnel.Get(r.Context(), valuer.MustNewUUID(funnelID), valuer.MustNewUUID(claims.OrgID))
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorNotFound, Err: fmt.Errorf("funnel not found: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var stepTransition traceFunnels.StepTransitionRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&stepTransition); err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("error decoding time range: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := traceFunnelsModule.GetFunnelAnalytics(funnel, stepTransition.TimeRange)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error building clickhouse query: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error converting clickhouse results to list: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.Respond(w, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) handleFunnelStepAnalytics(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
funnelID := vars["funnel_id"]
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
render.Error(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
funnel, err := aH.Signoz.Modules.TraceFunnel.Get(r.Context(), valuer.MustNewUUID(funnelID), valuer.MustNewUUID(claims.OrgID))
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorNotFound, Err: fmt.Errorf("funnel not found: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var stepTransition traceFunnels.StepTransitionRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&stepTransition); err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("error decoding time range: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := traceFunnelsModule.GetFunnelStepAnalytics(funnel, stepTransition.TimeRange, stepTransition.StepStart, stepTransition.StepEnd)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error building clickhouse query: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error converting clickhouse results to list: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.Respond(w, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) handleStepAnalytics(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
funnelID := vars["funnel_id"]
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
render.Error(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
funnel, err := aH.Signoz.Modules.TraceFunnel.Get(r.Context(), valuer.MustNewUUID(funnelID), valuer.MustNewUUID(claims.OrgID))
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorNotFound, Err: fmt.Errorf("funnel not found: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeRange traceFunnels.TimeRange
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&timeRange); err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("error decoding time range: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := traceFunnelsModule.GetStepAnalytics(funnel, timeRange)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error building clickhouse query: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error converting clickhouse results to list: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.Respond(w, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) handleFunnelSlowTraces(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
funnelID := vars["funnel_id"]
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
render.Error(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
funnel, err := aH.Signoz.Modules.TraceFunnel.Get(r.Context(), valuer.MustNewUUID(funnelID), valuer.MustNewUUID(claims.OrgID))
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorNotFound, Err: fmt.Errorf("funnel not found: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req traceFunnels.StepTransitionRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("invalid request body: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := traceFunnelsModule.GetSlowestTraces(funnel, req.TimeRange, req.StepStart, req.StepEnd)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error building clickhouse query: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error converting clickhouse results to list: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.Respond(w, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aH *APIHandler) handleFunnelErrorTraces(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
funnelID := vars["funnel_id"]
|
||||||
|
|
||||||
|
claims, err := authtypes.ClaimsFromContext(r.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
render.Error(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
funnel, err := aH.Signoz.Modules.TraceFunnel.Get(r.Context(), valuer.MustNewUUID(funnelID), valuer.MustNewUUID(claims.OrgID))
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorNotFound, Err: fmt.Errorf("funnel not found: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req traceFunnels.StepTransitionRequest
|
||||||
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("invalid request body: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chq, err := traceFunnelsModule.GetErroredTraces(funnel, req.TimeRange, req.StepStart, req.StepEnd)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error building clickhouse query: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := aH.reader.GetListResultV3(r.Context(), chq.Query)
|
||||||
|
if err != nil {
|
||||||
|
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: fmt.Errorf("error converting clickhouse results to list: %v", err)}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
aH.Respond(w, results)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user