mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-31 16:22:04 +08:00
feat: add search span scope in the list view tab to add the scope at per Query level (#6810)
* feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level * feat: add search span scope in the list view tab to add the scope at per query level
This commit is contained in:
parent
0cf9003e3a
commit
044a124cc1
@ -93,8 +93,8 @@ func buildTracesFilterQuery(fs *v3.FilterSet) (string, error) {
|
||||
if fs != nil && len(fs.Items) != 0 {
|
||||
for _, item := range fs.Items {
|
||||
|
||||
// skip if it's a resource attribute
|
||||
if item.Key.Type == v3.AttributeKeyTypeResource {
|
||||
// skip if it's a resource attribute or Span search scope attribute
|
||||
if item.Key.Type == v3.AttributeKeyTypeResource || item.Key.Type == v3.AttributeKeyTypeSpanSearchScope {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -213,6 +213,31 @@ func orderByAttributeKeyTags(panelType v3.PanelType, items []v3.OrderBy, tags []
|
||||
return str
|
||||
}
|
||||
|
||||
func buildSpanScopeQuery(fs *v3.FilterSet) (string, error) {
|
||||
var query string
|
||||
if fs == nil || len(fs.Items) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
for _, item := range fs.Items {
|
||||
// skip anything other than Span Search scope attribute
|
||||
if item.Key.Type != v3.AttributeKeyTypeSpanSearchScope {
|
||||
continue
|
||||
}
|
||||
keyName := strings.ToLower(item.Key.Key)
|
||||
|
||||
if keyName == constants.SpanSearchScopeRoot {
|
||||
query = "parent_span_id = '' "
|
||||
return query, nil
|
||||
} else if keyName == constants.SpanSearchScopeEntryPoint {
|
||||
query = "((name, `resource_string_service$$name`) IN ( SELECT DISTINCT name, serviceName from " + constants.SIGNOZ_TRACE_DBNAME + "." + constants.SIGNOZ_TOP_LEVEL_OPERATIONS_TABLENAME + " )) "
|
||||
return query, nil
|
||||
} else {
|
||||
return "", fmt.Errorf("invalid scope item type: %s", item.Key.Type)
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func buildTracesQuery(start, end, step int64, mq *v3.BuilderQuery, panelType v3.PanelType, options v3.QBOptions) (string, error) {
|
||||
tracesStart := utils.GetEpochNanoSecs(start)
|
||||
tracesEnd := utils.GetEpochNanoSecs(end)
|
||||
@ -248,6 +273,11 @@ func buildTracesQuery(start, end, step int64, mq *v3.BuilderQuery, panelType v3.
|
||||
filterSubQuery = filterSubQuery + " AND (resource_fingerprint GLOBAL IN " + resourceSubQuery + ")"
|
||||
}
|
||||
|
||||
spanScopeSubQuery, err := buildSpanScopeQuery(mq.Filters)
|
||||
if spanScopeSubQuery != "" {
|
||||
filterSubQuery = filterSubQuery + " AND " + spanScopeSubQuery
|
||||
}
|
||||
|
||||
// timerange will be sent in epoch millisecond
|
||||
selectLabels := getSelectLabels(mq.GroupBy)
|
||||
if selectLabels != "" {
|
||||
@ -274,8 +304,8 @@ func buildTracesQuery(start, end, step int64, mq *v3.BuilderQuery, panelType v3.
|
||||
if len(mq.SelectColumns) == 0 {
|
||||
return "", fmt.Errorf("select columns cannot be empty for panelType %s", panelType)
|
||||
}
|
||||
// add it to the select labels
|
||||
selectLabels = getSelectLabels(mq.SelectColumns)
|
||||
// add it to the select labels
|
||||
queryNoOpTmpl := fmt.Sprintf("SELECT timestamp as timestamp_datetime, spanID, traceID,%s ", selectLabels) + "from " + constants.SIGNOZ_TRACE_DBNAME + "." + constants.SIGNOZ_SPAN_INDEX_V3 + " where %s %s" + "%s"
|
||||
query = fmt.Sprintf(queryNoOpTmpl, timeFilter, filterSubQuery, orderBy)
|
||||
} else {
|
||||
|
@ -552,6 +552,70 @@ func Test_buildTracesQuery(t *testing.T) {
|
||||
want: "SELECT timestamp as timestamp_datetime, spanID, traceID, name as `name` from signoz_traces.distributed_signoz_index_v3 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " +
|
||||
"AND (ts_bucket_start >= 1680064560 AND ts_bucket_start <= 1680066458) order by timestamp ASC",
|
||||
},
|
||||
{
|
||||
name: "test noop list view with entry_point_spans",
|
||||
args: args{
|
||||
panelType: v3.PanelTypeList,
|
||||
start: 1680066360726210000,
|
||||
end: 1680066458000000000,
|
||||
mq: &v3.BuilderQuery{
|
||||
AggregateOperator: v3.AggregateOperatorNoOp,
|
||||
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{{Key: v3.AttributeKey{Key: "isEntryPoint", Type: v3.AttributeKeyTypeSpanSearchScope, IsColumn: false}, Value: true, Operator: v3.FilterOperatorEqual}}},
|
||||
SelectColumns: []v3.AttributeKey{{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}},
|
||||
OrderBy: []v3.OrderBy{{ColumnName: "timestamp", Order: "ASC"}},
|
||||
},
|
||||
},
|
||||
want: "SELECT timestamp as timestamp_datetime, spanID, traceID, name as `name` from signoz_traces.distributed_signoz_index_v3 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " +
|
||||
"AND (ts_bucket_start >= 1680064560 AND ts_bucket_start <= 1680066458) AND ((name, `resource_string_service$$name`) IN ( SELECT DISTINCT name, serviceName from signoz_traces.distributed_top_level_operations )) order by timestamp ASC",
|
||||
},
|
||||
{
|
||||
name: "test noop list view with root_spans",
|
||||
args: args{
|
||||
panelType: v3.PanelTypeList,
|
||||
start: 1680066360726210000,
|
||||
end: 1680066458000000000,
|
||||
mq: &v3.BuilderQuery{
|
||||
AggregateOperator: v3.AggregateOperatorNoOp,
|
||||
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{{Key: v3.AttributeKey{Key: "isRoot", Type: v3.AttributeKeyTypeSpanSearchScope, IsColumn: false}, Value: true, Operator: v3.FilterOperatorEqual}}},
|
||||
SelectColumns: []v3.AttributeKey{{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}},
|
||||
OrderBy: []v3.OrderBy{{ColumnName: "timestamp", Order: "ASC"}},
|
||||
},
|
||||
},
|
||||
want: "SELECT timestamp as timestamp_datetime, spanID, traceID, name as `name` from signoz_traces.distributed_signoz_index_v3 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " +
|
||||
"AND (ts_bucket_start >= 1680064560 AND ts_bucket_start <= 1680066458) AND parent_span_id = '' order by timestamp ASC",
|
||||
},
|
||||
{
|
||||
name: "test noop list view with root_spans and entry_point_spans both existing",
|
||||
args: args{
|
||||
panelType: v3.PanelTypeList,
|
||||
start: 1680066360726210000,
|
||||
end: 1680066458000000000,
|
||||
mq: &v3.BuilderQuery{
|
||||
AggregateOperator: v3.AggregateOperatorNoOp,
|
||||
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{{Key: v3.AttributeKey{Key: "isRoot", Type: v3.AttributeKeyTypeSpanSearchScope, IsColumn: false}, Value: true, Operator: v3.FilterOperatorEqual}, {Key: v3.AttributeKey{Key: "isEntryPoint", Type: v3.AttributeKeyTypeSpanSearchScope, IsColumn: false}, Value: true, Operator: v3.FilterOperatorEqual}}},
|
||||
SelectColumns: []v3.AttributeKey{{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}},
|
||||
OrderBy: []v3.OrderBy{{ColumnName: "timestamp", Order: "ASC"}},
|
||||
},
|
||||
},
|
||||
want: "SELECT timestamp as timestamp_datetime, spanID, traceID, name as `name` from signoz_traces.distributed_signoz_index_v3 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " +
|
||||
"AND (ts_bucket_start >= 1680064560 AND ts_bucket_start <= 1680066458) AND parent_span_id = '' order by timestamp ASC",
|
||||
},
|
||||
{
|
||||
name: "test noop list view with root_spans with other attributes",
|
||||
args: args{
|
||||
panelType: v3.PanelTypeList,
|
||||
start: 1680066360726210000,
|
||||
end: 1680066458000000000,
|
||||
mq: &v3.BuilderQuery{
|
||||
AggregateOperator: v3.AggregateOperatorNoOp,
|
||||
Filters: &v3.FilterSet{Operator: "AND", Items: []v3.FilterItem{{Key: v3.AttributeKey{Key: "isRoot", Type: v3.AttributeKeyTypeSpanSearchScope, IsColumn: false}, Value: true, Operator: v3.FilterOperatorEqual}, {Key: v3.AttributeKey{Key: "service.name", Type: v3.AttributeKeyTypeResource, IsColumn: true, DataType: v3.AttributeKeyDataTypeString}, Value: "cartservice", Operator: v3.FilterOperatorEqual}}},
|
||||
SelectColumns: []v3.AttributeKey{{Key: "name", DataType: v3.AttributeKeyDataTypeString, Type: v3.AttributeKeyTypeTag, IsColumn: true}},
|
||||
OrderBy: []v3.OrderBy{{ColumnName: "timestamp", Order: "ASC"}},
|
||||
},
|
||||
},
|
||||
want: "SELECT timestamp as timestamp_datetime, spanID, traceID, name as `name` from signoz_traces.distributed_signoz_index_v3 where (timestamp >= '1680066360726210000' AND timestamp <= '1680066458000000000') " +
|
||||
"AND (ts_bucket_start >= 1680064560 AND ts_bucket_start <= 1680066458) AND (resource_fingerprint GLOBAL IN (SELECT fingerprint FROM signoz_traces.distributed_traces_v3_resource WHERE (seen_at_ts_bucket_start >= 1680064560) AND (seen_at_ts_bucket_start <= 1680066458) AND simpleJSONExtractString(labels, 'service.name') = 'cartservice' AND labels like '%service.name%cartservice%')) AND parent_span_id = '' order by timestamp ASC",
|
||||
},
|
||||
{
|
||||
name: "test noop list view-without ts",
|
||||
args: args{
|
||||
|
@ -54,6 +54,9 @@ const DurationSort = "DurationSort"
|
||||
const TimestampSort = "TimestampSort"
|
||||
const PreferRPM = "PreferRPM"
|
||||
|
||||
const SpanSearchScopeRoot = "isroot"
|
||||
const SpanSearchScopeEntryPoint = "isentrypoint"
|
||||
|
||||
func GetAlertManagerApiPrefix() string {
|
||||
if os.Getenv("ALERTMANAGER_API_PREFIX") != "" {
|
||||
return os.Getenv("ALERTMANAGER_API_PREFIX")
|
||||
@ -248,6 +251,7 @@ const (
|
||||
SIGNOZ_TIMESERIES_v4_1DAY_LOCAL_TABLENAME = "time_series_v4_1day"
|
||||
SIGNOZ_TIMESERIES_v4_1WEEK_LOCAL_TABLENAME = "time_series_v4_1week"
|
||||
SIGNOZ_TIMESERIES_v4_1DAY_TABLENAME = "distributed_time_series_v4_1day"
|
||||
SIGNOZ_TOP_LEVEL_OPERATIONS_TABLENAME = "distributed_top_level_operations"
|
||||
)
|
||||
|
||||
var TimeoutExcludedRoutes = map[string]bool{
|
||||
|
@ -322,6 +322,7 @@ const (
|
||||
AttributeKeyTypeTag AttributeKeyType = "tag"
|
||||
AttributeKeyTypeResource AttributeKeyType = "resource"
|
||||
AttributeKeyTypeInstrumentationScope AttributeKeyType = "scope"
|
||||
AttributeKeyTypeSpanSearchScope AttributeKeyType = "spanSearchScope"
|
||||
)
|
||||
|
||||
func (t AttributeKeyType) String() string {
|
||||
|
Loading…
x
Reference in New Issue
Block a user