summaryrefslogtreecommitdiff
path: root/plugins/logger/config.go
blob: f7a5742c203ae085c215f329d0235b6976b8c029 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package logger

import (
	"strings"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

// ChannelConfig configures loggers per channel.
type ChannelConfig struct {
	// Dedicated channels per logger. By default logger allocated via named logger.
	Channels map[string]Config `json:"channels" yaml:"channels"`
}

type Config struct {
	// Mode configures logger based on some default template (development, production, off).
	Mode string `json:"mode" yaml:"mode"`

	// Level is the minimum enabled logging level. Note that this is a dynamic
	// level, so calling ChannelConfig.Level.SetLevel will atomically change the log
	// level of all loggers descended from this config.
	Level string `json:"level" yaml:"level"`

	// Encoding sets the logger's encoding. Valid values are "json" and
	// "console", as well as any third-party encodings registered via
	// RegisterEncoder.
	Encoding string `json:"encoding" yaml:"encoding"`

	// Output is a list of URLs or file paths to write logging output to.
	// See Open for details.
	Output []string `json:"output" yaml:"output"`

	// ErrorOutput is a list of URLs to write internal logger errors to.
	// The default is standard error.
	//
	// Note that this setting only affects internal errors; for sample code that
	// sends error-level logs to a different location from info- and debug-level
	// logs, see the package-level AdvancedConfiguration example.
	ErrorOutput []string `json:"errorOutput" yaml:"errorOutput"`
}

// ZapConfig converts config into Zap configuration.
func (cfg *Config) BuildLogger() (*zap.Logger, error) {
	var zCfg zap.Config
	switch strings.ToLower(cfg.Mode) {
	case "off", "none":
		return zap.NewNop(), nil
	case "production":
		zCfg = zap.NewProductionConfig()
	case "development":
		zCfg = zap.NewDevelopmentConfig()
	default:
		zCfg = zap.Config{
			Level:    zap.NewAtomicLevelAt(zap.DebugLevel),
			Encoding: "console",
			EncoderConfig: zapcore.EncoderConfig{
				MessageKey:   "message",
				LevelKey:     "level",
				TimeKey:      "time",
				NameKey:      "name",
				EncodeName:   ColoredHashedNameEncoder,
				EncodeLevel:  ColoredLevelEncoder,
				EncodeTime:   UTCTimeEncoder,
				EncodeCaller: zapcore.ShortCallerEncoder,
			},
			OutputPaths:      []string{"stderr"},
			ErrorOutputPaths: []string{"stderr"},
		}
	}

	if cfg.Level != "" {
		level := zap.NewAtomicLevel()
		if err := level.UnmarshalText([]byte(cfg.Level)); err == nil {
			zCfg.Level = level
		}
	}

	if cfg.Encoding != "" {
		zCfg.Encoding = cfg.Encoding
	}

	if len(cfg.Output) != 0 {
		zCfg.OutputPaths = cfg.Output
	}

	if len(cfg.ErrorOutput) != 0 {
		zCfg.ErrorOutputPaths = cfg.ErrorOutput
	}

	// todo: https://github.com/uber-go/zap/blob/master/FAQ.md#does-zap-support-log-rotation

	return zCfg.Build()
}