Merge branch 'develop' into issue-2511

This commit is contained in:
Srikanth Chekuri 2023-03-28 06:09:02 +05:30 committed by GitHub
commit d6152510c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 139 additions and 98 deletions

View File

@ -1464,13 +1464,13 @@ func createTagQueryFromTagQueryParams(queryParams []model.TagQueryParam) []model
tags := []model.TagQuery{}
for _, tag := range queryParams {
if len(tag.StringValues) > 0 {
tags = append(tags, model.NewTagQueryString(tag.Key, tag.StringValues, tag.Operator))
tags = append(tags, model.NewTagQueryString(tag))
}
if len(tag.NumberValues) > 0 {
tags = append(tags, model.NewTagQueryNumber(tag.Key, tag.NumberValues, tag.Operator))
tags = append(tags, model.NewTagQueryNumber(tag))
}
if len(tag.BoolValues) > 0 {
tags = append(tags, model.NewTagQueryBool(tag.Key, tag.BoolValues, tag.Operator))
tags = append(tags, model.NewTagQueryBool(tag))
}
}
return tags
@ -1494,18 +1494,7 @@ func buildQueryWithTagParams(ctx context.Context, tags []model.TagQuery) (string
for _, item := range tags {
var subQuery string
var argsSubQuery []interface{}
tagMapType := ""
switch item.(type) {
case model.TagQueryString:
tagMapType = constants.StringTagMapCol
case model.TagQueryNumber:
tagMapType = constants.NumberTagMapCol
case model.TagQueryBool:
tagMapType = constants.BoolTagMapCol
default:
// type not supported error
return "", nil, &model.ApiError{Typ: model.ErrorBadData, Err: fmt.Errorf("type not supported")}
}
tagMapType := item.GetTagMapColumn()
switch item.GetOperator() {
case model.EqualOperator:
subQuery, argsSubQuery = addArithmeticOperator(item, tagMapType, "=")
@ -2698,6 +2687,17 @@ func (r *ClickHouseReader) ListErrors(ctx context.Context, queryParams *model.Li
query = query + " AND exceptionType ilike @exceptionType"
args = append(args, clickhouse.Named("exceptionType", "%"+queryParams.ExceptionType+"%"))
}
// create TagQuery from TagQueryParams
tags := createTagQueryFromTagQueryParams(queryParams.Tags)
subQuery, argsSubQuery, errStatus := buildQueryWithTagParams(ctx, tags)
query += subQuery
args = append(args, argsSubQuery...)
if errStatus != nil {
zap.S().Error("Error in processing tags: ", errStatus)
return nil, errStatus
}
query = query + " GROUP BY groupID"
if len(queryParams.ServiceName) != 0 {
query = query + ", serviceName"
@ -2747,6 +2747,18 @@ func (r *ClickHouseReader) CountErrors(ctx context.Context, queryParams *model.C
query = query + " AND exceptionType ilike @exceptionType"
args = append(args, clickhouse.Named("exceptionType", "%"+queryParams.ExceptionType+"%"))
}
// create TagQuery from TagQueryParams
tags := createTagQueryFromTagQueryParams(queryParams.Tags)
subQuery, argsSubQuery, errStatus := buildQueryWithTagParams(ctx, tags)
query += subQuery
args = append(args, argsSubQuery...)
if errStatus != nil {
zap.S().Error("Error in processing tags: ", errStatus)
return 0, errStatus
}
err := r.db.QueryRow(ctx, query, args...).Scan(&errorCount)
zap.S().Info(query)

View File

@ -328,8 +328,8 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *AuthMiddleware) {
router.HandleFunc("/api/v1/getFilteredSpans/aggregates", am.ViewAccess(aH.getFilteredSpanAggregates)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/getTagValues", am.ViewAccess(aH.getTagValues)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/listErrors", am.ViewAccess(aH.listErrors)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/countErrors", am.ViewAccess(aH.countErrors)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/listErrors", am.ViewAccess(aH.listErrors)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/countErrors", am.ViewAccess(aH.countErrors)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/errorFromErrorID", am.ViewAccess(aH.getErrorFromErrorID)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/errorFromGroupID", am.ViewAccess(aH.getErrorFromGroupID)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/nextPrevErrorIDs", am.ViewAccess(aH.getNextPrevErrorIDs)).Methods(http.MethodGet)

View File

@ -494,76 +494,54 @@ func parseListErrorsRequest(r *http.Request) (*model.ListErrorsParams, error) {
var allowedOrderParams = []string{"exceptionType", "exceptionCount", "firstSeen", "lastSeen", "serviceName"}
var allowedOrderDirections = []string{"ascending", "descending"}
startTime, err := parseTime("start", r)
if err != nil {
return nil, err
}
endTime, err := parseTimeMinusBuffer("end", r)
var postData *model.ListErrorsParams
err := json.NewDecoder(r.Body).Decode(&postData)
if err != nil {
return nil, err
}
order := r.URL.Query().Get("order")
if len(order) > 0 && !DoesExistInSlice(order, allowedOrderDirections) {
return nil, errors.New(fmt.Sprintf("given order: %s is not allowed in query", order))
}
orderParam := r.URL.Query().Get("orderParam")
if len(order) > 0 && !DoesExistInSlice(orderParam, allowedOrderParams) {
return nil, errors.New(fmt.Sprintf("given orderParam: %s is not allowed in query", orderParam))
}
limit := r.URL.Query().Get("limit")
offset := r.URL.Query().Get("offset")
if len(offset) == 0 || len(limit) == 0 {
return nil, fmt.Errorf("offset or limit param cannot be empty from the query")
}
limitInt, err := strconv.Atoi(limit)
postData.Start, err = parseTimeStr(postData.StartStr, "start")
if err != nil {
return nil, errors.New("limit param is not in correct format")
return nil, err
}
offsetInt, err := strconv.Atoi(offset)
postData.End, err = parseTimeMinusBufferStr(postData.EndStr, "end")
if err != nil {
return nil, errors.New("offset param is not in correct format")
return nil, err
}
serviceName := r.URL.Query().Get("serviceName")
exceptionType := r.URL.Query().Get("exceptionType")
params := &model.ListErrorsParams{
Start: startTime,
End: endTime,
OrderParam: orderParam,
Order: order,
Limit: int64(limitInt),
Offset: int64(offsetInt),
ServiceName: serviceName,
ExceptionType: exceptionType,
if postData.Limit == 0 {
return nil, fmt.Errorf("limit param cannot be empty from the query")
}
return params, nil
if len(postData.Order) > 0 && !DoesExistInSlice(postData.Order, allowedOrderDirections) {
return nil, errors.New(fmt.Sprintf("given order: %s is not allowed in query", postData.Order))
}
if len(postData.Order) > 0 && !DoesExistInSlice(postData.OrderParam, allowedOrderParams) {
return nil, errors.New(fmt.Sprintf("given orderParam: %s is not allowed in query", postData.OrderParam))
}
return postData, nil
}
func parseCountErrorsRequest(r *http.Request) (*model.CountErrorsParams, error) {
startTime, err := parseTime("start", r)
var postData *model.CountErrorsParams
err := json.NewDecoder(r.Body).Decode(&postData)
if err != nil {
return nil, err
}
endTime, err := parseTimeMinusBuffer("end", r)
postData.Start, err = parseTimeStr(postData.StartStr, "start")
if err != nil {
return nil, err
}
serviceName := r.URL.Query().Get("serviceName")
exceptionType := r.URL.Query().Get("exceptionType")
params := &model.CountErrorsParams{
Start: startTime,
End: endTime,
ServiceName: serviceName,
ExceptionType: exceptionType,
postData.End, err = parseTimeMinusBufferStr(postData.EndStr, "end")
if err != nil {
return nil, err
}
return params, nil
return postData, nil
}
func parseGetErrorRequest(r *http.Request) (*model.GetErrorParams, error) {

View File

@ -219,11 +219,5 @@ var ReservedColumnTargetAliases = map[string]struct{}{
"value": {},
}
const (
StringTagMapCol = "stringTagMap"
NumberTagMapCol = "numberTagMap"
BoolTagMapCol = "boolTagMap"
)
// logsPPLPfx is a short constant for logsPipelinePrefix
const LogsPPLPfx = "logstransform/pipeline_"

View File

@ -122,6 +122,13 @@ const (
LOGS
)
const (
StringTagMapCol = "stringTagMap"
NumberTagMapCol = "numberTagMap"
BoolTagMapCol = "boolTagMap"
ResourceTagMapCol = "resourceTagsMap"
)
type QueryRangeParamsV2 struct {
DataSource DataSource `json:"dataSource"`
Start int64 `json:"start"`
@ -187,6 +194,7 @@ type GetServiceOverviewParams struct {
type TagQueryParam struct {
Key string `json:"key"`
TagType TagType `json:"tagType"`
StringValues []string `json:"stringValues"`
BoolValues []bool `json:"boolValues"`
NumberValues []float64 `json:"numberValues"`
@ -212,23 +220,34 @@ const (
NotStartsWithOperator Operator = "NotStartsWith"
)
type TagType string
const (
ResourceAttributeTagType TagType = "ResourceAttribute"
SpanAttributeTagType TagType = "SpanAttribute"
)
type TagQuery interface {
GetKey() string
GetValues() []interface{}
GetOperator() Operator
GetTagType() TagType
GetTagMapColumn() string
}
type TagQueryString struct {
key string
values []string
operator Operator
tagType TagType
}
func NewTagQueryString(key string, values []string, operator Operator) TagQueryString {
func NewTagQueryString(tag TagQueryParam) TagQueryString {
return TagQueryString{
key: key,
values: values,
operator: operator,
key: tag.Key,
values: tag.StringValues,
operator: tag.Operator,
tagType: tag.TagType,
}
}
@ -248,17 +267,31 @@ func (tqs TagQueryString) GetOperator() Operator {
return tqs.operator
}
func (tqs TagQueryString) GetTagType() TagType {
return tqs.tagType
}
func (tqs TagQueryString) GetTagMapColumn() string {
if tqs.GetTagType() == ResourceAttributeTagType {
return ResourceTagMapCol
} else {
return StringTagMapCol
}
}
type TagQueryBool struct {
key string
values []bool
operator Operator
tagType TagType
}
func NewTagQueryBool(key string, values []bool, operator Operator) TagQueryBool {
func NewTagQueryBool(tag TagQueryParam) TagQueryBool {
return TagQueryBool{
key: key,
values: values,
operator: operator,
key: tag.Key,
values: tag.BoolValues,
operator: tag.Operator,
tagType: tag.TagType,
}
}
@ -278,17 +311,27 @@ func (tqb TagQueryBool) GetOperator() Operator {
return tqb.operator
}
func (tqb TagQueryBool) GetTagType() TagType {
return tqb.tagType
}
func (tqb TagQueryBool) GetTagMapColumn() string {
return BoolTagMapCol
}
type TagQueryNumber struct {
key string
values []float64
operator Operator
tagType TagType
}
func NewTagQueryNumber(key string, values []float64, operator Operator) TagQueryNumber {
func NewTagQueryNumber(tag TagQueryParam) TagQueryNumber {
return TagQueryNumber{
key: key,
values: values,
operator: operator,
key: tag.Key,
values: tag.NumberValues,
operator: tag.Operator,
tagType: tag.TagType,
}
}
@ -308,6 +351,14 @@ func (tqn TagQueryNumber) GetOperator() Operator {
return tqn.operator
}
func (tqn TagQueryNumber) GetTagType() TagType {
return tqn.tagType
}
func (tqn TagQueryNumber) GetTagMapColumn() string {
return NumberTagMapCol
}
type GetFilteredSpansParams struct {
TraceID []string `json:"traceID"`
ServiceName []string `json:"serviceName"`
@ -414,17 +465,17 @@ type TagFilterParams struct {
End *time.Time
}
type TagType string
type TagDataType string
const (
TagTypeString TagType = "string"
TagTypeNumber TagType = "number"
TagTypeBool TagType = "bool"
TagTypeString TagDataType = "string"
TagTypeNumber TagDataType = "number"
TagTypeBool TagDataType = "bool"
)
type TagKey struct {
Key string `json:"key"`
Type TagType `json:"type"`
Key string `json:"key"`
Type TagDataType `json:"type"`
}
type TTLParams struct {
@ -439,21 +490,27 @@ type GetTTLParams struct {
}
type ListErrorsParams struct {
StartStr string `json:"start"`
EndStr string `json:"end"`
Start *time.Time
End *time.Time
Limit int64
OrderParam string
Order string
Offset int64
ServiceName string
ExceptionType string
Limit int64 `json:"limit"`
OrderParam string `json:"orderParam"`
Order string `json:"order"`
Offset int64 `json:"offset"`
ServiceName string `json:"serviceName"`
ExceptionType string `json:"exceptionType"`
Tags []TagQueryParam `json:"tags"`
}
type CountErrorsParams struct {
StartStr string `json:"start"`
EndStr string `json:"end"`
Start *time.Time
End *time.Time
ServiceName string
ExceptionType string
ServiceName string `json:"serviceName"`
ExceptionType string `json:"exceptionType"`
Tags []TagQueryParam `json:"tags"`
}
type GetErrorParams struct {