Files
signoz/pkg/modules/spanpercentile/implspanpercentile/module.go
Vikrant Gupta bad80399a6
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
feat(serviceaccount): integrate service account (#10681)
* feat(serviceaccount): integrate service account

* feat(serviceaccount): integrate service account with better types

* feat(serviceaccount): fix lint and testing changes

* feat(serviceaccount): update integration tests

* feat(serviceaccount): fix formatting

* feat(serviceaccount): fix openapi spec

* feat(serviceaccount): update txlock to immediate to avoid busy snapshot errors

* feat(serviceaccount): add restrictions for factor_api_key

* feat(serviceaccount): add restrictions for factor_api_key

* feat: enabled service account and deprecated API Keys (#10715)

* feat: enabled service account and deprecated API Keys

* feat: deprecated API Keys

* feat: service account spec updates and role management changes

* feat: updated the error component for roles management

* feat: updated test case

* feat: updated the error component and added retries

* feat: refactored code and added retry to happend 3 times total

* feat: fixed feedbacks and added test case

* feat: refactored code and removed retry

* feat: updated the test cases

---------

Co-authored-by: SagarRajput-7 <162284829+SagarRajput-7@users.noreply.github.com>
2026-04-01 07:20:59 +00:00

133 lines
4.0 KiB
Go

package implspanpercentile
import (
"context"
"fmt"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/modules/spanpercentile"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/types/ctxtypes"
"github.com/SigNoz/signoz/pkg/types/instrumentationtypes"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/types/spanpercentiletypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
type module struct {
querier querier.Querier
}
func NewModule(
querier querier.Querier,
_ factory.ProviderSettings,
) spanpercentile.Module {
return &module{
querier: querier,
}
}
func (m *module) GetSpanPercentile(ctx context.Context, orgID valuer.UUID, req *spanpercentiletypes.SpanPercentileRequest) (*spanpercentiletypes.SpanPercentileResponse, error) {
ctx = ctxtypes.NewContextWithCommentVals(ctx, map[string]string{
instrumentationtypes.CodeNamespace: "spanpercentile",
instrumentationtypes.CodeFunctionName: "GetSpanPercentile",
})
queryRangeRequest, err := buildSpanPercentileQuery(ctx, req)
if err != nil {
return nil, err
}
if err := queryRangeRequest.Validate(); err != nil {
return nil, err
}
result, err := m.querier.QueryRange(ctx, orgID, queryRangeRequest)
if err != nil {
return nil, err
}
return transformToSpanPercentileResponse(result)
}
func transformToSpanPercentileResponse(queryResult *qbtypes.QueryRangeResponse) (*spanpercentiletypes.SpanPercentileResponse, error) {
if len(queryResult.Data.Results) == 0 {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "no data returned from query")
}
scalarData, ok := queryResult.Data.Results[0].(*qbtypes.ScalarData)
if !ok {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "unexpected result type")
}
if len(scalarData.Data) == 0 {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "no rows returned from query")
}
row := scalarData.Data[0]
columnMap := make(map[string]int)
for i, col := range scalarData.Columns {
columnMap[col.Name] = i
}
p50Idx, ok := columnMap["__result_0"]
if !ok {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "missing __result_0 column")
}
p90Idx, ok := columnMap["__result_1"]
if !ok {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "missing __result_1 column")
}
p99Idx, ok := columnMap["__result_2"]
if !ok {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "missing __result_2 column")
}
positionIdx, ok := columnMap["__result_3"]
if !ok {
return nil, errors.New(errors.TypeInternal, errors.CodeInternal, "missing __result_3 column")
}
p50, err := toFloat64(row[p50Idx])
if err != nil {
return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, "no spans found matching the specified criteria")
}
p90, err := toFloat64(row[p90Idx])
if err != nil {
return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, "no spans found matching the specified criteria")
}
p99, err := toFloat64(row[p99Idx])
if err != nil {
return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, "no spans found matching the specified criteria")
}
position, err := toFloat64(row[positionIdx])
if err != nil {
return nil, errors.New(errors.TypeNotFound, errors.CodeNotFound, "no spans found matching the specified criteria")
}
description := fmt.Sprintf("slower than %.1f%% of spans", position)
if position < 50 {
description = fmt.Sprintf("faster than %.1f%% of spans", 100-position)
}
return &spanpercentiletypes.SpanPercentileResponse{
Percentiles: spanpercentiletypes.PercentileStats{
P50: p50,
P90: p90,
P99: p99,
},
Position: spanpercentiletypes.PercentilePosition{
Percentile: position,
Description: description,
},
}, nil
}
func toFloat64(val any) (float64, error) {
result, ok := val.(float64)
if !ok {
return 0, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "cannot convert %T to float64", val)
}
return result, nil
}