zap.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2019 The etcd Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package logutil
  15. import (
  16. "sort"
  17. "go.uber.org/zap"
  18. "go.uber.org/zap/zapcore"
  19. )
  20. // CreateDefaultZapLogger creates a logger with default zap configuration
  21. func CreateDefaultZapLogger(level zapcore.Level) (*zap.Logger, error) {
  22. lcfg := DefaultZapLoggerConfig
  23. lcfg.Level = zap.NewAtomicLevelAt(level)
  24. c, err := lcfg.Build()
  25. if err != nil {
  26. return nil, err
  27. }
  28. return c, nil
  29. }
  30. // DefaultZapLoggerConfig defines default zap logger configuration.
  31. var DefaultZapLoggerConfig = zap.Config{
  32. Level: zap.NewAtomicLevelAt(ConvertToZapLevel(DefaultLogLevel)),
  33. Development: false,
  34. Sampling: &zap.SamplingConfig{
  35. Initial: 100,
  36. Thereafter: 100,
  37. },
  38. Encoding: "json",
  39. // copied from "zap.NewProductionEncoderConfig" with some updates
  40. EncoderConfig: zapcore.EncoderConfig{
  41. TimeKey: "ts",
  42. LevelKey: "level",
  43. NameKey: "logger",
  44. CallerKey: "caller",
  45. MessageKey: "msg",
  46. StacktraceKey: "stacktrace",
  47. LineEnding: zapcore.DefaultLineEnding,
  48. EncodeLevel: zapcore.LowercaseLevelEncoder,
  49. EncodeTime: zapcore.ISO8601TimeEncoder,
  50. EncodeDuration: zapcore.StringDurationEncoder,
  51. EncodeCaller: zapcore.ShortCallerEncoder,
  52. },
  53. // Use "/dev/null" to discard all
  54. OutputPaths: []string{"stderr"},
  55. ErrorOutputPaths: []string{"stderr"},
  56. }
  57. // MergeOutputPaths merges logging output paths, resolving conflicts.
  58. func MergeOutputPaths(cfg zap.Config) zap.Config {
  59. outputs := make(map[string]struct{})
  60. for _, v := range cfg.OutputPaths {
  61. outputs[v] = struct{}{}
  62. }
  63. outputSlice := make([]string, 0)
  64. if _, ok := outputs["/dev/null"]; ok {
  65. // "/dev/null" to discard all
  66. outputSlice = []string{"/dev/null"}
  67. } else {
  68. for k := range outputs {
  69. outputSlice = append(outputSlice, k)
  70. }
  71. }
  72. cfg.OutputPaths = outputSlice
  73. sort.Strings(cfg.OutputPaths)
  74. errOutputs := make(map[string]struct{})
  75. for _, v := range cfg.ErrorOutputPaths {
  76. errOutputs[v] = struct{}{}
  77. }
  78. errOutputSlice := make([]string, 0)
  79. if _, ok := errOutputs["/dev/null"]; ok {
  80. // "/dev/null" to discard all
  81. errOutputSlice = []string{"/dev/null"}
  82. } else {
  83. for k := range errOutputs {
  84. errOutputSlice = append(errOutputSlice, k)
  85. }
  86. }
  87. cfg.ErrorOutputPaths = errOutputSlice
  88. sort.Strings(cfg.ErrorOutputPaths)
  89. return cfg
  90. }