mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 14:35:56 +08:00
feat: add support for not regex (#1328)
* feat: add support for not regex Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
This commit is contained in:
parent
091d769ad8
commit
da368ab5e8
@ -50,6 +50,7 @@ import (
|
||||
"go.signoz.io/query-service/constants"
|
||||
am "go.signoz.io/query-service/integrations/alertManager"
|
||||
"go.signoz.io/query-service/model"
|
||||
"go.signoz.io/query-service/utils"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@ -2829,6 +2830,10 @@ func (r *ClickHouseReader) GetMetricAutocompleteMetricNames(ctx context.Context,
|
||||
// GetMetricResult runs the query and returns list of time series
|
||||
func (r *ClickHouseReader) GetMetricResult(ctx context.Context, query string) ([]*model.Series, error) {
|
||||
|
||||
defer utils.Elapsed("GetMetricResult")()
|
||||
|
||||
zap.S().Infof("Executing metric result query: %s", query)
|
||||
|
||||
rows, err := r.db.Query(ctx, query)
|
||||
|
||||
if err != nil {
|
||||
|
@ -180,10 +180,10 @@ func writeHttpResponse(w http.ResponseWriter, data interface{}) {
|
||||
}
|
||||
func (aH *APIHandler) RegisterMetricsRoutes(router *mux.Router) {
|
||||
subRouter := router.PathPrefix("/api/v2/metrics").Subrouter()
|
||||
subRouter.HandleFunc("/query_range", aH.queryRangeMetricsV2).Methods(http.MethodPost)
|
||||
subRouter.HandleFunc("/autocomplete/list", aH.metricAutocompleteMetricName).Methods(http.MethodGet)
|
||||
subRouter.HandleFunc("/autocomplete/tagKey", aH.metricAutocompleteTagKey).Methods(http.MethodGet)
|
||||
subRouter.HandleFunc("/autocomplete/tagValue", aH.metricAutocompleteTagValue).Methods(http.MethodGet)
|
||||
subRouter.HandleFunc("/query_range", ViewAccess(aH.queryRangeMetricsV2)).Methods(http.MethodPost)
|
||||
subRouter.HandleFunc("/autocomplete/list", ViewAccess(aH.metricAutocompleteMetricName)).Methods(http.MethodGet)
|
||||
subRouter.HandleFunc("/autocomplete/tagKey", ViewAccess(aH.metricAutocompleteTagKey)).Methods(http.MethodGet)
|
||||
subRouter.HandleFunc("/autocomplete/tagValue", ViewAccess(aH.metricAutocompleteTagValue)).Methods(http.MethodGet)
|
||||
}
|
||||
|
||||
func (aH *APIHandler) respond(w http.ResponseWriter, data interface{}) {
|
||||
|
@ -91,10 +91,9 @@ func BuildMetricsTimeSeriesFilterQuery(fs *model.FilterSet, groupTags []string,
|
||||
if fs != nil && len(fs.Items) != 0 {
|
||||
for _, item := range fs.Items {
|
||||
toFormat := item.Value
|
||||
op := strings.ToLower(strings.TrimSpace(item.Operator))
|
||||
// if the received value is an array for like/match op, just take the first value
|
||||
if strings.ToLower(item.Operation) == "like" ||
|
||||
strings.ToLower(item.Operation) == "match" ||
|
||||
strings.ToLower(item.Operation) == "nlike" {
|
||||
if op == "like" || op == "match" || op == "nlike" || op == "nmatch" {
|
||||
x, ok := item.Value.([]interface{})
|
||||
if ok {
|
||||
if len(x) == 0 {
|
||||
@ -104,7 +103,7 @@ func BuildMetricsTimeSeriesFilterQuery(fs *model.FilterSet, groupTags []string,
|
||||
}
|
||||
}
|
||||
fmtVal := formattedValue(toFormat)
|
||||
switch op := strings.ToLower(item.Operation); op {
|
||||
switch op {
|
||||
case "eq":
|
||||
conditions = append(conditions, fmt.Sprintf("labels_object.%s = %s", item.Key, fmtVal))
|
||||
case "neq":
|
||||
@ -119,6 +118,8 @@ func BuildMetricsTimeSeriesFilterQuery(fs *model.FilterSet, groupTags []string,
|
||||
conditions = append(conditions, fmt.Sprintf("notLike(labels_object.%s, %s)", item.Key, fmtVal))
|
||||
case "match":
|
||||
conditions = append(conditions, fmt.Sprintf("match(labels_object.%s, %s)", item.Key, fmtVal))
|
||||
case "nmatch":
|
||||
conditions = append(conditions, fmt.Sprintf("not match(labels_object.%s, %s)", item.Key, fmtVal))
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported operation")
|
||||
}
|
||||
@ -416,6 +417,5 @@ func PrepareBuilderMetricQueries(qp *model.QueryRangeParamsV2, tableName string)
|
||||
if len(errs) != 0 {
|
||||
return &RunQueries{Err: fmt.Errorf("errors with formulas: %s", FormatErrs(errs, "\n"))}
|
||||
}
|
||||
fmt.Println(namedQueries)
|
||||
return &RunQueries{Queries: namedQueries}
|
||||
}
|
||||
|
@ -42,8 +42,9 @@ func TestBuildQueryWithFilters(t *testing.T) {
|
||||
"a": {
|
||||
QueryName: "a",
|
||||
MetricName: "name",
|
||||
TagFilters: &model.FilterSet{Operation: "AND", Items: []model.FilterItem{
|
||||
{Key: "a", Value: "b", Operation: "neq"},
|
||||
TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{
|
||||
{Key: "a", Value: "b", Operator: "neq"},
|
||||
{Key: "code", Value: "ERROR_*", Operator: "nmatch"},
|
||||
}},
|
||||
AggregateOperator: model.RATE_MAX,
|
||||
Expression: "a",
|
||||
@ -56,6 +57,7 @@ func TestBuildQueryWithFilters(t *testing.T) {
|
||||
|
||||
So(queries["a"], ShouldContainSubstring, "WHERE metric_name = 'name' AND labels_object.a != 'b'")
|
||||
So(queries["a"], ShouldContainSubstring, "runningDifference(value)/runningDifference(ts)")
|
||||
So(queries["a"], ShouldContainSubstring, "not match(labels_object.code, 'ERROR_*')")
|
||||
})
|
||||
}
|
||||
|
||||
@ -70,8 +72,8 @@ func TestBuildQueryWithMultipleQueries(t *testing.T) {
|
||||
"a": {
|
||||
QueryName: "a",
|
||||
MetricName: "name",
|
||||
TagFilters: &model.FilterSet{Operation: "AND", Items: []model.FilterItem{
|
||||
{Key: "in", Value: []interface{}{"a", "b", "c"}, Operation: "in"},
|
||||
TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{
|
||||
{Key: "in", Value: []interface{}{"a", "b", "c"}, Operator: "in"},
|
||||
}},
|
||||
AggregateOperator: model.RATE_AVG,
|
||||
Expression: "a",
|
||||
@ -103,8 +105,8 @@ func TestBuildQueryWithMultipleQueriesAndFormula(t *testing.T) {
|
||||
"a": {
|
||||
QueryName: "a",
|
||||
MetricName: "name",
|
||||
TagFilters: &model.FilterSet{Operation: "AND", Items: []model.FilterItem{
|
||||
{Key: "in", Value: []interface{}{"a", "b", "c"}, Operation: "in"},
|
||||
TagFilters: &model.FilterSet{Operator: "AND", Items: []model.FilterItem{
|
||||
{Key: "in", Value: []interface{}{"a", "b", "c"}, Operator: "in"},
|
||||
}},
|
||||
AggregateOperator: model.RATE_MAX,
|
||||
Expression: "a",
|
||||
|
@ -296,15 +296,10 @@ type GetErrorParams struct {
|
||||
type FilterItem struct {
|
||||
Key string `json:"key"`
|
||||
Value interface{} `json:"value"`
|
||||
Operation string `json:"op"`
|
||||
Operator string `json:"op"`
|
||||
}
|
||||
|
||||
type FilterSet struct {
|
||||
Operation string `json:"op,omitempty"`
|
||||
Operator string `json:"op,omitempty"`
|
||||
Items []FilterItem `json:"items"`
|
||||
}
|
||||
|
||||
type RemoveTTLParams struct {
|
||||
Type string
|
||||
RemoveAllTTL bool
|
||||
}
|
||||
|
14
pkg/query-service/utils/time.go
Normal file
14
pkg/query-service/utils/time.go
Normal file
@ -0,0 +1,14 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func Elapsed(funcName string) func() {
|
||||
start := time.Now()
|
||||
return func() {
|
||||
zap.S().Infof("%s took %v\n", funcName, time.Since(start))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user