// 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(ConvertToZapLevel(DefaultLogLevel)), 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 }