mirror of
https://github.com/SigNoz/signoz.git
synced 2026-11-10 10:20:42 +00:00
Compare commits
2 Commits
fix/genera
...
tvats-quer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c200693b50 | ||
|
|
0d965d63c6 |
@@ -178,6 +178,9 @@ querier:
|
||||
# range with padding to include slightly delayed log exports. Logs only; set
|
||||
# to 0 to disable.
|
||||
log_trace_id_window_padding: 5m
|
||||
# How far past now a query's end time may be, tolerating client clock skew.
|
||||
# Requests ending later are rejected as malformed.
|
||||
max_end_time_ahead: 24h
|
||||
schemametadatastore:
|
||||
# How long found schema metadata stays cached; 0 caches it for the life of the process.
|
||||
cache_ttl: 0s
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"log/slog"
|
||||
"math"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
|
||||
@@ -75,36 +76,54 @@ func (p *BaseSeasonalProvider) getResults(ctx context.Context, orgID valuer.UUID
|
||||
})
|
||||
// TODO(srikanthccv): parallelize this?
|
||||
p.logger.InfoContext(ctx, "fetching results for current period", slog.Any("anomaly_current_period_query", params.CurrentPeriodQuery))
|
||||
if err := p.querier.ValidateRequest(¶ms.CurrentPeriodQuery); err != nil {
|
||||
p.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
currentPeriodResults, err := p.querier.QueryRange(ctx, orgID, ¶ms.CurrentPeriodQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.logger.InfoContext(ctx, "fetching results for past period", slog.Any("anomaly_past_period_query", params.PastPeriodQuery))
|
||||
if err := p.querier.ValidateRequest(¶ms.PastPeriodQuery); err != nil {
|
||||
p.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
pastPeriodResults, err := p.querier.QueryRange(ctx, orgID, ¶ms.PastPeriodQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.logger.InfoContext(ctx, "fetching results for current season", slog.Any("anomaly_current_season_query", params.CurrentSeasonQuery))
|
||||
if err := p.querier.ValidateRequest(¶ms.CurrentSeasonQuery); err != nil {
|
||||
p.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
currentSeasonResults, err := p.querier.QueryRange(ctx, orgID, ¶ms.CurrentSeasonQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.logger.InfoContext(ctx, "fetching results for past season", slog.Any("anomaly_past_season_query", params.PastSeasonQuery))
|
||||
if err := p.querier.ValidateRequest(¶ms.PastSeasonQuery); err != nil {
|
||||
p.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
pastSeasonResults, err := p.querier.QueryRange(ctx, orgID, ¶ms.PastSeasonQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.logger.InfoContext(ctx, "fetching results for past 2 season", slog.Any("anomaly_past_2season_query", params.Past2SeasonQuery))
|
||||
if err := p.querier.ValidateRequest(¶ms.Past2SeasonQuery); err != nil {
|
||||
p.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
past2SeasonResults, err := p.querier.QueryRange(ctx, orgID, ¶ms.Past2SeasonQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.logger.InfoContext(ctx, "fetching results for past 3 season", slog.Any("anomaly_past_3season_query", params.Past3SeasonQuery))
|
||||
if err := p.querier.ValidateRequest(¶ms.Past3SeasonQuery); err != nil {
|
||||
p.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
past3SeasonResults, err := p.querier.QueryRange(ctx, orgID, ¶ms.Past3SeasonQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -153,6 +153,9 @@ func (module *module) GetPublicWidgetQueryRangeV2(ctx context.Context, id valuer
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := module.querier.ValidateRequest(query); err != nil {
|
||||
module.settings.Logger().WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
return module.querier.QueryRange(ctx, dashboard.OrgID, query)
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func (h *handler) QueryRange(rw http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := queryRangeRequest.Validate(); err != nil {
|
||||
if err := h.querier.ValidateRequest(&queryRangeRequest); err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -191,6 +192,9 @@ func (m *module) getTopClusterGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/clickhousesql"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
"github.com/SigNoz/signoz/pkg/telemetryschema/metricstelemetryschema"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
@@ -232,6 +233,9 @@ func (m *module) getTopContainerGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -182,6 +183,9 @@ func (m *module) getTopDaemonSetGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -174,6 +175,9 @@ func (m *module) getTopDeploymentGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/clickhousesql"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/flagger"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
"github.com/SigNoz/signoz/pkg/telemetryschema/metricstelemetryschema"
|
||||
@@ -321,6 +322,9 @@ func (m *module) getTopHostGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -182,6 +183,9 @@ func (m *module) getTopJobGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/flagger"
|
||||
"github.com/SigNoz/signoz/pkg/modules/inframonitoring"
|
||||
@@ -222,6 +223,9 @@ func (m *module) ListHosts(ctx context.Context, orgID valuer.UUID, req *inframon
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -325,6 +329,9 @@ func (m *module) ListPods(ctx context.Context, orgID valuer.UUID, req *inframoni
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -436,6 +443,9 @@ func (m *module) ListContainers(ctx context.Context, orgID valuer.UUID, req *inf
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -552,6 +562,9 @@ func (m *module) ListNodes(ctx context.Context, orgID valuer.UUID, req *inframon
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -666,6 +679,9 @@ func (m *module) ListNamespaces(ctx context.Context, orgID valuer.UUID, req *inf
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -778,6 +794,9 @@ func (m *module) ListClusters(ctx context.Context, orgID valuer.UUID, req *infra
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -877,6 +896,9 @@ func (m *module) ListVolumes(ctx context.Context, orgID valuer.UUID, req *infram
|
||||
}
|
||||
|
||||
fullQueryReq := buildFullQueryRequest(req.Start, req.End, filterExpr, req.GroupBy, pageGroups, m.newVolumesTableListQuery())
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err := m.querier.QueryRange(ctx, orgID, fullQueryReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -974,6 +996,9 @@ func (m *module) ListDeployments(ctx context.Context, orgID valuer.UUID, req *in
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -1083,6 +1108,9 @@ func (m *module) ListStatefulSets(ctx context.Context, orgID valuer.UUID, req *i
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -1192,6 +1220,9 @@ func (m *module) ListJobs(ctx context.Context, orgID valuer.UUID, req *inframoni
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
@@ -1301,6 +1332,9 @@ func (m *module) ListDaemonSets(ctx context.Context, orgID valuer.UUID, req *inf
|
||||
|
||||
g.Go(func() error {
|
||||
var err error
|
||||
if err := m.querier.ValidateRequest(fullQueryReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
queryResp, err = m.querier.QueryRange(gCtx, orgID, fullQueryReq)
|
||||
return err
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -157,6 +158,9 @@ func (m *module) getTopNamespaceGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/clickhousesql"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
"github.com/SigNoz/signoz/pkg/telemetryschema/metricstelemetryschema"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
@@ -199,6 +200,9 @@ func (m *module) getTopNodeGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/clickhousesql"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
"github.com/SigNoz/signoz/pkg/telemetryschema/metricstelemetryschema"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
@@ -239,6 +240,9 @@ func (m *module) getTopPodGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -174,6 +175,9 @@ func (m *module) getTopStatefulSetGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
@@ -133,6 +134,9 @@ func (m *module) getTopVolumeGroupsAndMetadata(
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
if err := m.querier.ValidateRequest(topReq); err != nil {
|
||||
m.logger.WarnContext(gCtx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := m.querier.QueryRange(gCtx, orgID, topReq)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -4,9 +4,11 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/llmpricingrule"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
|
||||
@@ -24,10 +26,12 @@ const unmappedModelsLookback = time.Hour
|
||||
type module struct {
|
||||
store llmpricingruletypes.Store
|
||||
querier querier.Querier
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewModule(store llmpricingruletypes.Store, querier querier.Querier) llmpricingrule.Module {
|
||||
return &module{store: store, querier: querier}
|
||||
func NewModule(store llmpricingruletypes.Store, querier querier.Querier, settings factory.ProviderSettings) llmpricingrule.Module {
|
||||
logger := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/modules/llmpricingrule/impllmpricingrule").Logger()
|
||||
return &module{store: store, querier: querier, logger: logger}
|
||||
}
|
||||
|
||||
func (module *module) List(ctx context.Context, orgID valuer.UUID, offset, limit int, search string, isOverride *bool) ([]*llmpricingruletypes.LLMPricingRule, int, error) {
|
||||
@@ -201,6 +205,9 @@ func (module *module) discoverModels(ctx context.Context, orgID valuer.UUID) ([]
|
||||
},
|
||||
}
|
||||
|
||||
if err := module.querier.ValidateRequest(req); err != nil {
|
||||
module.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
resp, err := module.querier.QueryRange(ctx, orgID, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,8 +2,10 @@ package implrawdataexport
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/rawdataexport"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/types/ctxtypes"
|
||||
@@ -14,11 +16,13 @@ import (
|
||||
|
||||
type Module struct {
|
||||
querier querier.Querier
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func NewModule(querier querier.Querier) rawdataexport.Module {
|
||||
func NewModule(querier querier.Querier, settings factory.ProviderSettings) rawdataexport.Module {
|
||||
return &Module{
|
||||
querier: querier,
|
||||
logger: factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/modules/rawdataexport/implrawdataexport").Logger(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +32,10 @@ func (m *Module) ExportRawData(ctx context.Context, orgID valuer.UUID, rangeRequ
|
||||
instrumentationtypes.CodeFunctionName: "ExportRawData",
|
||||
})
|
||||
|
||||
if err := m.querier.ValidateRequest(rangeRequest, qbtypes.WithSkipLimitOffsetValidation()); err != nil {
|
||||
m.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
|
||||
traceOperatorQueryIndex := rangeRequest.TraceOperatorQueryIndex()
|
||||
|
||||
queries := rangeRequest.CompositeQuery.Queries
|
||||
|
||||
@@ -3,12 +3,14 @@ package implservices
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"strconv"
|
||||
|
||||
"github.com/ClickHouse/clickhouse-go/v2"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/modules/services"
|
||||
"github.com/SigNoz/signoz/pkg/querier"
|
||||
"github.com/SigNoz/signoz/pkg/telemetryschema/tracestelemetryschema"
|
||||
@@ -24,13 +26,15 @@ import (
|
||||
type module struct {
|
||||
Querier querier.Querier
|
||||
TelemetryStore telemetrystore.TelemetryStore
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
// NewModule constructs the services module with the provided querier dependency.
|
||||
func NewModule(q querier.Querier, ts telemetrystore.TelemetryStore) services.Module {
|
||||
func NewModule(q querier.Querier, ts telemetrystore.TelemetryStore, settings factory.ProviderSettings) services.Module {
|
||||
return &module{
|
||||
Querier: q,
|
||||
TelemetryStore: ts,
|
||||
logger: factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/modules/services/implservices").Logger(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +224,9 @@ func (m *module) buildQueryRangeRequest(req *servicetypesv1.Request) (*qbtypes.Q
|
||||
|
||||
// executeQuery calls the underlying Querier with the provided request.
|
||||
func (m *module) executeQuery(ctx context.Context, orgUUID valuer.UUID, qr *qbtypes.QueryRangeRequest) (*qbtypes.QueryRangeResponse, error) {
|
||||
if err := m.Querier.ValidateRequest(qr); err != nil {
|
||||
m.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
return m.Querier.QueryRange(ctx, orgUUID, qr)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ func (m *module) GetSpanPercentile(ctx context.Context, orgID valuer.UUID, req *
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := queryRangeRequest.Validate(); err != nil {
|
||||
if err := m.querier.ValidateRequest(queryRangeRequest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ func (handler *handler) QueryRange(rw http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
|
||||
// Validate the query request
|
||||
if err := queryRangeRequest.Validate(); err != nil {
|
||||
if err := handler.querier.ValidateRequest(&queryRangeRequest); err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
@@ -188,7 +188,7 @@ func (handler *handler) QueryRawStream(rw http.ResponseWriter, req *http.Request
|
||||
}
|
||||
|
||||
// Validate the query request
|
||||
if err := queryRangeRequest.Validate(); err != nil {
|
||||
if err := handler.querier.ValidateRequest(&queryRangeRequest); err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/statementbuilder"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
)
|
||||
|
||||
const DefaultMaxConcurrentQueries = 8
|
||||
@@ -20,6 +21,8 @@ type Config struct {
|
||||
MaxConcurrentQueries int `yaml:"max_concurrent_queries" mapstructure:"max_concurrent_queries"`
|
||||
// LogTraceIDWindowPadding is the padding added to narrowed down timerange from trace summary to logs with trace_id filter.
|
||||
LogTraceIDWindowPadding time.Duration `yaml:"log_trace_id_window_padding" mapstructure:"log_trace_id_window_padding"`
|
||||
// MaxEndTimeAhead is how far past now a query's end time may be; it tolerates client clock skew.
|
||||
MaxEndTimeAhead time.Duration `yaml:"max_end_time_ahead" mapstructure:"max_end_time_ahead"`
|
||||
|
||||
// Keys sit under querier.skip_resource_fingerprint.
|
||||
statementbuilder.Config `mapstructure:",squash" yaml:",squash"`
|
||||
@@ -37,6 +40,7 @@ func newConfig() factory.Config {
|
||||
FluxInterval: 5 * time.Minute,
|
||||
MaxConcurrentQueries: DefaultMaxConcurrentQueries,
|
||||
LogTraceIDWindowPadding: 5 * time.Minute,
|
||||
MaxEndTimeAhead: qbtypes.DefaultMaxEndTimeAhead,
|
||||
Config: statementbuilder.NewConfig(),
|
||||
}
|
||||
}
|
||||
@@ -55,6 +59,9 @@ func (c Config) Validate() error {
|
||||
if c.LogTraceIDWindowPadding < 0 {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "log_trace_id_window_padding must not be negative, got %v", c.LogTraceIDWindowPadding)
|
||||
}
|
||||
if c.MaxEndTimeAhead <= 0 {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "max_end_time_ahead must be positive, got %v", c.MaxEndTimeAhead)
|
||||
}
|
||||
// Embedded Validate is shadowed by this one; call it explicitly.
|
||||
if err := c.Config.Validate(); err != nil {
|
||||
return err
|
||||
|
||||
@@ -23,7 +23,7 @@ func (q *querier) QueryRangePreview(
|
||||
opts qbtypes.QueryRangePreviewOptions,
|
||||
) (*qbtypes.QueryRangePreviewResponse, error) {
|
||||
|
||||
validationOpts, err := req.ValidateRequestScope()
|
||||
validationOpts, err := req.ValidateRequestScope(q.validationOptions()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ type Querier interface {
|
||||
statsreporter.StatsCollector
|
||||
// QueryRangePreview validates and renders the queries without executing them.
|
||||
QueryRangePreview(ctx context.Context, orgID valuer.UUID, req *qbtypes.QueryRangeRequest, opts qbtypes.QueryRangePreviewOptions) (*qbtypes.QueryRangePreviewResponse, error)
|
||||
// ValidateRequest checks req against the querier's preconditions; opts add to the querier's own.
|
||||
ValidateRequest(req *qbtypes.QueryRangeRequest, opts ...qbtypes.ValidationOption) error
|
||||
}
|
||||
|
||||
type querier struct {
|
||||
@@ -62,6 +64,7 @@ type querier struct {
|
||||
liveDataRefresh time.Duration
|
||||
builderConfig builderConfig
|
||||
maxConcurrentQueries int
|
||||
config Config
|
||||
}
|
||||
|
||||
var _ Querier = (*querier)(nil)
|
||||
@@ -80,12 +83,14 @@ func New(
|
||||
traceOperatorStmtBuilder qbtypes.TraceOperatorStatementBuilder,
|
||||
bucketCache BucketCache,
|
||||
flagger flagger.Flagger,
|
||||
logTraceIDWindowPadding time.Duration,
|
||||
maxConcurrentQueries int,
|
||||
config Config,
|
||||
) *querier {
|
||||
querierSettings := factory.NewScopedProviderSettings(settings, "github.com/SigNoz/signoz/pkg/querier")
|
||||
if maxConcurrentQueries <= 0 {
|
||||
maxConcurrentQueries = DefaultMaxConcurrentQueries
|
||||
if config.MaxConcurrentQueries <= 0 {
|
||||
config.MaxConcurrentQueries = DefaultMaxConcurrentQueries
|
||||
}
|
||||
if config.MaxEndTimeAhead <= 0 {
|
||||
config.MaxEndTimeAhead = qbtypes.DefaultMaxEndTimeAhead
|
||||
}
|
||||
return &querier{
|
||||
logger: querierSettings.Logger(),
|
||||
@@ -103,12 +108,21 @@ func New(
|
||||
bucketCache: bucketCache,
|
||||
liveDataRefresh: 5 * time.Second,
|
||||
builderConfig: builderConfig{
|
||||
logTraceIDWindowPaddingMS: uint64(logTraceIDWindowPadding.Milliseconds()),
|
||||
logTraceIDWindowPaddingMS: uint64(config.LogTraceIDWindowPadding.Milliseconds()),
|
||||
},
|
||||
maxConcurrentQueries: maxConcurrentQueries,
|
||||
maxConcurrentQueries: config.MaxConcurrentQueries,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (q *querier) ValidateRequest(req *qbtypes.QueryRangeRequest, opts ...qbtypes.ValidationOption) error {
|
||||
return req.Validate(append(opts, q.validationOptions()...)...)
|
||||
}
|
||||
|
||||
func (q *querier) validationOptions() []qbtypes.ValidationOption {
|
||||
return []qbtypes.ValidationOption{qbtypes.WithMaxEndTimeAhead(q.config.MaxEndTimeAhead)}
|
||||
}
|
||||
|
||||
func (q *querier) QueryRange(ctx context.Context, orgID valuer.UUID, req *qbtypes.QueryRangeRequest) (*qbtypes.QueryRangeResponse, error) {
|
||||
|
||||
// Callers that build the request in-process never pass through
|
||||
@@ -116,6 +130,11 @@ func (q *querier) QueryRange(ctx context.Context, orgID valuer.UUID, req *qbtype
|
||||
req.Start = qbtypes.ToMilliSecs(req.Start)
|
||||
req.End = qbtypes.ToMilliSecs(req.End)
|
||||
|
||||
// In-process callers skip ValidateRequest; the time window still guards the querier.
|
||||
if err := req.ValidateTimeRange(q.validationOptions()...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
event := &qbtypes.QBEvent{
|
||||
Version: "v5",
|
||||
NumberOfQueries: len(req.CompositeQuery.Queries),
|
||||
|
||||
@@ -57,8 +57,7 @@ func TestQueryRange_MetricTypeMissing(t *testing.T) {
|
||||
nil, // traceOperatorStmtBuilder
|
||||
nil, // bucketCache
|
||||
flaggertest.New(t), // flagger
|
||||
0, // logTraceIDWindowPadding
|
||||
0, // maxConcurrentQueries
|
||||
Config{},
|
||||
)
|
||||
|
||||
req := &qbtypes.QueryRangeRequest{
|
||||
@@ -130,8 +129,7 @@ func TestQueryRange_MetricTypeFromStore(t *testing.T) {
|
||||
nil, // traceOperatorStmtBuilder
|
||||
nil, // bucketCache
|
||||
flaggertest.New(t), // flagger
|
||||
0, // logTraceIDWindowPadding
|
||||
0, // maxConcurrentQueries
|
||||
Config{},
|
||||
)
|
||||
|
||||
req := &qbtypes.QueryRangeRequest{
|
||||
|
||||
@@ -37,6 +37,10 @@ func (m *MockQuerier) QueryRawStream(ctx context.Context, orgID valuer.UUID, req
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MockQuerier) ValidateRequest(req *qbtypes.QueryRangeRequest, opts ...qbtypes.ValidationOption) error {
|
||||
return req.Validate(opts...)
|
||||
}
|
||||
|
||||
func (m *MockQuerier) QueryRangePreview(ctx context.Context, orgID valuer.UUID, req *qbtypes.QueryRangeRequest, opts qbtypes.QueryRangePreviewOptions) (*qbtypes.QueryRangePreviewResponse, error) {
|
||||
if m.QueryRangePreviewFunc != nil {
|
||||
return m.QueryRangePreviewFunc(ctx, orgID, req, opts)
|
||||
|
||||
@@ -50,8 +50,7 @@ func NewFactory(
|
||||
traceOperatorStmtBuilder,
|
||||
bucketCache,
|
||||
flagger,
|
||||
cfg.LogTraceIDWindowPadding,
|
||||
cfg.MaxConcurrentQueries,
|
||||
cfg,
|
||||
), nil
|
||||
},
|
||||
)
|
||||
|
||||
@@ -3718,6 +3718,9 @@ func (aH *APIHandler) getDomainList(w http.ResponseWriter, r *http.Request) {
|
||||
instrumentationtypes.CodeFunctionName: "getDomainList",
|
||||
})
|
||||
// Execute the query using the v5 querier
|
||||
if err := aH.Signoz.Querier.ValidateRequest(queryRangeRequest); err != nil {
|
||||
aH.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
result, err := aH.Signoz.Querier.QueryRange(ctx, orgID, queryRangeRequest)
|
||||
if err != nil {
|
||||
aH.logger.ErrorContext(r.Context(), "query execution failed", errors.Attr(err))
|
||||
@@ -3778,6 +3781,9 @@ func (aH *APIHandler) getDomainInfo(w http.ResponseWriter, r *http.Request) {
|
||||
instrumentationtypes.CodeFunctionName: "getDomainInfo",
|
||||
})
|
||||
// Execute the query using the v5 querier
|
||||
if err := aH.Signoz.Querier.ValidateRequest(queryRangeRequest); err != nil {
|
||||
aH.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
result, err := aH.Signoz.Querier.QueryRange(ctx, orgID, queryRangeRequest)
|
||||
if err != nil {
|
||||
aH.logger.ErrorContext(r.Context(), "query execution failed", errors.Attr(err))
|
||||
|
||||
@@ -50,8 +50,7 @@ func prepareQuerierForMetrics(t *testing.T, telemetryStore telemetrystore.Teleme
|
||||
nil, // traceOperatorStmtBuilder
|
||||
nil, // bucketCache
|
||||
fl,
|
||||
0,
|
||||
0, // maxConcurrentQueries (0 means default)
|
||||
querier.Config{},
|
||||
), metadataStore
|
||||
}
|
||||
|
||||
@@ -85,8 +84,7 @@ func prepareQuerierForLogs(t *testing.T, telemetryStore telemetrystore.Telemetry
|
||||
nil, // traceOperatorStmtBuilder
|
||||
nil, // bucketCache
|
||||
fl,
|
||||
5*time.Minute, // logTraceIDWindowPadding
|
||||
0, // maxConcurrentQueries (0 means default)
|
||||
querier.Config{LogTraceIDWindowPadding: 5 * time.Minute},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -121,8 +119,7 @@ func prepareQuerierForTraces(t *testing.T, telemetryStore telemetrystore.Telemet
|
||||
nil, // traceOperatorStmtBuilder
|
||||
nil, // bucketCache
|
||||
fl,
|
||||
0,
|
||||
0, // maxConcurrentQueries (0 means default)
|
||||
querier.Config{},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -157,7 +154,6 @@ func prepareQuerierForAITraces(t *testing.T, telemetryStore telemetrystore.Telem
|
||||
nil, // traceOperatorStmtBuilder
|
||||
nil, // bucketCache
|
||||
fl,
|
||||
0,
|
||||
0, // maxConcurrentQueries (0 means default)
|
||||
querier.Config{},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -138,6 +138,9 @@ func (r *ThresholdRule) buildAndRunQuery(ctx context.Context, orgID valuer.UUID,
|
||||
instrumentationtypes.CodeFunctionName: "buildAndRunQuery",
|
||||
})
|
||||
|
||||
if err := r.querier.ValidateRequest(params); err != nil {
|
||||
r.logger.WarnContext(ctx, "invalid query range request", errors.Attr(err))
|
||||
}
|
||||
v5Result, err := r.querier.QueryRange(ctx, orgID, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -148,11 +148,11 @@ func NewModules(
|
||||
RetentionGetter: retentionGetter,
|
||||
QuickFilter: quickfilter,
|
||||
TraceFunnel: impltracefunnel.NewModule(impltracefunnel.NewStore(sqlstore)),
|
||||
RawDataExport: implrawdataexport.NewModule(querier),
|
||||
RawDataExport: implrawdataexport.NewModule(querier, providerSettings),
|
||||
AuthDomain: authDomainModule,
|
||||
Session: implsession.NewModule(providerSettings, authNs, userSetter, userGetter, authDomainModule, tokenizer, orgGetter, authz, config.Global),
|
||||
SpanPercentile: implspanpercentile.NewModule(querier, providerSettings),
|
||||
Services: implservices.NewModule(querier, telemetryStore),
|
||||
Services: implservices.NewModule(querier, telemetryStore, providerSettings),
|
||||
MetricsExplorer: implmetricsexplorer.NewModule(telemetryStore, telemetryMetadataStore, cache, ruleStore, dashboard, fl, providerSettings, config.MetricsExplorer),
|
||||
MetricReductionRule: metricReductionRule,
|
||||
InfraMonitoring: implinframonitoring.NewModule(telemetryStore, telemetryMetadataStore, querier, fl, providerSettings, config.InfraMonitoring),
|
||||
@@ -164,7 +164,7 @@ func NewModules(
|
||||
CloudIntegration: cloudIntegrationModule,
|
||||
TraceDetail: impltracedetail.NewModule(impltracedetail.NewTraceStore(telemetryStore, telemetryMetadataStore, schemaMetadataStore, fl), providerSettings, config.TraceDetail),
|
||||
SpanMapper: spanMapper,
|
||||
LLMPricingRule: impllmpricingrule.NewModule(impllmpricingrule.NewStore(sqlstore), querier),
|
||||
LLMPricingRule: impllmpricingrule.NewModule(impllmpricingrule.NewStore(sqlstore), querier, providerSettings),
|
||||
Tag: tagModule,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
)
|
||||
|
||||
// maxEndTimeAhead tolerates client clock skew; anything further ahead is a malformed timestamp.
|
||||
const maxEndTimeAhead = 24 * time.Hour
|
||||
|
||||
// getQueryIdentifier returns a friendly identifier for a query based on its type and name/content.
|
||||
func getQueryIdentifier(envelope QueryEnvelope, index int) string {
|
||||
name := envelope.GetQueryName()
|
||||
@@ -74,6 +71,9 @@ const (
|
||||
MaxNumBuckets = 512
|
||||
)
|
||||
|
||||
// DefaultMaxEndTimeAhead tolerates client clock skew; an end time further ahead is a malformed timestamp.
|
||||
const DefaultMaxEndTimeAhead = 24 * time.Hour
|
||||
|
||||
// ValidationOption is a functional option for configuring validation behaviour.
|
||||
type ValidationOption func(*validationConfig)
|
||||
|
||||
@@ -86,6 +86,7 @@ type validationConfig struct {
|
||||
skipGroupByValidation bool
|
||||
withTimestampGroupByValidation bool
|
||||
withReduceToValidation bool
|
||||
maxEndTimeAhead time.Duration
|
||||
}
|
||||
|
||||
func applyValidationOptions(opts []ValidationOption) validationConfig {
|
||||
@@ -160,6 +161,13 @@ func WithReduceToValidation() ValidationOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxEndTimeAhead sets how far past now a request's end time may be.
|
||||
func WithMaxEndTimeAhead(d time.Duration) ValidationOption {
|
||||
return func(cfg *validationConfig) {
|
||||
cfg.maxEndTimeAhead = d
|
||||
}
|
||||
}
|
||||
|
||||
// Validate performs preliminary validation on QueryBuilderQuery.
|
||||
func (q *QueryBuilderQuery[T]) Validate(opts ...ValidationOption) error {
|
||||
cfg := applyValidationOptions(opts)
|
||||
@@ -578,7 +586,7 @@ func (q *QueryBuilderQuery[T]) validateOrderByForAggregation() error {
|
||||
|
||||
// Validate validates the entire query range request.
|
||||
func (r *QueryRangeRequest) Validate(opts ...ValidationOption) error {
|
||||
if err := r.validateTimeRange(); err != nil {
|
||||
if err := r.ValidateTimeRange(opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -630,15 +638,14 @@ func (r *QueryRangeRequest) Validate(opts ...ValidationOption) error {
|
||||
// specs) and returns the request type's ValidationOptions. The dry-run path uses
|
||||
// this so per-query errors can be attributed individually via QueryEnvelope.Validate
|
||||
// instead of failing fast like Validate does.
|
||||
func (r *QueryRangeRequest) ValidateRequestScope() ([]ValidationOption, error) {
|
||||
if err := r.validateTimeRange(); err != nil {
|
||||
func (r *QueryRangeRequest) ValidateRequestScope(opts ...ValidationOption) ([]ValidationOption, error) {
|
||||
if err := r.ValidateTimeRange(opts...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var opts []ValidationOption
|
||||
switch r.RequestType {
|
||||
case RequestTypeRaw, RequestTypeRawStream, RequestTypeTrace, RequestTypeTimeSeries, RequestTypeScalar, RequestTypeHeatmap:
|
||||
opts = GetValidationOptions(r.RequestType)
|
||||
opts = append(opts, GetValidationOptions(r.RequestType)...)
|
||||
default:
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "invalid request type: %s", r.RequestType).
|
||||
WithAdditional("Valid request types are: raw, timeseries, scalar, heatmap")
|
||||
@@ -699,7 +706,9 @@ func (e QueryEnvelope) Validate(opts ...ValidationOption) error {
|
||||
return validateQueryEnvelope(e, opts...)
|
||||
}
|
||||
|
||||
func (r *QueryRangeRequest) validateTimeRange() error {
|
||||
// ValidateTimeRange checks only the request's time window.
|
||||
func (r *QueryRangeRequest) ValidateTimeRange(opts ...ValidationOption) error {
|
||||
cfg := applyValidationOptions(opts)
|
||||
if r.RequestType == RequestTypeRawStream {
|
||||
return nil
|
||||
}
|
||||
@@ -709,7 +718,11 @@ func (r *QueryRangeRequest) validateTimeRange() error {
|
||||
if r.Start >= r.End {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "start time must be before end time")
|
||||
}
|
||||
if r.End > uint64(time.Now().Add(maxEndTimeAhead).UnixMilli()) {
|
||||
maxAhead := cfg.maxEndTimeAhead
|
||||
if maxAhead <= 0 {
|
||||
maxAhead = DefaultMaxEndTimeAhead
|
||||
}
|
||||
if r.End > uint64(time.Now().Add(maxAhead).UnixMilli()) {
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "end time %s is too far in the future", time.UnixMilli(int64(r.End)).UTC().Format(time.RFC3339))
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user