| // Copyright 2019 The etcd Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package logutil |
| |
| import ( |
| "sort" |
| |
| "go.uber.org/zap" |
| "go.uber.org/zap/zapcore" |
| ) |
| |
| // DefaultZapLoggerConfig defines default zap logger configuration. |
| var DefaultZapLoggerConfig = zap.Config{ |
| Level: zap.NewAtomicLevelAt(zap.InfoLevel), |
| |
| Development: false, |
| Sampling: &zap.SamplingConfig{ |
| Initial: 100, |
| Thereafter: 100, |
| }, |
| |
| Encoding: "json", |
| |
| // copied from "zap.NewProductionEncoderConfig" with some updates |
| EncoderConfig: zapcore.EncoderConfig{ |
| TimeKey: "ts", |
| LevelKey: "level", |
| NameKey: "logger", |
| CallerKey: "caller", |
| MessageKey: "msg", |
| StacktraceKey: "stacktrace", |
| LineEnding: zapcore.DefaultLineEnding, |
| EncodeLevel: zapcore.LowercaseLevelEncoder, |
| EncodeTime: zapcore.ISO8601TimeEncoder, |
| EncodeDuration: zapcore.StringDurationEncoder, |
| EncodeCaller: zapcore.ShortCallerEncoder, |
| }, |
| |
| // Use "/dev/null" to discard all |
| OutputPaths: []string{"stderr"}, |
| ErrorOutputPaths: []string{"stderr"}, |
| } |
| |
| // AddOutputPaths adds output paths to the existing output paths, resolving conflicts. |
| func AddOutputPaths(cfg zap.Config, outputPaths, errorOutputPaths []string) zap.Config { |
| outputs := make(map[string]struct{}) |
| for _, v := range cfg.OutputPaths { |
| outputs[v] = struct{}{} |
| } |
| for _, v := range outputPaths { |
| outputs[v] = struct{}{} |
| } |
| outputSlice := make([]string, 0) |
| if _, ok := outputs["/dev/null"]; ok { |
| // "/dev/null" to discard all |
| outputSlice = []string{"/dev/null"} |
| } else { |
| for k := range outputs { |
| outputSlice = append(outputSlice, k) |
| } |
| } |
| cfg.OutputPaths = outputSlice |
| sort.Strings(cfg.OutputPaths) |
| |
| errOutputs := make(map[string]struct{}) |
| for _, v := range cfg.ErrorOutputPaths { |
| errOutputs[v] = struct{}{} |
| } |
| for _, v := range errorOutputPaths { |
| errOutputs[v] = struct{}{} |
| } |
| errOutputSlice := make([]string, 0) |
| if _, ok := errOutputs["/dev/null"]; ok { |
| // "/dev/null" to discard all |
| errOutputSlice = []string{"/dev/null"} |
| } else { |
| for k := range errOutputs { |
| errOutputSlice = append(errOutputSlice, k) |
| } |
| } |
| cfg.ErrorOutputPaths = errOutputSlice |
| sort.Strings(cfg.ErrorOutputPaths) |
| |
| return cfg |
| } |