mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-12 08:13:19 +00:00
* feat: add span percentile for traces * feat: fixed merge conflicts * feat: fixed merge conflicts * feat: fixed merge conflicts * feat: added span percentile * feat: added span percentile * feat: added test for span percentiles * feat: added test for span percentiles * feat: added test for span percentiles * feat: added test for span percentiles * feat: removed comments * feat: moved everything to module * feat: refactored span percentile * feat: refactored span percentile * feat: refactored module package * feat: fixed tests for span percentile * feat: refactored span percentile and changed query * feat: refactored span percentile and changed query * feat: refactored span percentile and changed query * feat: refactored span percentile and changed query * feat: added better error handling * feat: added better error handling * feat: addressed pr comments * feat: addressed pr comments * feat: renamed translator.go * feat: added query settings * feat: added full query test * feat: added fingerprinting * feat: refactored tests * feat: refactored to use fingerprinting and changed tests * feat: refactored to use fingerprinting and changed tests * feat: refactored to use fingerprinting and changed tests * feat: changed errors * feat: removed redundant tests * feat: removed redundant tests * feat: moved everything to trace aggregation and updated tests * feat: addressed comments regarding metadatastore * feat: addressed comments regarding metadatastore * feat: addressed comments regarding metadatastore * feat: addressed comments for float64 * feat: cleaned up code * feat: cleaned up code
119 lines
3.0 KiB
Go
119 lines
3.0 KiB
Go
package implspanpercentile
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
|
"github.com/SigNoz/signoz/pkg/types/spanpercentiletypes"
|
|
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
|
)
|
|
|
|
func buildSpanPercentileQuery(
|
|
_ context.Context,
|
|
req *spanpercentiletypes.SpanPercentileRequest,
|
|
) (*qbtypes.QueryRangeRequest, error) {
|
|
if err := req.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var attrKeys []string
|
|
for key := range req.ResourceAttributes {
|
|
attrKeys = append(attrKeys, key)
|
|
}
|
|
sort.Strings(attrKeys)
|
|
|
|
filterConditions := []string{
|
|
fmt.Sprintf("service.name = '%s'", strings.ReplaceAll(req.ServiceName, "'", `\'`)),
|
|
fmt.Sprintf("name = '%s'", strings.ReplaceAll(req.Name, "'", `\'`)),
|
|
}
|
|
|
|
for _, key := range attrKeys {
|
|
value := req.ResourceAttributes[key]
|
|
filterConditions = append(filterConditions,
|
|
fmt.Sprintf("%s = '%s'", key, strings.ReplaceAll(value, "'", `\'`)))
|
|
}
|
|
|
|
filterExpr := strings.Join(filterConditions, " AND ")
|
|
|
|
groupByKeys := []qbtypes.GroupByKey{
|
|
{
|
|
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{
|
|
Name: "service.name",
|
|
Signal: telemetrytypes.SignalTraces,
|
|
FieldContext: telemetrytypes.FieldContextResource,
|
|
FieldDataType: telemetrytypes.FieldDataTypeString,
|
|
},
|
|
},
|
|
{
|
|
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{
|
|
Name: "name",
|
|
Signal: telemetrytypes.SignalTraces,
|
|
FieldContext: telemetrytypes.FieldContextSpan,
|
|
FieldDataType: telemetrytypes.FieldDataTypeString,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, key := range attrKeys {
|
|
groupByKeys = append(groupByKeys, qbtypes.GroupByKey{
|
|
TelemetryFieldKey: telemetrytypes.TelemetryFieldKey{
|
|
Name: key,
|
|
Signal: telemetrytypes.SignalTraces,
|
|
FieldContext: telemetrytypes.FieldContextResource,
|
|
FieldDataType: telemetrytypes.FieldDataTypeString,
|
|
},
|
|
})
|
|
}
|
|
|
|
query := qbtypes.QueryBuilderQuery[qbtypes.TraceAggregation]{
|
|
Name: "span_percentile",
|
|
Signal: telemetrytypes.SignalTraces,
|
|
Aggregations: []qbtypes.TraceAggregation{
|
|
{
|
|
Expression: "p50(duration_nano)",
|
|
Alias: "p50_duration_nano",
|
|
},
|
|
{
|
|
Expression: "p90(duration_nano)",
|
|
Alias: "p90_duration_nano",
|
|
},
|
|
{
|
|
Expression: "p99(duration_nano)",
|
|
Alias: "p99_duration_nano",
|
|
},
|
|
{
|
|
Expression: fmt.Sprintf(
|
|
"(100.0 * countIf(duration_nano <= %d)) / count()",
|
|
req.DurationNano,
|
|
),
|
|
Alias: "percentile_position",
|
|
},
|
|
},
|
|
GroupBy: groupByKeys,
|
|
Filter: &qbtypes.Filter{
|
|
Expression: filterExpr,
|
|
},
|
|
}
|
|
|
|
queryEnvelope := qbtypes.QueryEnvelope{
|
|
Type: qbtypes.QueryTypeBuilder,
|
|
Spec: query,
|
|
}
|
|
|
|
return &qbtypes.QueryRangeRequest{
|
|
SchemaVersion: "v5",
|
|
Start: req.Start,
|
|
End: req.End,
|
|
RequestType: qbtypes.RequestTypeScalar,
|
|
CompositeQuery: qbtypes.CompositeQuery{
|
|
Queries: []qbtypes.QueryEnvelope{queryEnvelope},
|
|
},
|
|
FormatOptions: &qbtypes.FormatOptions{
|
|
FormatTableResultForUI: true,
|
|
},
|
|
}, nil
|
|
}
|