ceph-csi/vendor/github.com/gemalto/flume/config.go

222 lines
6.5 KiB
Go
Raw Permalink Normal View History

package flume
import (
"encoding/json"
"fmt"
"go.uber.org/zap/zapcore"
"os"
"strings"
"time"
)
// DefaultConfigEnvVars is a list of the environment variables
// that ConfigFromEnv will search by default.
var DefaultConfigEnvVars = []string{"FLUME"}
// ConfigFromEnv configures flume from environment variables.
// It should be called from main():
//
// func main() {
// flume.ConfigFromEnv()
// ...
// }
//
// It searches envvars for the first environment
// variable that is set, and attempts to parse the value.
//
// If no environment variable is set, it silently does nothing.
//
// If an environment variable with a value is found, but parsing
// fails, an error is printed to stdout, and the error is returned.
//
// If envvars is empty, it defaults to DefaultConfigEnvVars.
//
func ConfigFromEnv(envvars ...string) error {
if len(envvars) == 0 {
envvars = DefaultConfigEnvVars
}
var configString string
for _, v := range envvars {
configString = os.Getenv(v)
if configString != "" {
err := ConfigString(configString)
if err != nil {
fmt.Println("error parsing log config from env var " + v + ": " + err.Error())
}
return err
}
}
return nil
}
// Config offers a declarative way to configure a Factory.
//
// The same things can be done by calling Factory methods, but
// Configs can be unmarshaled from JSON, making it a convenient
// way to configure most logging options from env vars or files, i.e.:
//
// err := flume.ConfigString(os.Getenv("flume"))
//
// Configs can be created and applied programmatically:
//
// err := flume.Configure(flume.Config{})
//
// Defaults are appropriate for a JSON encoded production logger:
//
// - LTSV encoder
// - full timestamps
// - default log level set to INFO
// - call sites are not logged
//
// An alternate set of defaults, more appropriate for development environments,
// can be configured with `Config{Development:true}`:
//
// err := flume.Configure(flume.Config{Development:true})
//
// - colorized terminal encoder
// - short timestamps
// - call sites are logged
//
// err := flume.Configure(flume.Config{Development:true})
//
// Any of the other configuration options can be specified to override
// the defaults.
//
// Note: If configuring the EncoderConfig setting, if any of the *Key properties
// are omitted, that entire field will be omitted.
type Config struct {
// DefaultLevel is the default log level for all loggers not
// otherwise configured by Levels. Defaults to Info.
DefaultLevel Level `json:"level" yaml:"level"`
// Levels configures log levels for particular named loggers. See
// LevelsString for format.
Levels string `json:"levels" yaml:"levels"`
// AddCaller annotates logs with the calling function's file
// name and line number. Defaults to true when the Development
// flag is set, false otherwise.
AddCaller *bool `json:"addCaller" yaml:"addCaller"`
// Encoding sets the logger's encoding. Valid values are "json",
// "console", "ltsv", "term", and "term-color".
// Defaults to "term-color" if development is true, else
// "ltsv"
Encoding string `json:"encoding" yaml:"encoding"`
// Development toggles the defaults used for the other
// settings. Defaults to false.
Development bool `json:"development" yaml:"development"`
// EncoderConfig sets options for the chosen encoder. See
// EncoderConfig for details. Defaults to NewEncoderConfig() if
// Development is false, otherwise defaults to NewDevelopmentEncoderConfig().
EncoderConfig *EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"`
}
// SetAddCaller sets the Config's AddCaller flag.
func (c *Config) SetAddCaller(b bool) {
c.AddCaller = &b
}
// UnsetAddCaller unsets the Config's AddCaller flag (reverting to defaults).
func (c *Config) UnsetAddCaller() {
c.AddCaller = nil
}
// EncoderConfig captures the options for encoders.
// Type alias to avoid exporting zap.
type EncoderConfig zapcore.EncoderConfig
type privEncCfg struct {
EncodeLevel string `json:"levelEncoder" yaml:"levelEncoder"`
EncodeTime string `json:"timeEncoder" yaml:"timeEncoder"`
}
// UnmarshalJSON implements json.Marshaler
func (enc *EncoderConfig) UnmarshalJSON(b []byte) error {
var zapCfg zapcore.EncoderConfig
err := json.Unmarshal(b, &zapCfg)
if err != nil {
return err
}
var pc privEncCfg
err = json.Unmarshal(b, &pc)
if err == nil {
switch pc.EncodeLevel {
case "", "abbr":
zapCfg.EncodeLevel = AbbrLevelEncoder
}
switch pc.EncodeTime {
case "":
zapCfg.EncodeTime = zapcore.ISO8601TimeEncoder
case "justtime":
zapCfg.EncodeTime = JustTimeEncoder
}
}
*enc = EncoderConfig(zapCfg)
return nil
}
// NewEncoderConfig returns an EncoderConfig with default settings.
func NewEncoderConfig() *EncoderConfig {
return &EncoderConfig{
MessageKey: "msg",
TimeKey: "time",
LevelKey: "level",
NameKey: "name",
CallerKey: "caller",
StacktraceKey: "stacktrace",
EncodeTime: zapcore.ISO8601TimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeLevel: AbbrLevelEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
}
// NewDevelopmentEncoderConfig returns an EncoderConfig which is intended
// for local development.
func NewDevelopmentEncoderConfig() *EncoderConfig {
cfg := NewEncoderConfig()
cfg.EncodeTime = JustTimeEncoder
cfg.EncodeDuration = zapcore.StringDurationEncoder
return cfg
}
// JustTimeEncoder is a timestamp encoder function which encodes time
// as a simple time of day, without a date. Intended for development and testing.
// Not good in a production system, where you probably need to know the date.
//
// encConfig := flume.EncoderConfig{}
// encConfig.EncodeTime = flume.JustTimeEncoder
//
func JustTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("15:04:05.000"))
}
// AbbrLevelEncoder encodes logging levels to the strings in the log entries.
// Encodes levels as 3-char abbreviations in upper case.
//
// encConfig := flume.EncoderConfig{}
// encConfig.EncodeTime = flume.AbbrLevelEncoder
//
func AbbrLevelEncoder(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
switch l {
case zapcore.DebugLevel:
enc.AppendString("DBG")
case zapcore.InfoLevel:
enc.AppendString("INF")
case zapcore.WarnLevel:
enc.AppendString("WRN")
case zapcore.ErrorLevel:
enc.AppendString("ERR")
case zapcore.PanicLevel, zapcore.FatalLevel, zapcore.DPanicLevel:
enc.AppendString("FTL")
default:
s := l.String()
if len(s) > 3 {
s = s[:3]
}
enc.AppendString(strings.ToUpper(s))
}
}