Skip to content

Commit 9d20c2f

Browse files
authored
feat: add resource tags to ListErrors API (SigNoz#2487)
1 parent 8ea0f72 commit 9d20c2f

File tree

5 files changed

+136
-95
lines changed

5 files changed

+136
-95
lines changed

pkg/query-service/app/clickhouseReader/reader.go

+27-15
Original file line numberDiff line numberDiff line change
@@ -1464,13 +1464,13 @@ func createTagQueryFromTagQueryParams(queryParams []model.TagQueryParam) []model
14641464
tags := []model.TagQuery{}
14651465
for _, tag := range queryParams {
14661466
if len(tag.StringValues) > 0 {
1467-
tags = append(tags, model.NewTagQueryString(tag.Key, tag.StringValues, tag.Operator))
1467+
tags = append(tags, model.NewTagQueryString(tag))
14681468
}
14691469
if len(tag.NumberValues) > 0 {
1470-
tags = append(tags, model.NewTagQueryNumber(tag.Key, tag.NumberValues, tag.Operator))
1470+
tags = append(tags, model.NewTagQueryNumber(tag))
14711471
}
14721472
if len(tag.BoolValues) > 0 {
1473-
tags = append(tags, model.NewTagQueryBool(tag.Key, tag.BoolValues, tag.Operator))
1473+
tags = append(tags, model.NewTagQueryBool(tag))
14741474
}
14751475
}
14761476
return tags
@@ -1494,18 +1494,7 @@ func buildQueryWithTagParams(ctx context.Context, tags []model.TagQuery) (string
14941494
for _, item := range tags {
14951495
var subQuery string
14961496
var argsSubQuery []interface{}
1497-
tagMapType := ""
1498-
switch item.(type) {
1499-
case model.TagQueryString:
1500-
tagMapType = constants.StringTagMapCol
1501-
case model.TagQueryNumber:
1502-
tagMapType = constants.NumberTagMapCol
1503-
case model.TagQueryBool:
1504-
tagMapType = constants.BoolTagMapCol
1505-
default:
1506-
// type not supported error
1507-
return "", nil, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("type not supported")}
1508-
}
1497+
tagMapType := item.GetTagMapColumn()
15091498
switch item.GetOperator() {
15101499
case model.EqualOperator:
15111500
subQuery, argsSubQuery = addArithmeticOperator(item, tagMapType, "=")
@@ -2698,6 +2687,17 @@ func (r *ClickHouseReader) ListErrors(ctx context.Context, queryParams *model.Li
26982687
query = query + " AND exceptionType ilike @exceptionType"
26992688
args = append(args, clickhouse.Named("exceptionType", "%"+queryParams.ExceptionType+"%"))
27002689
}
2690+
2691+
// create TagQuery from TagQueryParams
2692+
tags := createTagQueryFromTagQueryParams(queryParams.Tags)
2693+
subQuery, argsSubQuery, errStatus := buildQueryWithTagParams(ctx, tags)
2694+
query += subQuery
2695+
args = append(args, argsSubQuery...)
2696+
2697+
if errStatus != nil {
2698+
zap.S().Error("Error in processing tags: ", errStatus)
2699+
return nil, errStatus
2700+
}
27012701
query = query + " GROUP BY groupID"
27022702
if len(queryParams.ServiceName) != 0 {
27032703
query = query + ", serviceName"
@@ -2747,6 +2747,18 @@ func (r *ClickHouseReader) CountErrors(ctx context.Context, queryParams *model.C
27472747
query = query + " AND exceptionType ilike @exceptionType"
27482748
args = append(args, clickhouse.Named("exceptionType", "%"+queryParams.ExceptionType+"%"))
27492749
}
2750+
2751+
// create TagQuery from TagQueryParams
2752+
tags := createTagQueryFromTagQueryParams(queryParams.Tags)
2753+
subQuery, argsSubQuery, errStatus := buildQueryWithTagParams(ctx, tags)
2754+
query += subQuery
2755+
args = append(args, argsSubQuery...)
2756+
2757+
if errStatus != nil {
2758+
zap.S().Error("Error in processing tags: ", errStatus)
2759+
return 0, errStatus
2760+
}
2761+
27502762
err := r.db.QueryRow(ctx, query, args...).Scan(&errorCount)
27512763
zap.S().Info(query)
27522764

pkg/query-service/app/http_handler.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,8 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *AuthMiddleware) {
328328
router.HandleFunc("/api/v1/getFilteredSpans/aggregates", am.ViewAccess(aH.getFilteredSpanAggregates)).Methods(http.MethodPost)
329329
router.HandleFunc("/api/v1/getTagValues", am.ViewAccess(aH.getTagValues)).Methods(http.MethodPost)
330330

331-
router.HandleFunc("/api/v1/listErrors", am.ViewAccess(aH.listErrors)).Methods(http.MethodGet)
332-
router.HandleFunc("/api/v1/countErrors", am.ViewAccess(aH.countErrors)).Methods(http.MethodGet)
331+
router.HandleFunc("/api/v1/listErrors", am.ViewAccess(aH.listErrors)).Methods(http.MethodPost)
332+
router.HandleFunc("/api/v1/countErrors", am.ViewAccess(aH.countErrors)).Methods(http.MethodPost)
333333
router.HandleFunc("/api/v1/errorFromErrorID", am.ViewAccess(aH.getErrorFromErrorID)).Methods(http.MethodGet)
334334
router.HandleFunc("/api/v1/errorFromGroupID", am.ViewAccess(aH.getErrorFromGroupID)).Methods(http.MethodGet)
335335
router.HandleFunc("/api/v1/nextPrevErrorIDs", am.ViewAccess(aH.getNextPrevErrorIDs)).Methods(http.MethodGet)

pkg/query-service/app/parser.go

+24-46
Original file line numberDiff line numberDiff line change
@@ -494,76 +494,54 @@ func parseListErrorsRequest(r *http.Request) (*model.ListErrorsParams, error) {
494494
var allowedOrderParams = []string{"exceptionType", "exceptionCount", "firstSeen", "lastSeen", "serviceName"}
495495
var allowedOrderDirections = []string{"ascending", "descending"}
496496

497-
startTime, err := parseTime("start", r)
497+
var postData *model.ListErrorsParams
498+
err := json.NewDecoder(r.Body).Decode(&postData)
499+
498500
if err != nil {
499501
return nil, err
500502
}
501-
endTime, err := parseTimeMinusBuffer("end", r)
503+
504+
postData.Start, err = parseTimeStr(postData.StartStr, "start")
502505
if err != nil {
503506
return nil, err
504507
}
505-
506-
order := r.URL.Query().Get("order")
507-
if len(order) > 0 && !DoesExistInSlice(order, allowedOrderDirections) {
508-
return nil, errors.New(fmt.Sprintf("given order: %s is not allowed in query", order))
509-
}
510-
orderParam := r.URL.Query().Get("orderParam")
511-
if len(order) > 0 && !DoesExistInSlice(orderParam, allowedOrderParams) {
512-
return nil, errors.New(fmt.Sprintf("given orderParam: %s is not allowed in query", orderParam))
508+
postData.End, err = parseTimeMinusBufferStr(postData.EndStr, "end")
509+
if err != nil {
510+
return nil, err
513511
}
514-
limit := r.URL.Query().Get("limit")
515-
offset := r.URL.Query().Get("offset")
516-
517-
if len(offset) == 0 || len(limit) == 0 {
518-
return nil, fmt.Errorf("offset or limit param cannot be empty from the query")
512+
if postData.Limit == 0 {
513+
return nil, fmt.Errorf("limit param cannot be empty from the query")
519514
}
520515

521-
limitInt, err := strconv.Atoi(limit)
522-
if err != nil {
523-
return nil, errors.New("limit param is not in correct format")
524-
}
525-
offsetInt, err := strconv.Atoi(offset)
526-
if err != nil {
527-
return nil, errors.New("offset param is not in correct format")
516+
if len(postData.Order) > 0 && !DoesExistInSlice(postData.Order, allowedOrderDirections) {
517+
return nil, errors.New(fmt.Sprintf("given order: %s is not allowed in query", postData.Order))
528518
}
529-
serviceName := r.URL.Query().Get("serviceName")
530-
exceptionType := r.URL.Query().Get("exceptionType")
531519

532-
params := &model.ListErrorsParams{
533-
Start: startTime,
534-
End: endTime,
535-
OrderParam: orderParam,
536-
Order: order,
537-
Limit: int64(limitInt),
538-
Offset: int64(offsetInt),
539-
ServiceName: serviceName,
540-
ExceptionType: exceptionType,
520+
if len(postData.Order) > 0 && !DoesExistInSlice(postData.OrderParam, allowedOrderParams) {
521+
return nil, errors.New(fmt.Sprintf("given orderParam: %s is not allowed in query", postData.OrderParam))
541522
}
542523

543-
return params, nil
524+
return postData, nil
544525
}
545526

546527
func parseCountErrorsRequest(r *http.Request) (*model.CountErrorsParams, error) {
547528

548-
startTime, err := parseTime("start", r)
529+
var postData *model.CountErrorsParams
530+
err := json.NewDecoder(r.Body).Decode(&postData)
531+
549532
if err != nil {
550533
return nil, err
551534
}
552-
endTime, err := parseTimeMinusBuffer("end", r)
535+
536+
postData.Start, err = parseTimeStr(postData.StartStr, "start")
553537
if err != nil {
554538
return nil, err
555539
}
556-
serviceName := r.URL.Query().Get("serviceName")
557-
exceptionType := r.URL.Query().Get("exceptionType")
558-
559-
params := &model.CountErrorsParams{
560-
Start: startTime,
561-
End: endTime,
562-
ServiceName: serviceName,
563-
ExceptionType: exceptionType,
540+
postData.End, err = parseTimeMinusBufferStr(postData.EndStr, "end")
541+
if err != nil {
542+
return nil, err
564543
}
565-
566-
return params, nil
544+
return postData, nil
567545
}
568546

569547
func parseGetErrorRequest(r *http.Request) (*model.GetErrorParams, error) {

pkg/query-service/constants/constants.go

-6
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,5 @@ var ReservedColumnTargetAliases = map[string]struct{}{
219219
"value": {},
220220
}
221221

222-
const (
223-
StringTagMapCol = "stringTagMap"
224-
NumberTagMapCol = "numberTagMap"
225-
BoolTagMapCol = "boolTagMap"
226-
)
227-
228222
// logsPPLPfx is a short constant for logsPipelinePrefix
229223
const LogsPPLPfx = "logstransform/pipeline_"

0 commit comments

Comments
 (0)