From fcbb30364a9b2afc5d14571a28d4a6ec9c171372 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 11:59:49 -0700 Subject: [PATCH 01/22] pkg/logutil: add "NewJournaldWriter" Signed-off-by: Gyuho Lee --- pkg/logutil/{zap.go => zap_grpc.go} | 64 -------------- pkg/logutil/{zap_test.go => zap_grpc_test.go} | 45 +--------- pkg/logutil/zap_journald.go | 85 +++++++++++++++++++ pkg/logutil/zap_journald_test.go | 42 +++++++++ pkg/logutil/zap_raft.go | 68 +++++++++++++++ pkg/logutil/zap_raft_test.go | 70 +++++++++++++++ 6 files changed, 266 insertions(+), 108 deletions(-) rename pkg/logutil/{zap.go => zap_grpc.go} (63%) rename pkg/logutil/{zap_test.go => zap_grpc_test.go} (61%) create mode 100644 pkg/logutil/zap_journald.go create mode 100644 pkg/logutil/zap_journald_test.go create mode 100644 pkg/logutil/zap_raft.go create mode 100644 pkg/logutil/zap_raft_test.go diff --git a/pkg/logutil/zap.go b/pkg/logutil/zap_grpc.go similarity index 63% rename from pkg/logutil/zap.go rename to pkg/logutil/zap_grpc.go index 440173911a0..0a28dbf858d 100644 --- a/pkg/logutil/zap.go +++ b/pkg/logutil/zap_grpc.go @@ -15,8 +15,6 @@ package logutil import ( - "github.com/coreos/etcd/raft" - "go.uber.org/zap" "go.uber.org/zap/zapcore" "google.golang.org/grpc/grpclog" @@ -102,65 +100,3 @@ func (zl *zapGRPCLogger) V(l int) bool { } return true } - -// NewRaftLogger converts "*zap.Logger" to "raft.Logger". -func NewRaftLogger(lcfg zap.Config) (raft.Logger, error) { - lg, err := lcfg.Build(zap.AddCallerSkip(1)) // to annotate caller outside of "logutil" - if err != nil { - return nil, err - } - return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}, nil -} - -type zapRaftLogger struct { - lg *zap.Logger - sugar *zap.SugaredLogger -} - -func (zl *zapRaftLogger) Debug(args ...interface{}) { - zl.sugar.Debug(args...) -} - -func (zl *zapRaftLogger) Debugf(format string, args ...interface{}) { - zl.sugar.Debugf(format, args...) -} - -func (zl *zapRaftLogger) Error(args ...interface{}) { - zl.sugar.Error(args...) -} - -func (zl *zapRaftLogger) Errorf(format string, args ...interface{}) { - zl.sugar.Errorf(format, args...) -} - -func (zl *zapRaftLogger) Info(args ...interface{}) { - zl.sugar.Info(args...) -} - -func (zl *zapRaftLogger) Infof(format string, args ...interface{}) { - zl.sugar.Infof(format, args...) -} - -func (zl *zapRaftLogger) Warning(args ...interface{}) { - zl.sugar.Warn(args...) -} - -func (zl *zapRaftLogger) Warningf(format string, args ...interface{}) { - zl.sugar.Warnf(format, args...) -} - -func (zl *zapRaftLogger) Fatal(args ...interface{}) { - zl.sugar.Fatal(args...) -} - -func (zl *zapRaftLogger) Fatalf(format string, args ...interface{}) { - zl.sugar.Fatalf(format, args...) -} - -func (zl *zapRaftLogger) Panic(args ...interface{}) { - zl.sugar.Panic(args...) -} - -func (zl *zapRaftLogger) Panicf(format string, args ...interface{}) { - zl.sugar.Panicf(format, args...) -} diff --git a/pkg/logutil/zap_test.go b/pkg/logutil/zap_grpc_test.go similarity index 61% rename from pkg/logutil/zap_test.go rename to pkg/logutil/zap_grpc_test.go index 15ac2c00652..95b11486987 100644 --- a/pkg/logutil/zap_test.go +++ b/pkg/logutil/zap_grpc_test.go @@ -66,50 +66,7 @@ func TestNewGRPCLoggerV2(t *testing.T) { if !bytes.Contains(data, []byte("etcd-logutil-2")) { t.Fatalf("can't find data in log %q", string(data)) } - if !bytes.Contains(data, []byte("logutil/zap_test.go:")) { - t.Fatalf("unexpected caller; %q", string(data)) - } -} - -func TestNewRaftLogger(t *testing.T) { - logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-%d", time.Now().UnixNano())) - defer os.RemoveAll(logPath) - - lcfg := zap.Config{ - Level: zap.NewAtomicLevelAt(zap.DebugLevel), - Development: false, - Sampling: &zap.SamplingConfig{ - Initial: 100, - Thereafter: 100, - }, - Encoding: "json", - EncoderConfig: zap.NewProductionEncoderConfig(), - OutputPaths: []string{logPath}, - ErrorOutputPaths: []string{logPath}, - } - gl, err := NewRaftLogger(lcfg) - if err != nil { - t.Fatal(err) - } - - gl.Info("etcd-logutil-1") - data, err := ioutil.ReadFile(logPath) - if err != nil { - t.Fatal(err) - } - if !bytes.Contains(data, []byte("etcd-logutil-1")) { - t.Fatalf("can't find data in log %q", string(data)) - } - - gl.Warning("etcd-logutil-2") - data, err = ioutil.ReadFile(logPath) - if err != nil { - t.Fatal(err) - } - if !bytes.Contains(data, []byte("etcd-logutil-2")) { - t.Fatalf("can't find data in log %q", string(data)) - } - if !bytes.Contains(data, []byte("logutil/zap_test.go:")) { + if !bytes.Contains(data, []byte("logutil/zap_grpc_test.go:")) { t.Fatalf("unexpected caller; %q", string(data)) } } diff --git a/pkg/logutil/zap_journald.go b/pkg/logutil/zap_journald.go new file mode 100644 index 00000000000..4489b990553 --- /dev/null +++ b/pkg/logutil/zap_journald.go @@ -0,0 +1,85 @@ +// Copyright 2018 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 ( + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/coreos/go-systemd/journal" + "go.uber.org/zap/zapcore" +) + +// NewJournaldWriter wraps "io.Writer" to redirect log output +// to the local systemd journal. If journald send fails, it fails +// back to writing to the original writer. +// The decode overhead is only <30µs per write. +// Reference: https://github.com/coreos/pkg/blob/master/capnslog/journald_formatter.go +func NewJournaldWriter(wr io.Writer) io.Writer { + return &journaldWriter{Writer: wr} +} + +type journaldWriter struct { + io.Writer +} + +type logLine struct { + Level string `json:"level"` + Caller string `json:"caller"` +} + +func (w *journaldWriter) Write(p []byte) (int, error) { + line := &logLine{} + if err := json.NewDecoder(bytes.NewReader(p)).Decode(line); err != nil { + return 0, err + } + + var pri journal.Priority + switch line.Level { + case zapcore.DebugLevel.String(): + pri = journal.PriDebug + case zapcore.InfoLevel.String(): + pri = journal.PriInfo + + case zapcore.WarnLevel.String(): + pri = journal.PriWarning + case zapcore.ErrorLevel.String(): + pri = journal.PriErr + + case zapcore.DPanicLevel.String(): + pri = journal.PriCrit + case zapcore.PanicLevel.String(): + pri = journal.PriCrit + case zapcore.FatalLevel.String(): + pri = journal.PriCrit + + default: + panic(fmt.Errorf("unknown log level: %q", line.Level)) + } + + err := journal.Send(string(p), pri, map[string]string{ + "PACKAGE": filepath.Dir(line.Caller), + "SYSLOG_IDENTIFIER": filepath.Base(os.Args[0]), + }) + if err != nil { + fmt.Println("FAILED TO WRITE TO JOURNALD", err, string(p)) + return w.Writer.Write(p) + } + return 0, nil +} diff --git a/pkg/logutil/zap_journald_test.go b/pkg/logutil/zap_journald_test.go new file mode 100644 index 00000000000..f9291cec688 --- /dev/null +++ b/pkg/logutil/zap_journald_test.go @@ -0,0 +1,42 @@ +// Copyright 2018 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 ( + "bytes" + "testing" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func TestNewJournaldWriter(t *testing.T) { + buf := bytes.NewBuffer(nil) + syncer := zapcore.AddSync(NewJournaldWriter(buf)) + cr := zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + syncer, + zap.NewAtomicLevelAt(zap.InfoLevel), + ) + + lg := zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)) + defer lg.Sync() + + lg.Info("TestNewJournaldWriter") + if buf.String() == "" { + // check with "journalctl -f" + t.Log("sent logs successfully to journald") + } +} diff --git a/pkg/logutil/zap_raft.go b/pkg/logutil/zap_raft.go new file mode 100644 index 00000000000..4dd754bc74f --- /dev/null +++ b/pkg/logutil/zap_raft.go @@ -0,0 +1,68 @@ +package logutil + +import ( + "github.com/coreos/etcd/raft" + "go.uber.org/zap" +) + +// NewRaftLogger converts "*zap.Logger" to "raft.Logger". +func NewRaftLogger(lcfg zap.Config) (raft.Logger, error) { + lg, err := lcfg.Build(zap.AddCallerSkip(1)) // to annotate caller outside of "logutil" + if err != nil { + return nil, err + } + return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}, nil +} + +type zapRaftLogger struct { + lg *zap.Logger + sugar *zap.SugaredLogger +} + +func (zl *zapRaftLogger) Debug(args ...interface{}) { + zl.sugar.Debug(args...) +} + +func (zl *zapRaftLogger) Debugf(format string, args ...interface{}) { + zl.sugar.Debugf(format, args...) +} + +func (zl *zapRaftLogger) Error(args ...interface{}) { + zl.sugar.Error(args...) +} + +func (zl *zapRaftLogger) Errorf(format string, args ...interface{}) { + zl.sugar.Errorf(format, args...) +} + +func (zl *zapRaftLogger) Info(args ...interface{}) { + zl.sugar.Info(args...) +} + +func (zl *zapRaftLogger) Infof(format string, args ...interface{}) { + zl.sugar.Infof(format, args...) +} + +func (zl *zapRaftLogger) Warning(args ...interface{}) { + zl.sugar.Warn(args...) +} + +func (zl *zapRaftLogger) Warningf(format string, args ...interface{}) { + zl.sugar.Warnf(format, args...) +} + +func (zl *zapRaftLogger) Fatal(args ...interface{}) { + zl.sugar.Fatal(args...) +} + +func (zl *zapRaftLogger) Fatalf(format string, args ...interface{}) { + zl.sugar.Fatalf(format, args...) +} + +func (zl *zapRaftLogger) Panic(args ...interface{}) { + zl.sugar.Panic(args...) +} + +func (zl *zapRaftLogger) Panicf(format string, args ...interface{}) { + zl.sugar.Panicf(format, args...) +} diff --git a/pkg/logutil/zap_raft_test.go b/pkg/logutil/zap_raft_test.go new file mode 100644 index 00000000000..b7b402c981b --- /dev/null +++ b/pkg/logutil/zap_raft_test.go @@ -0,0 +1,70 @@ +// Copyright 2018 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 ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "testing" + "time" + + "go.uber.org/zap" +) + +func TestNewRaftLogger(t *testing.T) { + logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-%d", time.Now().UnixNano())) + defer os.RemoveAll(logPath) + + lcfg := zap.Config{ + Level: zap.NewAtomicLevelAt(zap.DebugLevel), + Development: false, + Sampling: &zap.SamplingConfig{ + Initial: 100, + Thereafter: 100, + }, + Encoding: "json", + EncoderConfig: zap.NewProductionEncoderConfig(), + OutputPaths: []string{logPath}, + ErrorOutputPaths: []string{logPath}, + } + gl, err := NewRaftLogger(lcfg) + if err != nil { + t.Fatal(err) + } + + gl.Info("etcd-logutil-1") + data, err := ioutil.ReadFile(logPath) + if err != nil { + t.Fatal(err) + } + if !bytes.Contains(data, []byte("etcd-logutil-1")) { + t.Fatalf("can't find data in log %q", string(data)) + } + + gl.Warning("etcd-logutil-2") + data, err = ioutil.ReadFile(logPath) + if err != nil { + t.Fatal(err) + } + if !bytes.Contains(data, []byte("etcd-logutil-2")) { + t.Fatalf("can't find data in log %q", string(data)) + } + if !bytes.Contains(data, []byte("logutil/zap_raft_test.go:")) { + t.Fatalf("unexpected caller; %q", string(data)) + } +} From 1fa80bf52022ecb492dca0092642a7ab88db7b8d Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:23:40 -0700 Subject: [PATCH 02/22] pkg/logutil: add "NewGRPCLoggerV2FromZapCore" Signed-off-by: Gyuho Lee --- pkg/logutil/zap_grpc.go | 9 +++++++++ pkg/logutil/zap_grpc_test.go | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/pkg/logutil/zap_grpc.go b/pkg/logutil/zap_grpc.go index 0a28dbf858d..3f48d813dab 100644 --- a/pkg/logutil/zap_grpc.go +++ b/pkg/logutil/zap_grpc.go @@ -31,6 +31,15 @@ func NewGRPCLoggerV2(lcfg zap.Config) (grpclog.LoggerV2, error) { return &zapGRPCLogger{lg: lg, sugar: lg.Sugar()}, nil } +// NewGRPCLoggerV2FromZapCore creates "grpclog.LoggerV2" from "zap.Core" +// and "zapcore.WriteSyncer". It discards all INFO level logging in gRPC, +// if debug level is not enabled in "*zap.Logger". +func NewGRPCLoggerV2FromZapCore(cr zapcore.Core, syncer zapcore.WriteSyncer) grpclog.LoggerV2 { + // "AddCallerSkip" to annotate caller outside of "logutil" + lg := zap.New(cr, zap.AddCaller(), zap.AddCallerSkip(1), zap.ErrorOutput(syncer)) + return &zapGRPCLogger{lg: lg, sugar: lg.Sugar()} +} + type zapGRPCLogger struct { lg *zap.Logger sugar *zap.SugaredLogger diff --git a/pkg/logutil/zap_grpc_test.go b/pkg/logutil/zap_grpc_test.go index 95b11486987..7bd71e53b05 100644 --- a/pkg/logutil/zap_grpc_test.go +++ b/pkg/logutil/zap_grpc_test.go @@ -20,10 +20,12 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "testing" "time" "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) func TestNewGRPCLoggerV2(t *testing.T) { @@ -70,3 +72,20 @@ func TestNewGRPCLoggerV2(t *testing.T) { t.Fatalf("unexpected caller; %q", string(data)) } } + +func TestNewGRPCLoggerV2FromZapCore(t *testing.T) { + buf := bytes.NewBuffer(nil) + syncer := zapcore.AddSync(buf) + cr := zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + syncer, + zap.NewAtomicLevelAt(zap.InfoLevel), + ) + + lg := NewGRPCLoggerV2FromZapCore(cr, syncer) + lg.Warning("TestNewGRPCLoggerV2FromZapCore") + txt := buf.String() + if !strings.Contains(txt, "TestNewGRPCLoggerV2FromZapCore") { + t.Fatalf("unexpected log %q", txt) + } +} From 48d5542a76bb5c0922c9ca24da2ff7377aa30ab3 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:25:20 -0700 Subject: [PATCH 03/22] embed: set journald logging with zap Signed-off-by: Gyuho Lee --- embed/config.go | 92 ++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/embed/config.go b/embed/config.go index 28c3a0d78d7..b4df9188f3e 100644 --- a/embed/config.go +++ b/embed/config.go @@ -41,6 +41,7 @@ import ( "github.com/coreos/pkg/capnslog" "github.com/ghodss/yaml" "go.uber.org/zap" + "go.uber.org/zap/zapcore" "google.golang.org/grpc" "google.golang.org/grpc/grpclog" ) @@ -468,19 +469,17 @@ func (cfg *Config) setupLogging() error { ErrorOutputPaths: make([]string, 0), } outputPaths, errOutputPaths := make(map[string]struct{}), make(map[string]struct{}) + isJournald := false for _, v := range cfg.LogOutput { switch v { case DefaultLogOutput: if syscall.Getppid() == 1 { // capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr)) // where "NewDefaultFormatter" returns "NewJournaldFormatter" - // when syscall.Getppid() == 1, specify 'stdout' or 'stderr' to - // skip journald logging even when running under systemd - // TODO: capnlog.NewJournaldFormatter() - fmt.Println("running under init, which may be systemd!") - outputPaths["stderr"] = struct{}{} - errOutputPaths["stderr"] = struct{}{} - continue + // specify 'stdout' or 'stderr' to override this redirects + // when syscall.Getppid() == 1 + isJournald = true + break } outputPaths["stderr"] = struct{}{} @@ -499,38 +498,59 @@ func (cfg *Config) setupLogging() error { errOutputPaths[v] = struct{}{} } } - for v := range outputPaths { - lcfg.OutputPaths = append(lcfg.OutputPaths, v) - } - for v := range errOutputPaths { - lcfg.ErrorOutputPaths = append(lcfg.ErrorOutputPaths, v) - } - sort.Strings(lcfg.OutputPaths) - sort.Strings(lcfg.ErrorOutputPaths) - if cfg.Debug { - lcfg.Level = zap.NewAtomicLevelAt(zap.DebugLevel) - grpc.EnableTracing = true - } + if !isJournald { + for v := range outputPaths { + lcfg.OutputPaths = append(lcfg.OutputPaths, v) + } + for v := range errOutputPaths { + lcfg.ErrorOutputPaths = append(lcfg.ErrorOutputPaths, v) + } + sort.Strings(lcfg.OutputPaths) + sort.Strings(lcfg.ErrorOutputPaths) - var err error - cfg.logger, err = lcfg.Build() - if err != nil { - return err - } - cfg.loggerConfig = lcfg - - grpcLogOnce.Do(func() { - // debug true, enable info, warning, error - // debug false, only discard info - var gl grpclog.LoggerV2 - gl, err = logutil.NewGRPCLoggerV2(lcfg) - if err == nil { - grpclog.SetLoggerV2(gl) + if cfg.Debug { + lcfg.Level = zap.NewAtomicLevelAt(zap.DebugLevel) + grpc.EnableTracing = true } - }) - if err != nil { - return err + + var err error + cfg.logger, err = lcfg.Build() + if err != nil { + return err + } + cfg.loggerConfig = lcfg + + grpcLogOnce.Do(func() { + // debug true, enable info, warning, error + // debug false, only discard info + var gl grpclog.LoggerV2 + gl, err = logutil.NewGRPCLoggerV2(lcfg) + if err == nil { + grpclog.SetLoggerV2(gl) + } + }) + if err != nil { + return err + } + } else { + // use stderr as fallback + syncer := zapcore.AddSync(logutil.NewJournaldWriter(os.Stderr)) + lvl := zap.NewAtomicLevelAt(zap.InfoLevel) + if cfg.Debug { + lvl = zap.NewAtomicLevelAt(zap.DebugLevel) + grpc.EnableTracing = true + } + cr := zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + syncer, + lvl, + ) + cfg.logger = zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)) + + grpcLogOnce.Do(func() { + grpclog.SetLoggerV2(logutil.NewGRPCLoggerV2FromZapCore(cr, syncer)) + }) } logTLSHandshakeFailure := func(conn *tls.Conn, err error) { From 6df3179c06b2cd0c17a504dbdf3ff7d32b3b153c Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:26:16 -0700 Subject: [PATCH 04/22] pkg/logutil: add "NewRaftLoggerFromZapCore" Signed-off-by: Gyuho Lee --- pkg/logutil/zap_raft.go | 24 ++++++++++++++++++++++++ pkg/logutil/zap_raft_test.go | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/pkg/logutil/zap_raft.go b/pkg/logutil/zap_raft.go index 4dd754bc74f..5fb11c8c43f 100644 --- a/pkg/logutil/zap_raft.go +++ b/pkg/logutil/zap_raft.go @@ -1,8 +1,24 @@ +// Copyright 2018 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 ( "github.com/coreos/etcd/raft" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) // NewRaftLogger converts "*zap.Logger" to "raft.Logger". @@ -14,6 +30,14 @@ func NewRaftLogger(lcfg zap.Config) (raft.Logger, error) { return &zapRaftLogger{lg: lg, sugar: lg.Sugar()}, nil } +// NewRaftLoggerFromZapCore creates "raft.Logger" from "zap.Core" +// and "zapcore.WriteSyncer". +func NewRaftLoggerFromZapCore(cr zapcore.Core, syncer zapcore.WriteSyncer) raft.Logger { + // "AddCallerSkip" to annotate caller outside of "logutil" + lg := zap.New(cr, zap.AddCaller(), zap.AddCallerSkip(1), zap.ErrorOutput(syncer)) + return &zapRaftLogger{lg: lg, sugar: lg.Sugar()} +} + type zapRaftLogger struct { lg *zap.Logger sugar *zap.SugaredLogger diff --git a/pkg/logutil/zap_raft_test.go b/pkg/logutil/zap_raft_test.go index b7b402c981b..7885af3898a 100644 --- a/pkg/logutil/zap_raft_test.go +++ b/pkg/logutil/zap_raft_test.go @@ -20,10 +20,12 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "testing" "time" "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) func TestNewRaftLogger(t *testing.T) { @@ -68,3 +70,20 @@ func TestNewRaftLogger(t *testing.T) { t.Fatalf("unexpected caller; %q", string(data)) } } + +func TestNewRaftLoggerFromZapCore(t *testing.T) { + buf := bytes.NewBuffer(nil) + syncer := zapcore.AddSync(buf) + cr := zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + syncer, + zap.NewAtomicLevelAt(zap.InfoLevel), + ) + + lg := NewRaftLoggerFromZapCore(cr, syncer) + lg.Info("TestNewRaftLoggerFromZapCore") + txt := buf.String() + if !strings.Contains(txt, "TestNewRaftLoggerFromZapCore") { + t.Fatalf("unexpected log %q", txt) + } +} From 69c51e2c4abf2fafc646b2c394b8bb34cba18481 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:32:12 -0700 Subject: [PATCH 05/22] embed: change "loggerConfig" to "*zap.Config" Signed-off-by: Gyuho Lee --- embed/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/embed/config.go b/embed/config.go index b4df9188f3e..565e3962c98 100644 --- a/embed/config.go +++ b/embed/config.go @@ -266,7 +266,7 @@ type Config struct { // Do not set logger directly. loggerMu *sync.RWMutex logger *zap.Logger - loggerConfig zap.Config + loggerConfig *zap.Config // Logger is logger options: "zap", "capnslog". // WARN: "capnslog" is being deprecated in v3.5. @@ -519,7 +519,7 @@ func (cfg *Config) setupLogging() error { if err != nil { return err } - cfg.loggerConfig = lcfg + cfg.loggerConfig = &lcfg grpcLogOnce.Do(func() { // debug true, enable info, warning, error From a34dd272b04b9ae5814328ecc6d617abf945d90b Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:40:36 -0700 Subject: [PATCH 06/22] pkg/logutil: change "NewRaftLogger" function signature Signed-off-by: Gyuho Lee --- pkg/logutil/zap_raft.go | 7 ++++++- pkg/logutil/zap_raft_test.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/logutil/zap_raft.go b/pkg/logutil/zap_raft.go index 5fb11c8c43f..5ee703dd2fb 100644 --- a/pkg/logutil/zap_raft.go +++ b/pkg/logutil/zap_raft.go @@ -15,6 +15,8 @@ package logutil import ( + "errors" + "github.com/coreos/etcd/raft" "go.uber.org/zap" @@ -22,7 +24,10 @@ import ( ) // NewRaftLogger converts "*zap.Logger" to "raft.Logger". -func NewRaftLogger(lcfg zap.Config) (raft.Logger, error) { +func NewRaftLogger(lcfg *zap.Config) (raft.Logger, error) { + if lcfg == nil { + return nil, errors.New("nil zap.Config") + } lg, err := lcfg.Build(zap.AddCallerSkip(1)) // to annotate caller outside of "logutil" if err != nil { return nil, err diff --git a/pkg/logutil/zap_raft_test.go b/pkg/logutil/zap_raft_test.go index 7885af3898a..c2992ed3ee1 100644 --- a/pkg/logutil/zap_raft_test.go +++ b/pkg/logutil/zap_raft_test.go @@ -32,7 +32,7 @@ func TestNewRaftLogger(t *testing.T) { logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-%d", time.Now().UnixNano())) defer os.RemoveAll(logPath) - lcfg := zap.Config{ + lcfg := &zap.Config{ Level: zap.NewAtomicLevelAt(zap.DebugLevel), Development: false, Sampling: &zap.SamplingConfig{ From d33a74d3808a10f16df423c71f8dd1508e614ee6 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:40:52 -0700 Subject: [PATCH 07/22] embed: add "loggerCore" field for Raft logger Signed-off-by: Gyuho Lee --- embed/config.go | 30 +++++++++++++++++++++++------- embed/etcd.go | 2 ++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/embed/config.go b/embed/config.go index 565e3962c98..9de6127a26b 100644 --- a/embed/config.go +++ b/embed/config.go @@ -261,13 +261,6 @@ type Config struct { ListenMetricsUrls []url.URL ListenMetricsUrlsJSON string `json:"listen-metrics-urls"` - // logger logs server-side operations. The default is nil, - // and "setupLogging" must be called before starting server. - // Do not set logger directly. - loggerMu *sync.RWMutex - logger *zap.Logger - loggerConfig *zap.Config - // Logger is logger options: "zap", "capnslog". // WARN: "capnslog" is being deprecated in v3.5. Logger string `json:"logger"` @@ -282,6 +275,22 @@ type Config struct { // Debug is true, to enable debug level logging. Debug bool `json:"debug"` + // logger logs server-side operations. The default is nil, + // and "setupLogging" must be called before starting server. + // Do not set logger directly. + loggerMu *sync.RWMutex + logger *zap.Logger + + // loggerConfig is server logger configuration for Raft logger. + // Must be either: "loggerConfig != nil" or "loggerCore != nil && loggerWriteSyncer != nil". + loggerConfig *zap.Config + // loggerCore is "zapcore.Core" for raft logger. + // Must be either: "loggerConfig != nil" or "loggerCore != nil && loggerWriteSyncer != nil". + loggerCore zapcore.Core + loggerWriteSyncer zapcore.WriteSyncer + + // TO BE DEPRECATED + // LogPkgLevels is being deprecated in v3.5. // Only valid if "logger" option is "capnslog". // WARN: DO NOT USE THIS! @@ -519,7 +528,10 @@ func (cfg *Config) setupLogging() error { if err != nil { return err } + cfg.loggerConfig = &lcfg + cfg.loggerCore = nil + cfg.loggerWriteSyncer = nil grpcLogOnce.Do(func() { // debug true, enable info, warning, error @@ -548,6 +560,10 @@ func (cfg *Config) setupLogging() error { ) cfg.logger = zap.New(cr, zap.AddCaller(), zap.ErrorOutput(syncer)) + cfg.loggerConfig = nil + cfg.loggerCore = cr + cfg.loggerWriteSyncer = syncer + grpcLogOnce.Do(func() { grpclog.SetLoggerV2(logutil.NewGRPCLoggerV2FromZapCore(cr, syncer)) }) diff --git a/embed/etcd.go b/embed/etcd.go index c0958e49a77..a500a86e9b3 100644 --- a/embed/etcd.go +++ b/embed/etcd.go @@ -190,6 +190,8 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) { PreVote: cfg.PreVote, Logger: cfg.logger, LoggerConfig: cfg.loggerConfig, + LoggerCore: cfg.loggerCore, + LoggerWriteSyncer: cfg.loggerWriteSyncer, Debug: cfg.Debug, ForceNewCluster: cfg.ForceNewCluster, } From 3ea7a5d0bda994e89a07b6ef2d07dff02f992c85 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Tue, 24 Apr 2018 15:41:09 -0700 Subject: [PATCH 08/22] etcdserver: add "LoggerCore" field for Raft logger Signed-off-by: Gyuho Lee --- etcdserver/config.go | 9 ++++++++- etcdserver/raft.go | 30 +++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/etcdserver/config.go b/etcdserver/config.go index 4ea8e128b76..9b854e68280 100644 --- a/etcdserver/config.go +++ b/etcdserver/config.go @@ -27,6 +27,7 @@ import ( "github.com/coreos/etcd/pkg/types" "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) // ServerConfig holds the configuration of etcd as taken from the command line or discovery. @@ -115,8 +116,14 @@ type ServerConfig struct { // Logger logs server-side operations. // If not nil, it disables "capnslog" and uses the given logger. Logger *zap.Logger + // LoggerConfig is server logger configuration for Raft logger. - LoggerConfig zap.Config + // Must be either: "LoggerConfig != nil" or "LoggerCore != nil && LoggerWriteSyncer != nil". + LoggerConfig *zap.Config + // LoggerCore is "zapcore.Core" for raft logger. + // Must be either: "LoggerConfig != nil" or "LoggerCore != nil && LoggerWriteSyncer != nil". + LoggerCore zapcore.Core + LoggerWriteSyncer zapcore.WriteSyncer Debug bool diff --git a/etcdserver/raft.go b/etcdserver/raft.go index ec319ad18a6..4b3ad2808e3 100644 --- a/etcdserver/raft.go +++ b/etcdserver/raft.go @@ -468,9 +468,13 @@ func startNode(cfg ServerConfig, cl *membership.RaftCluster, ids []types.ID) (id } if cfg.Logger != nil { // called after capnslog setting in "init" function - c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig) - if err != nil { - log.Fatalf("cannot create raft logger %v", err) + if cfg.LoggerConfig != nil { + c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig) + if err != nil { + log.Fatalf("cannot create raft logger %v", err) + } + } else if cfg.LoggerCore != nil && cfg.LoggerWriteSyncer != nil { + c.Logger = logutil.NewRaftLoggerFromZapCore(cfg.LoggerCore, cfg.LoggerWriteSyncer) } } @@ -519,9 +523,13 @@ func restartNode(cfg ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *member if cfg.Logger != nil { // called after capnslog setting in "init" function var err error - c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig) - if err != nil { - log.Fatalf("cannot create raft logger %v", err) + if cfg.LoggerConfig != nil { + c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig) + if err != nil { + log.Fatalf("cannot create raft logger %v", err) + } + } else if cfg.LoggerCore != nil && cfg.LoggerWriteSyncer != nil { + c.Logger = logutil.NewRaftLoggerFromZapCore(cfg.LoggerCore, cfg.LoggerWriteSyncer) } } @@ -611,9 +619,13 @@ func restartAsStandaloneNode(cfg ServerConfig, snapshot *raftpb.Snapshot) (types } if cfg.Logger != nil { // called after capnslog setting in "init" function - c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig) - if err != nil { - log.Fatalf("cannot create raft logger %v", err) + if cfg.LoggerConfig != nil { + c.Logger, err = logutil.NewRaftLogger(cfg.LoggerConfig) + if err != nil { + log.Fatalf("cannot create raft logger %v", err) + } + } else if cfg.LoggerCore != nil && cfg.LoggerWriteSyncer != nil { + c.Logger = logutil.NewRaftLoggerFromZapCore(cfg.LoggerCore, cfg.LoggerWriteSyncer) } } From f99cb35d299ef1b3d7fd9e071e37ed60dfadab67 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 10:28:13 -0700 Subject: [PATCH 09/22] embed: rename "LogOutput" to "LogOutputs" Signed-off-by: Gyuho Lee --- embed/config.go | 22 +++++++++++----------- etcdmain/config.go | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/embed/config.go b/embed/config.go index 9de6127a26b..7ac19adf3da 100644 --- a/embed/config.go +++ b/embed/config.go @@ -265,13 +265,13 @@ type Config struct { // WARN: "capnslog" is being deprecated in v3.5. Logger string `json:"logger"` - // LogOutput is either: + // LogOutputs is either: // - "default" as os.Stderr, // - "stderr" as os.Stderr, // - "stdout" as os.Stdout, // - file path to append server logs to. // It can be multiple when "Logger" is zap. - LogOutput []string `json:"log-output"` + LogOutputs []string `json:"log-output"` // Debug is true, to enable debug level logging. Debug bool `json:"debug"` @@ -371,7 +371,7 @@ func NewConfig() *Config { loggerMu: new(sync.RWMutex), logger: nil, Logger: "capnslog", - LogOutput: []string{DefaultLogOutput}, + LogOutputs: []string{DefaultLogOutput}, Debug: false, LogPkgLevels: "", } @@ -433,14 +433,14 @@ func (cfg *Config) setupLogging() error { repoLog.SetLogLevel(settings) } - if len(cfg.LogOutput) != 1 { - fmt.Printf("expected only 1 value in 'log-output', got %v\n", cfg.LogOutput) + if len(cfg.LogOutputs) != 1 { + fmt.Printf("expected only 1 value in 'log-output', got %v\n", cfg.LogOutputs) os.Exit(1) } // capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr)) // where NewDefaultFormatter returns NewJournaldFormatter when syscall.Getppid() == 1 // specify 'stdout' or 'stderr' to skip journald logging even when running under systemd - output := cfg.LogOutput[0] + output := cfg.LogOutputs[0] switch output { case "stdout": capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, cfg.Debug)) @@ -452,11 +452,11 @@ func (cfg *Config) setupLogging() error { } case "zap": - if len(cfg.LogOutput) == 0 { - cfg.LogOutput = []string{DefaultLogOutput} + if len(cfg.LogOutputs) == 0 { + cfg.LogOutputs = []string{DefaultLogOutput} } - if len(cfg.LogOutput) > 1 { - for _, v := range cfg.LogOutput { + if len(cfg.LogOutputs) > 1 { + for _, v := range cfg.LogOutputs { if v == DefaultLogOutput { panic(fmt.Errorf("multi logoutput for %q is not supported yet", DefaultLogOutput)) } @@ -479,7 +479,7 @@ func (cfg *Config) setupLogging() error { } outputPaths, errOutputPaths := make(map[string]struct{}), make(map[string]struct{}) isJournald := false - for _, v := range cfg.LogOutput { + for _, v := range cfg.LogOutputs { switch v { case DefaultLogOutput: if syscall.Getppid() == 1 { diff --git a/etcdmain/config.go b/etcdmain/config.go index b884a111311..8d152a08512 100644 --- a/etcdmain/config.go +++ b/etcdmain/config.go @@ -312,7 +312,7 @@ func (cfg *config) configFromCmdLine() error { oss = append(oss, v) } sort.Strings(oss) - cfg.ec.LogOutput = oss + cfg.ec.LogOutputs = oss cfg.ec.ClusterState = cfg.cf.clusterState.String() cfg.cp.Fallback = cfg.cf.fallback.String() From d4987f463324755457eff59e7a4e1db3fd14e8b9 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 10:47:58 -0700 Subject: [PATCH 10/22] CHANGELOG: track logger changes Signed-off-by: Gyuho Lee --- CHANGELOG-3.1.md | 6 ++++++ CHANGELOG-3.2.md | 4 ++++ CHANGELOG-3.4.md | 21 +++++++++++---------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index 98aafaf04b9..d0f74834ad6 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -1,3 +1,5 @@ + + ## [v3.1.14](https://github.com/coreos/etcd/releases/tag/v3.1.14) (2018-04-24) See [code changes](https://github.com/coreos/etcd/compare/v3.1.13...v3.1.14) and [v3.1 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_1.md) for any breaking changes. @@ -18,6 +20,10 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.1.13...v3.1.14) and - If single-node, it advances ticks regardless. - Address [disruptive rejoining follower node](https://github.com/coreos/etcd/issues/9333). +### Go + +- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8). + ## [v3.1.13](https://github.com/coreos/etcd/releases/tag/v3.1.13) (2018-03-29) diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index 09b5575840c..0238473fd02 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -29,6 +29,10 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.2.18...v3.2.19) and - If single-node, it advances ticks regardless. - Address [disruptive rejoining follower node](https://github.com/coreos/etcd/issues/9333). +### Go + +- Compile with [*Go 1.8.7*](https://golang.org/doc/devel/release.html#go1.8). + ## [v3.2.18](https://github.com/coreos/etcd/releases/tag/v3.2.18) (2018-03-29) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 26411e7ac88..18db2ce635a 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -1,6 +1,6 @@ -## v3.4.0 (TBD 2018-06-01) +## v3.4.0 (TBD 2018-07-01) See [code changes](https://github.com/coreos/etcd/compare/v3.3.0...v3.4.0) and [v3.4 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_4.md) for any breaking changes. @@ -56,6 +56,12 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.3.0...v3.4.0) and [ - e.g. exit with error on `ETCDCTL_ENDPOINTS=abc.com ETCDCTL_API=3 etcdctl endpoint health --endpoints=def.com`. - Change [`etcdserverpb.AuthRoleRevokePermissionRequest/key,range_end` fields type from `string` to `bytes`](https://github.com/coreos/etcd/pull/9433). - Change [`embed.Config.CorsInfo` in `*cors.CORSInfo` type to `embed.Config.CORS` in `map[string]struct{}` type](https://github.com/coreos/etcd/pull/9490). +- Remove [`embed.Config.SetupLogging`](https://github.com/coreos/etcd/pull/9572). + - Now logger is set up automatically based on [`embed.Config.Logger`, `embed.Config.LogOutputs`, `embed.Config.Debug` fields](https://github.com/coreos/etcd/pull/9572). +- Rename [**`embed.Config.LogOutput`** to **`embed.Config.LogOutputs`**](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. +- Change [**`embed.Config.LogOutputs`** type from `string` to `[]string`](https://github.com/coreos/etcd/pull/9579) to support multiple log outputs. + - Now that `--log-output` accepts multiple writers, etcd configuration YAML file `log-output` field must be changed to `[]string` type. + - Previously, `--config-file etcd.config.yaml` can have `log-output: default` field, now must be `log-output: [default]`. - Change v3 `etcdctl snapshot` exit codes with [`snapshot` package](https://github.com/coreos/etcd/pull/9118/commits/df689f4280e1cce4b9d61300be13ca604d41670a). - Exit on error with exit code 1 (no more exit code 5 or 6 on `snapshot save/restore` commands). - Migrate dependency management tool from `glide` to [`golang/dep`](https://github.com/coreos/etcd/pull/9155). @@ -72,11 +78,6 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.3.0...v3.4.0) and [ - Previously, `OpenForRead(dirpath string, snap walpb.Snapshot) (*WAL, error)`, now `OpenForRead(lg *zap.Logger, dirpath string, snap walpb.Snapshot) (*WAL, error)`. - Previously, `Repair(dirpath string) bool`, now `Repair(lg *zap.Logger, dirpath string) bool`. - Previously, `Create(dirpath string, metadata []byte) (*WAL, error)`, now `Create(lg *zap.Logger, dirpath string, metadata []byte) (*WAL, error)`. -- Remove [`embed.Config.SetupLogging`](https://github.com/coreos/etcd/pull/9572). - - Now logger is set up automatically based on [`embed.Config.Logger`, `embed.Config.LogOutput`, `embed.Config.Debug` fields](https://github.com/coreos/etcd/pull/9572). -- Change [`embed.Config.LogOutput` type from `string` to `[]string`](https://github.com/coreos/etcd/pull/9579) to support multiple log outputs. - - Now that `--log-output` accepts multiple writers, etcd configuration YAML file `log-output` field must be changed to `[]string` type. - - Previously, `--config-file etcd.config.yaml` can have `log-output: default` field, now must be `log-output: [default]`. - Remove [`pkg/cors` package](https://github.com/coreos/etcd/pull/9490). - Move `"github.com/coreos/etcd/snap"` to [`"github.com/coreos/etcd/raftsnap"`](https://github.com/coreos/etcd/pull/9211). - Move `"github.com/coreos/etcd/etcdserver/auth"` to [`"github.com/coreos/etcd/etcdserver/v2auth"`](https://github.com/coreos/etcd/pull/9275). @@ -155,11 +156,11 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Support [`etcd --cors`](https://github.com/coreos/etcd/pull/9490) in v3 HTTP requests (gRPC gateway). - Add [`--logger`](https://github.com/coreos/etcd/pull/9572) flag to support [structured logger and logging to file](https://github.com/coreos/etcd/issues/9438) in server-side. - e.g. `--logger=capnslog --log-output=default` is the default setting and same as previous etcd server logging format. - - TODO: `--logger=zap` is experimental, and journald logging may not work when etcd runs as PID 1. - - e.g. `--logger=zap --log-output=/tmp/test.log` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to the specified file `/tmp/test.log`. - e.g. `--logger=zap --log-output=default` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr` (detect systemd journald TODO). - - e.g. `--logger=zap --log-output=stderr` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr` (bypass journald TODO). - - e.g. `--logger=zap --log-output=stdout` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stdout` (bypass journald TODO). + - e.g. If etcd parent process ID (`ppid`) is 1 (e.g. run with systemd), `--logger=zap --log-output=default` will [redirect server logs to local systemd journal](https://github.com/coreos/etcd/pull/9624) in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig). And if write to journald fails, it writes to `os.Stderr` as a fallback. + - e.g. `--logger=zap --log-output=stderr` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr`. Use this to override journald log redirects. + - e.g. `--logger=zap --log-output=stdout` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stdout` Use this to override journald log redirects. + - e.g. `--logger=zap --log-output=a.log` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to the specified file `a.log`. - e.g. `--logger=zap --log-output=a.log,b.log,c.log,stdout` [writes server logs to multiple files `a.log`, `b.log` and `c.log` at the same time](https://github.com/coreos/etcd/pull/9579) and outputs to `stdout`, in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig). - e.g. `--logger=zap --log-output=/dev/null` will discard all server logs. From 53c5cd55f7e035ba3e95aca3797806f0f4a7fe1b Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 10:49:37 -0700 Subject: [PATCH 11/22] Documentation/upgrades: highlight "embed.Config.LogOutputs" change Signed-off-by: Gyuho Lee --- Documentation/upgrades/upgrade_3_4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/upgrades/upgrade_3_4.md b/Documentation/upgrades/upgrade_3_4.md index 27cfed3dfd5..988402cb79e 100644 --- a/Documentation/upgrades/upgrade_3_4.md +++ b/Documentation/upgrades/upgrade_3_4.md @@ -79,14 +79,14 @@ cfg := &embed.Config{Debug: false} -cfg.SetupLogging() ``` -Changed [`embed.Config.LogOutput` type from `string` to `[]string`](https://github.com/coreos/etcd/pull/9579) to support multiple log outputs. +Renamed [**`embed.Config.LogOutput`** to **`embed.Config.LogOutputs`**](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. And changed [`embed.Config.LogOutput` type from `string` to `[]string`](https://github.com/coreos/etcd/pull/9579) to support multiple log outputs. ```diff import "github.com/coreos/etcd/embed" cfg := &embed.Config{Debug: false} -cfg.LogOutput = "stderr" -+cfg.LogOutput = []string{"stderr"} ++cfg.LogOutputs = []string{"stderr"} ``` #### Change in `etcd --config-file` From a113d6c1606a3587c8eec5b6dffe0b1cf920a8c7 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:05:09 -0700 Subject: [PATCH 12/22] functional/rpcpb: change to LogOutputs Signed-off-by: Gyuho Lee --- functional/rpcpb/etcd_config.go | 4 +- functional/rpcpb/etcd_config_test.go | 8 +- functional/rpcpb/rpc.pb.go | 376 +++++++++++++-------------- functional/rpcpb/rpc.proto | 4 +- 4 files changed, 196 insertions(+), 196 deletions(-) diff --git a/functional/rpcpb/etcd_config.go b/functional/rpcpb/etcd_config.go index bc347ad2ace..e84a6e6cc2f 100644 --- a/functional/rpcpb/etcd_config.go +++ b/functional/rpcpb/etcd_config.go @@ -59,7 +59,7 @@ var etcdFields = []string{ "InitialCorruptCheck", "Logger", - "LogOutput", + "LogOutputs", "Debug", } @@ -167,7 +167,7 @@ func (e *Etcd) EmbedConfig() (cfg *embed.Config, err error) { cfg.ExperimentalInitialCorruptCheck = e.InitialCorruptCheck cfg.Logger = e.Logger - cfg.LogOutput = e.LogOutput + cfg.LogOutputs = e.LogOutputs cfg.Debug = e.Debug return cfg, nil diff --git a/functional/rpcpb/etcd_config_test.go b/functional/rpcpb/etcd_config_test.go index 89bc2947084..6785bdd7682 100644 --- a/functional/rpcpb/etcd_config_test.go +++ b/functional/rpcpb/etcd_config_test.go @@ -57,9 +57,9 @@ func TestEtcd(t *testing.T) { PreVote: true, InitialCorruptCheck: true, - Logger: "zap", - LogOutput: []string{"/tmp/etcd-functional-1/etcd.log"}, - Debug: true, + Logger: "zap", + LogOutputs: []string{"/tmp/etcd-functional-1/etcd.log"}, + Debug: true, } exps := []string{ @@ -133,7 +133,7 @@ func TestEtcd(t *testing.T) { expc.PreVote = true expc.ExperimentalInitialCorruptCheck = true expc.Logger = "zap" - expc.LogOutput = []string{"/tmp/etcd-functional-1/etcd.log"} + expc.LogOutputs = []string{"/tmp/etcd-functional-1/etcd.log"} expc.Debug = true cfg, err := e.EmbedConfig() if err != nil { diff --git a/functional/rpcpb/rpc.pb.go b/functional/rpcpb/rpc.pb.go index 9eb4eb1bec1..8f1d8731cd5 100644 --- a/functional/rpcpb/rpc.pb.go +++ b/functional/rpcpb/rpc.pb.go @@ -760,9 +760,9 @@ type Etcd struct { PreVote bool `protobuf:"varint,63,opt,name=PreVote,proto3" json:"PreVote,omitempty" yaml:"pre-vote"` InitialCorruptCheck bool `protobuf:"varint,64,opt,name=InitialCorruptCheck,proto3" json:"InitialCorruptCheck,omitempty" yaml:"initial-corrupt-check"` Logger string `protobuf:"bytes,71,opt,name=Logger,proto3" json:"Logger,omitempty" yaml:"logger"` - // LogOutput is the log file to store current etcd server logs. - LogOutput []string `protobuf:"bytes,72,rep,name=LogOutput" json:"LogOutput,omitempty" yaml:"log-output"` - Debug bool `protobuf:"varint,73,opt,name=Debug,proto3" json:"Debug,omitempty" yaml:"debug"` + // LogOutputs is the log file to store current etcd server logs. + LogOutputs []string `protobuf:"bytes,72,rep,name=LogOutputs" json:"LogOutputs,omitempty" yaml:"log-output"` + Debug bool `protobuf:"varint,73,opt,name=Debug,proto3" json:"Debug,omitempty" yaml:"debug"` } func (m *Etcd) Reset() { *m = Etcd{} } @@ -1789,8 +1789,8 @@ func (m *Etcd) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintRpc(dAtA, i, uint64(len(m.Logger))) i += copy(dAtA[i:], m.Logger) } - if len(m.LogOutput) > 0 { - for _, s := range m.LogOutput { + if len(m.LogOutputs) > 0 { + for _, s := range m.LogOutputs { dAtA[i] = 0xc2 i++ dAtA[i] = 0x4 @@ -2209,8 +2209,8 @@ func (m *Etcd) Size() (n int) { if l > 0 { n += 2 + l + sovRpc(uint64(l)) } - if len(m.LogOutput) > 0 { - for _, s := range m.LogOutput { + if len(m.LogOutputs) > 0 { + for _, s := range m.LogOutputs { l = len(s) n += 2 + l + sovRpc(uint64(l)) } @@ -4845,7 +4845,7 @@ func (m *Etcd) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 72: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LogOutput", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LogOutputs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4870,7 +4870,7 @@ func (m *Etcd) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.LogOutput = append(m.LogOutput, string(dAtA[iNdEx:postIndex])) + m.LogOutputs = append(m.LogOutputs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 73: if wireType != 0 { @@ -5021,184 +5021,184 @@ var ( func init() { proto.RegisterFile("rpcpb/rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2854 bytes of a gzipped FileDescriptorProto + // 2855 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x59, 0xcb, 0x77, 0xdb, 0xc6, - 0xf5, 0x36, 0x45, 0x49, 0x96, 0xae, 0x5e, 0xd4, 0xc8, 0xb2, 0xe1, 0x97, 0x20, 0xc3, 0x71, 0x7e, - 0xb2, 0x12, 0xd8, 0xf9, 0xd9, 0x39, 0x79, 0x38, 0x4d, 0x1c, 0x90, 0x82, 0x2d, 0x56, 0x10, 0x49, - 0x0f, 0x21, 0xdb, 0x59, 0xf1, 0x40, 0xe4, 0x48, 0xe2, 0x31, 0x05, 0x30, 0xc0, 0xd0, 0x91, 0xb2, - 0xeb, 0xaa, 0xdb, 0x36, 0x7d, 0x9c, 0xf6, 0x9c, 0xae, 0xba, 0x6e, 0xda, 0x7f, 0xc3, 0x79, 0xb5, - 0x69, 0xbb, 0x6a, 0x17, 0x3c, 0x6d, 0xba, 0xe9, 0xaa, 0x0b, 0x9e, 0xbe, 0x57, 0x3d, 0x33, 0x03, - 0x88, 0x03, 0x80, 0x94, 0xb4, 0xb2, 0xe7, 0xde, 0xef, 0xfb, 0xe6, 0xce, 0xdc, 0x99, 0xb9, 0x17, - 0x14, 0xcc, 0xf9, 0xed, 0x7a, 0x7b, 0xfb, 0xb6, 0xdf, 0xae, 0xdf, 0x6a, 0xfb, 0x1e, 0xf5, 0xd0, - 0x18, 0x37, 0x5c, 0xd2, 0x77, 0x9b, 0x74, 0xaf, 0xb3, 0x7d, 0xab, 0xee, 0xed, 0xdf, 0xde, 0xf5, - 0x76, 0xbd, 0xdb, 0xdc, 0xbb, 0xdd, 0xd9, 0xe1, 0x23, 0x3e, 0xe0, 0xff, 0x13, 0x2c, 0xed, 0xbb, - 0x19, 0x38, 0x8b, 0xc9, 0x87, 0x1d, 0x12, 0x50, 0x74, 0x0b, 0x26, 0xcb, 0x6d, 0xe2, 0x3b, 0xb4, - 0xe9, 0xb9, 0x4a, 0x66, 0x39, 0xb3, 0x32, 0x7b, 0x27, 0x77, 0x8b, 0xab, 0xde, 0x3a, 0xb2, 0xe3, - 0x3e, 0x04, 0xdd, 0x80, 0xf1, 0x4d, 0xb2, 0xbf, 0x4d, 0x7c, 0x65, 0x64, 0x39, 0xb3, 0x32, 0x75, - 0x67, 0x26, 0x04, 0x0b, 0x23, 0x0e, 0x9d, 0x0c, 0x66, 0x93, 0x80, 0x12, 0x5f, 0xc9, 0xc6, 0x60, - 0xc2, 0x88, 0x43, 0xa7, 0xf6, 0xd7, 0x11, 0x98, 0xae, 0xba, 0x4e, 0x3b, 0xd8, 0xf3, 0x68, 0xd1, - 0xdd, 0xf1, 0xd0, 0x12, 0x80, 0x50, 0x28, 0x39, 0xfb, 0x84, 0xc7, 0x33, 0x89, 0x25, 0x0b, 0x5a, - 0x85, 0x9c, 0x18, 0x15, 0x5a, 0x4d, 0xe2, 0xd2, 0x2d, 0x6c, 0x05, 0xca, 0xc8, 0x72, 0x76, 0x65, - 0x12, 0xa7, 0xec, 0x48, 0xeb, 0x6b, 0x57, 0x1c, 0xba, 0xc7, 0x23, 0x99, 0xc4, 0x31, 0x1b, 0xd3, - 0x8b, 0xc6, 0x0f, 0x9a, 0x2d, 0x52, 0x6d, 0x7e, 0x4c, 0x94, 0x51, 0x8e, 0x4b, 0xd9, 0xd1, 0xab, - 0x30, 0x1f, 0xd9, 0x6c, 0x8f, 0x3a, 0x2d, 0x0e, 0x1e, 0xe3, 0xe0, 0xb4, 0x43, 0x56, 0xe6, 0xc6, - 0x0d, 0x72, 0xa8, 0x8c, 0x2f, 0x67, 0x56, 0xb2, 0x38, 0x65, 0x97, 0x23, 0x5d, 0x77, 0x82, 0x3d, - 0xe5, 0x2c, 0xc7, 0xc5, 0x6c, 0xb2, 0x1e, 0x26, 0xcf, 0x9b, 0x01, 0xcb, 0xd7, 0x44, 0x5c, 0x2f, - 0xb2, 0x23, 0x04, 0xa3, 0xb6, 0xe7, 0x3d, 0x53, 0x26, 0x79, 0x70, 0xfc, 0xff, 0xda, 0xcf, 0x32, - 0x30, 0x81, 0x49, 0xd0, 0xf6, 0xdc, 0x80, 0x20, 0x05, 0xce, 0x56, 0x3b, 0xf5, 0x3a, 0x09, 0x02, - 0xbe, 0xc7, 0x13, 0x38, 0x1a, 0xa2, 0xf3, 0x30, 0x5e, 0xa5, 0x0e, 0xed, 0x04, 0x3c, 0xbf, 0x93, - 0x38, 0x1c, 0x49, 0x79, 0xcf, 0x1e, 0x97, 0xf7, 0x37, 0xe3, 0xf9, 0xe4, 0x7b, 0x39, 0x75, 0x67, - 0x21, 0x04, 0xcb, 0x2e, 0x1c, 0x03, 0x6a, 0x9f, 0x4c, 0x47, 0x13, 0xa0, 0xd7, 0x60, 0xc2, 0xa4, - 0xf5, 0x86, 0x79, 0x40, 0xea, 0xe2, 0x04, 0xe4, 0xcf, 0xf5, 0xba, 0x6a, 0xee, 0xd0, 0xd9, 0x6f, - 0xdd, 0xd3, 0x08, 0xad, 0x37, 0x74, 0x72, 0x40, 0xea, 0x1a, 0x3e, 0x42, 0xa1, 0xbb, 0x30, 0x69, - 0xec, 0x12, 0x97, 0x1a, 0x8d, 0x86, 0xaf, 0x4c, 0x71, 0xca, 0x62, 0xaf, 0xab, 0xce, 0x0b, 0x8a, - 0xc3, 0x5c, 0xba, 0xd3, 0x68, 0xf8, 0x1a, 0xee, 0xe3, 0x90, 0x05, 0xf3, 0x0f, 0x9c, 0x66, 0xab, - 0xed, 0x35, 0x5d, 0xba, 0x6e, 0xdb, 0x15, 0x4e, 0x9e, 0xe6, 0xe4, 0xa5, 0x5e, 0x57, 0xbd, 0x24, - 0xc8, 0x3b, 0x11, 0x44, 0xdf, 0xa3, 0xb4, 0x1d, 0xaa, 0xa4, 0x89, 0x48, 0x87, 0xb3, 0x79, 0x27, - 0x20, 0x6b, 0x4d, 0x5f, 0x21, 0x5c, 0x63, 0xa1, 0xd7, 0x55, 0xe7, 0x84, 0xc6, 0xb6, 0x13, 0x10, - 0xbd, 0xd1, 0xf4, 0x35, 0x1c, 0x61, 0xd0, 0x43, 0x98, 0x63, 0xd1, 0x8b, 0xd3, 0x5a, 0xf1, 0xbd, - 0x83, 0x43, 0xe5, 0x33, 0x9e, 0x89, 0xfc, 0x95, 0x5e, 0x57, 0x55, 0xa4, 0xb5, 0xd6, 0x39, 0x44, - 0x6f, 0x33, 0x8c, 0x86, 0x93, 0x2c, 0x64, 0xc0, 0x0c, 0x33, 0x55, 0x08, 0xf1, 0x85, 0xcc, 0xe7, - 0x42, 0xe6, 0x52, 0xaf, 0xab, 0x9e, 0x97, 0x64, 0xda, 0x84, 0xf8, 0x91, 0x48, 0x9c, 0x81, 0x2a, - 0x80, 0xfa, 0xaa, 0xa6, 0xdb, 0xe0, 0x0b, 0x53, 0x3e, 0xe5, 0xf9, 0xcf, 0xab, 0xbd, 0xae, 0x7a, - 0x39, 0x1d, 0x0e, 0x09, 0x61, 0x1a, 0x1e, 0xc0, 0x45, 0xff, 0x0f, 0xa3, 0xcc, 0xaa, 0xfc, 0x52, - 0xbc, 0x11, 0x53, 0x61, 0xfa, 0x99, 0x2d, 0x3f, 0xd7, 0xeb, 0xaa, 0x53, 0x7d, 0x41, 0x0d, 0x73, - 0x28, 0xca, 0xc3, 0x22, 0xfb, 0xb7, 0xec, 0xf6, 0x0f, 0x73, 0x40, 0x3d, 0x9f, 0x28, 0xbf, 0x4a, - 0x6b, 0xe0, 0xc1, 0x50, 0xb4, 0x06, 0xb3, 0x22, 0x90, 0x02, 0xf1, 0xe9, 0x9a, 0x43, 0x1d, 0xe5, - 0xfb, 0xfc, 0xce, 0xe7, 0x2f, 0xf7, 0xba, 0xea, 0x05, 0x31, 0x67, 0x18, 0x7f, 0x9d, 0xf8, 0x54, - 0x6f, 0x38, 0xd4, 0xd1, 0x70, 0x82, 0x13, 0x57, 0xe1, 0x0f, 0xc7, 0x27, 0xc7, 0xaa, 0xb4, 0x1d, - 0xba, 0x17, 0x53, 0xe1, 0x0f, 0x8b, 0x01, 0x33, 0xc2, 0xb2, 0x41, 0x0e, 0x79, 0x28, 0x3f, 0x10, - 0x22, 0x52, 0x5e, 0x42, 0x91, 0x67, 0xe4, 0x30, 0x8c, 0x24, 0xce, 0x88, 0x49, 0xf0, 0x38, 0x7e, - 0x78, 0x9c, 0x84, 0x08, 0x23, 0xce, 0x40, 0x36, 0x2c, 0x08, 0x83, 0xed, 0x77, 0x02, 0x4a, 0x1a, - 0x05, 0x83, 0xc7, 0xf2, 0x23, 0x21, 0x74, 0xad, 0xd7, 0x55, 0xaf, 0xc6, 0x84, 0xa8, 0x80, 0xe9, - 0x75, 0x27, 0x0c, 0x69, 0x10, 0x7d, 0x80, 0x2a, 0x0f, 0xef, 0xc7, 0xa7, 0x50, 0x15, 0x51, 0x0e, - 0xa2, 0xa3, 0xf7, 0x60, 0x9a, 0x9d, 0xc9, 0xa3, 0xdc, 0xfd, 0x43, 0xc8, 0x5d, 0xec, 0x75, 0xd5, - 0x45, 0x21, 0xc7, 0xcf, 0xb0, 0x94, 0xb9, 0x18, 0x5e, 0xe6, 0xf3, 0x70, 0xfe, 0x79, 0x0c, 0x5f, - 0x84, 0x11, 0xc3, 0xa3, 0x77, 0x60, 0x8a, 0x8d, 0xa3, 0x7c, 0xfd, 0x4b, 0xd0, 0x95, 0x5e, 0x57, - 0x3d, 0x27, 0xd1, 0xfb, 0xd9, 0x92, 0xd1, 0x12, 0x99, 0xcf, 0xfd, 0xef, 0xe1, 0x64, 0x31, 0xb5, - 0x8c, 0x46, 0x25, 0x98, 0x67, 0xc3, 0x78, 0x8e, 0xfe, 0x93, 0x4d, 0xde, 0x3f, 0x2e, 0x91, 0xca, - 0x50, 0x9a, 0x9a, 0xd2, 0xe3, 0x21, 0xfd, 0xf7, 0x44, 0x3d, 0x11, 0x59, 0x9a, 0x8a, 0xde, 0x4d, - 0x14, 0xd2, 0x3f, 0x8c, 0x26, 0x57, 0x17, 0x84, 0xee, 0x68, 0x63, 0x63, 0x35, 0xf6, 0xad, 0x44, - 0x4d, 0xf8, 0xe3, 0xa9, 0x8b, 0xc2, 0xcf, 0xa7, 0xa3, 0x36, 0x82, 0xbd, 0xaf, 0x6c, 0x6d, 0xec, - 0x7d, 0xcd, 0x24, 0xdf, 0x57, 0xb6, 0x11, 0xe1, 0xfb, 0x1a, 0x62, 0xd0, 0xab, 0x70, 0xb6, 0x44, - 0xe8, 0x47, 0x9e, 0xff, 0x4c, 0xd4, 0xb1, 0x3c, 0xea, 0x75, 0xd5, 0x59, 0x01, 0x77, 0x85, 0x43, - 0xc3, 0x11, 0x04, 0x5d, 0x87, 0x51, 0xfe, 0xfa, 0x8b, 0x2d, 0x92, 0x5e, 0x28, 0xf1, 0xdc, 0x73, - 0x27, 0x2a, 0xc0, 0xec, 0x1a, 0x69, 0x39, 0x87, 0x96, 0x43, 0x89, 0x5b, 0x3f, 0xdc, 0x0c, 0x78, - 0xa5, 0x99, 0x91, 0x9f, 0x85, 0x06, 0xf3, 0xeb, 0x2d, 0x01, 0xd0, 0xf7, 0x03, 0x0d, 0x27, 0x28, - 0xe8, 0xdb, 0x90, 0x8b, 0x5b, 0xf0, 0x73, 0x5e, 0x73, 0x66, 0xe4, 0x9a, 0x93, 0x94, 0xd1, 0xfd, - 0xe7, 0x1a, 0x4e, 0xf1, 0xd0, 0x07, 0xb0, 0xb8, 0xd5, 0x6e, 0x38, 0x94, 0x34, 0x12, 0x71, 0xcd, - 0x70, 0xc1, 0xeb, 0xbd, 0xae, 0xaa, 0x0a, 0xc1, 0x8e, 0x80, 0xe9, 0xe9, 0xf8, 0x06, 0x2b, 0xa0, - 0x37, 0x00, 0xb0, 0xd7, 0x71, 0x1b, 0x56, 0x73, 0xbf, 0x49, 0x95, 0xc5, 0xe5, 0xcc, 0xca, 0x58, - 0xfe, 0x7c, 0xaf, 0xab, 0x22, 0xa1, 0xe7, 0x33, 0x9f, 0xde, 0x62, 0x4e, 0x0d, 0x4b, 0x48, 0x94, - 0x87, 0x59, 0xf3, 0xa0, 0x49, 0xcb, 0x6e, 0xc1, 0x09, 0x08, 0x2b, 0x92, 0xca, 0xf9, 0x54, 0x35, - 0x3a, 0x68, 0x52, 0xdd, 0x73, 0x75, 0x56, 0x58, 0x3b, 0x3e, 0xd1, 0x70, 0x82, 0x81, 0xde, 0x86, - 0x29, 0xd3, 0x75, 0xb6, 0x5b, 0xa4, 0xd2, 0xf6, 0xbd, 0x1d, 0xe5, 0x02, 0x17, 0xb8, 0xd0, 0xeb, - 0xaa, 0x0b, 0xa1, 0x00, 0x77, 0xea, 0x6d, 0xe6, 0xd5, 0xb0, 0x8c, 0x45, 0xf7, 0x60, 0x8a, 0xc9, - 0xf0, 0xc5, 0x6c, 0x06, 0x8a, 0xca, 0xf7, 0x41, 0x3a, 0xa6, 0x75, 0x5e, 0x88, 0xf9, 0x26, 0xb0, - 0xc5, 0xcb, 0x60, 0x36, 0x2d, 0x1b, 0x56, 0xf7, 0x3a, 0x3b, 0x3b, 0x2d, 0xa2, 0x2c, 0x27, 0xa7, - 0xe5, 0xdc, 0x40, 0x78, 0x43, 0x6a, 0x88, 0x45, 0x2f, 0xc3, 0x18, 0x1b, 0x06, 0xca, 0x35, 0xd6, - 0x89, 0xe6, 0x73, 0xbd, 0xae, 0x3a, 0xdd, 0x27, 0x05, 0x1a, 0x16, 0x6e, 0xb4, 0x21, 0x75, 0x1c, - 0x05, 0x6f, 0x7f, 0xdf, 0x71, 0x1b, 0x81, 0xa2, 0x71, 0xce, 0xd5, 0x5e, 0x57, 0xbd, 0x98, 0xec, - 0x38, 0xea, 0x21, 0x46, 0x6e, 0x38, 0x22, 0x1e, 0x3b, 0x8e, 0xb8, 0xe3, 0xba, 0xc4, 0x67, 0x1d, - 0x10, 0xbf, 0x96, 0x37, 0x93, 0x55, 0xca, 0xe7, 0x7e, 0xde, 0x2d, 0x45, 0x55, 0x2a, 0x4e, 0x41, - 0x45, 0xc8, 0x99, 0x07, 0x94, 0xf8, 0xae, 0xd3, 0x3a, 0x92, 0x59, 0xe5, 0x32, 0x52, 0x40, 0x24, - 0x44, 0xc8, 0x42, 0x29, 0x1a, 0xba, 0x03, 0x93, 0x55, 0xea, 0x93, 0x20, 0x20, 0x7e, 0xa0, 0x10, - 0xbe, 0x28, 0xa9, 0x6d, 0x0b, 0x22, 0x97, 0x86, 0xfb, 0x30, 0x74, 0x1b, 0x26, 0x0a, 0x7b, 0xa4, - 0xfe, 0x8c, 0x51, 0x76, 0x38, 0x45, 0xba, 0xd5, 0xf5, 0xd0, 0xa3, 0xe1, 0x23, 0x10, 0x2b, 0x89, - 0x82, 0xbd, 0x41, 0x0e, 0x79, 0xfb, 0xcd, 0x9b, 0xa6, 0x31, 0xf9, 0x7c, 0x89, 0x99, 0xf8, 0x53, - 0x1b, 0x34, 0x3f, 0x26, 0x1a, 0x8e, 0x33, 0xd0, 0x23, 0x40, 0x31, 0x83, 0xe5, 0xf8, 0xbb, 0x44, - 0x74, 0x4d, 0x63, 0xf9, 0xe5, 0x5e, 0x57, 0xbd, 0x32, 0x50, 0x47, 0x6f, 0x31, 0x9c, 0x86, 0x07, - 0x90, 0xd1, 0x13, 0x38, 0xd7, 0xb7, 0x76, 0x76, 0x76, 0x9a, 0x07, 0xd8, 0x71, 0x77, 0x89, 0xf2, - 0x85, 0x10, 0xd5, 0x7a, 0x5d, 0x75, 0x29, 0x2d, 0xca, 0x81, 0xba, 0xcf, 0x90, 0x1a, 0x1e, 0x28, - 0x80, 0x1c, 0xb8, 0x30, 0xc8, 0x6e, 0x1f, 0xb8, 0xca, 0x97, 0x42, 0xfb, 0xe5, 0x5e, 0x57, 0xd5, - 0x8e, 0xd5, 0xd6, 0xe9, 0x81, 0xab, 0xe1, 0x61, 0x3a, 0x68, 0x1d, 0xe6, 0x8e, 0x5c, 0xf6, 0x81, - 0x5b, 0x6e, 0x07, 0xca, 0x57, 0x42, 0x5a, 0x3a, 0x01, 0x92, 0x34, 0x3d, 0x70, 0x75, 0xaf, 0x1d, - 0x68, 0x38, 0x49, 0x43, 0xef, 0x47, 0xb9, 0x11, 0xc5, 0x3d, 0x10, 0x1d, 0xe4, 0x98, 0x5c, 0x80, - 0x43, 0x1d, 0xd1, 0x16, 0x04, 0x47, 0xa9, 0x09, 0x09, 0xe8, 0xf5, 0xe8, 0x08, 0x3d, 0xaa, 0x54, - 0x45, 0xef, 0x38, 0x26, 0xf7, 0xf1, 0x21, 0xfb, 0xc3, 0x76, 0xff, 0x10, 0x3d, 0xaa, 0x54, 0xb5, - 0xef, 0xcc, 0x89, 0x6e, 0x93, 0xbd, 0xe2, 0xfd, 0xaf, 0x46, 0xf9, 0x15, 0x77, 0x9d, 0x7d, 0xa2, - 0x61, 0xee, 0x94, 0xeb, 0xc8, 0xc8, 0x29, 0xea, 0xc8, 0x2a, 0x8c, 0x3f, 0x31, 0x2c, 0x86, 0xce, - 0x26, 0xcb, 0xc8, 0x47, 0x4e, 0x4b, 0x80, 0x43, 0x04, 0x2a, 0xc3, 0xc2, 0x3a, 0x71, 0x7c, 0xba, - 0x4d, 0x1c, 0x5a, 0x74, 0x29, 0xf1, 0x9f, 0x3b, 0xad, 0xb0, 0x4a, 0x64, 0xe5, 0xdd, 0xdc, 0x8b, - 0x40, 0x7a, 0x33, 0x44, 0x69, 0x78, 0x10, 0x13, 0x15, 0x61, 0xde, 0x6c, 0x91, 0x3a, 0xfb, 0xee, - 0xb6, 0x9b, 0xfb, 0xc4, 0xeb, 0xd0, 0xcd, 0x80, 0x57, 0x8b, 0xac, 0x7c, 0xcb, 0x49, 0x08, 0xd1, - 0xa9, 0xc0, 0x68, 0x38, 0xcd, 0x62, 0x17, 0xdd, 0x6a, 0x06, 0x94, 0xb8, 0xd2, 0x77, 0xf3, 0x62, - 0xf2, 0xe5, 0x69, 0x71, 0x44, 0xd4, 0xe2, 0x77, 0xfc, 0x56, 0xa0, 0xe1, 0x14, 0x0d, 0x61, 0x58, - 0x30, 0x1a, 0xcf, 0x89, 0x4f, 0x9b, 0x01, 0x91, 0xd4, 0xce, 0x73, 0x35, 0xe9, 0x02, 0x39, 0x11, - 0x28, 0x2e, 0x38, 0x88, 0x8c, 0xde, 0x8e, 0x5a, 0x5d, 0xa3, 0x43, 0x3d, 0xdb, 0xaa, 0x86, 0xaf, - 0xbe, 0x94, 0x1b, 0xa7, 0x43, 0x3d, 0x9d, 0x32, 0x81, 0x38, 0x92, 0xbd, 0x83, 0xfd, 0xd6, 0xdb, - 0xe8, 0xd0, 0x3d, 0x45, 0xe1, 0xdc, 0x21, 0xdd, 0xba, 0xd3, 0x49, 0x74, 0xeb, 0x8c, 0x82, 0xbe, - 0x25, 0x8b, 0xb0, 0x0f, 0x7e, 0xe5, 0x62, 0xf2, 0xc3, 0x93, 0xb3, 0x77, 0x9a, 0xec, 0xf1, 0x4f, - 0x60, 0xfb, 0xd1, 0x6f, 0x90, 0x43, 0x4e, 0xbe, 0x94, 0x3c, 0x59, 0xec, 0xe6, 0x08, 0x6e, 0x1c, - 0x89, 0xac, 0x54, 0x2b, 0xcd, 0x05, 0x2e, 0x27, 0x1b, 0x7d, 0xa9, 0x4d, 0x13, 0x3a, 0x83, 0x68, - 0x6c, 0x2f, 0x44, 0xba, 0x58, 0x0f, 0xc7, 0xb3, 0xa2, 0xf2, 0xac, 0x48, 0x7b, 0x11, 0xe6, 0x98, - 0xf7, 0x7e, 0x22, 0x21, 0x09, 0x0a, 0xb2, 0x61, 0xfe, 0x28, 0x45, 0x47, 0x3a, 0xcb, 0x5c, 0x47, - 0x7a, 0x6d, 0x9a, 0x6e, 0x93, 0x36, 0x9d, 0x96, 0xde, 0xcf, 0xb2, 0x24, 0x99, 0x16, 0x60, 0xa5, - 0x99, 0xfd, 0x3f, 0xca, 0xef, 0x35, 0x9e, 0xa3, 0x64, 0x7f, 0xdc, 0x4f, 0xb2, 0x0c, 0x66, 0x1f, - 0xa8, 0xbc, 0x53, 0x8f, 0xa7, 0x59, 0xe3, 0x12, 0xd2, 0x81, 0x13, 0xed, 0x7d, 0x2a, 0xd7, 0x03, - 0xb8, 0xac, 0xa3, 0x8d, 0x7a, 0x7f, 0xbe, 0xdf, 0xd7, 0x87, 0x7f, 0x2a, 0x88, 0xed, 0x8e, 0xc1, - 0xa3, 0xc5, 0x44, 0xe9, 0x7e, 0x69, 0x68, 0xb3, 0x2f, 0xc8, 0x32, 0x18, 0x6d, 0x26, 0x9a, 0x73, - 0xae, 0x70, 0xe3, 0xa4, 0xde, 0x5c, 0x08, 0xa5, 0x99, 0xac, 0xe3, 0x2a, 0x8a, 0x54, 0x14, 0x5a, - 0x1d, 0xfe, 0x83, 0xdb, 0xcd, 0xe4, 0xd9, 0x89, 0x52, 0x55, 0x17, 0x00, 0x0d, 0x27, 0x18, 0xec, - 0x46, 0xc7, 0x2d, 0x55, 0xea, 0x50, 0x12, 0x36, 0x02, 0xd2, 0x06, 0x27, 0x84, 0xf4, 0x80, 0xc1, - 0x34, 0x3c, 0x88, 0x9c, 0xd6, 0xb4, 0xbd, 0x67, 0xc4, 0x55, 0x5e, 0x39, 0x49, 0x93, 0x32, 0x58, - 0x4a, 0x93, 0x93, 0xd1, 0x7d, 0x98, 0x89, 0x3e, 0x0f, 0x0a, 0x5e, 0xc7, 0xa5, 0xca, 0x5d, 0xfe, - 0x16, 0xca, 0x05, 0x26, 0xfa, 0x0e, 0xa9, 0x33, 0x3f, 0x2b, 0x30, 0x32, 0x1e, 0x59, 0x30, 0xff, - 0xa8, 0xe3, 0x51, 0x27, 0xef, 0xd4, 0x9f, 0x11, 0xb7, 0x91, 0x3f, 0xa4, 0x24, 0x50, 0x5e, 0xe7, - 0x22, 0x52, 0xfb, 0xfd, 0x21, 0x83, 0xe8, 0xdb, 0x02, 0xa3, 0x6f, 0x33, 0x90, 0x86, 0xd3, 0x44, - 0x56, 0x4a, 0x2a, 0x3e, 0x79, 0xec, 0x51, 0xa2, 0xdc, 0x4f, 0x3e, 0x57, 0x6d, 0x9f, 0xe8, 0xcf, - 0x3d, 0xb6, 0x3b, 0x11, 0x46, 0xde, 0x11, 0xcf, 0xf7, 0x3b, 0x6d, 0xca, 0xbb, 0x1a, 0xe5, 0xfd, - 0xe4, 0x31, 0x3e, 0xda, 0x11, 0x81, 0xd2, 0x79, 0x1f, 0x24, 0xed, 0x88, 0x44, 0x46, 0x37, 0x61, - 0xdc, 0xf2, 0x76, 0x77, 0x89, 0xaf, 0x3c, 0xe4, 0x1b, 0x3b, 0xdf, 0xeb, 0xaa, 0x33, 0xe1, 0x45, - 0xe7, 0x76, 0x0d, 0x87, 0x00, 0x74, 0x17, 0x26, 0x2d, 0x6f, 0xb7, 0xdc, 0xa1, 0xed, 0x0e, 0x55, - 0xd6, 0xf9, 0x75, 0x96, 0x6a, 0x6b, 0xcb, 0xdb, 0xd5, 0x3d, 0xee, 0xd3, 0x70, 0x1f, 0xc7, 0x3a, - 0xdb, 0x35, 0xb2, 0xdd, 0xd9, 0x55, 0x8a, 0x3c, 0x4a, 0xa9, 0xb3, 0x6d, 0x30, 0xb3, 0x86, 0x85, - 0x7b, 0xf5, 0xa7, 0x59, 0xe9, 0x67, 0x64, 0x34, 0x07, 0x53, 0xa5, 0xb2, 0x5d, 0xab, 0xda, 0x06, - 0xb6, 0xcd, 0xb5, 0xdc, 0x19, 0x74, 0x1e, 0x50, 0xb1, 0x54, 0xb4, 0x8b, 0x86, 0x25, 0x8c, 0x35, - 0xd3, 0x2e, 0xac, 0xe5, 0x00, 0xe5, 0x60, 0x1a, 0x9b, 0x92, 0x65, 0x8a, 0x59, 0xaa, 0xc5, 0x87, - 0xb6, 0x89, 0x37, 0x85, 0xe5, 0x1c, 0x5a, 0x86, 0x2b, 0xd5, 0xe2, 0xc3, 0x47, 0x5b, 0x45, 0x81, - 0xa9, 0x19, 0xa5, 0xb5, 0x1a, 0x36, 0x37, 0xcb, 0x8f, 0xcd, 0xda, 0x9a, 0x61, 0x1b, 0xb9, 0x45, - 0x34, 0x0f, 0x33, 0x55, 0xe3, 0xb1, 0x59, 0xab, 0x96, 0x8c, 0x4a, 0x75, 0xbd, 0x6c, 0xe7, 0x96, - 0xd0, 0x35, 0xb8, 0xca, 0x84, 0xcb, 0xd8, 0xac, 0x45, 0x13, 0x3c, 0xc0, 0xe5, 0xcd, 0x3e, 0x44, - 0x45, 0x17, 0x61, 0x71, 0xb0, 0x6b, 0x99, 0xb1, 0x53, 0x53, 0x1a, 0xb8, 0xb0, 0x5e, 0x8c, 0xe6, - 0x5c, 0x41, 0xb7, 0xe1, 0x95, 0xe3, 0xa2, 0xe2, 0xe3, 0xaa, 0x5d, 0xae, 0xd4, 0x8c, 0x87, 0x66, - 0xc9, 0xce, 0xdd, 0x44, 0x57, 0xe1, 0x62, 0xde, 0x32, 0x0a, 0x1b, 0xeb, 0x65, 0xcb, 0xac, 0x55, - 0x4c, 0x13, 0xd7, 0x2a, 0x65, 0x6c, 0xd7, 0xec, 0xa7, 0x35, 0xfc, 0x34, 0xd7, 0x40, 0x2a, 0x5c, - 0xde, 0x2a, 0x0d, 0x07, 0x10, 0x74, 0x09, 0x16, 0xd7, 0x4c, 0xcb, 0xf8, 0x20, 0xe5, 0x7a, 0x91, - 0x41, 0x57, 0xe0, 0xc2, 0x56, 0x69, 0xb0, 0xf7, 0xb3, 0xcc, 0xea, 0xdf, 0x00, 0x46, 0xd9, 0xf7, - 0x07, 0x52, 0xe0, 0x5c, 0xb4, 0xb7, 0xe5, 0x92, 0x59, 0x7b, 0x50, 0xb6, 0xac, 0xf2, 0x13, 0x13, - 0xe7, 0xce, 0x84, 0xab, 0x49, 0x79, 0x6a, 0x5b, 0x25, 0xbb, 0x68, 0xd5, 0x6c, 0x5c, 0x7c, 0xf8, - 0xd0, 0xc4, 0xfd, 0x1d, 0xca, 0x20, 0x04, 0xb3, 0x11, 0xc1, 0x32, 0x8d, 0x35, 0x13, 0xe7, 0x46, - 0xd0, 0x4d, 0xb8, 0x11, 0xb7, 0x0d, 0xa3, 0x67, 0x65, 0xfa, 0xa3, 0xad, 0x32, 0xde, 0xda, 0xcc, - 0x8d, 0xb2, 0x43, 0x13, 0xd9, 0x0c, 0xcb, 0xca, 0x8d, 0xa1, 0xeb, 0xa0, 0x46, 0x5b, 0x2c, 0xed, - 0x6e, 0x2c, 0x72, 0x40, 0xf7, 0xe0, 0x8d, 0x13, 0x40, 0xc3, 0xa2, 0x98, 0x62, 0x29, 0x19, 0xc0, - 0x0d, 0xd7, 0x33, 0x8d, 0x5e, 0x87, 0xd7, 0x86, 0xba, 0x87, 0x89, 0xce, 0xa0, 0x07, 0x90, 0x1f, - 0xc0, 0x12, 0xab, 0x0c, 0x2d, 0xe2, 0x5c, 0x86, 0x42, 0x11, 0x35, 0x3c, 0x84, 0x05, 0x6c, 0xd8, - 0x85, 0xf5, 0xdc, 0x2c, 0x5a, 0x85, 0x97, 0x87, 0x1e, 0x87, 0xf8, 0x26, 0x34, 0x90, 0x01, 0xef, - 0x9e, 0x0e, 0x3b, 0x2c, 0x6c, 0x82, 0x5e, 0x82, 0xe5, 0xe1, 0x12, 0xe1, 0x96, 0xec, 0xa0, 0x77, - 0xe0, 0xcd, 0x93, 0x50, 0xc3, 0xa6, 0xd8, 0x3d, 0x7e, 0x8a, 0xf0, 0x18, 0xec, 0xb1, 0xbb, 0x37, - 0x1c, 0xc5, 0x0e, 0x46, 0x13, 0xfd, 0x1f, 0x68, 0x03, 0x0f, 0x7b, 0x7c, 0x5b, 0x5e, 0x64, 0xd0, - 0x2d, 0xb8, 0x89, 0x8d, 0xd2, 0x5a, 0x79, 0xb3, 0x76, 0x0a, 0xfc, 0x67, 0x19, 0xf4, 0x1e, 0xbc, - 0x7d, 0x32, 0x70, 0xd8, 0x02, 0x3f, 0xcf, 0x20, 0x13, 0xde, 0x3f, 0xf5, 0x7c, 0xc3, 0x64, 0xbe, - 0xc8, 0xa0, 0x6b, 0x70, 0x65, 0x30, 0x3f, 0xcc, 0xc3, 0x97, 0x19, 0xb4, 0x02, 0xd7, 0x8f, 0x9d, - 0x29, 0x44, 0x7e, 0x95, 0x41, 0x6f, 0xc1, 0xdd, 0xe3, 0x20, 0xc3, 0xc2, 0xf8, 0x75, 0x06, 0xdd, - 0x87, 0x7b, 0xa7, 0x98, 0x63, 0x98, 0xc0, 0x6f, 0x8e, 0x59, 0x47, 0x98, 0xec, 0xaf, 0x4f, 0x5e, - 0x47, 0x88, 0xfc, 0x6d, 0x06, 0x2d, 0xc1, 0xc5, 0xc1, 0x10, 0x76, 0x26, 0x7e, 0x97, 0x41, 0x37, - 0x60, 0xf9, 0x58, 0x25, 0x06, 0xfb, 0x7d, 0x06, 0x29, 0xb0, 0x50, 0x2a, 0xd7, 0x1e, 0x18, 0x45, - 0xab, 0xf6, 0xa4, 0x68, 0xaf, 0xd7, 0xaa, 0x36, 0x36, 0xab, 0xd5, 0xdc, 0x2f, 0x46, 0x58, 0x28, - 0x31, 0x4f, 0xa9, 0x1c, 0x3a, 0x6b, 0x0f, 0xca, 0xb8, 0x66, 0x15, 0x1f, 0x9b, 0x25, 0x86, 0xfc, - 0x74, 0x04, 0xcd, 0x01, 0x30, 0x58, 0xa5, 0x5c, 0x2c, 0xd9, 0xd5, 0xdc, 0xf7, 0xb2, 0x68, 0x06, - 0x26, 0xcc, 0xa7, 0xb6, 0x89, 0x4b, 0x86, 0x95, 0xfb, 0x7b, 0x76, 0x75, 0x1f, 0x26, 0xa2, 0x9f, - 0x38, 0xd0, 0x38, 0x8c, 0x6c, 0x3c, 0xce, 0x9d, 0x41, 0x93, 0x30, 0x66, 0x99, 0x46, 0xd5, 0xcc, - 0x65, 0xd0, 0x02, 0xcc, 0x99, 0x96, 0x59, 0xb0, 0x8b, 0xe5, 0x52, 0x0d, 0x6f, 0x95, 0x4a, 0xfc, - 0xf1, 0xcc, 0xc1, 0xf4, 0x13, 0x76, 0xf3, 0x23, 0x4b, 0x16, 0x2d, 0xc2, 0xbc, 0x55, 0x2e, 0x6c, - 0xd4, 0xb0, 0x51, 0x30, 0x71, 0x64, 0x1e, 0x65, 0x40, 0x2e, 0x14, 0x59, 0xc6, 0x56, 0xf3, 0x70, - 0x36, 0xfc, 0x7d, 0x04, 0x4d, 0xc1, 0xd9, 0x8d, 0xc7, 0xb5, 0x75, 0xa3, 0xba, 0x9e, 0x3b, 0xd3, - 0x47, 0x9a, 0x4f, 0x2b, 0x45, 0xcc, 0x66, 0x06, 0x18, 0x3f, 0x9a, 0x70, 0x1a, 0x26, 0x4a, 0xe5, - 0x5a, 0x61, 0xdd, 0x2c, 0x6c, 0xe4, 0xb2, 0x77, 0xee, 0xc3, 0xa4, 0xed, 0x3b, 0x6e, 0xd0, 0xf6, - 0x7c, 0x8a, 0xee, 0xc8, 0x83, 0xd9, 0xf0, 0x57, 0xda, 0xf0, 0xef, 0xc5, 0x97, 0xe6, 0x8e, 0xc6, - 0xe2, 0x4f, 0x89, 0xda, 0x99, 0x95, 0xcc, 0x6b, 0x99, 0xfc, 0xb9, 0x17, 0x7f, 0x5e, 0x3a, 0xf3, - 0xe2, 0x9b, 0xa5, 0xcc, 0xd7, 0xdf, 0x2c, 0x65, 0xfe, 0xf4, 0xcd, 0x52, 0xe6, 0x27, 0x7f, 0x59, - 0x3a, 0xb3, 0x3d, 0xce, 0xff, 0xde, 0x7c, 0xf7, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xdc, - 0x19, 0xd8, 0xb8, 0x1e, 0x00, 0x00, + 0xd5, 0x37, 0x45, 0x49, 0x96, 0xae, 0x5e, 0xd4, 0xc8, 0xb2, 0xe1, 0x97, 0x20, 0xc3, 0x71, 0x3e, + 0x59, 0x09, 0xec, 0x7c, 0x76, 0xbe, 0x3c, 0x9c, 0x2f, 0x71, 0x40, 0x0a, 0xb6, 0x58, 0x41, 0x24, + 0x3d, 0x84, 0x6c, 0x67, 0xc5, 0x03, 0x91, 0x23, 0x89, 0xc7, 0x14, 0xc0, 0x00, 0x43, 0x47, 0xca, + 0xb6, 0x8b, 0x6e, 0xdb, 0xf4, 0x71, 0xda, 0x73, 0xba, 0xea, 0xba, 0x69, 0xff, 0x0d, 0xe7, 0xd5, + 0xa6, 0xed, 0xaa, 0x5d, 0xf0, 0xb4, 0xe9, 0xa6, 0xab, 0x2e, 0x78, 0xfa, 0x5e, 0xf5, 0xcc, 0x0c, + 0x20, 0x0e, 0x00, 0x52, 0xd2, 0xca, 0x9e, 0x7b, 0x7f, 0xbf, 0xdf, 0xdc, 0x99, 0x3b, 0x33, 0xf7, + 0x82, 0x82, 0x39, 0xbf, 0x5d, 0x6f, 0x6f, 0xdf, 0xf6, 0xdb, 0xf5, 0x5b, 0x6d, 0xdf, 0xa3, 0x1e, + 0x1a, 0xe3, 0x86, 0x4b, 0xfa, 0x6e, 0x93, 0xee, 0x75, 0xb6, 0x6f, 0xd5, 0xbd, 0xfd, 0xdb, 0xbb, + 0xde, 0xae, 0x77, 0x9b, 0x7b, 0xb7, 0x3b, 0x3b, 0x7c, 0xc4, 0x07, 0xfc, 0x7f, 0x82, 0xa5, 0x7d, + 0x27, 0x03, 0x67, 0x31, 0xf9, 0xb0, 0x43, 0x02, 0x8a, 0x6e, 0xc1, 0x64, 0xb9, 0x4d, 0x7c, 0x87, + 0x36, 0x3d, 0x57, 0xc9, 0x2c, 0x67, 0x56, 0x66, 0xef, 0xe4, 0x6e, 0x71, 0xd5, 0x5b, 0x47, 0x76, + 0xdc, 0x87, 0xa0, 0x1b, 0x30, 0xbe, 0x49, 0xf6, 0xb7, 0x89, 0xaf, 0x8c, 0x2c, 0x67, 0x56, 0xa6, + 0xee, 0xcc, 0x84, 0x60, 0x61, 0xc4, 0xa1, 0x93, 0xc1, 0x6c, 0x12, 0x50, 0xe2, 0x2b, 0xd9, 0x18, + 0x4c, 0x18, 0x71, 0xe8, 0xd4, 0xfe, 0x32, 0x02, 0xd3, 0x55, 0xd7, 0x69, 0x07, 0x7b, 0x1e, 0x2d, + 0xba, 0x3b, 0x1e, 0x5a, 0x02, 0x10, 0x0a, 0x25, 0x67, 0x9f, 0xf0, 0x78, 0x26, 0xb1, 0x64, 0x41, + 0xab, 0x90, 0x13, 0xa3, 0x42, 0xab, 0x49, 0x5c, 0xba, 0x85, 0xad, 0x40, 0x19, 0x59, 0xce, 0xae, + 0x4c, 0xe2, 0x94, 0x1d, 0x69, 0x7d, 0xed, 0x8a, 0x43, 0xf7, 0x78, 0x24, 0x93, 0x38, 0x66, 0x63, + 0x7a, 0xd1, 0xf8, 0x41, 0xb3, 0x45, 0xaa, 0xcd, 0x8f, 0x89, 0x32, 0xca, 0x71, 0x29, 0x3b, 0x7a, + 0x15, 0xe6, 0x23, 0x9b, 0xed, 0x51, 0xa7, 0xc5, 0xc1, 0x63, 0x1c, 0x9c, 0x76, 0xc8, 0xca, 0xdc, + 0xb8, 0x41, 0x0e, 0x95, 0xf1, 0xe5, 0xcc, 0x4a, 0x16, 0xa7, 0xec, 0x72, 0xa4, 0xeb, 0x4e, 0xb0, + 0xa7, 0x9c, 0xe5, 0xb8, 0x98, 0x4d, 0xd6, 0xc3, 0xe4, 0x79, 0x33, 0x60, 0xf9, 0x9a, 0x88, 0xeb, + 0x45, 0x76, 0x84, 0x60, 0xd4, 0xf6, 0xbc, 0x67, 0xca, 0x24, 0x0f, 0x8e, 0xff, 0x5f, 0xfb, 0x69, + 0x06, 0x26, 0x30, 0x09, 0xda, 0x9e, 0x1b, 0x10, 0xa4, 0xc0, 0xd9, 0x6a, 0xa7, 0x5e, 0x27, 0x41, + 0xc0, 0xf7, 0x78, 0x02, 0x47, 0x43, 0x74, 0x1e, 0xc6, 0xab, 0xd4, 0xa1, 0x9d, 0x80, 0xe7, 0x77, + 0x12, 0x87, 0x23, 0x29, 0xef, 0xd9, 0xe3, 0xf2, 0xfe, 0x66, 0x3c, 0x9f, 0x7c, 0x2f, 0xa7, 0xee, + 0x2c, 0x84, 0x60, 0xd9, 0x85, 0x63, 0x40, 0xed, 0x93, 0xe9, 0x68, 0x02, 0xf4, 0x1a, 0x4c, 0x98, + 0xb4, 0xde, 0x30, 0x0f, 0x48, 0x5d, 0x9c, 0x80, 0xfc, 0xb9, 0x5e, 0x57, 0xcd, 0x1d, 0x3a, 0xfb, + 0xad, 0x7b, 0x1a, 0xa1, 0xf5, 0x86, 0x4e, 0x0e, 0x48, 0x5d, 0xc3, 0x47, 0x28, 0x74, 0x17, 0x26, + 0x8d, 0x5d, 0xe2, 0x52, 0xa3, 0xd1, 0xf0, 0x95, 0x29, 0x4e, 0x59, 0xec, 0x75, 0xd5, 0x79, 0x41, + 0x71, 0x98, 0x4b, 0x77, 0x1a, 0x0d, 0x5f, 0xc3, 0x7d, 0x1c, 0xb2, 0x60, 0xfe, 0x81, 0xd3, 0x6c, + 0xb5, 0xbd, 0xa6, 0x4b, 0xd7, 0x6d, 0xbb, 0xc2, 0xc9, 0xd3, 0x9c, 0xbc, 0xd4, 0xeb, 0xaa, 0x97, + 0x04, 0x79, 0x27, 0x82, 0xe8, 0x7b, 0x94, 0xb6, 0x43, 0x95, 0x34, 0x11, 0xe9, 0x70, 0x36, 0xef, + 0x04, 0x64, 0xad, 0xe9, 0x2b, 0x84, 0x6b, 0x2c, 0xf4, 0xba, 0xea, 0x9c, 0xd0, 0xd8, 0x76, 0x02, + 0xa2, 0x37, 0x9a, 0xbe, 0x86, 0x23, 0x0c, 0x7a, 0x08, 0x73, 0x2c, 0x7a, 0x71, 0x5a, 0x2b, 0xbe, + 0x77, 0x70, 0xa8, 0x7c, 0xc6, 0x33, 0x91, 0xbf, 0xd2, 0xeb, 0xaa, 0x8a, 0xb4, 0xd6, 0x3a, 0x87, + 0xe8, 0x6d, 0x86, 0xd1, 0x70, 0x92, 0x85, 0x0c, 0x98, 0x61, 0xa6, 0x0a, 0x21, 0xbe, 0x90, 0xf9, + 0x5c, 0xc8, 0x5c, 0xea, 0x75, 0xd5, 0xf3, 0x92, 0x4c, 0x9b, 0x10, 0x3f, 0x12, 0x89, 0x33, 0x50, + 0x05, 0x50, 0x5f, 0xd5, 0x74, 0x1b, 0x7c, 0x61, 0xca, 0xa7, 0x3c, 0xff, 0x79, 0xb5, 0xd7, 0x55, + 0x2f, 0xa7, 0xc3, 0x21, 0x21, 0x4c, 0xc3, 0x03, 0xb8, 0xe8, 0x7f, 0x61, 0x94, 0x59, 0x95, 0x5f, + 0x88, 0x37, 0x62, 0x2a, 0x4c, 0x3f, 0xb3, 0xe5, 0xe7, 0x7a, 0x5d, 0x75, 0xaa, 0x2f, 0xa8, 0x61, + 0x0e, 0x45, 0x79, 0x58, 0x64, 0xff, 0x96, 0xdd, 0xfe, 0x61, 0x0e, 0xa8, 0xe7, 0x13, 0xe5, 0x97, + 0x69, 0x0d, 0x3c, 0x18, 0x8a, 0xd6, 0x60, 0x56, 0x04, 0x52, 0x20, 0x3e, 0x5d, 0x73, 0xa8, 0xa3, + 0x7c, 0x8f, 0xdf, 0xf9, 0xfc, 0xe5, 0x5e, 0x57, 0xbd, 0x20, 0xe6, 0x0c, 0xe3, 0xaf, 0x13, 0x9f, + 0xea, 0x0d, 0x87, 0x3a, 0x1a, 0x4e, 0x70, 0xe2, 0x2a, 0xfc, 0xe1, 0xf8, 0xe4, 0x58, 0x95, 0xb6, + 0x43, 0xf7, 0x62, 0x2a, 0xfc, 0x61, 0x31, 0x60, 0x46, 0x58, 0x36, 0xc8, 0x21, 0x0f, 0xe5, 0xfb, + 0x42, 0x44, 0xca, 0x4b, 0x28, 0xf2, 0x8c, 0x1c, 0x86, 0x91, 0xc4, 0x19, 0x31, 0x09, 0x1e, 0xc7, + 0x0f, 0x8e, 0x93, 0x10, 0x61, 0xc4, 0x19, 0xc8, 0x86, 0x05, 0x61, 0xb0, 0xfd, 0x4e, 0x40, 0x49, + 0xa3, 0x60, 0xf0, 0x58, 0x7e, 0x28, 0x84, 0xae, 0xf5, 0xba, 0xea, 0xd5, 0x98, 0x10, 0x15, 0x30, + 0xbd, 0xee, 0x84, 0x21, 0x0d, 0xa2, 0x0f, 0x50, 0xe5, 0xe1, 0xfd, 0xe8, 0x14, 0xaa, 0x22, 0xca, + 0x41, 0x74, 0xf4, 0x1e, 0x4c, 0xb3, 0x33, 0x79, 0x94, 0xbb, 0xbf, 0x0b, 0xb9, 0x8b, 0xbd, 0xae, + 0xba, 0x28, 0xe4, 0xf8, 0x19, 0x96, 0x32, 0x17, 0xc3, 0xcb, 0x7c, 0x1e, 0xce, 0x3f, 0x8e, 0xe1, + 0x8b, 0x30, 0x62, 0x78, 0xf4, 0x0e, 0x4c, 0xb1, 0x71, 0x94, 0xaf, 0x7f, 0x0a, 0xba, 0xd2, 0xeb, + 0xaa, 0xe7, 0x24, 0x7a, 0x3f, 0x5b, 0x32, 0x5a, 0x22, 0xf3, 0xb9, 0xff, 0x35, 0x9c, 0x2c, 0xa6, + 0x96, 0xd1, 0xa8, 0x04, 0xf3, 0x6c, 0x18, 0xcf, 0xd1, 0xbf, 0xb3, 0xc9, 0xfb, 0xc7, 0x25, 0x52, + 0x19, 0x4a, 0x53, 0x53, 0x7a, 0x3c, 0xa4, 0xff, 0x9c, 0xa8, 0x27, 0x22, 0x4b, 0x53, 0xd1, 0xbb, + 0x89, 0x42, 0xfa, 0xfb, 0xd1, 0xe4, 0xea, 0x82, 0xd0, 0x1d, 0x6d, 0x6c, 0xac, 0xc6, 0xbe, 0x95, + 0xa8, 0x09, 0x7f, 0x38, 0x75, 0x51, 0xf8, 0xd9, 0x74, 0xd4, 0x46, 0xb0, 0xf7, 0x95, 0xad, 0x8d, + 0xbd, 0xaf, 0x99, 0xe4, 0xfb, 0xca, 0x36, 0x22, 0x7c, 0x5f, 0x43, 0x0c, 0x7a, 0x15, 0xce, 0x96, + 0x08, 0xfd, 0xc8, 0xf3, 0x9f, 0x89, 0x3a, 0x96, 0x47, 0xbd, 0xae, 0x3a, 0x2b, 0xe0, 0xae, 0x70, + 0x68, 0x38, 0x82, 0xa0, 0xeb, 0x30, 0xca, 0x5f, 0x7f, 0xb1, 0x45, 0xd2, 0x0b, 0x25, 0x9e, 0x7b, + 0xee, 0x44, 0x05, 0x98, 0x5d, 0x23, 0x2d, 0xe7, 0xd0, 0x72, 0x28, 0x71, 0xeb, 0x87, 0x9b, 0x01, + 0xaf, 0x34, 0x33, 0xf2, 0xb3, 0xd0, 0x60, 0x7e, 0xbd, 0x25, 0x00, 0xfa, 0x7e, 0xa0, 0xe1, 0x04, + 0x05, 0x7d, 0x0b, 0x72, 0x71, 0x0b, 0x7e, 0xce, 0x6b, 0xce, 0x8c, 0x5c, 0x73, 0x92, 0x32, 0xba, + 0xff, 0x5c, 0xc3, 0x29, 0x1e, 0xfa, 0x00, 0x16, 0xb7, 0xda, 0x0d, 0x87, 0x92, 0x46, 0x22, 0xae, + 0x19, 0x2e, 0x78, 0xbd, 0xd7, 0x55, 0x55, 0x21, 0xd8, 0x11, 0x30, 0x3d, 0x1d, 0xdf, 0x60, 0x05, + 0xf4, 0x06, 0x00, 0xf6, 0x3a, 0x6e, 0xc3, 0x6a, 0xee, 0x37, 0xa9, 0xb2, 0xb8, 0x9c, 0x59, 0x19, + 0xcb, 0x9f, 0xef, 0x75, 0x55, 0x24, 0xf4, 0x7c, 0xe6, 0xd3, 0x5b, 0xcc, 0xa9, 0x61, 0x09, 0x89, + 0xf2, 0x30, 0x6b, 0x1e, 0x34, 0x69, 0xd9, 0x2d, 0x38, 0x01, 0x61, 0x45, 0x52, 0x39, 0x9f, 0xaa, + 0x46, 0x07, 0x4d, 0xaa, 0x7b, 0xae, 0xce, 0x0a, 0x6b, 0xc7, 0x27, 0x1a, 0x4e, 0x30, 0xd0, 0xdb, + 0x30, 0x65, 0xba, 0xce, 0x76, 0x8b, 0x54, 0xda, 0xbe, 0xb7, 0xa3, 0x5c, 0xe0, 0x02, 0x17, 0x7a, + 0x5d, 0x75, 0x21, 0x14, 0xe0, 0x4e, 0xbd, 0xcd, 0xbc, 0x1a, 0x96, 0xb1, 0xe8, 0x1e, 0x4c, 0x31, + 0x19, 0xbe, 0x98, 0xcd, 0x40, 0x51, 0xf9, 0x3e, 0x48, 0xc7, 0xb4, 0xce, 0x0b, 0x31, 0xdf, 0x04, + 0xb6, 0x78, 0x19, 0xcc, 0xa6, 0x65, 0xc3, 0xea, 0x5e, 0x67, 0x67, 0xa7, 0x45, 0x94, 0xe5, 0xe4, + 0xb4, 0x9c, 0x1b, 0x08, 0x6f, 0x48, 0x0d, 0xb1, 0xe8, 0x65, 0x18, 0x63, 0xc3, 0x40, 0xb9, 0xc6, + 0x3a, 0xd1, 0x7c, 0xae, 0xd7, 0x55, 0xa7, 0xfb, 0xa4, 0x40, 0xc3, 0xc2, 0x8d, 0x36, 0xa4, 0x8e, + 0xa3, 0xe0, 0xed, 0xef, 0x3b, 0x6e, 0x23, 0x50, 0x34, 0xce, 0xb9, 0xda, 0xeb, 0xaa, 0x17, 0x93, + 0x1d, 0x47, 0x3d, 0xc4, 0xc8, 0x0d, 0x47, 0xc4, 0x63, 0xc7, 0x11, 0x77, 0x5c, 0x97, 0xf8, 0xac, + 0x03, 0xe2, 0xd7, 0xf2, 0x66, 0xb2, 0x4a, 0xf9, 0xdc, 0xcf, 0xbb, 0xa5, 0xa8, 0x4a, 0xc5, 0x29, + 0xa8, 0x08, 0x39, 0xf3, 0x80, 0x12, 0xdf, 0x75, 0x5a, 0x47, 0x32, 0xab, 0x5c, 0x46, 0x0a, 0x88, + 0x84, 0x08, 0x59, 0x28, 0x45, 0x43, 0x77, 0x60, 0xb2, 0x4a, 0x7d, 0x12, 0x04, 0xc4, 0x0f, 0x14, + 0xc2, 0x17, 0x25, 0xb5, 0x6d, 0x41, 0xe4, 0xd2, 0x70, 0x1f, 0x86, 0x6e, 0xc3, 0x44, 0x61, 0x8f, + 0xd4, 0x9f, 0x31, 0xca, 0x0e, 0xa7, 0x48, 0xb7, 0xba, 0x1e, 0x7a, 0x34, 0x7c, 0x04, 0x62, 0x25, + 0x51, 0xb0, 0x37, 0xc8, 0x21, 0x6f, 0xbf, 0x79, 0xd3, 0x34, 0x26, 0x9f, 0x2f, 0x31, 0x13, 0x7f, + 0x6a, 0x83, 0xe6, 0xc7, 0x44, 0xc3, 0x71, 0x06, 0x7a, 0x04, 0x28, 0x66, 0xb0, 0x1c, 0x7f, 0x97, + 0x88, 0xae, 0x69, 0x2c, 0xbf, 0xdc, 0xeb, 0xaa, 0x57, 0x06, 0xea, 0xe8, 0x2d, 0x86, 0xd3, 0xf0, + 0x00, 0x32, 0x7a, 0x02, 0xe7, 0xfa, 0xd6, 0xce, 0xce, 0x4e, 0xf3, 0x00, 0x3b, 0xee, 0x2e, 0x51, + 0xbe, 0x10, 0xa2, 0x5a, 0xaf, 0xab, 0x2e, 0xa5, 0x45, 0x39, 0x50, 0xf7, 0x19, 0x52, 0xc3, 0x03, + 0x05, 0x90, 0x03, 0x17, 0x06, 0xd9, 0xed, 0x03, 0x57, 0xf9, 0x52, 0x68, 0xbf, 0xdc, 0xeb, 0xaa, + 0xda, 0xb1, 0xda, 0x3a, 0x3d, 0x70, 0x35, 0x3c, 0x4c, 0x07, 0xad, 0xc3, 0xdc, 0x91, 0xcb, 0x3e, + 0x70, 0xcb, 0xed, 0x40, 0xf9, 0x4a, 0x48, 0x4b, 0x27, 0x40, 0x92, 0xa6, 0x07, 0xae, 0xee, 0xb5, + 0x03, 0x0d, 0x27, 0x69, 0xe8, 0xfd, 0x28, 0x37, 0xa2, 0xb8, 0x07, 0xa2, 0x83, 0x1c, 0x93, 0x0b, + 0x70, 0xa8, 0x23, 0xda, 0x82, 0xe0, 0x28, 0x35, 0x21, 0x01, 0xbd, 0x1e, 0x1d, 0xa1, 0x47, 0x95, + 0xaa, 0xe8, 0x1d, 0xc7, 0xe4, 0x3e, 0x3e, 0x64, 0x7f, 0xd8, 0xee, 0x1f, 0xa2, 0x47, 0x95, 0xaa, + 0xf6, 0xed, 0x39, 0xd1, 0x6d, 0xb2, 0x57, 0xbc, 0xff, 0xd5, 0x28, 0xbf, 0xe2, 0xae, 0xb3, 0x4f, + 0x34, 0xcc, 0x9d, 0x72, 0x1d, 0x19, 0x39, 0x45, 0x1d, 0x59, 0x85, 0xf1, 0x27, 0x86, 0xc5, 0xd0, + 0xd9, 0x64, 0x19, 0xf9, 0xc8, 0x69, 0x09, 0x70, 0x88, 0x40, 0x65, 0x58, 0x58, 0x27, 0x8e, 0x4f, + 0xb7, 0x89, 0x43, 0x8b, 0x2e, 0x25, 0xfe, 0x73, 0xa7, 0x15, 0x56, 0x89, 0xac, 0xbc, 0x9b, 0x7b, + 0x11, 0x48, 0x6f, 0x86, 0x28, 0x0d, 0x0f, 0x62, 0xa2, 0x22, 0xcc, 0x9b, 0x2d, 0x52, 0x67, 0xdf, + 0xdd, 0x76, 0x73, 0x9f, 0x78, 0x1d, 0xba, 0x19, 0xf0, 0x6a, 0x91, 0x95, 0x6f, 0x39, 0x09, 0x21, + 0x3a, 0x15, 0x18, 0x0d, 0xa7, 0x59, 0xec, 0xa2, 0x5b, 0xcd, 0x80, 0x12, 0x57, 0xfa, 0x6e, 0x5e, + 0x4c, 0xbe, 0x3c, 0x2d, 0x8e, 0x88, 0x5a, 0xfc, 0x8e, 0xdf, 0x0a, 0x34, 0x9c, 0xa2, 0x21, 0x0c, + 0x0b, 0x46, 0xe3, 0x39, 0xf1, 0x69, 0x33, 0x20, 0x92, 0xda, 0x79, 0xae, 0x26, 0x5d, 0x20, 0x27, + 0x02, 0xc5, 0x05, 0x07, 0x91, 0xd1, 0xdb, 0x51, 0xab, 0x6b, 0x74, 0xa8, 0x67, 0x5b, 0xd5, 0xf0, + 0xd5, 0x97, 0x72, 0xe3, 0x74, 0xa8, 0xa7, 0x53, 0x26, 0x10, 0x47, 0xb2, 0x77, 0xb0, 0xdf, 0x7a, + 0x1b, 0x1d, 0xba, 0xa7, 0x28, 0x9c, 0x3b, 0xa4, 0x5b, 0x77, 0x3a, 0x89, 0x6e, 0x9d, 0x51, 0xd0, + 0xff, 0xcb, 0x22, 0xec, 0x83, 0x5f, 0xb9, 0x98, 0xfc, 0xf0, 0xe4, 0xec, 0x9d, 0x26, 0x7b, 0xfc, + 0x13, 0xd8, 0x7e, 0xf4, 0x1b, 0xe4, 0x90, 0x93, 0x2f, 0x25, 0x4f, 0x16, 0xbb, 0x39, 0x82, 0x1b, + 0x47, 0x22, 0x2b, 0xd5, 0x4a, 0x73, 0x81, 0xcb, 0xc9, 0x46, 0x5f, 0x6a, 0xd3, 0x84, 0xce, 0x20, + 0x1a, 0xdb, 0x0b, 0x91, 0x2e, 0xd6, 0xc3, 0xf1, 0xac, 0xa8, 0x3c, 0x2b, 0xd2, 0x5e, 0x84, 0x39, + 0xe6, 0xbd, 0x9f, 0x48, 0x48, 0x82, 0x82, 0x6c, 0x98, 0x3f, 0x4a, 0xd1, 0x91, 0xce, 0x32, 0xd7, + 0x91, 0x5e, 0x9b, 0xa6, 0xdb, 0xa4, 0x4d, 0xa7, 0xa5, 0xf7, 0xb3, 0x2c, 0x49, 0xa6, 0x05, 0x58, + 0x69, 0x66, 0xff, 0x8f, 0xf2, 0x7b, 0x8d, 0xe7, 0x28, 0xd9, 0x1f, 0xf7, 0x93, 0x2c, 0x83, 0xd9, + 0x07, 0x2a, 0xef, 0xd4, 0xe3, 0x69, 0xd6, 0xb8, 0x84, 0x74, 0xe0, 0x44, 0x7b, 0x9f, 0xca, 0xf5, + 0x00, 0x2e, 0xeb, 0x68, 0xa3, 0xde, 0x9f, 0xef, 0xf7, 0xf5, 0xe1, 0x9f, 0x0a, 0x62, 0xbb, 0x63, + 0xf0, 0x68, 0x31, 0x51, 0xba, 0x5f, 0x1a, 0xda, 0xec, 0x0b, 0xb2, 0x0c, 0x46, 0x9b, 0x89, 0xe6, + 0x9c, 0x2b, 0xdc, 0x38, 0xa9, 0x37, 0x17, 0x42, 0x69, 0x26, 0xeb, 0xb8, 0x8a, 0x22, 0x15, 0x85, + 0x56, 0x87, 0xff, 0xe0, 0x76, 0x33, 0x79, 0x76, 0xa2, 0x54, 0xd5, 0x05, 0x40, 0xc3, 0x09, 0x06, + 0xbb, 0xd1, 0x71, 0x4b, 0x95, 0x3a, 0x94, 0x84, 0x8d, 0x80, 0xb4, 0xc1, 0x09, 0x21, 0x3d, 0x60, + 0x30, 0x0d, 0x0f, 0x22, 0xa7, 0x35, 0x6d, 0xef, 0x19, 0x71, 0x95, 0x57, 0x4e, 0xd2, 0xa4, 0x0c, + 0x96, 0xd2, 0xe4, 0x64, 0x74, 0x1f, 0x66, 0xa2, 0xcf, 0x83, 0x82, 0xd7, 0x71, 0xa9, 0x72, 0x97, + 0xbf, 0x85, 0x72, 0x81, 0x89, 0xbe, 0x43, 0xea, 0xcc, 0xcf, 0x0a, 0x8c, 0x8c, 0x47, 0x16, 0xcc, + 0x3f, 0xea, 0x78, 0xd4, 0xc9, 0x3b, 0xf5, 0x67, 0xc4, 0x6d, 0xe4, 0x0f, 0x29, 0x09, 0x94, 0xd7, + 0xb9, 0x88, 0xd4, 0x7e, 0x7f, 0xc8, 0x20, 0xfa, 0xb6, 0xc0, 0xe8, 0xdb, 0x0c, 0xa4, 0xe1, 0x34, + 0x91, 0x95, 0x92, 0x8a, 0x4f, 0x1e, 0x7b, 0x94, 0x28, 0xf7, 0x93, 0xcf, 0x55, 0xdb, 0x27, 0xfa, + 0x73, 0x8f, 0xed, 0x4e, 0x84, 0x91, 0x77, 0xc4, 0xf3, 0xfd, 0x4e, 0x9b, 0xf2, 0xae, 0x46, 0x79, + 0x3f, 0x79, 0x8c, 0x8f, 0x76, 0x44, 0xa0, 0x74, 0xde, 0x07, 0x49, 0x3b, 0x22, 0x91, 0xd1, 0x4d, + 0x18, 0xb7, 0xbc, 0xdd, 0x5d, 0xe2, 0x2b, 0x0f, 0xf9, 0xc6, 0xce, 0xf7, 0xba, 0xea, 0x4c, 0x78, + 0xd1, 0xb9, 0x5d, 0xc3, 0x21, 0x00, 0xfd, 0x1f, 0x80, 0xe5, 0xed, 0x96, 0x3b, 0xb4, 0xdd, 0xa1, + 0x81, 0xb2, 0xce, 0xef, 0xb3, 0x54, 0x5c, 0x5b, 0xde, 0xae, 0xee, 0x71, 0xa7, 0x86, 0x25, 0x20, + 0xeb, 0x6d, 0xd7, 0xc8, 0x76, 0x67, 0x57, 0x29, 0xf2, 0x38, 0xa5, 0xde, 0xb6, 0xc1, 0xcc, 0x1a, + 0x16, 0xee, 0xd5, 0x9f, 0x64, 0xa5, 0x1f, 0x92, 0xd1, 0x1c, 0x4c, 0x95, 0xca, 0x76, 0xad, 0x6a, + 0x1b, 0xd8, 0x36, 0xd7, 0x72, 0x67, 0xd0, 0x79, 0x40, 0xc5, 0x52, 0xd1, 0x2e, 0x1a, 0x96, 0x30, + 0xd6, 0x4c, 0xbb, 0xb0, 0x96, 0x03, 0x94, 0x83, 0x69, 0x6c, 0x4a, 0x96, 0x29, 0x66, 0xa9, 0x16, + 0x1f, 0xda, 0x26, 0xde, 0x14, 0x96, 0x73, 0x68, 0x19, 0xae, 0x54, 0x8b, 0x0f, 0x1f, 0x6d, 0x15, + 0x05, 0xa6, 0x66, 0x94, 0xd6, 0x6a, 0xd8, 0xdc, 0x2c, 0x3f, 0x36, 0x6b, 0x6b, 0x86, 0x6d, 0xe4, + 0x16, 0xd1, 0x3c, 0xcc, 0x54, 0x8d, 0xc7, 0x66, 0xad, 0x5a, 0x32, 0x2a, 0xd5, 0xf5, 0xb2, 0x9d, + 0x5b, 0x42, 0xd7, 0xe0, 0x2a, 0x13, 0x2e, 0x63, 0xb3, 0x16, 0x4d, 0xf0, 0x00, 0x97, 0x37, 0xfb, + 0x10, 0x15, 0x5d, 0x84, 0xc5, 0xc1, 0xae, 0x65, 0xc6, 0x4e, 0x4d, 0x69, 0xe0, 0xc2, 0x7a, 0x31, + 0x9a, 0x73, 0x05, 0xdd, 0x86, 0x57, 0x8e, 0x8b, 0x8a, 0x8f, 0xab, 0x76, 0xb9, 0x52, 0x33, 0x1e, + 0x9a, 0x25, 0x3b, 0x77, 0x13, 0x5d, 0x85, 0x8b, 0x79, 0xcb, 0x28, 0x6c, 0xac, 0x97, 0x2d, 0xb3, + 0x56, 0x31, 0x4d, 0x5c, 0xab, 0x94, 0xb1, 0x5d, 0xb3, 0x9f, 0xd6, 0xf0, 0xd3, 0x5c, 0x03, 0xa9, + 0x70, 0x79, 0xab, 0x34, 0x1c, 0x40, 0xd0, 0x25, 0x58, 0x5c, 0x33, 0x2d, 0xe3, 0x83, 0x94, 0xeb, + 0x45, 0x06, 0x5d, 0x81, 0x0b, 0x5b, 0xa5, 0xc1, 0xde, 0xcf, 0x32, 0xab, 0x7f, 0x05, 0x18, 0x65, + 0x5f, 0x20, 0x48, 0x81, 0x73, 0xd1, 0xde, 0x96, 0x4b, 0x66, 0xed, 0x41, 0xd9, 0xb2, 0xca, 0x4f, + 0x4c, 0x9c, 0x3b, 0x13, 0xae, 0x26, 0xe5, 0xa9, 0x6d, 0x95, 0xec, 0xa2, 0x55, 0xb3, 0x71, 0xf1, + 0xe1, 0x43, 0x13, 0xf7, 0x77, 0x28, 0x83, 0x10, 0xcc, 0x46, 0x04, 0xcb, 0x34, 0xd6, 0x4c, 0x9c, + 0x1b, 0x41, 0x37, 0xe1, 0x46, 0xdc, 0x36, 0x8c, 0x9e, 0x95, 0xe9, 0x8f, 0xb6, 0xca, 0x78, 0x6b, + 0x33, 0x37, 0xca, 0x0e, 0x4d, 0x64, 0x33, 0x2c, 0x2b, 0x37, 0x86, 0xae, 0x83, 0x1a, 0x6d, 0xb1, + 0xb4, 0xbb, 0xb1, 0xc8, 0x01, 0xdd, 0x83, 0x37, 0x4e, 0x00, 0x0d, 0x8b, 0x62, 0x8a, 0xa5, 0x64, + 0x00, 0x37, 0x5c, 0xcf, 0x34, 0x7a, 0x1d, 0x5e, 0x1b, 0xea, 0x1e, 0x26, 0x3a, 0x83, 0x1e, 0x40, + 0x7e, 0x00, 0x4b, 0xac, 0x32, 0xb4, 0x88, 0x73, 0x19, 0x0a, 0x45, 0xd4, 0xf0, 0x10, 0x16, 0xb0, + 0x61, 0x17, 0xd6, 0x73, 0xb3, 0x68, 0x15, 0x5e, 0x1e, 0x7a, 0x1c, 0xe2, 0x9b, 0xd0, 0x40, 0x06, + 0xbc, 0x7b, 0x3a, 0xec, 0xb0, 0xb0, 0x09, 0x7a, 0x09, 0x96, 0x87, 0x4b, 0x84, 0x5b, 0xb2, 0x83, + 0xde, 0x81, 0x37, 0x4f, 0x42, 0x0d, 0x9b, 0x62, 0xf7, 0xf8, 0x29, 0xc2, 0x63, 0xb0, 0xc7, 0xee, + 0xde, 0x70, 0x14, 0x3b, 0x18, 0x4d, 0xf4, 0x3f, 0xa0, 0x0d, 0x3c, 0xec, 0xf1, 0x6d, 0x79, 0x91, + 0x41, 0xb7, 0xe0, 0x26, 0x36, 0x4a, 0x6b, 0xe5, 0xcd, 0xda, 0x29, 0xf0, 0x9f, 0x65, 0xd0, 0x7b, + 0xf0, 0xf6, 0xc9, 0xc0, 0x61, 0x0b, 0xfc, 0x3c, 0x83, 0x4c, 0x78, 0xff, 0xd4, 0xf3, 0x0d, 0x93, + 0xf9, 0x22, 0x83, 0xae, 0xc1, 0x95, 0xc1, 0xfc, 0x30, 0x0f, 0x5f, 0x66, 0xd0, 0x0a, 0x5c, 0x3f, + 0x76, 0xa6, 0x10, 0xf9, 0x55, 0x06, 0xbd, 0x05, 0x77, 0x8f, 0x83, 0x0c, 0x0b, 0xe3, 0x57, 0x19, + 0x74, 0x1f, 0xee, 0x9d, 0x62, 0x8e, 0x61, 0x02, 0xbf, 0x3e, 0x66, 0x1d, 0x61, 0xb2, 0xbf, 0x3e, + 0x79, 0x1d, 0x21, 0xf2, 0x37, 0x19, 0xb4, 0x04, 0x17, 0x07, 0x43, 0xd8, 0x99, 0xf8, 0x6d, 0x06, + 0xdd, 0x80, 0xe5, 0x63, 0x95, 0x18, 0xec, 0x77, 0x19, 0xa4, 0xc0, 0x42, 0xa9, 0x5c, 0x7b, 0x60, + 0x14, 0xad, 0xda, 0x93, 0xa2, 0xbd, 0x5e, 0xab, 0xda, 0xd8, 0xac, 0x56, 0x73, 0x3f, 0x1f, 0x61, + 0xa1, 0xc4, 0x3c, 0xa5, 0x72, 0xe8, 0xac, 0x3d, 0x28, 0xe3, 0x9a, 0x55, 0x7c, 0x6c, 0x96, 0x18, + 0xf2, 0xd3, 0x11, 0x34, 0x07, 0xc0, 0x60, 0x95, 0x72, 0xb1, 0x64, 0x57, 0x73, 0xdf, 0xcd, 0xa2, + 0x19, 0x98, 0x30, 0x9f, 0xda, 0x26, 0x2e, 0x19, 0x56, 0xee, 0x6f, 0xd9, 0xd5, 0x7d, 0x98, 0x88, + 0x7e, 0xe4, 0x40, 0xe3, 0x30, 0xb2, 0xf1, 0x38, 0x77, 0x06, 0x4d, 0xc2, 0x98, 0x65, 0x1a, 0x55, + 0x33, 0x97, 0x41, 0x0b, 0x30, 0x67, 0x5a, 0x66, 0xc1, 0x2e, 0x96, 0x4b, 0x35, 0xbc, 0x55, 0x2a, + 0xf1, 0xc7, 0x33, 0x07, 0xd3, 0x4f, 0xd8, 0xcd, 0x8f, 0x2c, 0x59, 0xb4, 0x08, 0xf3, 0x56, 0xb9, + 0xb0, 0x51, 0xc3, 0x46, 0xc1, 0xc4, 0x91, 0x79, 0x94, 0x01, 0xb9, 0x50, 0x64, 0x19, 0x5b, 0xcd, + 0xc3, 0xd9, 0xf0, 0x17, 0x12, 0x34, 0x05, 0x67, 0x37, 0x1e, 0xd7, 0xd6, 0x8d, 0xea, 0x7a, 0xee, + 0x4c, 0x1f, 0x69, 0x3e, 0xad, 0x14, 0x31, 0x9b, 0x19, 0x60, 0xfc, 0x68, 0xc2, 0x69, 0x98, 0x28, + 0x95, 0x6b, 0x85, 0x75, 0xb3, 0xb0, 0x91, 0xcb, 0xde, 0xb9, 0x0f, 0x93, 0xb6, 0xef, 0xb8, 0x41, + 0xdb, 0xf3, 0x29, 0xba, 0x23, 0x0f, 0x66, 0xc3, 0xdf, 0x69, 0xc3, 0xbf, 0x18, 0x5f, 0x9a, 0x3b, + 0x1a, 0x8b, 0x3f, 0x26, 0x6a, 0x67, 0x56, 0x32, 0xaf, 0x65, 0xf2, 0xe7, 0x5e, 0xfc, 0x69, 0xe9, + 0xcc, 0x8b, 0x6f, 0x96, 0x32, 0x5f, 0x7f, 0xb3, 0x94, 0xf9, 0xe3, 0x37, 0x4b, 0x99, 0x1f, 0xff, + 0x79, 0xe9, 0xcc, 0xf6, 0x38, 0xff, 0x8b, 0xf3, 0xdd, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x49, + 0xaa, 0x88, 0xde, 0xba, 0x1e, 0x00, 0x00, } diff --git a/functional/rpcpb/rpc.proto b/functional/rpcpb/rpc.proto index 359db161acb..cbbe1ece8c2 100644 --- a/functional/rpcpb/rpc.proto +++ b/functional/rpcpb/rpc.proto @@ -203,8 +203,8 @@ message Etcd { bool InitialCorruptCheck = 64 [(gogoproto.moretags) = "yaml:\"initial-corrupt-check\""]; string Logger = 71 [(gogoproto.moretags) = "yaml:\"logger\""]; - // LogOutput is the log file to store current etcd server logs. - repeated string LogOutput = 72 [(gogoproto.moretags) = "yaml:\"log-output\""]; + // LogOutputs is the log file to store current etcd server logs. + repeated string LogOutputs = 72 [(gogoproto.moretags) = "yaml:\"log-output\""]; bool Debug = 73 [(gogoproto.moretags) = "yaml:\"debug\""]; } From 0e4c94c052d90d7212ef3affe9546b413b4a2ec3 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:15:43 -0700 Subject: [PATCH 13/22] CHANGELOG: highlight "--log-outputs" flag Signed-off-by: Gyuho Lee --- CHANGELOG-3.1.md | 2 +- CHANGELOG-3.2.md | 16 ++++++++-------- CHANGELOG-3.3.md | 18 +++++++++--------- CHANGELOG-3.4.md | 49 ++++++++++++++++++++++++++++-------------------- CHANGELOG-3.5.md | 2 +- 5 files changed, 48 insertions(+), 39 deletions(-) diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index d0f74834ad6..a47ea7dec80 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -8,7 +8,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.1.13...v3.1.14) and - Add [`etcd_server_is_leader`](https://github.com/coreos/etcd/pull/9587) Prometheus metric. -### Added: `etcd` +### `etcd` - Add [`--initial-election-tick-advance`](https://github.com/coreos/etcd/pull/9591) flag to configure initial election tick fast-forward. - By default, `--initial-election-tick-advance=true`, then local member fast-forwards election ticks to speed up "initial" leader election trigger. diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index 0238473fd02..8b99f068ddb 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -17,7 +17,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.2.18...v3.2.19) and - However, a certificate whose SAN field does [not include any domain names but only IP addresses](https://github.com/coreos/etcd/issues/9541) would request `*tls.ClientHelloInfo` with an empty `ServerName` field, thus failing to trigger the TLS reload on initial TLS handshake; this becomes a problem when expired certificates need to be replaced online. - Now, `(*tls.Config).Certificates` is created empty on initial TLS client handshake, first to trigger `(*tls.Config).GetCertificate`, and then to populate rest of the certificates on every new TLS connection, even when client SNI is empty (e.g. cert only includes IPs). -### Added: `etcd` +### `etcd` - Add [`--initial-election-tick-advance`](https://github.com/coreos/etcd/pull/9591) flag to configure initial election tick fast-forward. - By default, `--initial-election-tick-advance=true`, then local member fast-forwards election ticks to speed up "initial" leader election trigger. @@ -153,7 +153,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.2.11...v3.2.12) and - Fix [error message of `Revision` compactor](https://github.com/coreos/etcd/pull/8999) in server-side. -### Added: `clientv3` +### `clientv3` - Add [`MaxCallSendMsgSize` and `MaxCallRecvMsgSize`](https://github.com/coreos/etcd/pull/9047) fields to [`clientv3.Config`](https://godoc.org/github.com/coreos/etcd/clientv3#Config). - Fix [exceeded response size limit error in client-side](https://github.com/coreos/etcd/issues/9043). @@ -299,7 +299,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.2.5...v3.2.6) and [ See [code changes](https://github.com/coreos/etcd/compare/v3.2.4...v3.2.5) and [v3.2 upgrade guide](https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_2.md) for any breaking changes. -### Added: v3 `etcdctl` +### v3 `etcdctl` - Return non-zero exit code on unhealthy `endpoint health`. @@ -457,7 +457,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Logging, monitoring - Server warns large snapshot operations. -### Added: `etcd` +### `etcd` - Add `--enable-v2` flag to enable v2 API server. - `--enable-v2=true` by default. @@ -472,14 +472,14 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - If compaction succeeds or requested revision has already been compacted, it resets period timer and removes used compacted revision from historical revision records (e.g. start next revision collect and compaction from previously collected revisions). - If compaction fails, it retries in 5 minutes. -### Added: `clientv3` +### `clientv3` - STM prefetching. - Add namespace feature. - Add `ErrOldCluster` with server version checking. - Translate `WithPrefix()` into `WithFromKey()` for empty key. -### Added: v3 `etcdctl` +### v3 `etcdctl` - Add `check perf` command. - Add `--from-key` flag to role grant-permission command. @@ -489,13 +489,13 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Allow snapshot over 512MB. -### Added: `grpc-proxy` +### `grpc-proxy` - Proxy endpoint discovery. - Namespaces. - Coalesce lease requests. -### Added: `gateway` +### `gateway` - Support [DNS SRV priority](https://github.com/coreos/etcd/pull/7882) for [smart proxy routing](https://github.com/coreos/etcd/issues/4378). diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md index 6011895aead..c1d4b3e6aa0 100644 --- a/CHANGELOG-3.3.md +++ b/CHANGELOG-3.3.md @@ -17,7 +17,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.3.3...v3.3.4) and [ - However, a certificate whose SAN field does [not include any domain names but only IP addresses](https://github.com/coreos/etcd/issues/9541) would request `*tls.ClientHelloInfo` with an empty `ServerName` field, thus failing to trigger the TLS reload on initial TLS handshake; this becomes a problem when expired certificates need to be replaced online. - Now, `(*tls.Config).Certificates` is created empty on initial TLS client handshake, first to trigger `(*tls.Config).GetCertificate`, and then to populate rest of the certificates on every new TLS connection, even when client SNI is empty (e.g. cert only includes IPs). -### Added: `etcd` +### `etcd` - Add [`--initial-election-tick-advance`](https://github.com/coreos/etcd/pull/9591) flag to configure initial election tick fast-forward. - By default, `--initial-election-tick-advance=true`, then local member fast-forwards election ticks to speed up "initial" leader election trigger. @@ -29,7 +29,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.3.3...v3.3.4) and [ - If single-node, it advances ticks regardless. - Address [disruptive rejoining follower node](https://github.com/coreos/etcd/issues/9333). -### Added: `embed` +### Package `embed` - Add [`embed.Config.InitialElectionTickAdvance`](https://github.com/coreos/etcd/pull/9591) to enable/disable initial election tick fast-forward. - `embed.NewConfig()` would return `*embed.Config` with `InitialElectionTickAdvance` as true by default. @@ -205,7 +205,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Provide user's role on [auth permission error](https://github.com/coreos/etcd/pull/8164). - Fix [auth store panic with disabled token](https://github.com/coreos/etcd/pull/8695). -### Added: `etcd` +### `etcd` - Add [`--experimental-initial-corrupt-check`](https://github.com/coreos/etcd/pull/8554) flag to [check cluster database hashes before serving client/peer traffic](https://github.com/coreos/etcd/issues/8313). - `--experimental-initial-corrupt-check=false` by default. @@ -253,7 +253,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Address [error on shadowed environment variables](https://github.com/coreos/etcd/issues/8380). - etcd v3.4 will exit on this error. -### Added: API +### API - Support [ranges in transaction comparisons](https://github.com/coreos/etcd/pull/8025) for [disconnected linearized reads](https://github.com/coreos/etcd/issues/7924). - Add [nested transactions](https://github.com/coreos/etcd/pull/8102) to extend [proxy use cases](https://github.com/coreos/etcd/issues/7857). @@ -261,7 +261,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Add [lease list](https://github.com/coreos/etcd/pull/8358). - Add [hash by revision](https://github.com/coreos/etcd/pull/8263) for [better corruption checking against boltdb](https://github.com/coreos/etcd/issues/8016). -### Added: `clientv3` +### `clientv3` - Add [health balancer](https://github.com/coreos/etcd/pull/8545) to fix [watch API hangs](https://github.com/coreos/etcd/issues/7247), improve [endpoint switch under network faults](https://github.com/coreos/etcd/issues/7941). - [Refactor balancer](https://github.com/coreos/etcd/pull/8840) and add [client-side keepalive pings](https://github.com/coreos/etcd/pull/8199) to handle [network partitions](https://github.com/coreos/etcd/issues/8711). @@ -285,7 +285,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Fix [`concurrency/stm` `Put` with serializable snapshot](https://github.com/coreos/etcd/pull/8439). - Use store revision from first fetch to resolve write conflicts instead of modified revision. -### Added: v3 `etcdctl` +### v3 `etcdctl` - Add [`--discovery-srv`](https://github.com/coreos/etcd/pull/8462) flag. - Add [`--keepalive-time`, `--keepalive-timeout`](https://github.com/coreos/etcd/pull/8663) flags. @@ -311,11 +311,11 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Handle [empty key permission](https://github.com/coreos/etcd/pull/8514) in `etcdctl`. -### Added: v2 `etcdctl` +### v2 `etcdctl` - Add [`backup --with-v3`](https://github.com/coreos/etcd/pull/8479) flag. -### Added: `grpc-proxy` +### `grpc-proxy` - Add [`grpc-proxy start --experimental-leasing-prefix`](https://github.com/coreos/etcd/pull/8341) flag. - For disconnected linearized reads. @@ -336,7 +336,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Fix [KV API `PrevKv` flag handling](https://github.com/coreos/etcd/pull/8366). - Fix [KV API `KeysOnly` flag handling](https://github.com/coreos/etcd/pull/8552). -### Added: gRPC gateway +### gRPC gateway - Replace [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) endpoint `/v3alpha` with [`/v3beta`](https://github.com/coreos/etcd/pull/8880). - To deprecate [`/v3alpha`](https://github.com/coreos/etcd/issues/8125) in v3.4. diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 18db2ce635a..1d58009c3df 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -58,10 +58,12 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.3.0...v3.4.0) and [ - Change [`embed.Config.CorsInfo` in `*cors.CORSInfo` type to `embed.Config.CORS` in `map[string]struct{}` type](https://github.com/coreos/etcd/pull/9490). - Remove [`embed.Config.SetupLogging`](https://github.com/coreos/etcd/pull/9572). - Now logger is set up automatically based on [`embed.Config.Logger`, `embed.Config.LogOutputs`, `embed.Config.Debug` fields](https://github.com/coreos/etcd/pull/9572). +- Rename [`etcd --log-output` to `--log-outputs`](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. + - **`etcd --log-output`** will be deprecated in v3.5. - Rename [**`embed.Config.LogOutput`** to **`embed.Config.LogOutputs`**](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. - Change [**`embed.Config.LogOutputs`** type from `string` to `[]string`](https://github.com/coreos/etcd/pull/9579) to support multiple log outputs. - - Now that `--log-output` accepts multiple writers, etcd configuration YAML file `log-output` field must be changed to `[]string` type. - - Previously, `--config-file etcd.config.yaml` can have `log-output: default` field, now must be `log-output: [default]`. + - Now that `--log-outputs` accepts multiple writers, etcd configuration YAML file `log-outputs` field must be changed to `[]string` type. + - Previously, `--config-file etcd.config.yaml` can have `log-outputs: default` field, now must be `log-outputs: [default]`. - Change v3 `etcdctl snapshot` exit codes with [`snapshot` package](https://github.com/coreos/etcd/pull/9118/commits/df689f4280e1cce4b9d61300be13ca604d41670a). - Exit on error with exit code 1 (no more exit code 5 or 6 on `snapshot save/restore` commands). - Migrate dependency management tool from `glide` to [`golang/dep`](https://github.com/coreos/etcd/pull/9155). @@ -79,10 +81,10 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.3.0...v3.4.0) and [ - Previously, `Repair(dirpath string) bool`, now `Repair(lg *zap.Logger, dirpath string) bool`. - Previously, `Create(dirpath string, metadata []byte) (*WAL, error)`, now `Create(lg *zap.Logger, dirpath string, metadata []byte) (*WAL, error)`. - Remove [`pkg/cors` package](https://github.com/coreos/etcd/pull/9490). -- Move `"github.com/coreos/etcd/snap"` to [`"github.com/coreos/etcd/raftsnap"`](https://github.com/coreos/etcd/pull/9211). -- Move `"github.com/coreos/etcd/etcdserver/auth"` to [`"github.com/coreos/etcd/etcdserver/v2auth"`](https://github.com/coreos/etcd/pull/9275). -- Move `"github.com/coreos/etcd/error"` to [`"github.com/coreos/etcd/etcdserver/v2error"`](https://github.com/coreos/etcd/pull/9274). -- Move `"github.com/coreos/etcd/store"` to [`"github.com/coreos/etcd/etcdserver/v2store"`](https://github.com/coreos/etcd/pull/9274). +- Move internal package `"github.com/coreos/etcd/snap"` to [`"github.com/coreos/etcd/raftsnap"`](https://github.com/coreos/etcd/pull/9211). +- Move internal package `"github.com/coreos/etcd/etcdserver/auth"` to [`"github.com/coreos/etcd/etcdserver/v2auth"`](https://github.com/coreos/etcd/pull/9275). +- Move internal package `"github.com/coreos/etcd/error"` to [`"github.com/coreos/etcd/etcdserver/v2error"`](https://github.com/coreos/etcd/pull/9274). +- Move internal package `"github.com/coreos/etcd/store"` to [`"github.com/coreos/etcd/etcdserver/v2store"`](https://github.com/coreos/etcd/pull/9274). ### Dependency @@ -124,7 +126,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - However, a certificate whose SAN field does [not include any domain names but only IP addresses](https://github.com/coreos/etcd/issues/9541) would request `*tls.ClientHelloInfo` with an empty `ServerName` field, thus failing to trigger the TLS reload on initial TLS handshake; this becomes a problem when expired certificates need to be replaced online. - Now, `(*tls.Config).Certificates` is created empty on initial TLS client handshake, first to trigger `(*tls.Config).GetCertificate`, and then to populate rest of the certificates on every new TLS connection, even when client SNI is empty (e.g. cert only includes IPs). -### Added: `etcd` +### `etcd` - Add [`--initial-election-tick-advance`](https://github.com/coreos/etcd/pull/9591) flag to configure initial election tick fast-forward. - By default, `--initial-election-tick-advance=true`, then local member fast-forwards election ticks to speed up "initial" leader election trigger. @@ -154,25 +156,32 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - If `--discovery-srv-name="foo"`, then query `_etcd-server-ssl-foo._tcp.[YOUR_HOST]` and `_etcd-server-foo._tcp.[YOUR_HOST]`. - Useful for operating multiple etcd clusters under the same domain. - Support [`etcd --cors`](https://github.com/coreos/etcd/pull/9490) in v3 HTTP requests (gRPC gateway). +- Rename [`etcd --log-output` to `--log-outputs`](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. + - **`etcd --log-output`** will be deprecated in v3.5. - Add [`--logger`](https://github.com/coreos/etcd/pull/9572) flag to support [structured logger and logging to file](https://github.com/coreos/etcd/issues/9438) in server-side. - - e.g. `--logger=capnslog --log-output=default` is the default setting and same as previous etcd server logging format. - - e.g. `--logger=zap --log-output=default` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr` (detect systemd journald TODO). - - e.g. If etcd parent process ID (`ppid`) is 1 (e.g. run with systemd), `--logger=zap --log-output=default` will [redirect server logs to local systemd journal](https://github.com/coreos/etcd/pull/9624) in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig). And if write to journald fails, it writes to `os.Stderr` as a fallback. - - e.g. `--logger=zap --log-output=stderr` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr`. Use this to override journald log redirects. - - e.g. `--logger=zap --log-output=stdout` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stdout` Use this to override journald log redirects. - - e.g. `--logger=zap --log-output=a.log` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to the specified file `a.log`. - - e.g. `--logger=zap --log-output=a.log,b.log,c.log,stdout` [writes server logs to multiple files `a.log`, `b.log` and `c.log` at the same time](https://github.com/coreos/etcd/pull/9579) and outputs to `stdout`, in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig). - - e.g. `--logger=zap --log-output=/dev/null` will discard all server logs. + - e.g. `--logger=capnslog --log-outputs=default` is the default setting and same as previous etcd server logging format. + - e.g. `--logger=zap --log-outputs=default` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr`. + - e.g. If etcd parent process ID (`ppid`) is 1 (e.g. run with systemd), `--logger=zap --log-outputs=default` will [redirect server logs to local systemd journal](https://github.com/coreos/etcd/pull/9624) in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig). And if write to journald fails, it writes to `os.Stderr` as a fallback. + - e.g. `--logger=zap --log-outputs=stderr` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stderr`. Use this to override journald log redirects. + - e.g. `--logger=zap --log-outputs=stdout` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to `os.Stdout` Use this to override journald log redirects. + - e.g. `--logger=zap --log-outputs=a.log` will log server operations in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig) and writes logs to the specified file `a.log`. + - e.g. `--logger=zap --log-outputs=a.log,b.log,c.log,stdout` [writes server logs to multiple files `a.log`, `b.log` and `c.log` at the same time](https://github.com/coreos/etcd/pull/9579) and outputs to `stdout`, in [JSON-encoded format](https://godoc.org/go.uber.org/zap#NewProductionEncoderConfig). + - e.g. `--logger=zap --log-outputs=/dev/null` will discard all server logs. -### Added: `embed` +### Package `embed` - Add [`embed.Config.InitialElectionTickAdvance`](https://github.com/coreos/etcd/pull/9591) to enable/disable initial election tick fast-forward. - `embed.NewConfig()` would return `*embed.Config` with `InitialElectionTickAdvance` as true by default. - Add [`embed.Config.Logger`](https://github.com/coreos/etcd/pull/9518) to support [structured logger `zap`](https://github.com/uber-go/zap) in server-side. - Define [`embed.CompactorModePeriodic`](https://godoc.org/github.com/coreos/etcd/embed#pkg-variables) for `compactor.ModePeriodic`. - Define [`embed.CompactorModeRevision`](https://godoc.org/github.com/coreos/etcd/embed#pkg-variables) for `compactor.ModeRevision`. +- Change [`embed.Config.CorsInfo` in `*cors.CORSInfo` type to `embed.Config.CORS` in `map[string]struct{}` type](https://github.com/coreos/etcd/pull/9490). +- Remove [`embed.Config.SetupLogging`](https://github.com/coreos/etcd/pull/9572). + - Now logger is set up automatically based on [`embed.Config.Logger`, `embed.Config.LogOutputs`, `embed.Config.Debug` fields](https://github.com/coreos/etcd/pull/9572). +- Rename [**`embed.Config.LogOutput`** to **`embed.Config.LogOutputs`**](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. +- Change [**`embed.Config.LogOutputs`** type from `string` to `[]string`](https://github.com/coreos/etcd/pull/9579) to support multiple log outputs. -### Added: API +### API - Add [`snapshot`](https://github.com/coreos/etcd/pull/9118) package for snapshot restore/save operations (see [`godoc.org/github.com/etcd/snapshot`](https://godoc.org/github.com/coreos/etcd/snapshot) for more). - Add [`watch_id` field to `etcdserverpb.WatchCreateRequest`](https://github.com/coreos/etcd/pull/9065), allow user-provided watch ID to `mvcc`. @@ -182,7 +191,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - e.g. `"etcdserver: no leader", "NOSPACE", "CORRUPT"` - Add [`dbSizeInUse` field to `etcdserverpb.StatusResponse`](https://github.com/coreos/etcd/pull/9256) for actual DB size after compaction. -### Added: v3 `etcdctl` +### v3 `etcdctl` - Add [`check datascale`](https://github.com/coreos/etcd/pull/9185) command. - Add [`check datascale --auto-compact, --auto-defrag`](https://github.com/coreos/etcd/pull/9351) flags. @@ -193,7 +202,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Add [`endpoint health --write-out` support](https://github.com/coreos/etcd/pull/9540). - Previously, [`endpoint health --write-out json` did not work](https://github.com/coreos/etcd/issues/9532). -### Added: gRPC gateway +### gRPC gateway - Replace [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) endpoint `/v3beta` with [`/v3`](https://github.com/coreos/etcd/pull/9298). - Deprecated [`/v3alpha`](https://github.com/coreos/etcd/pull/9298). @@ -236,5 +245,5 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g ### Go - Require *Go 1.10+*. -- Compile with [*Go 1.10*](https://golang.org/doc/devel/release.html#go1.10). +- Compile with [*Go 1.10.1*](https://golang.org/doc/devel/release.html#go1.10). diff --git a/CHANGELOG-3.5.md b/CHANGELOG-3.5.md index 64540dc0f77..e25d1c02cda 100644 --- a/CHANGELOG-3.5.md +++ b/CHANGELOG-3.5.md @@ -10,7 +10,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.4.0...v3.5.0) and [ - Deprecated [`/v3beta`](https://github.com/coreos/etcd/pull/9298). - `curl -L http://localhost:2379/v3beta/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` does work in v3.5. Use `curl -L http://localhost:2379/v3/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` instead. -### Added: gRPC gateway +### gRPC gateway - [gRPC gateway](https://github.com/grpc-ecosystem/grpc-gateway) only supports [`/v3`](TODO) endpoint. - Deprecated [`/v3beta`](https://github.com/coreos/etcd/pull/9298). From 22609a65b52b3cb5c35c24d2aa30e73b782b58a2 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:17:42 -0700 Subject: [PATCH 14/22] Documentation/upgrades: highlight "--log-outputs" Signed-off-by: Gyuho Lee --- Documentation/upgrades/upgrade_3_4.md | 30 +++++- Documentation/upgrades/upgrade_3_5.md | 149 ++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 Documentation/upgrades/upgrade_3_5.md diff --git a/Documentation/upgrades/upgrade_3_4.md b/Documentation/upgrades/upgrade_3_4.md index 988402cb79e..08d219f1219 100644 --- a/Documentation/upgrades/upgrade_3_4.md +++ b/Documentation/upgrades/upgrade_3_4.md @@ -26,6 +26,15 @@ Highlighted breaking changes in 3.4. +etcd --peer-trusted-ca-file ca-peer.crt ``` +Rename [`etcd --log-output` to `--log-outputs`](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. + +**`etcd --log-output`** will be deprecated in v3.5. + +```diff +-etcd --log-output stderr ++etcd --log-outputs stderr,a.log +``` + #### Change in `pkg/transport` Deprecated `pkg/transport.TLSInfo.CAFile` field. @@ -89,14 +98,31 @@ cfg := &embed.Config{Debug: false} +cfg.LogOutputs = []string{"stderr"} ``` +#### Change in `etcd --log-output` (now `--log-outputs`) + +Rename [`etcd --log-output` to `--log-outputs`](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. + +**`etcd --log-output`** will be deprecated in v3.5. + +```diff +-etcd --log-output stderr ++etcd --log-outputs stderr,a.log +``` + +```diff + # Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd. +-log-output: [default] ++log-outputs: [default] +``` + #### Change in `etcd --config-file` -Now that `log-output` accepts multiple writers, etcd configuration YAML file `log-output` field must be changed to `[]string` type as below: +Now that `log-outputs` (old field name `log-output`) accepts multiple writers, etcd configuration YAML file `log-outputs` field must be changed to `[]string` type as below: ```diff # Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd. -log-output: default -+log-output: [default] ++log-outputs: [default] ``` ### Server upgrade checklists diff --git a/Documentation/upgrades/upgrade_3_5.md b/Documentation/upgrades/upgrade_3_5.md new file mode 100644 index 00000000000..cda28060271 --- /dev/null +++ b/Documentation/upgrades/upgrade_3_5.md @@ -0,0 +1,149 @@ +## Upgrade etcd from 3.4 to 3.5 + +In the general case, upgrading from etcd 3.4 to 3.5 can be a zero-downtime, rolling upgrade: + - one by one, stop the etcd v3.4 processes and replace them with etcd v3.5 processes + - after running all v3.5 processes, new features in v3.5 are available to the cluster + +Before [starting an upgrade](#upgrade-procedure), read through the rest of this guide to prepare. + +### Upgrade checklists + +**NOTE:** When [migrating from v2 with no v3 data](https://github.com/coreos/etcd/issues/9480), etcd server v3.2+ panics when etcd restores from existing snapshots but no v3 `ETCD_DATA_DIR/member/snap/db` file. This happens when the server had migrated from v2 with no previous v3 data. This also prevents accidental v3 data loss (e.g. `db` file might have been moved). etcd requires that post v3 migration can only happen with v3 data. Do not upgrade to newer v3 versions until v3.0 server contains v3 data. + +Highlighted breaking changes in 3.5. + +#### Deprecated in `etcd --log-output` + +Rename [`etcd --log-output` to `--log-outputs`](https://github.com/coreos/etcd/pull/9624) to support multiple log outputs. + +**`etcd --log-output`** is deprecated in v3.5. + +```diff +-$ etcd --log-output stderr ++$ etcd --log-outputs stderr,a.log +``` + +### Server upgrade checklists + +#### Upgrade requirements + +To upgrade an existing etcd deployment to 3.5, the running cluster must be 3.4 or greater. If it's before 3.4, please [upgrade to 3.4](upgrade_3_3.md) before upgrading to 3.5. + +Also, to ensure a smooth rolling upgrade, the running cluster must be healthy. Check the health of the cluster by using the `etcdctl endpoint health` command before proceeding. + +#### Preparation + +Before upgrading etcd, always test the services relying on etcd in a staging environment before deploying the upgrade to the production environment. + +Before beginning, [backup the etcd data](../op-guide/maintenance.md#snapshot-backup). Should something go wrong with the upgrade, it is possible to use this backup to [downgrade](#downgrade) back to existing etcd version. Please note that the `snapshot` command only backs up the v3 data. For v2 data, see [backing up v2 datastore](../v2/admin_guide.md#backing-up-the-datastore). + +#### Mixed versions + +While upgrading, an etcd cluster supports mixed versions of etcd members, and operates with the protocol of the lowest common version. The cluster is only considered upgraded once all of its members are upgraded to version 3.5. Internally, etcd members negotiate with each other to determine the overall cluster version, which controls the reported version and the supported features. + +#### Limitations + +Note: If the cluster only has v3 data and no v2 data, it is not subject to this limitation. + +If the cluster is serving a v2 data set larger than 50MB, each newly upgraded member may take up to two minutes to catch up with the existing cluster. Check the size of a recent snapshot to estimate the total data size. In other words, it is safest to wait for 2 minutes between upgrading each member. + +For a much larger total data size, 100MB or more , this one-time process might take even more time. Administrators of very large etcd clusters of this magnitude can feel free to contact the [etcd team][etcd-contact] before upgrading, and we'll be happy to provide advice on the procedure. + +#### Downgrade + +If all members have been upgraded to v3.5, the cluster will be upgraded to v3.5, and downgrade from this completed state is **not possible**. If any single member is still v3.4, however, the cluster and its operations remains "v3.4", and it is possible from this mixed cluster state to return to using a v3.4 etcd binary on all members. + +Please [backup the data directory](../op-guide/maintenance.md#snapshot-backup) of all etcd members to make downgrading the cluster possible even after it has been completely upgraded. + +### Upgrade procedure + +This example shows how to upgrade a 3-member v3.4 ectd cluster running on a local machine. + +#### 1. Check upgrade requirements + +Is the cluster healthy and running v3.4.x? + +``` +$ ETCDCTL_API=3 etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379 +localhost:2379 is healthy: successfully committed proposal: took = 6.600684ms +localhost:22379 is healthy: successfully committed proposal: took = 8.540064ms +localhost:32379 is healthy: successfully committed proposal: took = 8.763432ms + +$ curl http://localhost:2379/version +{"etcdserver":"3.4.0","etcdcluster":"3.4.0"} +``` + +#### 2. Stop the existing etcd process + +When each etcd process is stopped, expected errors will be logged by other cluster members. This is normal since a cluster member connection has been (temporarily) broken: + +``` +14:13:31.491746 I | raft: c89feb932daef420 [term 3] received MsgTimeoutNow from 6d4f535bae3ab960 and starts an election to get leadership. +14:13:31.491769 I | raft: c89feb932daef420 became candidate at term 4 +14:13:31.491788 I | raft: c89feb932daef420 received MsgVoteResp from c89feb932daef420 at term 4 +14:13:31.491797 I | raft: c89feb932daef420 [logterm: 3, index: 9] sent MsgVote request to 6d4f535bae3ab960 at term 4 +14:13:31.491805 I | raft: c89feb932daef420 [logterm: 3, index: 9] sent MsgVote request to 9eda174c7df8a033 at term 4 +14:13:31.491815 I | raft: raft.node: c89feb932daef420 lost leader 6d4f535bae3ab960 at term 4 +14:13:31.524084 I | raft: c89feb932daef420 received MsgVoteResp from 6d4f535bae3ab960 at term 4 +14:13:31.524108 I | raft: c89feb932daef420 [quorum:2] has received 2 MsgVoteResp votes and 0 vote rejections +14:13:31.524123 I | raft: c89feb932daef420 became leader at term 4 +14:13:31.524136 I | raft: raft.node: c89feb932daef420 elected leader c89feb932daef420 at term 4 +14:13:31.592650 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream MsgApp v2 reader) +14:13:31.592825 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream Message reader) +14:13:31.693275 E | rafthttp: failed to dial 6d4f535bae3ab960 on stream Message (dial tcp [::1]:2380: getsockopt: connection refused) +14:13:31.693289 I | rafthttp: peer 6d4f535bae3ab960 became inactive +14:13:31.936678 W | rafthttp: lost the TCP streaming connection with peer 6d4f535bae3ab960 (stream Message writer) +``` + +It's a good idea at this point to [backup the etcd data](../op-guide/maintenance.md#snapshot-backup) to provide a downgrade path should any problems occur: + +``` +$ etcdctl snapshot save backup.db +``` + +#### 3. Drop-in etcd v3.5 binary and start the new etcd process + +The new v3.5 etcd will publish its information to the cluster: + +``` +14:14:25.363225 I | etcdserver: published {Name:s1 ClientURLs:[http://localhost:2379]} to cluster a9ededbffcb1b1f1 +``` + +Verify that each member, and then the entire cluster, becomes healthy with the new v3.5 etcd binary: + +``` +$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379 +localhost:22379 is healthy: successfully committed proposal: took = 5.540129ms +localhost:32379 is healthy: successfully committed proposal: took = 7.321771ms +localhost:2379 is healthy: successfully committed proposal: took = 10.629901ms +``` + +Upgraded members will log warnings like the following until the entire cluster is upgraded. This is expected and will cease after all etcd cluster members are upgraded to v3.5: + +``` +14:15:17.071804 W | etcdserver: member c89feb932daef420 has a higher version 3.5.0 +14:15:21.073110 W | etcdserver: the local etcd version 3.4.0 is not up-to-date +14:15:21.073142 W | etcdserver: member 6d4f535bae3ab960 has a higher version 3.5.0 +14:15:21.073157 W | etcdserver: the local etcd version 3.4.0 is not up-to-date +14:15:21.073164 W | etcdserver: member c89feb932daef420 has a higher version 3.5.0 +``` + +#### 4. Repeat step 2 to step 3 for all other members + +#### 5. Finish + +When all members are upgraded, the cluster will report upgrading to 3.5 successfully: + +``` +14:15:54.536901 N | etcdserver/membership: updated the cluster version from 3.4 to 3.5 +14:15:54.537035 I | etcdserver/api: enabled capabilities for version 3.5 +``` + +``` +$ ETCDCTL_API=3 /etcdctl endpoint health --endpoints=localhost:2379,localhost:22379,localhost:32379 +localhost:2379 is healthy: successfully committed proposal: took = 2.312897ms +localhost:22379 is healthy: successfully committed proposal: took = 2.553476ms +localhost:32379 is healthy: successfully committed proposal: took = 2.517902ms +``` + +[etcd-contact]: https://groups.google.com/forum/#!forum/etcd-dev From 1539fddb274c242fa22ed78593f645af98fdfac6 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:21:30 -0700 Subject: [PATCH 15/22] etcd.conf.yml.sample: rename to "log-outputs" Signed-off-by: Gyuho Lee --- etcd.conf.yml.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etcd.conf.yml.sample b/etcd.conf.yml.sample index 9d1240b39a7..f7b80ecb418 100644 --- a/etcd.conf.yml.sample +++ b/etcd.conf.yml.sample @@ -132,7 +132,7 @@ debug: false log-package-levels: # Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd. -log-output: [default] +log-outputs: [default] # Force to create a new one member cluster. force-new-cluster: false From af5bc439b3b6bf76689ea7451f39d717cc93a9a9 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:38:11 -0700 Subject: [PATCH 16/22] embed,etcdmain: rename to "--log-outputs" flag Signed-off-by: Gyuho Lee --- embed/config.go | 49 +++++++++++++++++++++++++++++++++++++++------- etcdmain/config.go | 23 ++++++++++++++++------ etcdmain/help.go | 2 +- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/embed/config.go b/embed/config.go index 7ac19adf3da..73659e3aa60 100644 --- a/embed/config.go +++ b/embed/config.go @@ -16,6 +16,7 @@ package embed import ( "crypto/tls" + "errors" "fmt" "io/ioutil" "net" @@ -23,6 +24,7 @@ import ( "net/url" "os" "path/filepath" + "reflect" "sort" "strings" "sync" @@ -265,13 +267,17 @@ type Config struct { // 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"` + // LogOutputs is either: // - "default" as os.Stderr, // - "stderr" as os.Stderr, // - "stdout" as os.Stdout, // - file path to append server logs to. // It can be multiple when "Logger" is zap. - LogOutputs []string `json:"log-output"` + LogOutputs []string `json:"log-outputs"` // Debug is true, to enable debug level logging. Debug bool `json:"debug"` @@ -368,12 +374,13 @@ func NewConfig() *Config { PreVote: false, // TODO: enable by default in v3.5 - loggerMu: new(sync.RWMutex), - logger: nil, - Logger: "capnslog", - LogOutputs: []string{DefaultLogOutput}, - Debug: false, - LogPkgLevels: "", + loggerMu: new(sync.RWMutex), + logger: nil, + Logger: "capnslog", + DeprecatedLogOutput: []string{DefaultLogOutput}, + LogOutputs: []string{DefaultLogOutput}, + Debug: false, + LogPkgLevels: "", } cfg.InitialCluster = cfg.InitialClusterFromName(cfg.Name) return cfg @@ -406,6 +413,34 @@ var grpcLogOnce = new(sync.Once) // setupLogging initializes etcd logging. // Must be called after flag parsing or finishing configuring embed.Config. func (cfg *Config) setupLogging() error { + // handle "DeprecatedLogOutput" in v3.4 + // TODO: remove "DeprecatedLogOutput" in v3.5 + len1 := len(cfg.DeprecatedLogOutput) + len2 := len(cfg.LogOutputs) + if len1 != len2 { + switch { + case len1 > len2: // deprecate "log-output" flag is used + fmt.Fprintln(os.Stderr, "'--log-output' flag has been deprecated! Please use '--log-outputs'!") + cfg.LogOutputs = cfg.DeprecatedLogOutput + case len1 < len2: // "--log-outputs" flag has been set with multiple writers + cfg.DeprecatedLogOutput = []string{} + } + } else { + if len1 > 1 { + return errors.New("both '--log-output' and '--log-outputs' are set; only set '--log-outputs'") + } + if len1 < 1 { + return errors.New("either '--log-output' or '--log-outputs' flag must be set") + } + if reflect.DeepEqual(cfg.DeprecatedLogOutput, cfg.LogOutputs) && cfg.DeprecatedLogOutput[0] != DefaultLogOutput { + 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.Fprintln(os.Stderr, "Please use '--log-outputs' flag") + } + } + switch cfg.Logger { case "capnslog": // TODO: deprecate this in v3.5 cfg.ClientTLSInfo.HandshakeFailure = logTLSHandshakeFailure diff --git a/etcdmain/config.go b/etcdmain/config.go index 8d152a08512..5c2bd7c044f 100644 --- a/etcdmain/config.go +++ b/etcdmain/config.go @@ -218,7 +218,8 @@ func newConfig() *config { // logging fs.StringVar(&cfg.ec.Logger, "logger", "capnslog", "Specify 'zap' for structured logging or 'capnslog'.") - fs.Var(flags.NewUniqueStringsValue(embed.DefaultLogOutput), "log-output", "Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd, or list of comma separated output targets.") + fs.Var(flags.NewUniqueStringsValue(embed.DefaultLogOutput), "log-output", "DEPRECATED: 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').") @@ -306,13 +307,23 @@ func (cfg *config) configFromCmdLine() error { cfg.ec.CORS = flags.UniqueURLsMapFromFlag(cfg.cf.flagSet, "cors") cfg.ec.HostWhitelist = flags.UniqueStringsMapFromFlag(cfg.cf.flagSet, "host-whitelist") - outputs := flags.UniqueStringsMapFromFlag(cfg.cf.flagSet, "log-output") - oss := make([]string, 0, len(outputs)) + + // TODO: remove this in v3.5 + output := flags.UniqueStringsMapFromFlag(cfg.cf.flagSet, "log-output") + oss1 := make([]string, 0, len(output)) + for v := range output { + oss1 = append(oss1, v) + } + sort.Strings(oss1) + cfg.ec.DeprecatedLogOutput = oss1 + + outputs := flags.UniqueStringsMapFromFlag(cfg.cf.flagSet, "log-outputs") + oss2 := make([]string, 0, len(outputs)) for v := range outputs { - oss = append(oss, v) + oss2 = append(oss2, v) } - sort.Strings(oss) - cfg.ec.LogOutputs = oss + sort.Strings(oss2) + cfg.ec.LogOutputs = oss2 cfg.ec.ClusterState = cfg.cf.clusterState.String() cfg.cp.Fallback = cfg.cf.fallback.String() diff --git a/etcdmain/help.go b/etcdmain/help.go index 95cff0b8a53..d9521fadbe7 100644 --- a/etcdmain/help.go +++ b/etcdmain/help.go @@ -160,7 +160,7 @@ Profiling: Logging: --logger 'capnslog' Specify 'zap' for structured logging or 'capnslog'. - --log-output 'default' + --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. From a6c30eab965afd988806247a75f15eb206451028 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:42:05 -0700 Subject: [PATCH 17/22] functional: rename to "log-outputs" Signed-off-by: Gyuho Lee --- functional/rpcpb/etcd_config_test.go | 2 +- functional/rpcpb/rpc.pb.go | 360 +++++++++++------------ functional/rpcpb/rpc.proto | 2 +- functional/tester/cluster_read_config.go | 6 +- functional/tester/cluster_test.go | 6 +- 5 files changed, 188 insertions(+), 188 deletions(-) diff --git a/functional/rpcpb/etcd_config_test.go b/functional/rpcpb/etcd_config_test.go index 6785bdd7682..337b31353fc 100644 --- a/functional/rpcpb/etcd_config_test.go +++ b/functional/rpcpb/etcd_config_test.go @@ -84,7 +84,7 @@ func TestEtcd(t *testing.T) { "--pre-vote=true", "--experimental-initial-corrupt-check=true", "--logger=zap", - "--log-output=/tmp/etcd-functional-1/etcd.log", + "--log-outputs=/tmp/etcd-functional-1/etcd.log", "--debug=true", } fs := e.Flags() diff --git a/functional/rpcpb/rpc.pb.go b/functional/rpcpb/rpc.pb.go index 8f1d8731cd5..43b92d465ae 100644 --- a/functional/rpcpb/rpc.pb.go +++ b/functional/rpcpb/rpc.pb.go @@ -761,7 +761,7 @@ type Etcd struct { InitialCorruptCheck bool `protobuf:"varint,64,opt,name=InitialCorruptCheck,proto3" json:"InitialCorruptCheck,omitempty" yaml:"initial-corrupt-check"` Logger string `protobuf:"bytes,71,opt,name=Logger,proto3" json:"Logger,omitempty" yaml:"logger"` // LogOutputs is the log file to store current etcd server logs. - LogOutputs []string `protobuf:"bytes,72,rep,name=LogOutputs" json:"LogOutputs,omitempty" yaml:"log-output"` + LogOutputs []string `protobuf:"bytes,72,rep,name=LogOutputs" json:"LogOutputs,omitempty" yaml:"log-outputs"` Debug bool `protobuf:"varint,73,opt,name=Debug,proto3" json:"Debug,omitempty" yaml:"debug"` } @@ -5021,184 +5021,184 @@ var ( func init() { proto.RegisterFile("rpcpb/rpc.proto", fileDescriptorRpc) } var fileDescriptorRpc = []byte{ - // 2855 bytes of a gzipped FileDescriptorProto + // 2854 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x59, 0xcb, 0x77, 0xdb, 0xc6, - 0xd5, 0x37, 0x45, 0x49, 0x96, 0xae, 0x5e, 0xd4, 0xc8, 0xb2, 0xe1, 0x97, 0x20, 0xc3, 0x71, 0x3e, - 0x59, 0x09, 0xec, 0x7c, 0x76, 0xbe, 0x3c, 0x9c, 0x2f, 0x71, 0x40, 0x0a, 0xb6, 0x58, 0x41, 0x24, - 0x3d, 0x84, 0x6c, 0x67, 0xc5, 0x03, 0x91, 0x23, 0x89, 0xc7, 0x14, 0xc0, 0x00, 0x43, 0x47, 0xca, - 0xb6, 0x8b, 0x6e, 0xdb, 0xf4, 0x71, 0xda, 0x73, 0xba, 0xea, 0xba, 0x69, 0xff, 0x0d, 0xe7, 0xd5, - 0xa6, 0xed, 0xaa, 0x5d, 0xf0, 0xb4, 0xe9, 0xa6, 0xab, 0x2e, 0x78, 0xfa, 0x5e, 0xf5, 0xcc, 0x0c, - 0x20, 0x0e, 0x00, 0x52, 0xd2, 0xca, 0x9e, 0x7b, 0x7f, 0xbf, 0xdf, 0xdc, 0x99, 0x3b, 0x33, 0xf7, - 0x82, 0x82, 0x39, 0xbf, 0x5d, 0x6f, 0x6f, 0xdf, 0xf6, 0xdb, 0xf5, 0x5b, 0x6d, 0xdf, 0xa3, 0x1e, - 0x1a, 0xe3, 0x86, 0x4b, 0xfa, 0x6e, 0x93, 0xee, 0x75, 0xb6, 0x6f, 0xd5, 0xbd, 0xfd, 0xdb, 0xbb, - 0xde, 0xae, 0x77, 0x9b, 0x7b, 0xb7, 0x3b, 0x3b, 0x7c, 0xc4, 0x07, 0xfc, 0x7f, 0x82, 0xa5, 0x7d, - 0x27, 0x03, 0x67, 0x31, 0xf9, 0xb0, 0x43, 0x02, 0x8a, 0x6e, 0xc1, 0x64, 0xb9, 0x4d, 0x7c, 0x87, - 0x36, 0x3d, 0x57, 0xc9, 0x2c, 0x67, 0x56, 0x66, 0xef, 0xe4, 0x6e, 0x71, 0xd5, 0x5b, 0x47, 0x76, - 0xdc, 0x87, 0xa0, 0x1b, 0x30, 0xbe, 0x49, 0xf6, 0xb7, 0x89, 0xaf, 0x8c, 0x2c, 0x67, 0x56, 0xa6, - 0xee, 0xcc, 0x84, 0x60, 0x61, 0xc4, 0xa1, 0x93, 0xc1, 0x6c, 0x12, 0x50, 0xe2, 0x2b, 0xd9, 0x18, - 0x4c, 0x18, 0x71, 0xe8, 0xd4, 0xfe, 0x32, 0x02, 0xd3, 0x55, 0xd7, 0x69, 0x07, 0x7b, 0x1e, 0x2d, - 0xba, 0x3b, 0x1e, 0x5a, 0x02, 0x10, 0x0a, 0x25, 0x67, 0x9f, 0xf0, 0x78, 0x26, 0xb1, 0x64, 0x41, - 0xab, 0x90, 0x13, 0xa3, 0x42, 0xab, 0x49, 0x5c, 0xba, 0x85, 0xad, 0x40, 0x19, 0x59, 0xce, 0xae, - 0x4c, 0xe2, 0x94, 0x1d, 0x69, 0x7d, 0xed, 0x8a, 0x43, 0xf7, 0x78, 0x24, 0x93, 0x38, 0x66, 0x63, - 0x7a, 0xd1, 0xf8, 0x41, 0xb3, 0x45, 0xaa, 0xcd, 0x8f, 0x89, 0x32, 0xca, 0x71, 0x29, 0x3b, 0x7a, - 0x15, 0xe6, 0x23, 0x9b, 0xed, 0x51, 0xa7, 0xc5, 0xc1, 0x63, 0x1c, 0x9c, 0x76, 0xc8, 0xca, 0xdc, - 0xb8, 0x41, 0x0e, 0x95, 0xf1, 0xe5, 0xcc, 0x4a, 0x16, 0xa7, 0xec, 0x72, 0xa4, 0xeb, 0x4e, 0xb0, - 0xa7, 0x9c, 0xe5, 0xb8, 0x98, 0x4d, 0xd6, 0xc3, 0xe4, 0x79, 0x33, 0x60, 0xf9, 0x9a, 0x88, 0xeb, - 0x45, 0x76, 0x84, 0x60, 0xd4, 0xf6, 0xbc, 0x67, 0xca, 0x24, 0x0f, 0x8e, 0xff, 0x5f, 0xfb, 0x69, - 0x06, 0x26, 0x30, 0x09, 0xda, 0x9e, 0x1b, 0x10, 0xa4, 0xc0, 0xd9, 0x6a, 0xa7, 0x5e, 0x27, 0x41, - 0xc0, 0xf7, 0x78, 0x02, 0x47, 0x43, 0x74, 0x1e, 0xc6, 0xab, 0xd4, 0xa1, 0x9d, 0x80, 0xe7, 0x77, - 0x12, 0x87, 0x23, 0x29, 0xef, 0xd9, 0xe3, 0xf2, 0xfe, 0x66, 0x3c, 0x9f, 0x7c, 0x2f, 0xa7, 0xee, - 0x2c, 0x84, 0x60, 0xd9, 0x85, 0x63, 0x40, 0xed, 0x93, 0xe9, 0x68, 0x02, 0xf4, 0x1a, 0x4c, 0x98, - 0xb4, 0xde, 0x30, 0x0f, 0x48, 0x5d, 0x9c, 0x80, 0xfc, 0xb9, 0x5e, 0x57, 0xcd, 0x1d, 0x3a, 0xfb, - 0xad, 0x7b, 0x1a, 0xa1, 0xf5, 0x86, 0x4e, 0x0e, 0x48, 0x5d, 0xc3, 0x47, 0x28, 0x74, 0x17, 0x26, - 0x8d, 0x5d, 0xe2, 0x52, 0xa3, 0xd1, 0xf0, 0x95, 0x29, 0x4e, 0x59, 0xec, 0x75, 0xd5, 0x79, 0x41, - 0x71, 0x98, 0x4b, 0x77, 0x1a, 0x0d, 0x5f, 0xc3, 0x7d, 0x1c, 0xb2, 0x60, 0xfe, 0x81, 0xd3, 0x6c, - 0xb5, 0xbd, 0xa6, 0x4b, 0xd7, 0x6d, 0xbb, 0xc2, 0xc9, 0xd3, 0x9c, 0xbc, 0xd4, 0xeb, 0xaa, 0x97, - 0x04, 0x79, 0x27, 0x82, 0xe8, 0x7b, 0x94, 0xb6, 0x43, 0x95, 0x34, 0x11, 0xe9, 0x70, 0x36, 0xef, - 0x04, 0x64, 0xad, 0xe9, 0x2b, 0x84, 0x6b, 0x2c, 0xf4, 0xba, 0xea, 0x9c, 0xd0, 0xd8, 0x76, 0x02, - 0xa2, 0x37, 0x9a, 0xbe, 0x86, 0x23, 0x0c, 0x7a, 0x08, 0x73, 0x2c, 0x7a, 0x71, 0x5a, 0x2b, 0xbe, - 0x77, 0x70, 0xa8, 0x7c, 0xc6, 0x33, 0x91, 0xbf, 0xd2, 0xeb, 0xaa, 0x8a, 0xb4, 0xd6, 0x3a, 0x87, - 0xe8, 0x6d, 0x86, 0xd1, 0x70, 0x92, 0x85, 0x0c, 0x98, 0x61, 0xa6, 0x0a, 0x21, 0xbe, 0x90, 0xf9, - 0x5c, 0xc8, 0x5c, 0xea, 0x75, 0xd5, 0xf3, 0x92, 0x4c, 0x9b, 0x10, 0x3f, 0x12, 0x89, 0x33, 0x50, - 0x05, 0x50, 0x5f, 0xd5, 0x74, 0x1b, 0x7c, 0x61, 0xca, 0xa7, 0x3c, 0xff, 0x79, 0xb5, 0xd7, 0x55, - 0x2f, 0xa7, 0xc3, 0x21, 0x21, 0x4c, 0xc3, 0x03, 0xb8, 0xe8, 0x7f, 0x61, 0x94, 0x59, 0x95, 0x5f, - 0x88, 0x37, 0x62, 0x2a, 0x4c, 0x3f, 0xb3, 0xe5, 0xe7, 0x7a, 0x5d, 0x75, 0xaa, 0x2f, 0xa8, 0x61, - 0x0e, 0x45, 0x79, 0x58, 0x64, 0xff, 0x96, 0xdd, 0xfe, 0x61, 0x0e, 0xa8, 0xe7, 0x13, 0xe5, 0x97, - 0x69, 0x0d, 0x3c, 0x18, 0x8a, 0xd6, 0x60, 0x56, 0x04, 0x52, 0x20, 0x3e, 0x5d, 0x73, 0xa8, 0xa3, - 0x7c, 0x8f, 0xdf, 0xf9, 0xfc, 0xe5, 0x5e, 0x57, 0xbd, 0x20, 0xe6, 0x0c, 0xe3, 0xaf, 0x13, 0x9f, - 0xea, 0x0d, 0x87, 0x3a, 0x1a, 0x4e, 0x70, 0xe2, 0x2a, 0xfc, 0xe1, 0xf8, 0xe4, 0x58, 0x95, 0xb6, - 0x43, 0xf7, 0x62, 0x2a, 0xfc, 0x61, 0x31, 0x60, 0x46, 0x58, 0x36, 0xc8, 0x21, 0x0f, 0xe5, 0xfb, - 0x42, 0x44, 0xca, 0x4b, 0x28, 0xf2, 0x8c, 0x1c, 0x86, 0x91, 0xc4, 0x19, 0x31, 0x09, 0x1e, 0xc7, - 0x0f, 0x8e, 0x93, 0x10, 0x61, 0xc4, 0x19, 0xc8, 0x86, 0x05, 0x61, 0xb0, 0xfd, 0x4e, 0x40, 0x49, - 0xa3, 0x60, 0xf0, 0x58, 0x7e, 0x28, 0x84, 0xae, 0xf5, 0xba, 0xea, 0xd5, 0x98, 0x10, 0x15, 0x30, - 0xbd, 0xee, 0x84, 0x21, 0x0d, 0xa2, 0x0f, 0x50, 0xe5, 0xe1, 0xfd, 0xe8, 0x14, 0xaa, 0x22, 0xca, - 0x41, 0x74, 0xf4, 0x1e, 0x4c, 0xb3, 0x33, 0x79, 0x94, 0xbb, 0xbf, 0x0b, 0xb9, 0x8b, 0xbd, 0xae, - 0xba, 0x28, 0xe4, 0xf8, 0x19, 0x96, 0x32, 0x17, 0xc3, 0xcb, 0x7c, 0x1e, 0xce, 0x3f, 0x8e, 0xe1, - 0x8b, 0x30, 0x62, 0x78, 0xf4, 0x0e, 0x4c, 0xb1, 0x71, 0x94, 0xaf, 0x7f, 0x0a, 0xba, 0xd2, 0xeb, - 0xaa, 0xe7, 0x24, 0x7a, 0x3f, 0x5b, 0x32, 0x5a, 0x22, 0xf3, 0xb9, 0xff, 0x35, 0x9c, 0x2c, 0xa6, - 0x96, 0xd1, 0xa8, 0x04, 0xf3, 0x6c, 0x18, 0xcf, 0xd1, 0xbf, 0xb3, 0xc9, 0xfb, 0xc7, 0x25, 0x52, - 0x19, 0x4a, 0x53, 0x53, 0x7a, 0x3c, 0xa4, 0xff, 0x9c, 0xa8, 0x27, 0x22, 0x4b, 0x53, 0xd1, 0xbb, - 0x89, 0x42, 0xfa, 0xfb, 0xd1, 0xe4, 0xea, 0x82, 0xd0, 0x1d, 0x6d, 0x6c, 0xac, 0xc6, 0xbe, 0x95, - 0xa8, 0x09, 0x7f, 0x38, 0x75, 0x51, 0xf8, 0xd9, 0x74, 0xd4, 0x46, 0xb0, 0xf7, 0x95, 0xad, 0x8d, - 0xbd, 0xaf, 0x99, 0xe4, 0xfb, 0xca, 0x36, 0x22, 0x7c, 0x5f, 0x43, 0x0c, 0x7a, 0x15, 0xce, 0x96, - 0x08, 0xfd, 0xc8, 0xf3, 0x9f, 0x89, 0x3a, 0x96, 0x47, 0xbd, 0xae, 0x3a, 0x2b, 0xe0, 0xae, 0x70, - 0x68, 0x38, 0x82, 0xa0, 0xeb, 0x30, 0xca, 0x5f, 0x7f, 0xb1, 0x45, 0xd2, 0x0b, 0x25, 0x9e, 0x7b, - 0xee, 0x44, 0x05, 0x98, 0x5d, 0x23, 0x2d, 0xe7, 0xd0, 0x72, 0x28, 0x71, 0xeb, 0x87, 0x9b, 0x01, - 0xaf, 0x34, 0x33, 0xf2, 0xb3, 0xd0, 0x60, 0x7e, 0xbd, 0x25, 0x00, 0xfa, 0x7e, 0xa0, 0xe1, 0x04, - 0x05, 0x7d, 0x0b, 0x72, 0x71, 0x0b, 0x7e, 0xce, 0x6b, 0xce, 0x8c, 0x5c, 0x73, 0x92, 0x32, 0xba, - 0xff, 0x5c, 0xc3, 0x29, 0x1e, 0xfa, 0x00, 0x16, 0xb7, 0xda, 0x0d, 0x87, 0x92, 0x46, 0x22, 0xae, - 0x19, 0x2e, 0x78, 0xbd, 0xd7, 0x55, 0x55, 0x21, 0xd8, 0x11, 0x30, 0x3d, 0x1d, 0xdf, 0x60, 0x05, - 0xf4, 0x06, 0x00, 0xf6, 0x3a, 0x6e, 0xc3, 0x6a, 0xee, 0x37, 0xa9, 0xb2, 0xb8, 0x9c, 0x59, 0x19, - 0xcb, 0x9f, 0xef, 0x75, 0x55, 0x24, 0xf4, 0x7c, 0xe6, 0xd3, 0x5b, 0xcc, 0xa9, 0x61, 0x09, 0x89, - 0xf2, 0x30, 0x6b, 0x1e, 0x34, 0x69, 0xd9, 0x2d, 0x38, 0x01, 0x61, 0x45, 0x52, 0x39, 0x9f, 0xaa, - 0x46, 0x07, 0x4d, 0xaa, 0x7b, 0xae, 0xce, 0x0a, 0x6b, 0xc7, 0x27, 0x1a, 0x4e, 0x30, 0xd0, 0xdb, - 0x30, 0x65, 0xba, 0xce, 0x76, 0x8b, 0x54, 0xda, 0xbe, 0xb7, 0xa3, 0x5c, 0xe0, 0x02, 0x17, 0x7a, - 0x5d, 0x75, 0x21, 0x14, 0xe0, 0x4e, 0xbd, 0xcd, 0xbc, 0x1a, 0x96, 0xb1, 0xe8, 0x1e, 0x4c, 0x31, - 0x19, 0xbe, 0x98, 0xcd, 0x40, 0x51, 0xf9, 0x3e, 0x48, 0xc7, 0xb4, 0xce, 0x0b, 0x31, 0xdf, 0x04, - 0xb6, 0x78, 0x19, 0xcc, 0xa6, 0x65, 0xc3, 0xea, 0x5e, 0x67, 0x67, 0xa7, 0x45, 0x94, 0xe5, 0xe4, - 0xb4, 0x9c, 0x1b, 0x08, 0x6f, 0x48, 0x0d, 0xb1, 0xe8, 0x65, 0x18, 0x63, 0xc3, 0x40, 0xb9, 0xc6, - 0x3a, 0xd1, 0x7c, 0xae, 0xd7, 0x55, 0xa7, 0xfb, 0xa4, 0x40, 0xc3, 0xc2, 0x8d, 0x36, 0xa4, 0x8e, - 0xa3, 0xe0, 0xed, 0xef, 0x3b, 0x6e, 0x23, 0x50, 0x34, 0xce, 0xb9, 0xda, 0xeb, 0xaa, 0x17, 0x93, - 0x1d, 0x47, 0x3d, 0xc4, 0xc8, 0x0d, 0x47, 0xc4, 0x63, 0xc7, 0x11, 0x77, 0x5c, 0x97, 0xf8, 0xac, - 0x03, 0xe2, 0xd7, 0xf2, 0x66, 0xb2, 0x4a, 0xf9, 0xdc, 0xcf, 0xbb, 0xa5, 0xa8, 0x4a, 0xc5, 0x29, - 0xa8, 0x08, 0x39, 0xf3, 0x80, 0x12, 0xdf, 0x75, 0x5a, 0x47, 0x32, 0xab, 0x5c, 0x46, 0x0a, 0x88, - 0x84, 0x08, 0x59, 0x28, 0x45, 0x43, 0x77, 0x60, 0xb2, 0x4a, 0x7d, 0x12, 0x04, 0xc4, 0x0f, 0x14, - 0xc2, 0x17, 0x25, 0xb5, 0x6d, 0x41, 0xe4, 0xd2, 0x70, 0x1f, 0x86, 0x6e, 0xc3, 0x44, 0x61, 0x8f, - 0xd4, 0x9f, 0x31, 0xca, 0x0e, 0xa7, 0x48, 0xb7, 0xba, 0x1e, 0x7a, 0x34, 0x7c, 0x04, 0x62, 0x25, - 0x51, 0xb0, 0x37, 0xc8, 0x21, 0x6f, 0xbf, 0x79, 0xd3, 0x34, 0x26, 0x9f, 0x2f, 0x31, 0x13, 0x7f, - 0x6a, 0x83, 0xe6, 0xc7, 0x44, 0xc3, 0x71, 0x06, 0x7a, 0x04, 0x28, 0x66, 0xb0, 0x1c, 0x7f, 0x97, - 0x88, 0xae, 0x69, 0x2c, 0xbf, 0xdc, 0xeb, 0xaa, 0x57, 0x06, 0xea, 0xe8, 0x2d, 0x86, 0xd3, 0xf0, - 0x00, 0x32, 0x7a, 0x02, 0xe7, 0xfa, 0xd6, 0xce, 0xce, 0x4e, 0xf3, 0x00, 0x3b, 0xee, 0x2e, 0x51, - 0xbe, 0x10, 0xa2, 0x5a, 0xaf, 0xab, 0x2e, 0xa5, 0x45, 0x39, 0x50, 0xf7, 0x19, 0x52, 0xc3, 0x03, - 0x05, 0x90, 0x03, 0x17, 0x06, 0xd9, 0xed, 0x03, 0x57, 0xf9, 0x52, 0x68, 0xbf, 0xdc, 0xeb, 0xaa, - 0xda, 0xb1, 0xda, 0x3a, 0x3d, 0x70, 0x35, 0x3c, 0x4c, 0x07, 0xad, 0xc3, 0xdc, 0x91, 0xcb, 0x3e, - 0x70, 0xcb, 0xed, 0x40, 0xf9, 0x4a, 0x48, 0x4b, 0x27, 0x40, 0x92, 0xa6, 0x07, 0xae, 0xee, 0xb5, - 0x03, 0x0d, 0x27, 0x69, 0xe8, 0xfd, 0x28, 0x37, 0xa2, 0xb8, 0x07, 0xa2, 0x83, 0x1c, 0x93, 0x0b, - 0x70, 0xa8, 0x23, 0xda, 0x82, 0xe0, 0x28, 0x35, 0x21, 0x01, 0xbd, 0x1e, 0x1d, 0xa1, 0x47, 0x95, - 0xaa, 0xe8, 0x1d, 0xc7, 0xe4, 0x3e, 0x3e, 0x64, 0x7f, 0xd8, 0xee, 0x1f, 0xa2, 0x47, 0x95, 0xaa, - 0xf6, 0xed, 0x39, 0xd1, 0x6d, 0xb2, 0x57, 0xbc, 0xff, 0xd5, 0x28, 0xbf, 0xe2, 0xae, 0xb3, 0x4f, - 0x34, 0xcc, 0x9d, 0x72, 0x1d, 0x19, 0x39, 0x45, 0x1d, 0x59, 0x85, 0xf1, 0x27, 0x86, 0xc5, 0xd0, - 0xd9, 0x64, 0x19, 0xf9, 0xc8, 0x69, 0x09, 0x70, 0x88, 0x40, 0x65, 0x58, 0x58, 0x27, 0x8e, 0x4f, - 0xb7, 0x89, 0x43, 0x8b, 0x2e, 0x25, 0xfe, 0x73, 0xa7, 0x15, 0x56, 0x89, 0xac, 0xbc, 0x9b, 0x7b, - 0x11, 0x48, 0x6f, 0x86, 0x28, 0x0d, 0x0f, 0x62, 0xa2, 0x22, 0xcc, 0x9b, 0x2d, 0x52, 0x67, 0xdf, - 0xdd, 0x76, 0x73, 0x9f, 0x78, 0x1d, 0xba, 0x19, 0xf0, 0x6a, 0x91, 0x95, 0x6f, 0x39, 0x09, 0x21, - 0x3a, 0x15, 0x18, 0x0d, 0xa7, 0x59, 0xec, 0xa2, 0x5b, 0xcd, 0x80, 0x12, 0x57, 0xfa, 0x6e, 0x5e, - 0x4c, 0xbe, 0x3c, 0x2d, 0x8e, 0x88, 0x5a, 0xfc, 0x8e, 0xdf, 0x0a, 0x34, 0x9c, 0xa2, 0x21, 0x0c, - 0x0b, 0x46, 0xe3, 0x39, 0xf1, 0x69, 0x33, 0x20, 0x92, 0xda, 0x79, 0xae, 0x26, 0x5d, 0x20, 0x27, - 0x02, 0xc5, 0x05, 0x07, 0x91, 0xd1, 0xdb, 0x51, 0xab, 0x6b, 0x74, 0xa8, 0x67, 0x5b, 0xd5, 0xf0, - 0xd5, 0x97, 0x72, 0xe3, 0x74, 0xa8, 0xa7, 0x53, 0x26, 0x10, 0x47, 0xb2, 0x77, 0xb0, 0xdf, 0x7a, - 0x1b, 0x1d, 0xba, 0xa7, 0x28, 0x9c, 0x3b, 0xa4, 0x5b, 0x77, 0x3a, 0x89, 0x6e, 0x9d, 0x51, 0xd0, - 0xff, 0xcb, 0x22, 0xec, 0x83, 0x5f, 0xb9, 0x98, 0xfc, 0xf0, 0xe4, 0xec, 0x9d, 0x26, 0x7b, 0xfc, - 0x13, 0xd8, 0x7e, 0xf4, 0x1b, 0xe4, 0x90, 0x93, 0x2f, 0x25, 0x4f, 0x16, 0xbb, 0x39, 0x82, 0x1b, - 0x47, 0x22, 0x2b, 0xd5, 0x4a, 0x73, 0x81, 0xcb, 0xc9, 0x46, 0x5f, 0x6a, 0xd3, 0x84, 0xce, 0x20, - 0x1a, 0xdb, 0x0b, 0x91, 0x2e, 0xd6, 0xc3, 0xf1, 0xac, 0xa8, 0x3c, 0x2b, 0xd2, 0x5e, 0x84, 0x39, - 0xe6, 0xbd, 0x9f, 0x48, 0x48, 0x82, 0x82, 0x6c, 0x98, 0x3f, 0x4a, 0xd1, 0x91, 0xce, 0x32, 0xd7, - 0x91, 0x5e, 0x9b, 0xa6, 0xdb, 0xa4, 0x4d, 0xa7, 0xa5, 0xf7, 0xb3, 0x2c, 0x49, 0xa6, 0x05, 0x58, - 0x69, 0x66, 0xff, 0x8f, 0xf2, 0x7b, 0x8d, 0xe7, 0x28, 0xd9, 0x1f, 0xf7, 0x93, 0x2c, 0x83, 0xd9, - 0x07, 0x2a, 0xef, 0xd4, 0xe3, 0x69, 0xd6, 0xb8, 0x84, 0x74, 0xe0, 0x44, 0x7b, 0x9f, 0xca, 0xf5, - 0x00, 0x2e, 0xeb, 0x68, 0xa3, 0xde, 0x9f, 0xef, 0xf7, 0xf5, 0xe1, 0x9f, 0x0a, 0x62, 0xbb, 0x63, - 0xf0, 0x68, 0x31, 0x51, 0xba, 0x5f, 0x1a, 0xda, 0xec, 0x0b, 0xb2, 0x0c, 0x46, 0x9b, 0x89, 0xe6, - 0x9c, 0x2b, 0xdc, 0x38, 0xa9, 0x37, 0x17, 0x42, 0x69, 0x26, 0xeb, 0xb8, 0x8a, 0x22, 0x15, 0x85, - 0x56, 0x87, 0xff, 0xe0, 0x76, 0x33, 0x79, 0x76, 0xa2, 0x54, 0xd5, 0x05, 0x40, 0xc3, 0x09, 0x06, - 0xbb, 0xd1, 0x71, 0x4b, 0x95, 0x3a, 0x94, 0x84, 0x8d, 0x80, 0xb4, 0xc1, 0x09, 0x21, 0x3d, 0x60, - 0x30, 0x0d, 0x0f, 0x22, 0xa7, 0x35, 0x6d, 0xef, 0x19, 0x71, 0x95, 0x57, 0x4e, 0xd2, 0xa4, 0x0c, - 0x96, 0xd2, 0xe4, 0x64, 0x74, 0x1f, 0x66, 0xa2, 0xcf, 0x83, 0x82, 0xd7, 0x71, 0xa9, 0x72, 0x97, - 0xbf, 0x85, 0x72, 0x81, 0x89, 0xbe, 0x43, 0xea, 0xcc, 0xcf, 0x0a, 0x8c, 0x8c, 0x47, 0x16, 0xcc, - 0x3f, 0xea, 0x78, 0xd4, 0xc9, 0x3b, 0xf5, 0x67, 0xc4, 0x6d, 0xe4, 0x0f, 0x29, 0x09, 0x94, 0xd7, - 0xb9, 0x88, 0xd4, 0x7e, 0x7f, 0xc8, 0x20, 0xfa, 0xb6, 0xc0, 0xe8, 0xdb, 0x0c, 0xa4, 0xe1, 0x34, - 0x91, 0x95, 0x92, 0x8a, 0x4f, 0x1e, 0x7b, 0x94, 0x28, 0xf7, 0x93, 0xcf, 0x55, 0xdb, 0x27, 0xfa, - 0x73, 0x8f, 0xed, 0x4e, 0x84, 0x91, 0x77, 0xc4, 0xf3, 0xfd, 0x4e, 0x9b, 0xf2, 0xae, 0x46, 0x79, - 0x3f, 0x79, 0x8c, 0x8f, 0x76, 0x44, 0xa0, 0x74, 0xde, 0x07, 0x49, 0x3b, 0x22, 0x91, 0xd1, 0x4d, - 0x18, 0xb7, 0xbc, 0xdd, 0x5d, 0xe2, 0x2b, 0x0f, 0xf9, 0xc6, 0xce, 0xf7, 0xba, 0xea, 0x4c, 0x78, - 0xd1, 0xb9, 0x5d, 0xc3, 0x21, 0x00, 0xfd, 0x1f, 0x80, 0xe5, 0xed, 0x96, 0x3b, 0xb4, 0xdd, 0xa1, - 0x81, 0xb2, 0xce, 0xef, 0xb3, 0x54, 0x5c, 0x5b, 0xde, 0xae, 0xee, 0x71, 0xa7, 0x86, 0x25, 0x20, - 0xeb, 0x6d, 0xd7, 0xc8, 0x76, 0x67, 0x57, 0x29, 0xf2, 0x38, 0xa5, 0xde, 0xb6, 0xc1, 0xcc, 0x1a, - 0x16, 0xee, 0xd5, 0x9f, 0x64, 0xa5, 0x1f, 0x92, 0xd1, 0x1c, 0x4c, 0x95, 0xca, 0x76, 0xad, 0x6a, - 0x1b, 0xd8, 0x36, 0xd7, 0x72, 0x67, 0xd0, 0x79, 0x40, 0xc5, 0x52, 0xd1, 0x2e, 0x1a, 0x96, 0x30, - 0xd6, 0x4c, 0xbb, 0xb0, 0x96, 0x03, 0x94, 0x83, 0x69, 0x6c, 0x4a, 0x96, 0x29, 0x66, 0xa9, 0x16, - 0x1f, 0xda, 0x26, 0xde, 0x14, 0x96, 0x73, 0x68, 0x19, 0xae, 0x54, 0x8b, 0x0f, 0x1f, 0x6d, 0x15, - 0x05, 0xa6, 0x66, 0x94, 0xd6, 0x6a, 0xd8, 0xdc, 0x2c, 0x3f, 0x36, 0x6b, 0x6b, 0x86, 0x6d, 0xe4, - 0x16, 0xd1, 0x3c, 0xcc, 0x54, 0x8d, 0xc7, 0x66, 0xad, 0x5a, 0x32, 0x2a, 0xd5, 0xf5, 0xb2, 0x9d, - 0x5b, 0x42, 0xd7, 0xe0, 0x2a, 0x13, 0x2e, 0x63, 0xb3, 0x16, 0x4d, 0xf0, 0x00, 0x97, 0x37, 0xfb, - 0x10, 0x15, 0x5d, 0x84, 0xc5, 0xc1, 0xae, 0x65, 0xc6, 0x4e, 0x4d, 0x69, 0xe0, 0xc2, 0x7a, 0x31, - 0x9a, 0x73, 0x05, 0xdd, 0x86, 0x57, 0x8e, 0x8b, 0x8a, 0x8f, 0xab, 0x76, 0xb9, 0x52, 0x33, 0x1e, - 0x9a, 0x25, 0x3b, 0x77, 0x13, 0x5d, 0x85, 0x8b, 0x79, 0xcb, 0x28, 0x6c, 0xac, 0x97, 0x2d, 0xb3, - 0x56, 0x31, 0x4d, 0x5c, 0xab, 0x94, 0xb1, 0x5d, 0xb3, 0x9f, 0xd6, 0xf0, 0xd3, 0x5c, 0x03, 0xa9, - 0x70, 0x79, 0xab, 0x34, 0x1c, 0x40, 0xd0, 0x25, 0x58, 0x5c, 0x33, 0x2d, 0xe3, 0x83, 0x94, 0xeb, - 0x45, 0x06, 0x5d, 0x81, 0x0b, 0x5b, 0xa5, 0xc1, 0xde, 0xcf, 0x32, 0xab, 0x7f, 0x05, 0x18, 0x65, - 0x5f, 0x20, 0x48, 0x81, 0x73, 0xd1, 0xde, 0x96, 0x4b, 0x66, 0xed, 0x41, 0xd9, 0xb2, 0xca, 0x4f, - 0x4c, 0x9c, 0x3b, 0x13, 0xae, 0x26, 0xe5, 0xa9, 0x6d, 0x95, 0xec, 0xa2, 0x55, 0xb3, 0x71, 0xf1, - 0xe1, 0x43, 0x13, 0xf7, 0x77, 0x28, 0x83, 0x10, 0xcc, 0x46, 0x04, 0xcb, 0x34, 0xd6, 0x4c, 0x9c, - 0x1b, 0x41, 0x37, 0xe1, 0x46, 0xdc, 0x36, 0x8c, 0x9e, 0x95, 0xe9, 0x8f, 0xb6, 0xca, 0x78, 0x6b, - 0x33, 0x37, 0xca, 0x0e, 0x4d, 0x64, 0x33, 0x2c, 0x2b, 0x37, 0x86, 0xae, 0x83, 0x1a, 0x6d, 0xb1, - 0xb4, 0xbb, 0xb1, 0xc8, 0x01, 0xdd, 0x83, 0x37, 0x4e, 0x00, 0x0d, 0x8b, 0x62, 0x8a, 0xa5, 0x64, - 0x00, 0x37, 0x5c, 0xcf, 0x34, 0x7a, 0x1d, 0x5e, 0x1b, 0xea, 0x1e, 0x26, 0x3a, 0x83, 0x1e, 0x40, - 0x7e, 0x00, 0x4b, 0xac, 0x32, 0xb4, 0x88, 0x73, 0x19, 0x0a, 0x45, 0xd4, 0xf0, 0x10, 0x16, 0xb0, - 0x61, 0x17, 0xd6, 0x73, 0xb3, 0x68, 0x15, 0x5e, 0x1e, 0x7a, 0x1c, 0xe2, 0x9b, 0xd0, 0x40, 0x06, - 0xbc, 0x7b, 0x3a, 0xec, 0xb0, 0xb0, 0x09, 0x7a, 0x09, 0x96, 0x87, 0x4b, 0x84, 0x5b, 0xb2, 0x83, - 0xde, 0x81, 0x37, 0x4f, 0x42, 0x0d, 0x9b, 0x62, 0xf7, 0xf8, 0x29, 0xc2, 0x63, 0xb0, 0xc7, 0xee, - 0xde, 0x70, 0x14, 0x3b, 0x18, 0x4d, 0xf4, 0x3f, 0xa0, 0x0d, 0x3c, 0xec, 0xf1, 0x6d, 0x79, 0x91, - 0x41, 0xb7, 0xe0, 0x26, 0x36, 0x4a, 0x6b, 0xe5, 0xcd, 0xda, 0x29, 0xf0, 0x9f, 0x65, 0xd0, 0x7b, - 0xf0, 0xf6, 0xc9, 0xc0, 0x61, 0x0b, 0xfc, 0x3c, 0x83, 0x4c, 0x78, 0xff, 0xd4, 0xf3, 0x0d, 0x93, - 0xf9, 0x22, 0x83, 0xae, 0xc1, 0x95, 0xc1, 0xfc, 0x30, 0x0f, 0x5f, 0x66, 0xd0, 0x0a, 0x5c, 0x3f, - 0x76, 0xa6, 0x10, 0xf9, 0x55, 0x06, 0xbd, 0x05, 0x77, 0x8f, 0x83, 0x0c, 0x0b, 0xe3, 0x57, 0x19, - 0x74, 0x1f, 0xee, 0x9d, 0x62, 0x8e, 0x61, 0x02, 0xbf, 0x3e, 0x66, 0x1d, 0x61, 0xb2, 0xbf, 0x3e, - 0x79, 0x1d, 0x21, 0xf2, 0x37, 0x19, 0xb4, 0x04, 0x17, 0x07, 0x43, 0xd8, 0x99, 0xf8, 0x6d, 0x06, - 0xdd, 0x80, 0xe5, 0x63, 0x95, 0x18, 0xec, 0x77, 0x19, 0xa4, 0xc0, 0x42, 0xa9, 0x5c, 0x7b, 0x60, - 0x14, 0xad, 0xda, 0x93, 0xa2, 0xbd, 0x5e, 0xab, 0xda, 0xd8, 0xac, 0x56, 0x73, 0x3f, 0x1f, 0x61, - 0xa1, 0xc4, 0x3c, 0xa5, 0x72, 0xe8, 0xac, 0x3d, 0x28, 0xe3, 0x9a, 0x55, 0x7c, 0x6c, 0x96, 0x18, - 0xf2, 0xd3, 0x11, 0x34, 0x07, 0xc0, 0x60, 0x95, 0x72, 0xb1, 0x64, 0x57, 0x73, 0xdf, 0xcd, 0xa2, - 0x19, 0x98, 0x30, 0x9f, 0xda, 0x26, 0x2e, 0x19, 0x56, 0xee, 0x6f, 0xd9, 0xd5, 0x7d, 0x98, 0x88, - 0x7e, 0xe4, 0x40, 0xe3, 0x30, 0xb2, 0xf1, 0x38, 0x77, 0x06, 0x4d, 0xc2, 0x98, 0x65, 0x1a, 0x55, - 0x33, 0x97, 0x41, 0x0b, 0x30, 0x67, 0x5a, 0x66, 0xc1, 0x2e, 0x96, 0x4b, 0x35, 0xbc, 0x55, 0x2a, - 0xf1, 0xc7, 0x33, 0x07, 0xd3, 0x4f, 0xd8, 0xcd, 0x8f, 0x2c, 0x59, 0xb4, 0x08, 0xf3, 0x56, 0xb9, - 0xb0, 0x51, 0xc3, 0x46, 0xc1, 0xc4, 0x91, 0x79, 0x94, 0x01, 0xb9, 0x50, 0x64, 0x19, 0x5b, 0xcd, - 0xc3, 0xd9, 0xf0, 0x17, 0x12, 0x34, 0x05, 0x67, 0x37, 0x1e, 0xd7, 0xd6, 0x8d, 0xea, 0x7a, 0xee, - 0x4c, 0x1f, 0x69, 0x3e, 0xad, 0x14, 0x31, 0x9b, 0x19, 0x60, 0xfc, 0x68, 0xc2, 0x69, 0x98, 0x28, - 0x95, 0x6b, 0x85, 0x75, 0xb3, 0xb0, 0x91, 0xcb, 0xde, 0xb9, 0x0f, 0x93, 0xb6, 0xef, 0xb8, 0x41, - 0xdb, 0xf3, 0x29, 0xba, 0x23, 0x0f, 0x66, 0xc3, 0xdf, 0x69, 0xc3, 0xbf, 0x18, 0x5f, 0x9a, 0x3b, - 0x1a, 0x8b, 0x3f, 0x26, 0x6a, 0x67, 0x56, 0x32, 0xaf, 0x65, 0xf2, 0xe7, 0x5e, 0xfc, 0x69, 0xe9, - 0xcc, 0x8b, 0x6f, 0x96, 0x32, 0x5f, 0x7f, 0xb3, 0x94, 0xf9, 0xe3, 0x37, 0x4b, 0x99, 0x1f, 0xff, - 0x79, 0xe9, 0xcc, 0xf6, 0x38, 0xff, 0x8b, 0xf3, 0xdd, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x49, - 0xaa, 0x88, 0xde, 0xba, 0x1e, 0x00, 0x00, + 0xf5, 0x36, 0x45, 0x49, 0x96, 0xae, 0x5e, 0xd4, 0xc8, 0xb2, 0xe1, 0x97, 0x20, 0xc3, 0x71, 0x7e, + 0xb2, 0x12, 0xd8, 0xf9, 0xd9, 0x39, 0x79, 0x38, 0x4d, 0x1c, 0x90, 0x82, 0x2d, 0x56, 0x10, 0x49, + 0x0f, 0x21, 0xdb, 0x59, 0xf1, 0x40, 0xe4, 0x48, 0xe2, 0x31, 0x05, 0x30, 0xc0, 0xd0, 0x91, 0xb2, + 0xee, 0x39, 0xdd, 0xb6, 0xe9, 0xe3, 0xb4, 0xe7, 0x74, 0xd5, 0x75, 0xd3, 0xfe, 0x1b, 0xce, 0xab, + 0x4d, 0xdb, 0x55, 0xbb, 0xe0, 0x69, 0xd3, 0x4d, 0x57, 0x5d, 0xf0, 0xf4, 0xbd, 0xea, 0x99, 0x19, + 0x40, 0x1c, 0x00, 0xa4, 0xa4, 0x95, 0x3d, 0xf7, 0x7e, 0xdf, 0x37, 0x77, 0xe6, 0xce, 0xcc, 0xbd, + 0xa0, 0x60, 0xce, 0x6f, 0xd7, 0xdb, 0xdb, 0xb7, 0xfd, 0x76, 0xfd, 0x56, 0xdb, 0xf7, 0xa8, 0x87, + 0xc6, 0xb8, 0xe1, 0x92, 0xbe, 0xdb, 0xa4, 0x7b, 0x9d, 0xed, 0x5b, 0x75, 0x6f, 0xff, 0xf6, 0xae, + 0xb7, 0xeb, 0xdd, 0xe6, 0xde, 0xed, 0xce, 0x0e, 0x1f, 0xf1, 0x01, 0xff, 0x9f, 0x60, 0x69, 0xdf, + 0xcd, 0xc0, 0x59, 0x4c, 0x3e, 0xec, 0x90, 0x80, 0xa2, 0x5b, 0x30, 0x59, 0x6e, 0x13, 0xdf, 0xa1, + 0x4d, 0xcf, 0x55, 0x32, 0xcb, 0x99, 0x95, 0xd9, 0x3b, 0xb9, 0x5b, 0x5c, 0xf5, 0xd6, 0x91, 0x1d, + 0xf7, 0x21, 0xe8, 0x06, 0x8c, 0x6f, 0x92, 0xfd, 0x6d, 0xe2, 0x2b, 0x23, 0xcb, 0x99, 0x95, 0xa9, + 0x3b, 0x33, 0x21, 0x58, 0x18, 0x71, 0xe8, 0x64, 0x30, 0x9b, 0x04, 0x94, 0xf8, 0x4a, 0x36, 0x06, + 0x13, 0x46, 0x1c, 0x3a, 0xb5, 0xbf, 0x8e, 0xc0, 0x74, 0xd5, 0x75, 0xda, 0xc1, 0x9e, 0x47, 0x8b, + 0xee, 0x8e, 0x87, 0x96, 0x00, 0x84, 0x42, 0xc9, 0xd9, 0x27, 0x3c, 0x9e, 0x49, 0x2c, 0x59, 0xd0, + 0x2a, 0xe4, 0xc4, 0xa8, 0xd0, 0x6a, 0x12, 0x97, 0x6e, 0x61, 0x2b, 0x50, 0x46, 0x96, 0xb3, 0x2b, + 0x93, 0x38, 0x65, 0x47, 0x5a, 0x5f, 0xbb, 0xe2, 0xd0, 0x3d, 0x1e, 0xc9, 0x24, 0x8e, 0xd9, 0x98, + 0x5e, 0x34, 0x7e, 0xd0, 0x6c, 0x91, 0x6a, 0xf3, 0x63, 0xa2, 0x8c, 0x72, 0x5c, 0xca, 0x8e, 0x5e, + 0x85, 0xf9, 0xc8, 0x66, 0x7b, 0xd4, 0x69, 0x71, 0xf0, 0x18, 0x07, 0xa7, 0x1d, 0xb2, 0x32, 0x37, + 0x6e, 0x90, 0x43, 0x65, 0x7c, 0x39, 0xb3, 0x92, 0xc5, 0x29, 0xbb, 0x1c, 0xe9, 0xba, 0x13, 0xec, + 0x29, 0x67, 0x39, 0x2e, 0x66, 0x93, 0xf5, 0x30, 0x79, 0xde, 0x0c, 0x58, 0xbe, 0x26, 0xe2, 0x7a, + 0x91, 0x1d, 0x21, 0x18, 0xb5, 0x3d, 0xef, 0x99, 0x32, 0xc9, 0x83, 0xe3, 0xff, 0xd7, 0x7e, 0x96, + 0x81, 0x09, 0x4c, 0x82, 0xb6, 0xe7, 0x06, 0x04, 0x29, 0x70, 0xb6, 0xda, 0xa9, 0xd7, 0x49, 0x10, + 0xf0, 0x3d, 0x9e, 0xc0, 0xd1, 0x10, 0x9d, 0x87, 0xf1, 0x2a, 0x75, 0x68, 0x27, 0xe0, 0xf9, 0x9d, + 0xc4, 0xe1, 0x48, 0xca, 0x7b, 0xf6, 0xb8, 0xbc, 0xbf, 0x19, 0xcf, 0x27, 0xdf, 0xcb, 0xa9, 0x3b, + 0x0b, 0x21, 0x58, 0x76, 0xe1, 0x18, 0x50, 0xfb, 0x64, 0x3a, 0x9a, 0x00, 0xbd, 0x06, 0x13, 0x26, + 0xad, 0x37, 0xcc, 0x03, 0x52, 0x17, 0x27, 0x20, 0x7f, 0xae, 0xd7, 0x55, 0x73, 0x87, 0xce, 0x7e, + 0xeb, 0x9e, 0x46, 0x68, 0xbd, 0xa1, 0x93, 0x03, 0x52, 0xd7, 0xf0, 0x11, 0x0a, 0xdd, 0x85, 0x49, + 0x63, 0x97, 0xb8, 0xd4, 0x68, 0x34, 0x7c, 0x65, 0x8a, 0x53, 0x16, 0x7b, 0x5d, 0x75, 0x5e, 0x50, + 0x1c, 0xe6, 0xd2, 0x9d, 0x46, 0xc3, 0xd7, 0x70, 0x1f, 0x87, 0x2c, 0x98, 0x7f, 0xe0, 0x34, 0x5b, + 0x6d, 0xaf, 0xe9, 0xd2, 0x75, 0xdb, 0xae, 0x70, 0xf2, 0x34, 0x27, 0x2f, 0xf5, 0xba, 0xea, 0x25, + 0x41, 0xde, 0x89, 0x20, 0xfa, 0x1e, 0xa5, 0xed, 0x50, 0x25, 0x4d, 0x44, 0x3a, 0x9c, 0xcd, 0x3b, + 0x01, 0x59, 0x6b, 0xfa, 0x0a, 0xe1, 0x1a, 0x0b, 0xbd, 0xae, 0x3a, 0x27, 0x34, 0xb6, 0x9d, 0x80, + 0xe8, 0x8d, 0xa6, 0xaf, 0xe1, 0x08, 0x83, 0x1e, 0xc2, 0x1c, 0x8b, 0x5e, 0x9c, 0xd6, 0x8a, 0xef, + 0x1d, 0x1c, 0x2a, 0x9f, 0xf1, 0x4c, 0xe4, 0xaf, 0xf4, 0xba, 0xaa, 0x22, 0xad, 0xb5, 0xce, 0x21, + 0x7a, 0x9b, 0x61, 0x34, 0x9c, 0x64, 0x21, 0x03, 0x66, 0x98, 0xa9, 0x42, 0x88, 0x2f, 0x64, 0x3e, + 0x17, 0x32, 0x97, 0x7a, 0x5d, 0xf5, 0xbc, 0x24, 0xd3, 0x26, 0xc4, 0x8f, 0x44, 0xe2, 0x0c, 0x54, + 0x01, 0xd4, 0x57, 0x35, 0xdd, 0x06, 0x5f, 0x98, 0xf2, 0x29, 0xcf, 0x7f, 0x5e, 0xed, 0x75, 0xd5, + 0xcb, 0xe9, 0x70, 0x48, 0x08, 0xd3, 0xf0, 0x00, 0x2e, 0xfa, 0x7f, 0x18, 0x65, 0x56, 0xe5, 0x97, + 0xe2, 0x8d, 0x98, 0x0a, 0xd3, 0xcf, 0x6c, 0xf9, 0xb9, 0x5e, 0x57, 0x9d, 0xea, 0x0b, 0x6a, 0x98, + 0x43, 0x51, 0x1e, 0x16, 0xd9, 0xbf, 0x65, 0xb7, 0x7f, 0x98, 0x03, 0xea, 0xf9, 0x44, 0xf9, 0x55, + 0x5a, 0x03, 0x0f, 0x86, 0xa2, 0x35, 0x98, 0x15, 0x81, 0x14, 0x88, 0x4f, 0xd7, 0x1c, 0xea, 0x28, + 0xdf, 0xe7, 0x77, 0x3e, 0x7f, 0xb9, 0xd7, 0x55, 0x2f, 0x88, 0x39, 0xc3, 0xf8, 0xeb, 0xc4, 0xa7, + 0x7a, 0xc3, 0xa1, 0x8e, 0x86, 0x13, 0x9c, 0xb8, 0x0a, 0x7f, 0x38, 0x3e, 0x39, 0x56, 0xa5, 0xed, + 0xd0, 0xbd, 0x98, 0x0a, 0x7f, 0x58, 0x0c, 0x98, 0x11, 0x96, 0x0d, 0x72, 0xc8, 0x43, 0xf9, 0x81, + 0x10, 0x91, 0xf2, 0x12, 0x8a, 0x3c, 0x23, 0x87, 0x61, 0x24, 0x71, 0x46, 0x4c, 0x82, 0xc7, 0xf1, + 0xc3, 0xe3, 0x24, 0x44, 0x18, 0x71, 0x06, 0xb2, 0x61, 0x41, 0x18, 0x6c, 0xbf, 0x13, 0x50, 0xd2, + 0x28, 0x18, 0x3c, 0x96, 0x1f, 0x09, 0xa1, 0x6b, 0xbd, 0xae, 0x7a, 0x35, 0x26, 0x44, 0x05, 0x4c, + 0xaf, 0x3b, 0x61, 0x48, 0x83, 0xe8, 0x03, 0x54, 0x79, 0x78, 0x3f, 0x3e, 0x85, 0xaa, 0x88, 0x72, + 0x10, 0x1d, 0xbd, 0x07, 0xd3, 0xec, 0x4c, 0x1e, 0xe5, 0xee, 0x1f, 0x42, 0xee, 0x62, 0xaf, 0xab, + 0x2e, 0x0a, 0x39, 0x7e, 0x86, 0xa5, 0xcc, 0xc5, 0xf0, 0x32, 0x9f, 0x87, 0xf3, 0xcf, 0x63, 0xf8, + 0x22, 0x8c, 0x18, 0x1e, 0xbd, 0x03, 0x53, 0x6c, 0x1c, 0xe5, 0xeb, 0x5f, 0x82, 0xae, 0xf4, 0xba, + 0xea, 0x39, 0x89, 0xde, 0xcf, 0x96, 0x8c, 0x96, 0xc8, 0x7c, 0xee, 0x7f, 0x0f, 0x27, 0x8b, 0xa9, + 0x65, 0x34, 0x2a, 0xc1, 0x3c, 0x1b, 0xc6, 0x73, 0xf4, 0x9f, 0x6c, 0xf2, 0xfe, 0x71, 0x89, 0x54, + 0x86, 0xd2, 0xd4, 0x94, 0x1e, 0x0f, 0xe9, 0xbf, 0x27, 0xea, 0x89, 0xc8, 0xd2, 0x54, 0xf4, 0x6e, + 0xa2, 0x90, 0xfe, 0x61, 0x34, 0xb9, 0xba, 0x20, 0x74, 0x47, 0x1b, 0x1b, 0xab, 0xb1, 0x6f, 0x25, + 0x6a, 0xc2, 0x1f, 0x4f, 0x5d, 0x14, 0x7e, 0x3e, 0x1d, 0xb5, 0x11, 0xec, 0x7d, 0x65, 0x6b, 0x63, + 0xef, 0x6b, 0x26, 0xf9, 0xbe, 0xb2, 0x8d, 0x08, 0xdf, 0xd7, 0x10, 0x83, 0x5e, 0x85, 0xb3, 0x25, + 0x42, 0x3f, 0xf2, 0xfc, 0x67, 0xa2, 0x8e, 0xe5, 0x51, 0xaf, 0xab, 0xce, 0x0a, 0xb8, 0x2b, 0x1c, + 0x1a, 0x8e, 0x20, 0xe8, 0x3a, 0x8c, 0xf2, 0xd7, 0x5f, 0x6c, 0x91, 0xf4, 0x42, 0x89, 0xe7, 0x9e, + 0x3b, 0x51, 0x01, 0x66, 0xd7, 0x48, 0xcb, 0x39, 0xb4, 0x1c, 0x4a, 0xdc, 0xfa, 0xe1, 0x66, 0xc0, + 0x2b, 0xcd, 0x8c, 0xfc, 0x2c, 0x34, 0x98, 0x5f, 0x6f, 0x09, 0x80, 0xbe, 0x1f, 0x68, 0x38, 0x41, + 0x41, 0xdf, 0x86, 0x5c, 0xdc, 0x82, 0x9f, 0xf3, 0x9a, 0x33, 0x23, 0xd7, 0x9c, 0xa4, 0x8c, 0xee, + 0x3f, 0xd7, 0x70, 0x8a, 0x87, 0x3e, 0x80, 0xc5, 0xad, 0x76, 0xc3, 0xa1, 0xa4, 0x91, 0x88, 0x6b, + 0x86, 0x0b, 0x5e, 0xef, 0x75, 0x55, 0x55, 0x08, 0x76, 0x04, 0x4c, 0x4f, 0xc7, 0x37, 0x58, 0x01, + 0xbd, 0x01, 0x80, 0xbd, 0x8e, 0xdb, 0xb0, 0x9a, 0xfb, 0x4d, 0xaa, 0x2c, 0x2e, 0x67, 0x56, 0xc6, + 0xf2, 0xe7, 0x7b, 0x5d, 0x15, 0x09, 0x3d, 0x9f, 0xf9, 0xf4, 0x16, 0x73, 0x6a, 0x58, 0x42, 0xa2, + 0x3c, 0xcc, 0x9a, 0x07, 0x4d, 0x5a, 0x76, 0x0b, 0x4e, 0x40, 0x58, 0x91, 0x54, 0xce, 0xa7, 0xaa, + 0xd1, 0x41, 0x93, 0xea, 0x9e, 0xab, 0xb3, 0xc2, 0xda, 0xf1, 0x89, 0x86, 0x13, 0x0c, 0xf4, 0x36, + 0x4c, 0x99, 0xae, 0xb3, 0xdd, 0x22, 0x95, 0xb6, 0xef, 0xed, 0x28, 0x17, 0xb8, 0xc0, 0x85, 0x5e, + 0x57, 0x5d, 0x08, 0x05, 0xb8, 0x53, 0x6f, 0x33, 0xaf, 0x86, 0x65, 0x2c, 0xba, 0x07, 0x53, 0x4c, + 0x86, 0x2f, 0x66, 0x33, 0x50, 0x54, 0xbe, 0x0f, 0xd2, 0x31, 0xad, 0xf3, 0x42, 0xcc, 0x37, 0x81, + 0x2d, 0x5e, 0x06, 0xb3, 0x69, 0xd9, 0xb0, 0xba, 0xd7, 0xd9, 0xd9, 0x69, 0x11, 0x65, 0x39, 0x39, + 0x2d, 0xe7, 0x06, 0xc2, 0x1b, 0x52, 0x43, 0x2c, 0x7a, 0x19, 0xc6, 0xd8, 0x30, 0x50, 0xae, 0xb1, + 0x4e, 0x34, 0x9f, 0xeb, 0x75, 0xd5, 0xe9, 0x3e, 0x29, 0xd0, 0xb0, 0x70, 0xa3, 0x0d, 0xa9, 0xe3, + 0x28, 0x78, 0xfb, 0xfb, 0x8e, 0xdb, 0x08, 0x14, 0x8d, 0x73, 0xae, 0xf6, 0xba, 0xea, 0xc5, 0x64, + 0xc7, 0x51, 0x0f, 0x31, 0x72, 0xc3, 0x11, 0xf1, 0xd8, 0x71, 0xc4, 0x1d, 0xd7, 0x25, 0x3e, 0xeb, + 0x80, 0xf8, 0xb5, 0xbc, 0x99, 0xac, 0x52, 0x3e, 0xf7, 0xf3, 0x6e, 0x29, 0xaa, 0x52, 0x71, 0x0a, + 0x2a, 0x42, 0xce, 0x3c, 0xa0, 0xc4, 0x77, 0x9d, 0xd6, 0x91, 0xcc, 0x2a, 0x97, 0x91, 0x02, 0x22, + 0x21, 0x42, 0x16, 0x4a, 0xd1, 0xd0, 0x1d, 0x98, 0xac, 0x52, 0x9f, 0x04, 0x01, 0xf1, 0x03, 0x85, + 0xf0, 0x45, 0x49, 0x6d, 0x5b, 0x10, 0xb9, 0x34, 0xdc, 0x87, 0xa1, 0xdb, 0x30, 0x51, 0xd8, 0x23, + 0xf5, 0x67, 0x8c, 0xb2, 0xc3, 0x29, 0xd2, 0xad, 0xae, 0x87, 0x1e, 0x0d, 0x1f, 0x81, 0x58, 0x49, + 0x14, 0xec, 0x0d, 0x72, 0xc8, 0xdb, 0x6f, 0xde, 0x34, 0x8d, 0xc9, 0xe7, 0x4b, 0xcc, 0xc4, 0x9f, + 0xda, 0xa0, 0xf9, 0x31, 0xd1, 0x70, 0x9c, 0x81, 0x1e, 0x01, 0x8a, 0x19, 0x2c, 0xc7, 0xdf, 0x25, + 0xa2, 0x6b, 0x1a, 0xcb, 0x2f, 0xf7, 0xba, 0xea, 0x95, 0x81, 0x3a, 0x7a, 0x8b, 0xe1, 0x34, 0x3c, + 0x80, 0x8c, 0x9e, 0xc0, 0xb9, 0xbe, 0xb5, 0xb3, 0xb3, 0xd3, 0x3c, 0xc0, 0x8e, 0xbb, 0x4b, 0x94, + 0x2f, 0x84, 0xa8, 0xd6, 0xeb, 0xaa, 0x4b, 0x69, 0x51, 0x0e, 0xd4, 0x7d, 0x86, 0xd4, 0xf0, 0x40, + 0x01, 0xe4, 0xc0, 0x85, 0x41, 0x76, 0xfb, 0xc0, 0x55, 0xbe, 0x14, 0xda, 0x2f, 0xf7, 0xba, 0xaa, + 0x76, 0xac, 0xb6, 0x4e, 0x0f, 0x5c, 0x0d, 0x0f, 0xd3, 0x41, 0xeb, 0x30, 0x77, 0xe4, 0xb2, 0x0f, + 0xdc, 0x72, 0x3b, 0x50, 0xbe, 0x12, 0xd2, 0xd2, 0x09, 0x90, 0xa4, 0xe9, 0x81, 0xab, 0x7b, 0xed, + 0x40, 0xc3, 0x49, 0x1a, 0x7a, 0x3f, 0xca, 0x8d, 0x28, 0xee, 0x81, 0xe8, 0x20, 0xc7, 0xe4, 0x02, + 0x1c, 0xea, 0x88, 0xb6, 0x20, 0x38, 0x4a, 0x4d, 0x48, 0x40, 0xaf, 0x47, 0x47, 0xe8, 0x51, 0xa5, + 0x2a, 0x7a, 0xc7, 0x31, 0xb9, 0x8f, 0x0f, 0xd9, 0x1f, 0xb6, 0xfb, 0x87, 0xe8, 0x51, 0xa5, 0xaa, + 0x7d, 0x67, 0x4e, 0x74, 0x9b, 0xec, 0x15, 0xef, 0x7f, 0x35, 0xca, 0xaf, 0xb8, 0xeb, 0xec, 0x13, + 0x0d, 0x73, 0xa7, 0x5c, 0x47, 0x46, 0x4e, 0x51, 0x47, 0x56, 0x61, 0xfc, 0x89, 0x61, 0x31, 0x74, + 0x36, 0x59, 0x46, 0x3e, 0x72, 0x5a, 0x02, 0x1c, 0x22, 0x50, 0x19, 0x16, 0xd6, 0x89, 0xe3, 0xd3, + 0x6d, 0xe2, 0xd0, 0xa2, 0x4b, 0x89, 0xff, 0xdc, 0x69, 0x85, 0x55, 0x22, 0x2b, 0xef, 0xe6, 0x5e, + 0x04, 0xd2, 0x9b, 0x21, 0x4a, 0xc3, 0x83, 0x98, 0xa8, 0x08, 0xf3, 0x66, 0x8b, 0xd4, 0xd9, 0x77, + 0xb7, 0xdd, 0xdc, 0x27, 0x5e, 0x87, 0x6e, 0x06, 0xbc, 0x5a, 0x64, 0xe5, 0x5b, 0x4e, 0x42, 0x88, + 0x4e, 0x05, 0x46, 0xc3, 0x69, 0x16, 0xbb, 0xe8, 0x56, 0x33, 0xa0, 0xc4, 0x95, 0xbe, 0x9b, 0x17, + 0x93, 0x2f, 0x4f, 0x8b, 0x23, 0xa2, 0x16, 0xbf, 0xe3, 0xb7, 0x02, 0x0d, 0xa7, 0x68, 0x08, 0xc3, + 0x82, 0xd1, 0x78, 0x4e, 0x7c, 0xda, 0x0c, 0x88, 0xa4, 0x76, 0x9e, 0xab, 0x49, 0x17, 0xc8, 0x89, + 0x40, 0x71, 0xc1, 0x41, 0x64, 0xf4, 0x76, 0xd4, 0xea, 0x1a, 0x1d, 0xea, 0xd9, 0x56, 0x35, 0x7c, + 0xf5, 0xa5, 0xdc, 0x38, 0x1d, 0xea, 0xe9, 0x94, 0x09, 0xc4, 0x91, 0xec, 0x1d, 0xec, 0xb7, 0xde, + 0x46, 0x87, 0xee, 0x29, 0x0a, 0xe7, 0x0e, 0xe9, 0xd6, 0x9d, 0x4e, 0xa2, 0x5b, 0x67, 0x14, 0xf4, + 0x2d, 0x59, 0x84, 0x7d, 0xf0, 0x2b, 0x17, 0x93, 0x1f, 0x9e, 0x9c, 0xbd, 0xd3, 0x64, 0x8f, 0x7f, + 0x02, 0xdb, 0x8f, 0x7e, 0x83, 0x1c, 0x72, 0xf2, 0xa5, 0xe4, 0xc9, 0x62, 0x37, 0x47, 0x70, 0xe3, + 0x48, 0x64, 0xa5, 0x5a, 0x69, 0x2e, 0x70, 0x39, 0xd9, 0xe8, 0x4b, 0x6d, 0x9a, 0xd0, 0x19, 0x44, + 0x63, 0x7b, 0x21, 0xd2, 0xc5, 0x7a, 0x38, 0x9e, 0x15, 0x95, 0x67, 0x45, 0xda, 0x8b, 0x30, 0xc7, + 0xbc, 0xf7, 0x13, 0x09, 0x49, 0x50, 0x90, 0x0d, 0xf3, 0x47, 0x29, 0x3a, 0xd2, 0x59, 0xe6, 0x3a, + 0xd2, 0x6b, 0xd3, 0x74, 0x9b, 0xb4, 0xe9, 0xb4, 0xf4, 0x7e, 0x96, 0x25, 0xc9, 0xb4, 0x00, 0x2b, + 0xcd, 0xec, 0xff, 0x51, 0x7e, 0xaf, 0xf1, 0x1c, 0x25, 0xfb, 0xe3, 0x7e, 0x92, 0x65, 0x30, 0xfb, + 0x40, 0xe5, 0x9d, 0x7a, 0x3c, 0xcd, 0x1a, 0x97, 0x90, 0x0e, 0x9c, 0x68, 0xef, 0x53, 0xb9, 0x1e, + 0xc0, 0x65, 0x1d, 0x6d, 0xd4, 0xfb, 0xf3, 0xfd, 0xbe, 0x3e, 0xfc, 0x53, 0x41, 0x6c, 0x77, 0x0c, + 0x1e, 0x2d, 0x26, 0x4a, 0xf7, 0x4b, 0x43, 0x9b, 0x7d, 0x41, 0x96, 0xc1, 0x68, 0x33, 0xd1, 0x9c, + 0x73, 0x85, 0x1b, 0x27, 0xf5, 0xe6, 0x42, 0x28, 0xcd, 0x64, 0x1d, 0x57, 0x51, 0xa4, 0xa2, 0xd0, + 0xea, 0xf0, 0x1f, 0xdc, 0x6e, 0x26, 0xcf, 0x4e, 0x94, 0xaa, 0xba, 0x00, 0x68, 0x38, 0xc1, 0x60, + 0x37, 0x3a, 0x6e, 0xa9, 0x52, 0x87, 0x92, 0xb0, 0x11, 0x90, 0x36, 0x38, 0x21, 0xa4, 0x07, 0x0c, + 0xa6, 0xe1, 0x41, 0xe4, 0xb4, 0xa6, 0xed, 0x3d, 0x23, 0xae, 0xf2, 0xca, 0x49, 0x9a, 0x94, 0xc1, + 0x52, 0x9a, 0x9c, 0x8c, 0xee, 0xc3, 0x4c, 0xf4, 0x79, 0x50, 0xf0, 0x3a, 0x2e, 0x55, 0xee, 0xf2, + 0xb7, 0x50, 0x2e, 0x30, 0xd1, 0x77, 0x48, 0x9d, 0xf9, 0x59, 0x81, 0x91, 0xf1, 0xc8, 0x82, 0xf9, + 0x47, 0x1d, 0x8f, 0x3a, 0x79, 0xa7, 0xfe, 0x8c, 0xb8, 0x8d, 0xfc, 0x21, 0x25, 0x81, 0xf2, 0x3a, + 0x17, 0x91, 0xda, 0xef, 0x0f, 0x19, 0x44, 0xdf, 0x16, 0x18, 0x7d, 0x9b, 0x81, 0x34, 0x9c, 0x26, + 0xb2, 0x52, 0x52, 0xf1, 0xc9, 0x63, 0x8f, 0x12, 0xe5, 0x7e, 0xf2, 0xb9, 0x6a, 0xfb, 0x44, 0x7f, + 0xee, 0xb1, 0xdd, 0x89, 0x30, 0xf2, 0x8e, 0x78, 0xbe, 0xdf, 0x69, 0x53, 0xde, 0xd5, 0x28, 0xef, + 0x27, 0x8f, 0xf1, 0xd1, 0x8e, 0x08, 0x94, 0xce, 0xfb, 0x20, 0x69, 0x47, 0x24, 0x32, 0xba, 0x09, + 0xe3, 0x96, 0xb7, 0xbb, 0x4b, 0x7c, 0xe5, 0x21, 0xdf, 0xd8, 0xf9, 0x5e, 0x57, 0x9d, 0x09, 0x2f, + 0x3a, 0xb7, 0x6b, 0x38, 0x04, 0xb0, 0x96, 0xde, 0xf2, 0x76, 0xcb, 0x1d, 0xda, 0xee, 0xd0, 0x40, + 0x59, 0xe7, 0xf7, 0x59, 0x6a, 0xe9, 0x5b, 0xde, 0xae, 0xee, 0x09, 0xa7, 0x86, 0x25, 0x24, 0x6b, + 0x6e, 0xd7, 0xc8, 0x76, 0x67, 0x57, 0x29, 0xf2, 0x40, 0xa5, 0xe6, 0xb6, 0xc1, 0xcc, 0x1a, 0x16, + 0xee, 0xd5, 0x9f, 0x66, 0xa5, 0x5f, 0x92, 0xd1, 0x1c, 0x4c, 0x95, 0xca, 0x76, 0xad, 0x6a, 0x1b, + 0xd8, 0x36, 0xd7, 0x72, 0x67, 0xd0, 0x79, 0x40, 0xc5, 0x52, 0xd1, 0x2e, 0x1a, 0x96, 0x30, 0xd6, + 0x4c, 0xbb, 0xb0, 0x96, 0x03, 0x94, 0x83, 0x69, 0x6c, 0x4a, 0x96, 0x29, 0x66, 0xa9, 0x16, 0x1f, + 0xda, 0x26, 0xde, 0x14, 0x96, 0x73, 0x68, 0x19, 0xae, 0x54, 0x8b, 0x0f, 0x1f, 0x6d, 0x15, 0x05, + 0xa6, 0x66, 0x94, 0xd6, 0x6a, 0xd8, 0xdc, 0x2c, 0x3f, 0x36, 0x6b, 0x6b, 0x86, 0x6d, 0xe4, 0x16, + 0xd1, 0x3c, 0xcc, 0x54, 0x8d, 0xc7, 0x66, 0xad, 0x5a, 0x32, 0x2a, 0xd5, 0xf5, 0xb2, 0x9d, 0x5b, + 0x42, 0xd7, 0xe0, 0x2a, 0x13, 0x2e, 0x63, 0xb3, 0x16, 0x4d, 0xf0, 0x00, 0x97, 0x37, 0xfb, 0x10, + 0x15, 0x5d, 0x84, 0xc5, 0xc1, 0xae, 0x65, 0xc6, 0x4e, 0x4d, 0x69, 0xe0, 0xc2, 0x7a, 0x31, 0x9a, + 0x73, 0x05, 0xdd, 0x86, 0x57, 0x8e, 0x8b, 0x8a, 0x8f, 0xab, 0x76, 0xb9, 0x52, 0x33, 0x1e, 0x9a, + 0x25, 0x3b, 0x77, 0x13, 0x5d, 0x85, 0x8b, 0x79, 0xcb, 0x28, 0x6c, 0xac, 0x97, 0x2d, 0xb3, 0x56, + 0x31, 0x4d, 0x5c, 0xab, 0x94, 0xb1, 0x5d, 0xb3, 0x9f, 0xd6, 0xf0, 0xd3, 0x5c, 0x03, 0xa9, 0x70, + 0x79, 0xab, 0x34, 0x1c, 0x40, 0xd0, 0x25, 0x58, 0x5c, 0x33, 0x2d, 0xe3, 0x83, 0x94, 0xeb, 0x45, + 0x06, 0x5d, 0x81, 0x0b, 0x5b, 0xa5, 0xc1, 0xde, 0xcf, 0x32, 0xab, 0x7f, 0x03, 0x18, 0x65, 0x9f, + 0x20, 0x48, 0x81, 0x73, 0xd1, 0xde, 0x96, 0x4b, 0x66, 0xed, 0x41, 0xd9, 0xb2, 0xca, 0x4f, 0x4c, + 0x9c, 0x3b, 0x13, 0xae, 0x26, 0xe5, 0xa9, 0x6d, 0x95, 0xec, 0xa2, 0x55, 0xb3, 0x71, 0xf1, 0xe1, + 0x43, 0x13, 0xf7, 0x77, 0x28, 0x83, 0x10, 0xcc, 0x46, 0x04, 0xcb, 0x34, 0xd6, 0x4c, 0x9c, 0x1b, + 0x41, 0x37, 0xe1, 0x46, 0xdc, 0x36, 0x8c, 0x9e, 0x95, 0xe9, 0x8f, 0xb6, 0xca, 0x78, 0x6b, 0x33, + 0x37, 0xca, 0x0e, 0x4d, 0x64, 0x33, 0x2c, 0x2b, 0x37, 0x86, 0xae, 0x83, 0x1a, 0x6d, 0xb1, 0xb4, + 0xbb, 0xb1, 0xc8, 0x01, 0xdd, 0x83, 0x37, 0x4e, 0x00, 0x0d, 0x8b, 0x62, 0x8a, 0xa5, 0x64, 0x00, + 0x37, 0x5c, 0xcf, 0x34, 0x7a, 0x1d, 0x5e, 0x1b, 0xea, 0x1e, 0x26, 0x3a, 0x83, 0x1e, 0x40, 0x7e, + 0x00, 0x4b, 0xac, 0x32, 0xb4, 0x88, 0x73, 0x19, 0x0a, 0x45, 0xd4, 0xf0, 0x10, 0x16, 0xb0, 0x61, + 0x17, 0xd6, 0x73, 0xb3, 0x68, 0x15, 0x5e, 0x1e, 0x7a, 0x1c, 0xe2, 0x9b, 0xd0, 0x40, 0x06, 0xbc, + 0x7b, 0x3a, 0xec, 0xb0, 0xb0, 0x09, 0x7a, 0x09, 0x96, 0x87, 0x4b, 0x84, 0x5b, 0xb2, 0x83, 0xde, + 0x81, 0x37, 0x4f, 0x42, 0x0d, 0x9b, 0x62, 0xf7, 0xf8, 0x29, 0xc2, 0x63, 0xb0, 0xc7, 0xee, 0xde, + 0x70, 0x14, 0x3b, 0x18, 0x4d, 0xf4, 0x7f, 0xa0, 0x0d, 0x3c, 0xec, 0xf1, 0x6d, 0x79, 0x91, 0x41, + 0xb7, 0xe0, 0x26, 0x36, 0x4a, 0x6b, 0xe5, 0xcd, 0xda, 0x29, 0xf0, 0x9f, 0x65, 0xd0, 0x7b, 0xf0, + 0xf6, 0xc9, 0xc0, 0x61, 0x0b, 0xfc, 0x3c, 0x83, 0x4c, 0x78, 0xff, 0xd4, 0xf3, 0x0d, 0x93, 0xf9, + 0x22, 0x83, 0xae, 0xc1, 0x95, 0xc1, 0xfc, 0x30, 0x0f, 0x5f, 0x66, 0xd0, 0x0a, 0x5c, 0x3f, 0x76, + 0xa6, 0x10, 0xf9, 0x55, 0x06, 0xbd, 0x05, 0x77, 0x8f, 0x83, 0x0c, 0x0b, 0xe3, 0xd7, 0x19, 0x74, + 0x1f, 0xee, 0x9d, 0x62, 0x8e, 0x61, 0x02, 0xbf, 0x39, 0x66, 0x1d, 0x61, 0xb2, 0xbf, 0x3e, 0x79, + 0x1d, 0x21, 0xf2, 0xb7, 0x19, 0xb4, 0x04, 0x17, 0x07, 0x43, 0xd8, 0x99, 0xf8, 0x5d, 0x06, 0xdd, + 0x80, 0xe5, 0x63, 0x95, 0x18, 0xec, 0xf7, 0x19, 0xa4, 0xc0, 0x42, 0xa9, 0x5c, 0x7b, 0x60, 0x14, + 0xad, 0xda, 0x93, 0xa2, 0xbd, 0x5e, 0xab, 0xda, 0xd8, 0xac, 0x56, 0x73, 0xbf, 0x18, 0x61, 0xa1, + 0xc4, 0x3c, 0xa5, 0x72, 0xe8, 0xac, 0x3d, 0x28, 0xe3, 0x9a, 0x55, 0x7c, 0x6c, 0x96, 0x18, 0xf2, + 0xd3, 0x11, 0x34, 0x07, 0xc0, 0x60, 0x95, 0x72, 0xb1, 0x64, 0x57, 0x73, 0xdf, 0xcb, 0xa2, 0x19, + 0x98, 0x30, 0x9f, 0xda, 0x26, 0x2e, 0x19, 0x56, 0xee, 0xef, 0xd9, 0xd5, 0x7d, 0x98, 0x88, 0x7e, + 0xe5, 0x40, 0xe3, 0x30, 0xb2, 0xf1, 0x38, 0x77, 0x06, 0x4d, 0xc2, 0x98, 0x65, 0x1a, 0x55, 0x33, + 0x97, 0x41, 0x0b, 0x30, 0x67, 0x5a, 0x66, 0xc1, 0x2e, 0x96, 0x4b, 0x35, 0xbc, 0x55, 0x2a, 0xf1, + 0xc7, 0x33, 0x07, 0xd3, 0x4f, 0xd8, 0xcd, 0x8f, 0x2c, 0x59, 0xb4, 0x08, 0xf3, 0x56, 0xb9, 0xb0, + 0x51, 0xc3, 0x46, 0xc1, 0xc4, 0x91, 0x79, 0x94, 0x01, 0xb9, 0x50, 0x64, 0x19, 0x5b, 0xcd, 0xc3, + 0xd9, 0xf0, 0x27, 0x12, 0x34, 0x05, 0x67, 0x37, 0x1e, 0xd7, 0xd6, 0x8d, 0xea, 0x7a, 0xee, 0x4c, + 0x1f, 0x69, 0x3e, 0xad, 0x14, 0x31, 0x9b, 0x19, 0x60, 0xfc, 0x68, 0xc2, 0x69, 0x98, 0x28, 0x95, + 0x6b, 0x85, 0x75, 0xb3, 0xb0, 0x91, 0xcb, 0xde, 0xb9, 0x0f, 0x93, 0xb6, 0xef, 0xb8, 0x41, 0xdb, + 0xf3, 0x29, 0xba, 0x23, 0x0f, 0x66, 0xc3, 0x1f, 0x6a, 0xc3, 0x3f, 0x19, 0x5f, 0x9a, 0x3b, 0x1a, + 0x8b, 0xbf, 0x26, 0x6a, 0x67, 0x56, 0x32, 0xaf, 0x65, 0xf2, 0xe7, 0x5e, 0xfc, 0x79, 0xe9, 0xcc, + 0x8b, 0x6f, 0x96, 0x32, 0x5f, 0x7f, 0xb3, 0x94, 0xf9, 0xd3, 0x37, 0x4b, 0x99, 0x9f, 0xfc, 0x65, + 0xe9, 0xcc, 0xf6, 0x38, 0xff, 0x93, 0xf3, 0xdd, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x42, 0x92, + 0x53, 0x23, 0xbb, 0x1e, 0x00, 0x00, } diff --git a/functional/rpcpb/rpc.proto b/functional/rpcpb/rpc.proto index cbbe1ece8c2..57967d408a5 100644 --- a/functional/rpcpb/rpc.proto +++ b/functional/rpcpb/rpc.proto @@ -204,7 +204,7 @@ message Etcd { string Logger = 71 [(gogoproto.moretags) = "yaml:\"logger\""]; // LogOutputs is the log file to store current etcd server logs. - repeated string LogOutputs = 72 [(gogoproto.moretags) = "yaml:\"log-output\""]; + repeated string LogOutputs = 72 [(gogoproto.moretags) = "yaml:\"log-outputs\""]; bool Debug = 73 [(gogoproto.moretags) = "yaml:\"debug\""]; } diff --git a/functional/tester/cluster_read_config.go b/functional/tester/cluster_read_config.go index f8fb9e65222..eeaa5bc8a09 100644 --- a/functional/tester/cluster_read_config.go +++ b/functional/tester/cluster_read_config.go @@ -322,10 +322,10 @@ func read(lg *zap.Logger, fpath string) (*Cluster, error) { clus.Members[i].ClientCertData = string(data) } - if len(mem.Etcd.LogOutput) == 0 { - return nil, fmt.Errorf("mem.Etcd.LogOutput cannot be empty") + if len(mem.Etcd.LogOutputs) == 0 { + return nil, fmt.Errorf("mem.Etcd.LogOutputs cannot be empty") } - for _, v := range mem.Etcd.LogOutput { + for _, v := range mem.Etcd.LogOutputs { switch v { case "stderr", "stdout", "/dev/null", "default": default: diff --git a/functional/tester/cluster_test.go b/functional/tester/cluster_test.go index a5849abf438..661c006805b 100644 --- a/functional/tester/cluster_test.go +++ b/functional/tester/cluster_test.go @@ -63,7 +63,7 @@ func Test_read(t *testing.T) { PreVote: true, InitialCorruptCheck: true, Logger: "zap", - LogOutput: []string{"/tmp/etcd-functional-1/etcd.log"}, + LogOutputs: []string{"/tmp/etcd-functional-1/etcd.log"}, Debug: true, }, ClientCertData: "", @@ -116,7 +116,7 @@ func Test_read(t *testing.T) { PreVote: true, InitialCorruptCheck: true, Logger: "zap", - LogOutput: []string{"/tmp/etcd-functional-2/etcd.log"}, + LogOutputs: []string{"/tmp/etcd-functional-2/etcd.log"}, Debug: true, }, ClientCertData: "", @@ -169,7 +169,7 @@ func Test_read(t *testing.T) { PreVote: true, InitialCorruptCheck: true, Logger: "zap", - LogOutput: []string{"/tmp/etcd-functional-3/etcd.log"}, + LogOutputs: []string{"/tmp/etcd-functional-3/etcd.log"}, Debug: true, }, ClientCertData: "", From 58a603448a410bb9cdecb1c52052df629eee8aad Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:42:32 -0700 Subject: [PATCH 18/22] *: rename to "--log-outputs" in docs Signed-off-by: Gyuho Lee --- Documentation/op-guide/configuration.md | 2 +- Procfile | 6 +++--- embed/config_test.go | 2 +- functional.yaml | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/op-guide/configuration.md b/Documentation/op-guide/configuration.md index e48eff9e25b..1a5cd4d6b5e 100644 --- a/Documentation/op-guide/configuration.md +++ b/Documentation/op-guide/configuration.md @@ -317,7 +317,7 @@ The security flags help to [build a secure etcd cluster][security]. + default: capnslog + env variable: ETCD_LOGGER -### --log-output +### --log-outputs + Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd, or list of comma separated output targets. + default: default + env variable: ETCD_LOG_OUTPUT diff --git a/Procfile b/Procfile index 7026895add6..ca9b053c6c8 100644 --- a/Procfile +++ b/Procfile @@ -1,5 +1,5 @@ # Use goreman to run `go get github.com/mattn/goreman` -etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger zap --log-output stderr -etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger zap --log-output stderr -etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger zap --log-output stderr +etcd1: bin/etcd --name infra1 --listen-client-urls http://127.0.0.1:2379 --advertise-client-urls http://127.0.0.1:2379 --listen-peer-urls http://127.0.0.1:12380 --initial-advertise-peer-urls http://127.0.0.1:12380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger zap --log-outputs stderr +etcd2: bin/etcd --name infra2 --listen-client-urls http://127.0.0.1:22379 --advertise-client-urls http://127.0.0.1:22379 --listen-peer-urls http://127.0.0.1:22380 --initial-advertise-peer-urls http://127.0.0.1:22380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger zap --log-outputs stderr +etcd3: bin/etcd --name infra3 --listen-client-urls http://127.0.0.1:32379 --advertise-client-urls http://127.0.0.1:32379 --listen-peer-urls http://127.0.0.1:32380 --initial-advertise-peer-urls http://127.0.0.1:32380 --initial-cluster-token etcd-cluster-1 --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' --initial-cluster-state new --enable-pprof --logger zap --log-outputs stderr #proxy: bin/etcd grpc-proxy start --endpoints=127.0.0.1:2379,127.0.0.1:22379,127.0.0.1:32379 --listen-addr=127.0.0.1:23790 --advertise-client-url=127.0.0.1:23790 --enable-pprof diff --git a/embed/config_test.go b/embed/config_test.go index ef3d9dde11d..60b7c6d0315 100644 --- a/embed/config_test.go +++ b/embed/config_test.go @@ -34,7 +34,7 @@ func TestConfigFileOtherFields(t *testing.T) { PeerSecurityCfgFile securityConfig `json:"peer-transport-security"` ForceNewCluster bool `json:"force-new-cluster"` Logger string `json:"logger"` - LogOutputs []string `json:"log-output"` + LogOutputs []string `json:"log-outputs"` Debug bool `json:"debug"` }{ ctls, diff --git a/functional.yaml b/functional.yaml index a5e6cd7b6c7..ec3a5998a87 100644 --- a/functional.yaml +++ b/functional.yaml @@ -34,7 +34,7 @@ agent-configs: pre-vote: true initial-corrupt-check: true logger: zap - log-output: [/tmp/etcd-functional-1/etcd.log] + log-outputs: [/tmp/etcd-functional-1/etcd.log] debug: true client-cert-data: "" client-cert-path: "" @@ -85,7 +85,7 @@ agent-configs: pre-vote: true initial-corrupt-check: true logger: zap - log-output: [/tmp/etcd-functional-2/etcd.log] + log-outputs: [/tmp/etcd-functional-2/etcd.log] debug: true client-cert-data: "" client-cert-path: "" @@ -136,7 +136,7 @@ agent-configs: pre-vote: true initial-corrupt-check: true logger: zap - log-output: [/tmp/etcd-functional-3/etcd.log] + log-outputs: [/tmp/etcd-functional-3/etcd.log] debug: true client-cert-data: "" client-cert-path: "" From b748abca67264c2c3625cf5f9a82e02c615f733a Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 11:44:09 -0700 Subject: [PATCH 19/22] *: change typo in "auto-compaction-retention" field Signed-off-by: Gyuho Lee --- CHANGELOG-3.3.md | 4 ++-- Documentation/upgrades/upgrade_3_3.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md index c1d4b3e6aa0..e111aa5450c 100644 --- a/CHANGELOG-3.3.md +++ b/CHANGELOG-3.3.md @@ -156,7 +156,7 @@ See [code changes](https://github.com/coreos/etcd/compare/v3.2.0...v3.3.0) and [ - To deprecate [`/v3alpha`](https://github.com/coreos/etcd/issues/8125) in v3.4. - In v3.3, `curl -L http://localhost:2379/v3alpha/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` still works as a fallback to `curl -L http://localhost:2379/v3beta/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'`, but `curl -L http://localhost:2379/v3alpha/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` won't work in v3.4. Use `curl -L http://localhost:2379/v3beta/kv/put -X POST -d '{"key": "Zm9v", "value": "YmFy"}'` instead. - Change `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503). - - Now that `--auto-compaction-retention` accepts string values, etcd configuration YAML file `log-output` field must be changed to `string` type. + - Now that `--auto-compaction-retention` accepts string values, etcd configuration YAML file `auto-compaction-retention` field must be changed to `string` type. - Previously, `--config-file etcd.config.yaml` can have `auto-compaction-retention: 24` field, now must be `auto-compaction-retention: "24"` or `auto-compaction-retention: "24h"`. - If configured as `--auto-compaction-mode periodic --auto-compaction-retention "24h"`, the time duration value for `--auto-compaction-retention` flag must be valid for [`time.ParseDuration`](https://golang.org/pkg/time/#ParseDuration) function in Go. @@ -225,7 +225,7 @@ See [security doc](https://github.com/coreos/etcd/blob/master/Documentation/op-g - Useful for [bypassing critical APIs when monitoring etcd](https://github.com/coreos/etcd/issues/8060). - Add [`--auto-compaction-mode`](https://github.com/coreos/etcd/pull/8123) flag to [support revision-based compaction](https://github.com/coreos/etcd/issues/8098). - Change `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503). - - Now that `--auto-compaction-retention` accepts string values, etcd configuration YAML file `log-output` field must be changed to `string` type. + - Now that `--auto-compaction-retention` accepts string values, etcd configuration YAML file `auto-compaction-retention` field must be changed to `string` type. - Previously, `--config-file etcd.config.yaml` can have `auto-compaction-retention: 24` field, now must be `auto-compaction-retention: "24"` or `auto-compaction-retention: "24h"`. - If configured as `--auto-compaction-mode periodic --auto-compaction-retention "24h"`, the time duration value for `--auto-compaction-retention` flag must be valid for [`time.ParseDuration`](https://golang.org/pkg/time/#ParseDuration) function in Go. - e.g. `--auto-compaction-mode=revision --auto-compaction-retention=1000` automatically `Compact` on `"latest revision" - 1000` every 5-minute (when latest revision is 30000, compact on revision 29000). diff --git a/Documentation/upgrades/upgrade_3_3.md b/Documentation/upgrades/upgrade_3_3.md index bafcf4a85b5..8075ee5e088 100644 --- a/Documentation/upgrades/upgrade_3_3.md +++ b/Documentation/upgrades/upgrade_3_3.md @@ -14,7 +14,7 @@ Highlighted breaking changes in 3.3. #### Change in `--auto-compaction-retention` flag -Changed `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503). Now that `--auto-compaction-retention` accepts string values, etcd configuration YAML file `log-output` field must be changed to `string` type. Previously, `--config-file etcd.config.yaml` can have `auto-compaction-retention: 24` field, now must be `auto-compaction-retention: "24"` or `auto-compaction-retention: "24h"`. If configured as `--auto-compaction-mode periodic --auto-compaction-retention "24h"`, the time duration value for `--auto-compaction-retention` flag must be valid for [`time.ParseDuration`](https://golang.org/pkg/time/#ParseDuration) function in Go. +Changed `--auto-compaction-retention` flag to [accept string values](https://github.com/coreos/etcd/pull/8563) with [finer granularity](https://github.com/coreos/etcd/issues/8503). Now that `--auto-compaction-retention` accepts string values, etcd configuration YAML file `auto-compaction-retention` field must be changed to `string` type. Previously, `--config-file etcd.config.yaml` can have `auto-compaction-retention: 24` field, now must be `auto-compaction-retention: "24"` or `auto-compaction-retention: "24h"`. If configured as `--auto-compaction-mode periodic --auto-compaction-retention "24h"`, the time duration value for `--auto-compaction-retention` flag must be valid for [`time.ParseDuration`](https://golang.org/pkg/time/#ParseDuration) function in Go. ```diff # etcd.config.yaml From 88c70d0ca96185c8c5f6a72bfecb832c8ab61d8a Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 13:23:38 -0700 Subject: [PATCH 20/22] embed,integration,snapshot: use "LogOutputs" Signed-off-by: Gyuho Lee --- embed/config_test.go | 2 +- functional/agent/handler.go | 6 +++--- integration/embed_test.go | 4 ++-- snapshot/member_test.go | 2 +- snapshot/v3_snapshot_test.go | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/embed/config_test.go b/embed/config_test.go index 60b7c6d0315..3202b2e63b9 100644 --- a/embed/config_test.go +++ b/embed/config_test.go @@ -157,7 +157,7 @@ func mustCreateCfgFile(t *testing.T, b []byte) *os.File { func TestAutoCompactionModeInvalid(t *testing.T) { cfg := NewConfig() cfg.Logger = "zap" - cfg.LogOutput = []string{"/dev/null"} + cfg.LogOutputs = []string{"/dev/null"} cfg.Debug = false cfg.AutoCompactionMode = "period" err := cfg.Validate() diff --git a/functional/agent/handler.go b/functional/agent/handler.go index 714bcbd01a5..76f2eda3e90 100644 --- a/functional/agent/handler.go +++ b/functional/agent/handler.go @@ -88,11 +88,11 @@ func (srv *Server) handleTesterRequest(req *rpcpb.Request) (resp *rpcpb.Response // just archive the first file func (srv *Server) createEtcdLogFile() error { var err error - srv.etcdLogFile, err = os.Create(srv.Member.Etcd.LogOutput[0]) + srv.etcdLogFile, err = os.Create(srv.Member.Etcd.LogOutputs[0]) if err != nil { return err } - srv.lg.Info("created etcd log file", zap.String("path", srv.Member.Etcd.LogOutput[0])) + srv.lg.Info("created etcd log file", zap.String("path", srv.Member.Etcd.LogOutputs[0])) return nil } @@ -665,7 +665,7 @@ func (srv *Server) handle_SIGQUIT_ETCD_AND_ARCHIVE_DATA() (*rpcpb.Response, erro // TODO: support separate WAL directory if err = archive( srv.Member.BaseDir, - srv.Member.Etcd.LogOutput[0], + srv.Member.Etcd.LogOutputs[0], srv.Member.Etcd.DataDir, ); err != nil { return nil, err diff --git a/integration/embed_test.go b/integration/embed_test.go index 985fe3929fc..4df5ffbc6e6 100644 --- a/integration/embed_test.go +++ b/integration/embed_test.go @@ -53,7 +53,7 @@ func TestEmbedEtcd(t *testing.T) { for i := range tests { tests[i].cfg = *embed.NewConfig() tests[i].cfg.Logger = "zap" - tests[i].cfg.LogOutput = []string{"/dev/null"} + tests[i].cfg.LogOutputs = []string{"/dev/null"} tests[i].cfg.Debug = false } @@ -180,7 +180,7 @@ func newEmbedURLs(secure bool, n int) (urls []url.URL) { func setupEmbedCfg(cfg *embed.Config, curls []url.URL, purls []url.URL) { cfg.Logger = "zap" - cfg.LogOutput = []string{"/dev/null"} + cfg.LogOutputs = []string{"/dev/null"} cfg.Debug = false cfg.ClusterState = "new" diff --git a/snapshot/member_test.go b/snapshot/member_test.go index 652b0c94733..713297a978a 100644 --- a/snapshot/member_test.go +++ b/snapshot/member_test.go @@ -64,7 +64,7 @@ func TestSnapshotV3RestoreMultiMemberAdd(t *testing.T) { cfg := embed.NewConfig() cfg.Logger = "zap" - cfg.LogOutput = []string{"/dev/null"} + cfg.LogOutputs = []string{"/dev/null"} cfg.Debug = false cfg.Name = "3" cfg.InitialClusterToken = testClusterTkn diff --git a/snapshot/v3_snapshot_test.go b/snapshot/v3_snapshot_test.go index bed892efdd2..5443e9b79d7 100644 --- a/snapshot/v3_snapshot_test.go +++ b/snapshot/v3_snapshot_test.go @@ -44,7 +44,7 @@ func TestSnapshotV3RestoreSingle(t *testing.T) { cfg := embed.NewConfig() cfg.Logger = "zap" - cfg.LogOutput = []string{"/dev/null"} + cfg.LogOutputs = []string{"/dev/null"} cfg.Debug = false cfg.Name = "s1" cfg.InitialClusterToken = testClusterTkn @@ -153,7 +153,7 @@ func createSnapshotFile(t *testing.T, kvs []kv) string { cfg := embed.NewConfig() cfg.Logger = "zap" - cfg.LogOutput = []string{"/dev/null"} + cfg.LogOutputs = []string{"/dev/null"} cfg.Debug = false cfg.Name = "default" cfg.ClusterState = "new" @@ -220,7 +220,7 @@ func restoreCluster(t *testing.T, clusterN int, dbPath string) ( for i := 0; i < clusterN; i++ { cfg := embed.NewConfig() cfg.Logger = "zap" - cfg.LogOutput = []string{"/dev/null"} + cfg.LogOutputs = []string{"/dev/null"} cfg.Debug = false cfg.Name = fmt.Sprintf("%d", i) cfg.InitialClusterToken = testClusterTkn From 9cd9ae284ffcba4b4a23151daba54037e1cea3d2 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 13:52:30 -0700 Subject: [PATCH 21/22] pkg/logutil: do not build journald logger on windows Signed-off-by: Gyuho Lee --- pkg/logutil/zap_journald.go | 2 ++ pkg/logutil/zap_journald_test.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pkg/logutil/zap_journald.go b/pkg/logutil/zap_journald.go index 4489b990553..affef6418a2 100644 --- a/pkg/logutil/zap_journald.go +++ b/pkg/logutil/zap_journald.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build !windows + package logutil import ( diff --git a/pkg/logutil/zap_journald_test.go b/pkg/logutil/zap_journald_test.go index f9291cec688..3e9e727b151 100644 --- a/pkg/logutil/zap_journald_test.go +++ b/pkg/logutil/zap_journald_test.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build !windows + package logutil import ( From 154e2ac38e9513857c6707eaa6431a40c9167454 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Wed, 25 Apr 2018 13:52:53 -0700 Subject: [PATCH 22/22] embed: do not import journald dependencies on windows Signed-off-by: Gyuho Lee --- embed/config.go | 2 +- embed/journald_unix.go | 28 ++++++++++++++++++++++++++++ embed/journald_windows.go | 27 +++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 embed/journald_unix.go create mode 100644 embed/journald_windows.go diff --git a/embed/config.go b/embed/config.go index 73659e3aa60..9061b153c19 100644 --- a/embed/config.go +++ b/embed/config.go @@ -582,7 +582,7 @@ func (cfg *Config) setupLogging() error { } } else { // use stderr as fallback - syncer := zapcore.AddSync(logutil.NewJournaldWriter(os.Stderr)) + syncer := getZapWriteSyncer() lvl := zap.NewAtomicLevelAt(zap.InfoLevel) if cfg.Debug { lvl = zap.NewAtomicLevelAt(zap.DebugLevel) diff --git a/embed/journald_unix.go b/embed/journald_unix.go new file mode 100644 index 00000000000..8944b4c4a5a --- /dev/null +++ b/embed/journald_unix.go @@ -0,0 +1,28 @@ +// Copyright 2018 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. + +// +build !windows + +package embed + +import ( + "os" + + "github.com/coreos/etcd/pkg/logutil" + "go.uber.org/zap/zapcore" +) + +func getZapWriteSyncer() zapcore.WriteSyncer { + return zapcore.AddSync(logutil.NewJournaldWriter(os.Stderr)) +} diff --git a/embed/journald_windows.go b/embed/journald_windows.go new file mode 100644 index 00000000000..4ee146d35c8 --- /dev/null +++ b/embed/journald_windows.go @@ -0,0 +1,27 @@ +// Copyright 2018 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. + +// +build windows + +package embed + +import ( + "os" + + "go.uber.org/zap/zapcore" +) + +func getZapWriteSyncer() zapcore.WriteSyncer { + return zapcore.AddSync(os.Stderr) +}