From 05f9af3902e14508e84c7f17f7ac9f136c649643 Mon Sep 17 00:00:00 2001 From: albertteoh Date: Fri, 5 Mar 2021 19:38:43 +1100 Subject: [PATCH 1/3] Enable logging in ES client Signed-off-by: albertteoh --- pkg/es/config/config.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkg/es/config/config.go b/pkg/es/config/config.go index d5efe4c9411..2500f697987 100644 --- a/pkg/es/config/config.go +++ b/pkg/es/config/config.go @@ -32,6 +32,7 @@ import ( "github.com/olivere/elastic" "github.com/uber/jaeger-lib/metrics" "go.uber.org/zap" + "go.uber.org/zap/zapgrpc" "github.com/jaegertracing/jaeger/pkg/config/tlscfg" "github.com/jaegertracing/jaeger/pkg/es" @@ -362,6 +363,18 @@ func (c *Configuration) getConfigOptions(logger *zap.Logger) ([]elastic.ClientOp } options = append(options, elastic.SetHttpClient(httpClient)) options = append(options, elastic.SetBasicAuth(c.Username, c.Password)) + + // Elastic client requires a "Printf"-able logger. + l := zapgrpc.NewLogger(logger) + switch { + case logger.Core().Enabled(zap.DebugLevel): + l = zapgrpc.NewLogger(logger, zapgrpc.WithDebug()) + options = append(options, elastic.SetTraceLog(l)) + case logger.Core().Enabled(zap.InfoLevel): + options = append(options, elastic.SetInfoLog(l)) + default: + options = append(options, elastic.SetErrorLog(l)) + } transport, err := GetHTTPRoundTripper(c, logger) if err != nil { return nil, err From 729067c08b0bb3fc118e6ba3894770ceb5c4dc5f Mon Sep 17 00:00:00 2001 From: albertteoh Date: Wed, 10 Mar 2021 16:38:05 +1100 Subject: [PATCH 2/3] Decouple es logger from main logger Signed-off-by: albertteoh --- pkg/es/config/config.go | 51 +++++++++++++++++++++++++++++------- plugin/storage/es/options.go | 7 +++++ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/pkg/es/config/config.go b/pkg/es/config/config.go index 2500f697987..7c6b443bd6d 100644 --- a/pkg/es/config/config.go +++ b/pkg/es/config/config.go @@ -68,6 +68,7 @@ type Configuration struct { CreateIndexTemplates bool `mapstructure:"create_mappings"` UseILM bool `mapstructure:"use_ilm"` Version uint `mapstructure:"version"` + LogLevel string `mapstructure:"log_level"` } // TagsAsFields holds configuration for tag schema. @@ -103,6 +104,7 @@ type ClientBuilder interface { GetVersion() uint TagKeysAsFields() ([]string, error) GetUseILM() bool + GetLogLevel() string } // NewClient creates a new ElasticSearch client @@ -238,6 +240,9 @@ func (c *Configuration) ApplyDefaults(source *Configuration) { if c.MaxDocCount == 0 { c.MaxDocCount = source.MaxDocCount } + if c.LogLevel == "" { + c.LogLevel = source.LogLevel + } } // GetNumShards returns number of shards from Configuration @@ -301,6 +306,11 @@ func (c *Configuration) GetUseILM() bool { return c.UseILM } +// GetLogLevel returns the log-level the ES client should log at. +func (c *Configuration) GetLogLevel() string { + return c.LogLevel +} + // GetTokenFilePath returns file path containing the bearer token func (c *Configuration) GetTokenFilePath() string { return c.TokenFilePath @@ -364,17 +374,11 @@ func (c *Configuration) getConfigOptions(logger *zap.Logger) ([]elastic.ClientOp options = append(options, elastic.SetHttpClient(httpClient)) options = append(options, elastic.SetBasicAuth(c.Username, c.Password)) - // Elastic client requires a "Printf"-able logger. - l := zapgrpc.NewLogger(logger) - switch { - case logger.Core().Enabled(zap.DebugLevel): - l = zapgrpc.NewLogger(logger, zapgrpc.WithDebug()) - options = append(options, elastic.SetTraceLog(l)) - case logger.Core().Enabled(zap.InfoLevel): - options = append(options, elastic.SetInfoLog(l)) - default: - options = append(options, elastic.SetErrorLog(l)) + options, err := addLoggerOptions(options, c.LogLevel) + if err != nil { + return options, err } + transport, err := GetHTTPRoundTripper(c, logger) if err != nil { return nil, err @@ -383,6 +387,33 @@ func (c *Configuration) getConfigOptions(logger *zap.Logger) ([]elastic.ClientOp return options, nil } +func addLoggerOptions(options []elastic.ClientOptionFunc, logLevel string) ([]elastic.ClientOptionFunc, error) { + // Decouple ES logger from the log-level assigned to the parent application's log-level; otherwise, the least + // permissive log-level will dominate. + // e.g. --log-level=info and --es.log-level=debug would mute ES's debug logging and would require --log-level=debug + // to show ES debug logs. + prodConfig := zap.NewProductionConfig() + prodConfig.Level.SetLevel(zap.DebugLevel) + + esLogger, err := prodConfig.Build() + if err != nil { + return options, err + } + + // Elastic client requires a "Printf"-able logger. + l := zapgrpc.NewLogger(esLogger) + switch logLevel { + case "debug": + l = zapgrpc.NewLogger(esLogger, zapgrpc.WithDebug()) + options = append(options, elastic.SetTraceLog(l)) + case "info": + options = append(options, elastic.SetInfoLog(l)) + default: + options = append(options, elastic.SetErrorLog(l)) + } + return options, nil +} + // GetHTTPRoundTripper returns configured http.RoundTripper func GetHTTPRoundTripper(c *Configuration, logger *zap.Logger) (http.RoundTripper, error) { if c.TLS.Enabled { diff --git a/plugin/storage/es/options.go b/plugin/storage/es/options.go index 7353bd1ec9b..68ca71c6cb3 100644 --- a/plugin/storage/es/options.go +++ b/plugin/storage/es/options.go @@ -56,6 +56,7 @@ const ( suffixEnabled = ".enabled" suffixVersion = ".version" suffixMaxDocCount = ".max-doc-count" + suffixLogLevel = ".log-level" // default number of documents to return from a query (elasticsearch allowed limit) // see search.max_buckets and index.max_result_window defaultMaxDocCount = 10_000 @@ -102,6 +103,7 @@ func NewOptions(primaryNamespace string, otherNamespaces ...string) *Options { Version: 0, Servers: []string{defaultServerURL}, MaxDocCount: defaultMaxDocCount, + LogLevel: "error", } options := &Options{ Primary: namespaceConfig{ @@ -240,6 +242,10 @@ func addFlags(flagSet *flag.FlagSet, nsConfig *namespaceConfig) { nsConfig.namespace+suffixMaxDocCount, nsConfig.MaxDocCount, "The maximum document count to return from an Elasticsearch query. This will also apply to aggregations.") + flagSet.String( + nsConfig.namespace+suffixLogLevel, + nsConfig.LogLevel, + "The Elasticsearch client log-level. Valid levels: [debug, info, error]") if nsConfig.namespace == archiveNamespace { flagSet.Bool( @@ -290,6 +296,7 @@ func initFromViper(cfg *namespaceConfig, v *viper.Viper) { cfg.Enabled = v.GetBool(cfg.namespace + suffixEnabled) cfg.CreateIndexTemplates = v.GetBool(cfg.namespace + suffixCreateIndexTemplate) cfg.Version = uint(v.GetInt(cfg.namespace + suffixVersion)) + cfg.LogLevel = v.GetString(cfg.namespace + suffixLogLevel) cfg.MaxDocCount = v.GetInt(cfg.namespace + suffixMaxDocCount) cfg.UseILM = v.GetBool(cfg.namespace + suffixUseILM) From 62cdf8b5b1d649f1360bde542739c5c05abf27a7 Mon Sep 17 00:00:00 2001 From: albertteoh Date: Wed, 10 Mar 2021 16:43:33 +1100 Subject: [PATCH 3/3] Error on unrecognized level Signed-off-by: albertteoh --- pkg/es/config/config.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/es/config/config.go b/pkg/es/config/config.go index 7c6b443bd6d..0d625e67965 100644 --- a/pkg/es/config/config.go +++ b/pkg/es/config/config.go @@ -20,6 +20,7 @@ import ( "context" "crypto/tls" "errors" + "fmt" "io/ioutil" "net/http" "os" @@ -408,8 +409,10 @@ func addLoggerOptions(options []elastic.ClientOptionFunc, logLevel string) ([]el options = append(options, elastic.SetTraceLog(l)) case "info": options = append(options, elastic.SetInfoLog(l)) - default: + case "error": options = append(options, elastic.SetErrorLog(l)) + default: + return options, fmt.Errorf("unrecognized log-level: \"%s\"", logLevel) } return options, nil }