diff --git a/ee/query-service/app/api/api.go b/ee/query-service/app/api/api.go index 2eddf1d83c..c9d839fd39 100644 --- a/ee/query-service/app/api/api.go +++ b/ee/query-service/app/api/api.go @@ -15,13 +15,14 @@ import ( ) type APIHandlerOptions struct { - DataConnector interfaces.DataConnector - SkipConfig *basemodel.SkipConfig - PreferDelta bool - AppDao dao.ModelDao - RulesManager *rules.Manager - FeatureFlags baseint.FeatureLookup - LicenseManager *license.Manager + DataConnector interfaces.DataConnector + SkipConfig *basemodel.SkipConfig + PreferDelta bool + PreferSpanMetrics bool + AppDao dao.ModelDao + RulesManager *rules.Manager + FeatureFlags baseint.FeatureLookup + LicenseManager *license.Manager } type APIHandler struct { @@ -33,12 +34,13 @@ type APIHandler struct { func NewAPIHandler(opts APIHandlerOptions) (*APIHandler, error) { baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{ - Reader: opts.DataConnector, - SkipConfig: opts.SkipConfig, - PerferDelta: opts.PreferDelta, - AppDao: opts.AppDao, - RuleManager: opts.RulesManager, - FeatureFlags: opts.FeatureFlags}) + Reader: opts.DataConnector, + SkipConfig: opts.SkipConfig, + PerferDelta: opts.PreferDelta, + PreferSpanMetrics: opts.PreferSpanMetrics, + AppDao: opts.AppDao, + RuleManager: opts.RulesManager, + FeatureFlags: opts.FeatureFlags}) if err != nil { return nil, err diff --git a/ee/query-service/app/api/featureFlags.go b/ee/query-service/app/api/featureFlags.go index 63b36d45c4..22ee798bee 100644 --- a/ee/query-service/app/api/featureFlags.go +++ b/ee/query-service/app/api/featureFlags.go @@ -2,6 +2,8 @@ package api import ( "net/http" + + basemodel "go.signoz.io/signoz/pkg/query-service/model" ) func (ah *APIHandler) getFeatureFlags(w http.ResponseWriter, r *http.Request) { @@ -10,5 +12,13 @@ func (ah *APIHandler) getFeatureFlags(w http.ResponseWriter, r *http.Request) { ah.HandleError(w, err, http.StatusInternalServerError) return } + if ah.opts.PreferSpanMetrics { + for idx := range featureSet { + feature := &featureSet[idx] + if feature.Name == basemodel.UseSpanMetrics { + featureSet[idx].Active = true + } + } + } ah.Respond(w, featureSet) } diff --git a/ee/query-service/app/server.go b/ee/query-service/app/server.go index a2e86023e3..a74738eef5 100644 --- a/ee/query-service/app/server.go +++ b/ee/query-service/app/server.go @@ -54,9 +54,10 @@ type ServerOptions struct { HTTPHostPort string PrivateHostPort string // alert specific params - DisableRules bool - RuleRepoURL string - PreferDelta bool + DisableRules bool + RuleRepoURL string + PreferDelta bool + PreferSpanMetrics bool } // Server runs HTTP api service @@ -169,13 +170,14 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { telemetry.GetInstance().SetReader(reader) apiOpts := api.APIHandlerOptions{ - DataConnector: reader, - SkipConfig: skipConfig, - PreferDelta: serverOptions.PreferDelta, - AppDao: modelDao, - RulesManager: rm, - FeatureFlags: lm, - LicenseManager: lm, + DataConnector: reader, + SkipConfig: skipConfig, + PreferDelta: serverOptions.PreferDelta, + PreferSpanMetrics: serverOptions.PreferSpanMetrics, + AppDao: modelDao, + RulesManager: rm, + FeatureFlags: lm, + LicenseManager: lm, } apiHandler, err := api.NewAPIHandler(apiOpts) diff --git a/ee/query-service/main.go b/ee/query-service/main.go index 52ce63ba20..08a807c861 100644 --- a/ee/query-service/main.go +++ b/ee/query-service/main.go @@ -84,11 +84,13 @@ func main() { var enableQueryServiceLogOTLPExport bool var preferDelta bool + var preferSpanMetrics bool flag.StringVar(&promConfigPath, "config", "./config/prometheus.yml", "(prometheus config to read metrics)") flag.StringVar(&skipTopLvlOpsPath, "skip-top-level-ops", "", "(config file to skip top level operations)") flag.BoolVar(&disableRules, "rules.disable", false, "(disable rule evaluation)") - flag.BoolVar(&preferDelta, "prefer-delta", false, "(prefer delta over raw metrics)") + flag.BoolVar(&preferDelta, "prefer-delta", false, "(prefer delta over cumulative metrics)") + flag.BoolVar(&preferSpanMetrics, "prefer-span-metrics", false, "(prefer span metrics for service level metrics)") flag.StringVar(&ruleRepoURL, "rules.repo-url", baseconst.AlertHelpPage, "(host address used to build rule link in alert messages)") flag.BoolVar(&enableQueryServiceLogOTLPExport, "enable.query.service.log.otlp.export", false, "(enable query service log otlp export)") flag.Parse() @@ -105,6 +107,7 @@ func main() { PromConfigPath: promConfigPath, SkipTopLvlOpsPath: skipTopLvlOpsPath, PreferDelta: preferDelta, + PreferSpanMetrics: preferSpanMetrics, PrivateHostPort: baseconst.PrivateHostPort, DisableRules: disableRules, RuleRepoURL: ruleRepoURL, diff --git a/ee/query-service/model/plans.go b/ee/query-service/model/plans.go index 52ebd5c5b5..2be68f1ea7 100644 --- a/ee/query-service/model/plans.go +++ b/ee/query-service/model/plans.go @@ -60,6 +60,13 @@ var BasicPlan = basemodel.FeatureSet{ UsageLimit: 5, Route: "", }, + basemodel.Feature{ + Name: basemodel.UseSpanMetrics, + Active: false, + Usage: 0, + UsageLimit: -1, + Route: "", + }, } var ProPlan = basemodel.FeatureSet{ @@ -105,6 +112,13 @@ var ProPlan = basemodel.FeatureSet{ UsageLimit: -1, Route: "", }, + basemodel.Feature{ + Name: basemodel.UseSpanMetrics, + Active: false, + Usage: 0, + UsageLimit: -1, + Route: "", + }, } var EnterprisePlan = basemodel.FeatureSet{ @@ -150,4 +164,11 @@ var EnterprisePlan = basemodel.FeatureSet{ UsageLimit: -1, Route: "", }, + basemodel.Feature{ + Name: basemodel.UseSpanMetrics, + Active: false, + Usage: 0, + UsageLimit: -1, + Route: "", + }, } diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index 47e115343f..9181e5fdf4 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -61,17 +61,18 @@ func NewRouter() *mux.Router { type APIHandler struct { // queryService *querysvc.QueryService // queryParser queryParser - basePath string - apiPrefix string - reader interfaces.Reader - skipConfig *model.SkipConfig - appDao dao.ModelDao - alertManager am.Manager - ruleManager *rules.Manager - featureFlags interfaces.FeatureLookup - ready func(http.HandlerFunc) http.HandlerFunc - queryBuilder *queryBuilder.QueryBuilder - preferDelta bool + basePath string + apiPrefix string + reader interfaces.Reader + skipConfig *model.SkipConfig + appDao dao.ModelDao + alertManager am.Manager + ruleManager *rules.Manager + featureFlags interfaces.FeatureLookup + ready func(http.HandlerFunc) http.HandlerFunc + queryBuilder *queryBuilder.QueryBuilder + preferDelta bool + preferSpanMetrics bool // SetupCompleted indicates if SigNoz is ready for general use. // at the moment, we mark the app ready when the first user @@ -86,7 +87,8 @@ type APIHandlerOpts struct { SkipConfig *model.SkipConfig - PerferDelta bool + PerferDelta bool + PreferSpanMetrics bool // dao layer to perform crud on app objects like dashboard, alerts etc AppDao dao.ModelDao @@ -106,13 +108,14 @@ func NewAPIHandler(opts APIHandlerOpts) (*APIHandler, error) { } aH := &APIHandler{ - reader: opts.Reader, - appDao: opts.AppDao, - skipConfig: opts.SkipConfig, - preferDelta: opts.PerferDelta, - alertManager: alertManager, - ruleManager: opts.RuleManager, - featureFlags: opts.FeatureFlags, + reader: opts.Reader, + appDao: opts.AppDao, + skipConfig: opts.SkipConfig, + preferDelta: opts.PerferDelta, + preferSpanMetrics: opts.PreferSpanMetrics, + alertManager: alertManager, + ruleManager: opts.RuleManager, + featureFlags: opts.FeatureFlags, } builderOpts := queryBuilder.QueryBuilderOptions{ @@ -1668,6 +1671,14 @@ func (aH *APIHandler) getFeatureFlags(w http.ResponseWriter, r *http.Request) { aH.HandleError(w, err, http.StatusInternalServerError) return } + if aH.preferSpanMetrics { + for idx := range featureSet { + feature := &featureSet[idx] + if feature.Name == model.UseSpanMetrics { + featureSet[idx].Active = true + } + } + } aH.Respond(w, featureSet) } diff --git a/pkg/query-service/app/server.go b/pkg/query-service/app/server.go index 7e3a913fac..367fdbdd44 100644 --- a/pkg/query-service/app/server.go +++ b/pkg/query-service/app/server.go @@ -46,9 +46,10 @@ type ServerOptions struct { HTTPHostPort string PrivateHostPort string // alert specific params - DisableRules bool - RuleRepoURL string - PreferDelta bool + DisableRules bool + RuleRepoURL string + PreferDelta bool + PreferSpanMetrics bool } // Server runs HTTP, Mux and a grpc server @@ -124,12 +125,13 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) { telemetry.GetInstance().SetReader(reader) apiHandler, err := NewAPIHandler(APIHandlerOpts{ - Reader: reader, - SkipConfig: skipConfig, - PerferDelta: serverOptions.PreferDelta, - AppDao: dao.DB(), - RuleManager: rm, - FeatureFlags: fm, + Reader: reader, + SkipConfig: skipConfig, + PerferDelta: serverOptions.PreferDelta, + PreferSpanMetrics: serverOptions.PreferSpanMetrics, + AppDao: dao.DB(), + RuleManager: rm, + FeatureFlags: fm, }) if err != nil { return nil, err diff --git a/pkg/query-service/constants/constants.go b/pkg/query-service/constants/constants.go index 31d02b19f6..7781ce21fb 100644 --- a/pkg/query-service/constants/constants.go +++ b/pkg/query-service/constants/constants.go @@ -87,6 +87,13 @@ var DEFAULT_FEATURE_SET = model.FeatureSet{ UsageLimit: -1, Route: "", }, + model.Feature{ + Name: model.UseSpanMetrics, + Active: false, + Usage: 0, + UsageLimit: -1, + Route: "", + }, } func GetContextTimeout() time.Duration { diff --git a/pkg/query-service/main.go b/pkg/query-service/main.go index 7e8b8f4bf6..bd401d6be7 100644 --- a/pkg/query-service/main.go +++ b/pkg/query-service/main.go @@ -35,11 +35,13 @@ func main() { var ruleRepoURL string var preferDelta bool + var preferSpanMetrics bool flag.StringVar(&promConfigPath, "config", "./config/prometheus.yml", "(prometheus config to read metrics)") flag.StringVar(&skipTopLvlOpsPath, "skip-top-level-ops", "", "(config file to skip top level operations)") flag.BoolVar(&disableRules, "rules.disable", false, "(disable rule evaluation)") - flag.BoolVar(&preferDelta, "prefer-delta", false, "(prefer delta over gauge)") + flag.BoolVar(&preferDelta, "prefer-delta", false, "(prefer delta over cumulative metrics)") + flag.BoolVar(&preferSpanMetrics, "prefer-span-metrics", false, "(prefer span metrics for service level metrics)") flag.StringVar(&ruleRepoURL, "rules.repo-url", constants.AlertHelpPage, "(host address used to build rule link in alert messages)") flag.Parse() @@ -55,6 +57,7 @@ func main() { PromConfigPath: promConfigPath, SkipTopLvlOpsPath: skipTopLvlOpsPath, PreferDelta: preferDelta, + PreferSpanMetrics: preferSpanMetrics, PrivateHostPort: constants.PrivateHostPort, DisableRules: disableRules, RuleRepoURL: ruleRepoURL, diff --git a/pkg/query-service/model/featureSet.go b/pkg/query-service/model/featureSet.go index 7f4cfb645e..d8c1bfc9b3 100644 --- a/pkg/query-service/model/featureSet.go +++ b/pkg/query-service/model/featureSet.go @@ -13,4 +13,5 @@ const SmartTraceDetail = "SMART_TRACE_DETAIL" const CustomMetricsFunction = "CUSTOM_METRICS_FUNCTION" const OSS = "OSS" const QueryBuilderPanels = "QUERY_BUILDER_PANELS" -const QueryBuilderAlerts = "QUERY_BUILDER_ALERTS" \ No newline at end of file +const QueryBuilderAlerts = "QUERY_BUILDER_ALERTS" +const UseSpanMetrics = "USE_SPAN_METRICS"