mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #10947 from gyuho/log-level
*: make log level configurable
This commit is contained in:
commit
6e766ac5fb
@ -342,7 +342,8 @@ The security flags help to [build a secure etcd cluster][security].
|
||||
|
||||
### --logger
|
||||
|
||||
**Available from v3.4**
|
||||
**Available from v3.4.**
|
||||
**WARNING: `--logger=capnslog` to be deprecated in v3.5.**
|
||||
|
||||
+ Specify 'zap' for structured logging or 'capnslog'.
|
||||
+ default: capnslog
|
||||
@ -354,12 +355,27 @@ The security flags help to [build a secure etcd cluster][security].
|
||||
+ env variable: ETCD_LOG_OUTPUTS
|
||||
+ 'default' use 'stderr' config for v3.4 during zap logger migraion
|
||||
|
||||
### --log-level
|
||||
|
||||
**Available from v3.4.**
|
||||
|
||||
+ Configures log level. Only supports debug, info, warn, error, panic, or fatal.
|
||||
+ default: info
|
||||
+ env variable: ETCD_LOG_LEVEL
|
||||
+ 'default' use 'info'.
|
||||
|
||||
### --debug
|
||||
|
||||
**WARNING: to be deprecated in v3.5.**
|
||||
|
||||
+ Drop the default log level to DEBUG for all subpackages.
|
||||
+ default: false (INFO for all packages)
|
||||
+ env variable: ETCD_DEBUG
|
||||
|
||||
### --log-package-levels
|
||||
|
||||
**WARNING: to be deprecated in v3.5.**
|
||||
|
||||
+ Set individual etcd subpackages to specific log levels. An example being `etcdserver=WARNING,security=DEBUG`
|
||||
+ default: "" (INFO for all packages)
|
||||
+ env variable: ETCD_LOG_PACKAGE_LEVELS
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"go.etcd.io/etcd/etcdserver"
|
||||
"go.etcd.io/etcd/etcdserver/api/v3compactor"
|
||||
"go.etcd.io/etcd/pkg/flags"
|
||||
"go.etcd.io/etcd/pkg/logutil"
|
||||
"go.etcd.io/etcd/pkg/netutil"
|
||||
"go.etcd.io/etcd/pkg/srv"
|
||||
"go.etcd.io/etcd/pkg/tlsutil"
|
||||
@ -291,11 +292,8 @@ type Config struct {
|
||||
// Logger is logger options: "zap", "capnslog".
|
||||
// WARN: "capnslog" is being deprecated in v3.5.
|
||||
Logger string `json:"logger"`
|
||||
|
||||
// DeprecatedLogOutput is to be deprecated in v3.5.
|
||||
// Just here for safe migration in v3.4.
|
||||
DeprecatedLogOutput []string `json:"log-output"`
|
||||
|
||||
// LogLevel configures log level. Only supports debug, info, warn, error, panic, or fatal. Default 'info'.
|
||||
LogLevel string `json:"log-level"`
|
||||
// LogOutputs is either:
|
||||
// - "default" as os.Stderr,
|
||||
// - "stderr" as os.Stderr,
|
||||
@ -304,11 +302,8 @@ type Config struct {
|
||||
// It can be multiple when "Logger" is zap.
|
||||
LogOutputs []string `json:"log-outputs"`
|
||||
|
||||
// Debug is true, to enable debug level logging.
|
||||
Debug bool `json:"debug"`
|
||||
|
||||
// ZapLoggerBuilder is used to build the zap logger.
|
||||
ZapLoggerBuilder func(*Config) error
|
||||
// zapLoggerBuilder is used to build the zap logger.
|
||||
zapLoggerBuilder func(*Config) error
|
||||
|
||||
// logger logs server-side operations. The default is nil,
|
||||
// and "setupLogging" must be called before starting server.
|
||||
@ -329,6 +324,12 @@ type Config struct {
|
||||
|
||||
// TO BE DEPRECATED
|
||||
|
||||
// DeprecatedLogOutput is to be deprecated in v3.5.
|
||||
// Just here for safe migration in v3.4.
|
||||
DeprecatedLogOutput []string `json:"log-output"`
|
||||
// Debug is true, to enable debug level logging.
|
||||
// WARNING: to be deprecated in 3.5. Use "--log-level=debug" instead.
|
||||
Debug bool `json:"debug"`
|
||||
// LogPkgLevels is being deprecated in v3.5.
|
||||
// Only valid if "logger" option is "capnslog".
|
||||
// WARN: DO NOT USE THIS!
|
||||
@ -415,6 +416,7 @@ func NewConfig() *Config {
|
||||
DeprecatedLogOutput: []string{DefaultLogOutput},
|
||||
LogOutputs: []string{DefaultLogOutput},
|
||||
Debug: false,
|
||||
LogLevel: logutil.DefaultLogLevel,
|
||||
LogPkgLevels: "",
|
||||
}
|
||||
cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name)
|
||||
|
@ -69,11 +69,25 @@ func (cfg *Config) setupLogging() error {
|
||||
return fmt.Errorf("'--log-output=%q' and '--log-outputs=%q' are incompatible; only set --log-outputs", cfg.DeprecatedLogOutput, cfg.LogOutputs)
|
||||
}
|
||||
if !reflect.DeepEqual(cfg.DeprecatedLogOutput, []string{DefaultLogOutput}) {
|
||||
fmt.Fprintf(os.Stderr, "Deprecated '--log-output' flag is set to %q\n", cfg.DeprecatedLogOutput)
|
||||
fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--log-output' flag is set to %q\n", cfg.DeprecatedLogOutput)
|
||||
fmt.Fprintln(os.Stderr, "Please use '--log-outputs' flag")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove after deprecating log related flags in v3.5
|
||||
if cfg.Debug {
|
||||
fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--debug' flag is set to %v (use '--log-level=debug' instead\n", cfg.Debug)
|
||||
}
|
||||
if cfg.Debug && cfg.LogLevel != "debug" {
|
||||
fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--debug' flag is set to %v with inconsistent '--log-level=%s' flag\n", cfg.Debug, cfg.LogLevel)
|
||||
}
|
||||
if cfg.Logger == "capnslog" {
|
||||
fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--logger=%s' flag is set; use '--logger=zap' flag instead\n", cfg.Logger)
|
||||
}
|
||||
if cfg.LogPkgLevels != "" {
|
||||
fmt.Fprintf(os.Stderr, "[WARNING] Deprecated '--log-package-levels=%s' flag is set; use '--logger=zap' flag instead\n", cfg.LogPkgLevels)
|
||||
}
|
||||
|
||||
switch cfg.Logger {
|
||||
case "capnslog": // TODO: deprecate this in v3.5
|
||||
cfg.ClientTLSInfo.HandshakeFailure = logTLSHandshakeFailure
|
||||
@ -85,7 +99,7 @@ func (cfg *Config) setupLogging() error {
|
||||
// enable info, warning, error
|
||||
grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stderr, os.Stderr, os.Stderr))
|
||||
} else {
|
||||
capnslog.SetGlobalLogLevel(capnslog.INFO)
|
||||
capnslog.SetGlobalLogLevel(logutil.ConvertToCapnslogLogLevel(cfg.LogLevel))
|
||||
// only discard info
|
||||
grpclog.SetLoggerV2(grpclog.NewLoggerV2(ioutil.Discard, os.Stderr, os.Stderr))
|
||||
}
|
||||
@ -157,13 +171,15 @@ func (cfg *Config) setupLogging() error {
|
||||
|
||||
if !isJournal {
|
||||
copied := logutil.AddOutputPaths(logutil.DefaultZapLoggerConfig, outputPaths, errOutputPaths)
|
||||
|
||||
if cfg.Debug {
|
||||
copied.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
|
||||
copied.Level = zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(cfg.LogLevel))
|
||||
if cfg.Debug || cfg.LogLevel == "debug" {
|
||||
// enable tracing even when "--debug --log-level info"
|
||||
// in order to keep backward compatibility with <= v3.3
|
||||
// TODO: remove "Debug" check in v3.5
|
||||
grpc.EnableTracing = true
|
||||
}
|
||||
if cfg.ZapLoggerBuilder == nil {
|
||||
cfg.ZapLoggerBuilder = func(c *Config) error {
|
||||
if cfg.zapLoggerBuilder == nil {
|
||||
cfg.zapLoggerBuilder = func(c *Config) error {
|
||||
var err error
|
||||
c.logger, err = copied.Build()
|
||||
if err != nil {
|
||||
@ -201,9 +217,11 @@ func (cfg *Config) setupLogging() error {
|
||||
return lerr
|
||||
}
|
||||
|
||||
lvl := zap.NewAtomicLevelAt(zap.InfoLevel)
|
||||
if cfg.Debug {
|
||||
lvl = zap.NewAtomicLevelAt(zap.DebugLevel)
|
||||
lvl := zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(cfg.LogLevel))
|
||||
if cfg.Debug || cfg.LogLevel == "debug" {
|
||||
// enable tracing even when "--debug --log-level info"
|
||||
// in order to keep backward compatibility with <= v3.3
|
||||
// TODO: remove "Debug" check in v3.5
|
||||
grpc.EnableTracing = true
|
||||
}
|
||||
|
||||
@ -214,8 +232,8 @@ func (cfg *Config) setupLogging() error {
|
||||
syncer,
|
||||
lvl,
|
||||
)
|
||||
if cfg.ZapLoggerBuilder == nil {
|
||||
cfg.ZapLoggerBuilder = func(c *Config) error {
|
||||
if cfg.zapLoggerBuilder == nil {
|
||||
cfg.zapLoggerBuilder = func(c *Config) error {
|
||||
c.logger = zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer))
|
||||
c.loggerMu.Lock()
|
||||
defer c.loggerMu.Unlock()
|
||||
@ -231,7 +249,7 @@ func (cfg *Config) setupLogging() error {
|
||||
}
|
||||
}
|
||||
|
||||
err := cfg.ZapLoggerBuilder(cfg)
|
||||
err := cfg.zapLoggerBuilder(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
|
||||
"go.etcd.io/etcd/embed"
|
||||
"go.etcd.io/etcd/pkg/flags"
|
||||
"go.etcd.io/etcd/pkg/logutil"
|
||||
"go.etcd.io/etcd/pkg/types"
|
||||
"go.etcd.io/etcd/version"
|
||||
|
||||
@ -221,11 +222,12 @@ func newConfig() *config {
|
||||
fs.Var(flags.NewUniqueStringsValue("*"), "host-whitelist", "Comma-separated acceptable hostnames from HTTP client requests, if server is not secure (empty means allow all).")
|
||||
|
||||
// logging
|
||||
fs.StringVar(&cfg.ec.Logger, "logger", "capnslog", "Specify 'zap' for structured logging or 'capnslog'.")
|
||||
fs.Var(flags.NewUniqueStringsValue(embed.DefaultLogOutput), "log-output", "DEPRECATED: use '--log-outputs'.")
|
||||
fs.StringVar(&cfg.ec.Logger, "logger", "capnslog", "Specify 'zap' for structured logging or 'capnslog'. WARN: 'capnslog' is being deprecated in v3.5.")
|
||||
fs.Var(flags.NewUniqueStringsValue(embed.DefaultLogOutput), "log-output", "[TO BE DEPRECATED IN v3.5] use '--log-outputs'.")
|
||||
fs.Var(flags.NewUniqueStringsValue(embed.DefaultLogOutput), "log-outputs", "Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd, or list of comma separated output targets.")
|
||||
fs.BoolVar(&cfg.ec.Debug, "debug", false, "Enable debug-level logging for etcd.")
|
||||
fs.StringVar(&cfg.ec.LogPkgLevels, "log-package-levels", "", "(To be deprecated) Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').")
|
||||
fs.BoolVar(&cfg.ec.Debug, "debug", false, "[TO BE DEPRECATED IN v3.5] Enable debug-level logging for etcd. Use '--log-level=debug' instead.")
|
||||
fs.StringVar(&cfg.ec.LogLevel, "log-level", logutil.DefaultLogLevel, "Configures log level. Only supports debug, info, warn, error, panic, or fatal. Default 'info'.")
|
||||
fs.StringVar(&cfg.ec.LogPkgLevels, "log-package-levels", "", "[TO BE DEPRECATED IN v3.5] Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').")
|
||||
|
||||
// version
|
||||
fs.BoolVar(&cfg.printVersion, "version", false, "Print the version and exit.")
|
||||
|
@ -173,15 +173,11 @@ Profiling and Monitoring:
|
||||
|
||||
Logging:
|
||||
--logger 'capnslog'
|
||||
Specify 'zap' for structured logging or 'capnslog'.
|
||||
Specify 'zap' for structured logging or 'capnslog'. [WARN] 'capnslog' will be deprecated in v3.5.
|
||||
--log-outputs 'default'
|
||||
Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd, or list of comma separated output targets.
|
||||
--debug 'false'
|
||||
Enable debug-level logging for etcd.
|
||||
|
||||
Logging (to be deprecated in v3.5):
|
||||
--log-package-levels ''
|
||||
Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').
|
||||
--log-level 'info'
|
||||
Configures log level. Only supports debug, info, warn, error, panic, or fatal.
|
||||
|
||||
v2 Proxy (to be deprecated in v4):
|
||||
--proxy 'off'
|
||||
@ -214,5 +210,12 @@ Unsafe feature:
|
||||
Force to create a new one-member cluster.
|
||||
|
||||
CAUTIOUS with unsafe flag! It may break the guarantees given by the consensus protocol!
|
||||
|
||||
TO BE DEPRECATED:
|
||||
|
||||
--debug 'false'
|
||||
Enable debug-level logging for etcd. [WARN] Will be deprecated in v3.5. Use '--log-level=debug' instead.
|
||||
--log-package-levels ''
|
||||
Specify a particular log level for each etcd package (eg: 'etcdmain=CRITICAL,etcdserver=DEBUG').
|
||||
`
|
||||
)
|
||||
|
@ -58,13 +58,6 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
lcfg := logutil.DefaultZapLoggerConfig
|
||||
lg, err := logutil.NewRaftLogger(&lcfg)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot create raft logger %v", err)
|
||||
}
|
||||
raft.SetLogger(lg)
|
||||
|
||||
expvar.Publish("raft.status", expvar.Func(func() interface{} {
|
||||
raftStatusMu.Lock()
|
||||
defer raftStatusMu.Unlock()
|
||||
@ -124,6 +117,18 @@ type raftNodeConfig struct {
|
||||
}
|
||||
|
||||
func newRaftNode(cfg raftNodeConfig) *raftNode {
|
||||
var lg raft.Logger
|
||||
if cfg.lg != nil {
|
||||
lg = logutil.NewRaftLoggerZap(cfg.lg)
|
||||
} else {
|
||||
lcfg := logutil.DefaultZapLoggerConfig
|
||||
var err error
|
||||
lg, err = logutil.NewRaftLogger(&lcfg)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot create raft logger %v", err)
|
||||
}
|
||||
}
|
||||
raft.SetLogger(lg)
|
||||
r := &raftNode{
|
||||
lg: cfg.lg,
|
||||
tickMu: new(sync.Mutex),
|
||||
|
70
pkg/logutil/log_level.go
Normal file
70
pkg/logutil/log_level.go
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2019 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package logutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/coreos/pkg/capnslog"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
var DefaultLogLevel = "info"
|
||||
|
||||
// ConvertToZapLevel converts log level string to zapcore.Level.
|
||||
func ConvertToZapLevel(lvl string) zapcore.Level {
|
||||
switch lvl {
|
||||
case "debug":
|
||||
return zap.DebugLevel
|
||||
case "info":
|
||||
return zap.InfoLevel
|
||||
case "warn":
|
||||
return zap.WarnLevel
|
||||
case "error":
|
||||
return zap.ErrorLevel
|
||||
case "dpanic":
|
||||
return zap.DPanicLevel
|
||||
case "panic":
|
||||
return zap.PanicLevel
|
||||
case "fatal":
|
||||
return zap.FatalLevel
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown level %q", lvl))
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertToCapnslogLogLevel convert log level string to capnslog.LogLevel.
|
||||
// TODO: deprecate this in 3.5
|
||||
func ConvertToCapnslogLogLevel(lvl string) capnslog.LogLevel {
|
||||
switch lvl {
|
||||
case "debug":
|
||||
return capnslog.DEBUG
|
||||
case "info":
|
||||
return capnslog.INFO
|
||||
case "warn":
|
||||
return capnslog.WARNING
|
||||
case "error":
|
||||
return capnslog.ERROR
|
||||
case "dpanic":
|
||||
return capnslog.CRITICAL
|
||||
case "panic":
|
||||
return capnslog.CRITICAL
|
||||
case "fatal":
|
||||
return capnslog.CRITICAL
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown level %q", lvl))
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import (
|
||||
|
||||
// DefaultZapLoggerConfig defines default zap logger configuration.
|
||||
var DefaultZapLoggerConfig = zap.Config{
|
||||
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
|
||||
Level: zap.NewAtomicLevelAt(ConvertToZapLevel(DefaultLogLevel)),
|
||||
|
||||
Development: false,
|
||||
Sampling: &zap.SamplingConfig{
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// NewRaftLogger converts "*zap.Logger" to "raft.Logger".
|
||||
// NewRaftLogger builds "raft.Logger" from "*zap.Config".
|
||||
func NewRaftLogger(lcfg *zap.Config) (raft.Logger, error) {
|
||||
if lcfg == nil {
|
||||
return nil, errors.New("nil zap.Config")
|
||||
@ -35,6 +35,11 @@ func NewRaftLogger(lcfg *zap.Config) (raft.Logger, error) {
|
||||
return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}, nil
|
||||
}
|
||||
|
||||
// NewRaftLoggerZap converts "*zap.Logger" to "raft.Logger".
|
||||
func NewRaftLoggerZap(lg *zap.Logger) raft.Logger {
|
||||
return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}
|
||||
}
|
||||
|
||||
// NewRaftLoggerFromZapCore creates "raft.Logger" from "zap.Core"
|
||||
// and "zapcore.WriteSyncer".
|
||||
func NewRaftLoggerFromZapCore(cr zapcore.Core, syncer zapcore.WriteSyncer) raft.Logger {
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Logger interface {
|
||||
@ -41,11 +42,16 @@ type Logger interface {
|
||||
Panicf(format string, v ...interface{})
|
||||
}
|
||||
|
||||
func SetLogger(l Logger) { raftLogger = l }
|
||||
func SetLogger(l Logger) {
|
||||
raftLoggerMu.Lock()
|
||||
raftLogger = l
|
||||
raftLoggerMu.Unlock()
|
||||
}
|
||||
|
||||
var (
|
||||
defaultLogger = &DefaultLogger{Logger: log.New(os.Stderr, "raft", log.LstdFlags)}
|
||||
discardLogger = &DefaultLogger{Logger: log.New(ioutil.Discard, "", 0)}
|
||||
raftLoggerMu sync.Mutex
|
||||
raftLogger = Logger(defaultLogger)
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user