mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-10 00:08:58 +08:00
Merge pull request #689 from SigNoz/feat/tagValueSuggestion
feat: tag value suggestion API
This commit is contained in:
commit
2800b021e6
@ -1839,6 +1839,79 @@ func excludeTags(ctx context.Context, tags []model.TagFilters) []model.TagFilter
|
||||
return newTags
|
||||
}
|
||||
|
||||
func (r *ClickHouseReader) GetTagValues(ctx context.Context, queryParams *model.TagFilterParams) (*[]model.TagValues, *model.ApiError) {
|
||||
|
||||
excludeMap := make(map[string]struct{})
|
||||
for _, e := range queryParams.Exclude {
|
||||
if e == constants.OperationRequest {
|
||||
excludeMap[constants.OperationDB] = struct{}{}
|
||||
continue
|
||||
}
|
||||
excludeMap[e] = struct{}{}
|
||||
}
|
||||
|
||||
var query string
|
||||
args := []interface{}{queryParams.TagKey, strconv.FormatInt(queryParams.Start.UnixNano(), 10), strconv.FormatInt(queryParams.End.UnixNano(), 10)}
|
||||
if len(queryParams.ServiceName) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.ServiceName, constants.ServiceName, &query, args)
|
||||
}
|
||||
if len(queryParams.HttpRoute) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.HttpRoute, constants.HttpRoute, &query, args)
|
||||
}
|
||||
if len(queryParams.HttpCode) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.HttpCode, constants.HttpCode, &query, args)
|
||||
}
|
||||
if len(queryParams.HttpHost) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.HttpHost, constants.HttpHost, &query, args)
|
||||
}
|
||||
if len(queryParams.HttpMethod) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.HttpMethod, constants.HttpMethod, &query, args)
|
||||
}
|
||||
if len(queryParams.HttpUrl) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.HttpUrl, constants.HttpUrl, &query, args)
|
||||
}
|
||||
if len(queryParams.Component) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.Component, constants.Component, &query, args)
|
||||
}
|
||||
if len(queryParams.Operation) > 0 {
|
||||
args = buildFilterArrayQuery(ctx, excludeMap, queryParams.Operation, constants.OperationDB, &query, args)
|
||||
}
|
||||
if len(queryParams.MinDuration) != 0 {
|
||||
query = query + " AND durationNano >= ?"
|
||||
args = append(args, queryParams.MinDuration)
|
||||
}
|
||||
if len(queryParams.MaxDuration) != 0 {
|
||||
query = query + " AND durationNano <= ?"
|
||||
args = append(args, queryParams.MaxDuration)
|
||||
}
|
||||
|
||||
query = getStatusFilters(query, queryParams.Status, excludeMap)
|
||||
|
||||
tagValues := []model.TagValues{}
|
||||
|
||||
finalQuery := fmt.Sprintf(`SELECT tagMap[?] as tagValues FROM %s WHERE timestamp >= ? AND timestamp <= ?`, r.indexTable)
|
||||
finalQuery += query
|
||||
fmt.Println(finalQuery)
|
||||
finalQuery += "GROUP BY tagMap[?]"
|
||||
args = append(args, queryParams.TagKey)
|
||||
err := r.db.Select(&tagValues, finalQuery, args...)
|
||||
|
||||
zap.S().Info(query)
|
||||
|
||||
if err != nil {
|
||||
zap.S().Debug("Error in processing sql query: ", err)
|
||||
return nil, &model.ApiError{model.ErrorExec, fmt.Errorf("Error in processing sql query")}
|
||||
}
|
||||
|
||||
cleanedTagValues := []model.TagValues{}
|
||||
for _, e := range tagValues {
|
||||
if e.TagValues != "" {
|
||||
cleanedTagValues = append(cleanedTagValues, e)
|
||||
}
|
||||
}
|
||||
return &cleanedTagValues, nil
|
||||
}
|
||||
|
||||
func (r *ClickHouseReader) GetServiceDBOverview(ctx context.Context, queryParams *model.GetServiceOverviewParams) (*[]model.ServiceDBOverviewItem, error) {
|
||||
|
||||
var serviceDBOverviewItems []model.ServiceDBOverviewItem
|
||||
|
@ -173,6 +173,10 @@ func (druid *DruidReader) GetTagFilters(_ context.Context, _ *model.TagFilterPar
|
||||
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting tagFilters")}
|
||||
}
|
||||
|
||||
func (druid *DruidReader) GetTagValues(_ context.Context, _ *model.TagFilterParams) (*[]model.TagValues, *model.ApiError) {
|
||||
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting tagValues")}
|
||||
}
|
||||
|
||||
func (druid *DruidReader) GetFilteredSpans(_ context.Context, _ *model.GetFilteredSpansParams) (*model.GetFilterSpansResponse, *model.ApiError) {
|
||||
return nil, &model.ApiError{model.ErrorNotImplemented, fmt.Errorf("druid does not support getting FilteredSpans")}
|
||||
}
|
||||
|
@ -214,6 +214,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router) {
|
||||
router.HandleFunc("/api/v1/getFilteredSpans", aH.getFilteredSpans).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v1/getFilteredSpans/aggregates", aH.getFilteredSpanAggregates).Methods(http.MethodPost)
|
||||
|
||||
router.HandleFunc("/api/v1/getTagValues", aH.getTagValues).Methods(http.MethodPost)
|
||||
router.HandleFunc("/api/v1/errors", aH.getErrors).Methods(http.MethodGet)
|
||||
router.HandleFunc("/api/v1/errorWithId", aH.getErrorForId).Methods(http.MethodGet)
|
||||
router.HandleFunc("/api/v1/errorWithType", aH.getErrorForType).Methods(http.MethodGet)
|
||||
@ -1040,6 +1041,22 @@ func (aH *APIHandler) getTagFilters(w http.ResponseWriter, r *http.Request) {
|
||||
aH.writeJSON(w, r, result)
|
||||
}
|
||||
|
||||
func (aH *APIHandler) getTagValues(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
query, err := parseTagValueRequest(r)
|
||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
||||
return
|
||||
}
|
||||
|
||||
result, apiErr := (*aH.reader).GetTagValues(context.Background(), query)
|
||||
|
||||
if apiErr != nil && aH.handleError(w, apiErr.Err, http.StatusInternalServerError) {
|
||||
return
|
||||
}
|
||||
|
||||
aH.writeJSON(w, r, result)
|
||||
}
|
||||
|
||||
func (aH *APIHandler) setTTL(w http.ResponseWriter, r *http.Request) {
|
||||
ttlParams, err := parseDuration(r)
|
||||
if aH.handleError(w, err, http.StatusBadRequest) {
|
||||
|
@ -39,6 +39,7 @@ type Reader interface {
|
||||
GetTTL(ctx context.Context, ttlParams *model.GetTTLParams) (*model.GetTTLResponseItem, *model.ApiError)
|
||||
GetSpanFilters(ctx context.Context, query *model.SpanFilterParams) (*model.SpanFiltersResponse, *model.ApiError)
|
||||
GetTagFilters(ctx context.Context, query *model.TagFilterParams) (*[]model.TagFilters, *model.ApiError)
|
||||
GetTagValues(ctx context.Context, query *model.TagFilterParams) (*[]model.TagValues, *model.ApiError)
|
||||
GetFilteredSpans(ctx context.Context, query *model.GetFilteredSpansParams) (*model.GetFilterSpansResponse, *model.ApiError)
|
||||
GetFilteredSpansAggregates(ctx context.Context, query *model.GetFilteredSpanAggregatesParams) (*model.GetFilteredSpansAggregatesResponse, *model.ApiError)
|
||||
|
||||
|
@ -650,6 +650,31 @@ func parseTagFilterRequest(r *http.Request) (*model.TagFilterParams, error) {
|
||||
return postData, nil
|
||||
|
||||
}
|
||||
|
||||
func parseTagValueRequest(r *http.Request) (*model.TagFilterParams, error) {
|
||||
var postData *model.TagFilterParams
|
||||
err := json.NewDecoder(r.Body).Decode(&postData)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if postData.TagKey == "" {
|
||||
return nil, fmt.Errorf("%s param missing in query", postData.TagKey)
|
||||
}
|
||||
|
||||
postData.Start, err = parseTimeStr(postData.StartStr, "start")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
postData.End, err = parseTimeMinusBufferStr(postData.EndStr, "end")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return postData, nil
|
||||
|
||||
}
|
||||
|
||||
func parseErrorsRequest(r *http.Request) (*model.GetErrorsParams, error) {
|
||||
|
||||
startTime, err := parseTime("start", r)
|
||||
|
@ -201,6 +201,7 @@ type TagFilterParams struct {
|
||||
MaxDuration string `json:"maxDuration"`
|
||||
StartStr string `json:"start"`
|
||||
EndStr string `json:"end"`
|
||||
TagKey string `json:"tagKey"`
|
||||
Start *time.Time
|
||||
End *time.Time
|
||||
}
|
||||
|
@ -268,6 +268,10 @@ type TagItem struct {
|
||||
type TagFilters struct {
|
||||
TagKeys string `json:"tagKeys" db:"tagKeys"`
|
||||
}
|
||||
|
||||
type TagValues struct {
|
||||
TagValues string `json:"tagValues" db:"tagValues"`
|
||||
}
|
||||
type ServiceMapDependencyResponseItem struct {
|
||||
Parent string `json:"parent,omitempty" db:"parent,omitempty"`
|
||||
Child string `json:"child,omitempty" db:"child,omitempty"`
|
||||
|
Loading…
x
Reference in New Issue
Block a user