mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 07:25:53 +08:00
feat: ability to configure noisy top level operations to discard (#2978)
This commit is contained in:
parent
0f998a4845
commit
20687d5184
@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
type APIHandlerOptions struct {
|
type APIHandlerOptions struct {
|
||||||
DataConnector interfaces.DataConnector
|
DataConnector interfaces.DataConnector
|
||||||
|
SkipConfig *basemodel.SkipConfig
|
||||||
AppDao dao.ModelDao
|
AppDao dao.ModelDao
|
||||||
RulesManager *rules.Manager
|
RulesManager *rules.Manager
|
||||||
FeatureFlags baseint.FeatureLookup
|
FeatureFlags baseint.FeatureLookup
|
||||||
@ -32,6 +33,7 @@ func NewAPIHandler(opts APIHandlerOptions) (*APIHandler, error) {
|
|||||||
|
|
||||||
baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{
|
baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{
|
||||||
Reader: opts.DataConnector,
|
Reader: opts.DataConnector,
|
||||||
|
SkipConfig: opts.SkipConfig,
|
||||||
AppDao: opts.AppDao,
|
AppDao: opts.AppDao,
|
||||||
RuleManager: opts.RulesManager,
|
RuleManager: opts.RulesManager,
|
||||||
FeatureFlags: opts.FeatureFlags})
|
FeatureFlags: opts.FeatureFlags})
|
||||||
|
@ -49,9 +49,10 @@ import (
|
|||||||
const AppDbEngine = "sqlite"
|
const AppDbEngine = "sqlite"
|
||||||
|
|
||||||
type ServerOptions struct {
|
type ServerOptions struct {
|
||||||
PromConfigPath string
|
PromConfigPath string
|
||||||
HTTPHostPort string
|
SkipTopLvlOpsPath string
|
||||||
PrivateHostPort string
|
HTTPHostPort string
|
||||||
|
PrivateHostPort string
|
||||||
// alert specific params
|
// alert specific params
|
||||||
DisableRules bool
|
DisableRules bool
|
||||||
RuleRepoURL string
|
RuleRepoURL string
|
||||||
@ -119,7 +120,15 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
go qb.Start(readerReady)
|
go qb.Start(readerReady)
|
||||||
reader = qb
|
reader = qb
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage)
|
return nil, fmt.Errorf("storage type: %s is not supported in query service", storage)
|
||||||
|
}
|
||||||
|
skipConfig := &basemodel.SkipConfig{}
|
||||||
|
if serverOptions.SkipTopLvlOpsPath != "" {
|
||||||
|
// read skip config
|
||||||
|
skipConfig, err = basemodel.ReadSkipConfig(serverOptions.SkipTopLvlOpsPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<-readerReady
|
<-readerReady
|
||||||
@ -160,6 +169,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
|
|
||||||
apiOpts := api.APIHandlerOptions{
|
apiOpts := api.APIHandlerOptions{
|
||||||
DataConnector: reader,
|
DataConnector: reader,
|
||||||
|
SkipConfig: skipConfig,
|
||||||
AppDao: modelDao,
|
AppDao: modelDao,
|
||||||
RulesManager: rm,
|
RulesManager: rm,
|
||||||
FeatureFlags: lm,
|
FeatureFlags: lm,
|
||||||
|
@ -74,7 +74,7 @@ func initZapLog(enableQueryServiceLogOTLPExport bool) *zap.Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var promConfigPath string
|
var promConfigPath, skipTopLvlOpsPath string
|
||||||
|
|
||||||
// disables rule execution but allows change to the rule definition
|
// disables rule execution but allows change to the rule definition
|
||||||
var disableRules bool
|
var disableRules bool
|
||||||
@ -85,6 +85,7 @@ func main() {
|
|||||||
var enableQueryServiceLogOTLPExport bool
|
var enableQueryServiceLogOTLPExport bool
|
||||||
|
|
||||||
flag.StringVar(&promConfigPath, "config", "./config/prometheus.yml", "(prometheus config to read metrics)")
|
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(&disableRules, "rules.disable", false, "(disable rule evaluation)")
|
||||||
flag.StringVar(&ruleRepoURL, "rules.repo-url", baseconst.AlertHelpPage, "(host address used to build rule link in alert messages)")
|
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.BoolVar(&enableQueryServiceLogOTLPExport, "enable.query.service.log.otlp.export", false, "(enable query service log otlp export)")
|
||||||
@ -98,11 +99,12 @@ func main() {
|
|||||||
version.PrintVersion()
|
version.PrintVersion()
|
||||||
|
|
||||||
serverOptions := &app.ServerOptions{
|
serverOptions := &app.ServerOptions{
|
||||||
HTTPHostPort: baseconst.HTTPHostPort,
|
HTTPHostPort: baseconst.HTTPHostPort,
|
||||||
PromConfigPath: promConfigPath,
|
PromConfigPath: promConfigPath,
|
||||||
PrivateHostPort: baseconst.PrivateHostPort,
|
SkipTopLvlOpsPath: skipTopLvlOpsPath,
|
||||||
DisableRules: disableRules,
|
PrivateHostPort: baseconst.PrivateHostPort,
|
||||||
RuleRepoURL: ruleRepoURL,
|
DisableRules: disableRules,
|
||||||
|
RuleRepoURL: ruleRepoURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the jwt secret key
|
// Read the jwt secret key
|
||||||
|
@ -716,7 +716,7 @@ func (r *ClickHouseReader) GetServicesList(ctx context.Context) (*[]string, erro
|
|||||||
return &services, nil
|
return &services, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClickHouseReader) GetTopLevelOperations(ctx context.Context) (*map[string][]string, *model.ApiError) {
|
func (r *ClickHouseReader) GetTopLevelOperations(ctx context.Context, skipConfig *model.SkipConfig) (*map[string][]string, *model.ApiError) {
|
||||||
|
|
||||||
operations := map[string][]string{}
|
operations := map[string][]string{}
|
||||||
query := fmt.Sprintf(`SELECT DISTINCT name, serviceName FROM %s.%s`, r.TraceDB, r.topLevelOperationsTable)
|
query := fmt.Sprintf(`SELECT DISTINCT name, serviceName FROM %s.%s`, r.TraceDB, r.topLevelOperationsTable)
|
||||||
@ -737,18 +737,21 @@ func (r *ClickHouseReader) GetTopLevelOperations(ctx context.Context) (*map[stri
|
|||||||
if _, ok := operations[serviceName]; !ok {
|
if _, ok := operations[serviceName]; !ok {
|
||||||
operations[serviceName] = []string{}
|
operations[serviceName] = []string{}
|
||||||
}
|
}
|
||||||
|
if skipConfig.ShouldSkip(serviceName, name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
operations[serviceName] = append(operations[serviceName], name)
|
operations[serviceName] = append(operations[serviceName], name)
|
||||||
}
|
}
|
||||||
return &operations, nil
|
return &operations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClickHouseReader) GetServices(ctx context.Context, queryParams *model.GetServicesParams) (*[]model.ServiceItem, *model.ApiError) {
|
func (r *ClickHouseReader) GetServices(ctx context.Context, queryParams *model.GetServicesParams, skipConfig *model.SkipConfig) (*[]model.ServiceItem, *model.ApiError) {
|
||||||
|
|
||||||
if r.indexTable == "" {
|
if r.indexTable == "" {
|
||||||
return nil, &model.ApiError{Typ: model.ErrorExec, Err: ErrNoIndexTable}
|
return nil, &model.ApiError{Typ: model.ErrorExec, Err: ErrNoIndexTable}
|
||||||
}
|
}
|
||||||
|
|
||||||
topLevelOps, apiErr := r.GetTopLevelOperations(ctx)
|
topLevelOps, apiErr := r.GetTopLevelOperations(ctx, skipConfig)
|
||||||
if apiErr != nil {
|
if apiErr != nil {
|
||||||
return nil, apiErr
|
return nil, apiErr
|
||||||
}
|
}
|
||||||
@ -839,9 +842,9 @@ func (r *ClickHouseReader) GetServices(ctx context.Context, queryParams *model.G
|
|||||||
return &serviceItems, nil
|
return &serviceItems, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClickHouseReader) GetServiceOverview(ctx context.Context, queryParams *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, *model.ApiError) {
|
func (r *ClickHouseReader) GetServiceOverview(ctx context.Context, queryParams *model.GetServiceOverviewParams, skipConfig *model.SkipConfig) (*[]model.ServiceOverviewItem, *model.ApiError) {
|
||||||
|
|
||||||
topLevelOps, apiErr := r.GetTopLevelOperations(ctx)
|
topLevelOps, apiErr := r.GetTopLevelOperations(ctx, skipConfig)
|
||||||
if apiErr != nil {
|
if apiErr != nil {
|
||||||
return nil, apiErr
|
return nil, apiErr
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@ type APIHandler struct {
|
|||||||
basePath string
|
basePath string
|
||||||
apiPrefix string
|
apiPrefix string
|
||||||
reader interfaces.Reader
|
reader interfaces.Reader
|
||||||
|
skipConfig *model.SkipConfig
|
||||||
appDao dao.ModelDao
|
appDao dao.ModelDao
|
||||||
alertManager am.Manager
|
alertManager am.Manager
|
||||||
ruleManager *rules.Manager
|
ruleManager *rules.Manager
|
||||||
@ -81,6 +82,7 @@ type APIHandlerOpts struct {
|
|||||||
// business data reader e.g. clickhouse
|
// business data reader e.g. clickhouse
|
||||||
Reader interfaces.Reader
|
Reader interfaces.Reader
|
||||||
|
|
||||||
|
SkipConfig *model.SkipConfig
|
||||||
// dao layer to perform crud on app objects like dashboard, alerts etc
|
// dao layer to perform crud on app objects like dashboard, alerts etc
|
||||||
AppDao dao.ModelDao
|
AppDao dao.ModelDao
|
||||||
|
|
||||||
@ -102,6 +104,7 @@ func NewAPIHandler(opts APIHandlerOpts) (*APIHandler, error) {
|
|||||||
aH := &APIHandler{
|
aH := &APIHandler{
|
||||||
reader: opts.Reader,
|
reader: opts.Reader,
|
||||||
appDao: opts.AppDao,
|
appDao: opts.AppDao,
|
||||||
|
skipConfig: opts.SkipConfig,
|
||||||
alertManager: alertManager,
|
alertManager: alertManager,
|
||||||
ruleManager: opts.RuleManager,
|
ruleManager: opts.RuleManager,
|
||||||
featureFlags: opts.FeatureFlags,
|
featureFlags: opts.FeatureFlags,
|
||||||
@ -1316,7 +1319,7 @@ func (aH *APIHandler) getServiceOverview(w http.ResponseWriter, r *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, apiErr := aH.reader.GetServiceOverview(r.Context(), query)
|
result, apiErr := aH.reader.GetServiceOverview(r.Context(), query, aH.skipConfig)
|
||||||
if apiErr != nil && aH.HandleError(w, apiErr.Err, http.StatusInternalServerError) {
|
if apiErr != nil && aH.HandleError(w, apiErr.Err, http.StatusInternalServerError) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1327,7 +1330,7 @@ func (aH *APIHandler) getServiceOverview(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
func (aH *APIHandler) getServicesTopLevelOps(w http.ResponseWriter, r *http.Request) {
|
func (aH *APIHandler) getServicesTopLevelOps(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
result, apiErr := aH.reader.GetTopLevelOperations(r.Context())
|
result, apiErr := aH.reader.GetTopLevelOperations(r.Context(), aH.skipConfig)
|
||||||
if apiErr != nil {
|
if apiErr != nil {
|
||||||
RespondError(w, apiErr, nil)
|
RespondError(w, apiErr, nil)
|
||||||
return
|
return
|
||||||
@ -1343,7 +1346,7 @@ func (aH *APIHandler) getServices(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result, apiErr := aH.reader.GetServices(r.Context(), query)
|
result, apiErr := aH.reader.GetServices(r.Context(), query, aH.skipConfig)
|
||||||
if apiErr != nil && aH.HandleError(w, apiErr.Err, http.StatusInternalServerError) {
|
if apiErr != nil && aH.HandleError(w, apiErr.Err, http.StatusInternalServerError) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -41,9 +41,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ServerOptions struct {
|
type ServerOptions struct {
|
||||||
PromConfigPath string
|
PromConfigPath string
|
||||||
HTTPHostPort string
|
SkipTopLvlOpsPath string
|
||||||
PrivateHostPort string
|
HTTPHostPort string
|
||||||
|
PrivateHostPort string
|
||||||
// alert specific params
|
// alert specific params
|
||||||
DisableRules bool
|
DisableRules bool
|
||||||
RuleRepoURL string
|
RuleRepoURL string
|
||||||
@ -105,6 +106,14 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage)
|
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage)
|
||||||
}
|
}
|
||||||
|
var skipConfig *model.SkipConfig
|
||||||
|
if serverOptions.SkipTopLvlOpsPath != "" {
|
||||||
|
// read skip config
|
||||||
|
skipConfig, err = model.ReadSkipConfig(serverOptions.SkipTopLvlOpsPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<-readerReady
|
<-readerReady
|
||||||
rm, err := makeRulesManager(serverOptions.PromConfigPath, constants.GetAlertManagerApiPrefix(), serverOptions.RuleRepoURL, localDB, reader, serverOptions.DisableRules, fm)
|
rm, err := makeRulesManager(serverOptions.PromConfigPath, constants.GetAlertManagerApiPrefix(), serverOptions.RuleRepoURL, localDB, reader, serverOptions.DisableRules, fm)
|
||||||
@ -115,6 +124,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
|
|||||||
telemetry.GetInstance().SetReader(reader)
|
telemetry.GetInstance().SetReader(reader)
|
||||||
apiHandler, err := NewAPIHandler(APIHandlerOpts{
|
apiHandler, err := NewAPIHandler(APIHandlerOpts{
|
||||||
Reader: reader,
|
Reader: reader,
|
||||||
|
SkipConfig: skipConfig,
|
||||||
AppDao: dao.DB(),
|
AppDao: dao.DB(),
|
||||||
RuleManager: rm,
|
RuleManager: rm,
|
||||||
FeatureFlags: fm,
|
FeatureFlags: fm,
|
||||||
|
@ -21,9 +21,9 @@ type Reader interface {
|
|||||||
|
|
||||||
GetInstantQueryMetricsResult(ctx context.Context, query *model.InstantQueryMetricsParams) (*promql.Result, *stats.QueryStats, *model.ApiError)
|
GetInstantQueryMetricsResult(ctx context.Context, query *model.InstantQueryMetricsParams) (*promql.Result, *stats.QueryStats, *model.ApiError)
|
||||||
GetQueryRangeResult(ctx context.Context, query *model.QueryRangeParams) (*promql.Result, *stats.QueryStats, *model.ApiError)
|
GetQueryRangeResult(ctx context.Context, query *model.QueryRangeParams) (*promql.Result, *stats.QueryStats, *model.ApiError)
|
||||||
GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams) (*[]model.ServiceOverviewItem, *model.ApiError)
|
GetServiceOverview(ctx context.Context, query *model.GetServiceOverviewParams, skipConfig *model.SkipConfig) (*[]model.ServiceOverviewItem, *model.ApiError)
|
||||||
GetTopLevelOperations(ctx context.Context) (*map[string][]string, *model.ApiError)
|
GetTopLevelOperations(ctx context.Context, skipConfig *model.SkipConfig) (*map[string][]string, *model.ApiError)
|
||||||
GetServices(ctx context.Context, query *model.GetServicesParams) (*[]model.ServiceItem, *model.ApiError)
|
GetServices(ctx context.Context, query *model.GetServicesParams, skipConfig *model.SkipConfig) (*[]model.ServiceItem, *model.ApiError)
|
||||||
GetTopOperations(ctx context.Context, query *model.GetTopOperationsParams) (*[]model.TopOperationsItem, *model.ApiError)
|
GetTopOperations(ctx context.Context, query *model.GetTopOperationsParams) (*[]model.TopOperationsItem, *model.ApiError)
|
||||||
GetUsage(ctx context.Context, query *model.GetUsageParams) (*[]model.UsageItem, error)
|
GetUsage(ctx context.Context, query *model.GetUsageParams) (*[]model.UsageItem, error)
|
||||||
GetServicesList(ctx context.Context) (*[]string, error)
|
GetServicesList(ctx context.Context) (*[]string, error)
|
||||||
|
@ -26,7 +26,7 @@ func initZapLog() *zap.Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var promConfigPath string
|
var promConfigPath, skipTopLvlOpsPath string
|
||||||
|
|
||||||
// disables rule execution but allows change to the rule definition
|
// disables rule execution but allows change to the rule definition
|
||||||
var disableRules bool
|
var disableRules bool
|
||||||
@ -35,6 +35,7 @@ func main() {
|
|||||||
var ruleRepoURL string
|
var ruleRepoURL string
|
||||||
|
|
||||||
flag.StringVar(&promConfigPath, "config", "./config/prometheus.yml", "(prometheus config to read metrics)")
|
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(&disableRules, "rules.disable", false, "(disable rule evaluation)")
|
||||||
flag.StringVar(&ruleRepoURL, "rules.repo-url", constants.AlertHelpPage, "(host address used to build rule link in alert messages)")
|
flag.StringVar(&ruleRepoURL, "rules.repo-url", constants.AlertHelpPage, "(host address used to build rule link in alert messages)")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
@ -47,11 +48,12 @@ func main() {
|
|||||||
version.PrintVersion()
|
version.PrintVersion()
|
||||||
|
|
||||||
serverOptions := &app.ServerOptions{
|
serverOptions := &app.ServerOptions{
|
||||||
HTTPHostPort: constants.HTTPHostPort,
|
HTTPHostPort: constants.HTTPHostPort,
|
||||||
PromConfigPath: promConfigPath,
|
PromConfigPath: promConfigPath,
|
||||||
PrivateHostPort: constants.PrivateHostPort,
|
SkipTopLvlOpsPath: skipTopLvlOpsPath,
|
||||||
DisableRules: disableRules,
|
PrivateHostPort: constants.PrivateHostPort,
|
||||||
RuleRepoURL: ruleRepoURL,
|
DisableRules: disableRules,
|
||||||
|
RuleRepoURL: ruleRepoURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the jwt secret key
|
// Read the jwt secret key
|
||||||
|
57
pkg/query-service/model/config.go
Normal file
57
pkg/query-service/model/config.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SkipConfig struct {
|
||||||
|
Services []ServiceSkipConfig `yaml:"services"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServiceSkipConfig struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
Operations []string `yaml:"operations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SkipConfig) ShouldSkip(serviceName, name string) bool {
|
||||||
|
for _, service := range s.Services {
|
||||||
|
if service.Name == serviceName {
|
||||||
|
for _, operation := range service.Operations {
|
||||||
|
if name == operation {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadYaml(path string, v interface{}) error {
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
decoder := yaml.NewDecoder(f)
|
||||||
|
err = decoder.Decode(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadSkipConfig(path string) (*SkipConfig, error) {
|
||||||
|
if path == "" {
|
||||||
|
return &SkipConfig{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
skipConfig := &SkipConfig{}
|
||||||
|
err := ReadYaml(path, skipConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return skipConfig, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user