package fields import ( "net/http" "strconv" "github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/types/telemetrytypes" "github.com/SigNoz/signoz/pkg/valuer" ) func parseFieldKeyRequest(r *http.Request) (*telemetrytypes.FieldKeySelector, error) { var req telemetrytypes.FieldKeySelector var signal telemetrytypes.Signal var err error signalStr := r.URL.Query().Get("signal") if signalStr != "" { signal = telemetrytypes.Signal{String: valuer.NewString(signalStr)} } else { signal = telemetrytypes.SignalUnspecified } if r.URL.Query().Get("limit") != "" { limit, err := strconv.Atoi(r.URL.Query().Get("limit")) if err != nil { return nil, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to parse limit") } req.Limit = limit } else { req.Limit = 1000 } var startUnixMilli, endUnixMilli int64 if r.URL.Query().Get("startUnixMilli") != "" { startUnixMilli, err = strconv.ParseInt(r.URL.Query().Get("startUnixMilli"), 10, 64) if err != nil { return nil, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to parse startUnixMilli") } // Round down to the nearest 6 hours (21600000 milliseconds) startUnixMilli -= startUnixMilli % 21600000 } if r.URL.Query().Get("endUnixMilli") != "" { endUnixMilli, err = strconv.ParseInt(r.URL.Query().Get("endUnixMilli"), 10, 64) if err != nil { return nil, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to parse endUnixMilli") } } // Parse fieldContext directly instead of using JSON unmarshalling. var fieldContext telemetrytypes.FieldContext fieldContextStr := r.URL.Query().Get("fieldContext") if fieldContextStr != "" { fieldContext = telemetrytypes.FieldContext{String: valuer.NewString(fieldContextStr)} } // Parse fieldDataType directly instead of using JSON unmarshalling. var fieldDataType telemetrytypes.FieldDataType fieldDataTypeStr := r.URL.Query().Get("fieldDataType") if fieldDataTypeStr != "" { fieldDataType = telemetrytypes.FieldDataType{String: valuer.NewString(fieldDataTypeStr)} } metricName := r.URL.Query().Get("metricName") var metricContext *telemetrytypes.MetricContext if metricName != "" { metricContext = &telemetrytypes.MetricContext{ MetricName: metricName, } } name := r.URL.Query().Get("name") req = telemetrytypes.FieldKeySelector{ StartUnixMilli: startUnixMilli, EndUnixMilli: endUnixMilli, Signal: signal, Name: name, FieldContext: fieldContext, FieldDataType: fieldDataType, Limit: req.Limit, SelectorMatchType: telemetrytypes.FieldSelectorMatchTypeFuzzy, MetricContext: metricContext, } return &req, nil } func parseFieldValueRequest(r *http.Request) (*telemetrytypes.FieldValueSelector, error) { keySelector, err := parseFieldKeyRequest(r) if err != nil { return nil, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to parse field key request") } existingQuery := r.URL.Query().Get("existingQuery") value := r.URL.Query().Get("value") // Parse limit for fieldValue request, fallback to default 50 if parsing fails. limit, err := strconv.Atoi(r.URL.Query().Get("limit")) if err != nil { limit = 50 } req := telemetrytypes.FieldValueSelector{ FieldKeySelector: keySelector, ExistingQuery: existingQuery, Value: value, Limit: limit, } return &req, nil }