diff options
Diffstat (limited to 'vendor/github.com/mattermost/logr/v2/config/config.go')
-rw-r--r-- | vendor/github.com/mattermost/logr/v2/config/config.go | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/vendor/github.com/mattermost/logr/v2/config/config.go b/vendor/github.com/mattermost/logr/v2/config/config.go new file mode 100644 index 00000000..a93b7a25 --- /dev/null +++ b/vendor/github.com/mattermost/logr/v2/config/config.go @@ -0,0 +1,209 @@ +package config + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "strings" + + "github.com/mattermost/logr/v2" + "github.com/mattermost/logr/v2/formatters" + "github.com/mattermost/logr/v2/targets" +) + +type TargetCfg struct { + Type string `json:"type"` // one of "console", "file", "tcp", "syslog", "none". + Options json.RawMessage `json:"options,omitempty"` + Format string `json:"format"` // one of "json", "plain", "gelf" + FormatOptions json.RawMessage `json:"format_options,omitempty"` + Levels []logr.Level `json:"levels"` + MaxQueueSize int `json:"maxqueuesize,omitempty"` +} + +type ConsoleOptions struct { + Out string `json:"out"` // one of "stdout", "stderr" +} + +type TargetFactory func(targetType string, options json.RawMessage) (logr.Target, error) +type FormatterFactory func(format string, options json.RawMessage) (logr.Formatter, error) + +type Factories struct { + targetFactory TargetFactory // can be nil + formatterFactory FormatterFactory // can be nil +} + +var removeAll = func(ti logr.TargetInfo) bool { return true } + +// ConfigureTargets replaces the current list of log targets with a new one based on a map +// of name->TargetCfg. The map of TargetCfg's would typically be serialized from a JSON +// source or can be programmatically created. +// +// An optional set of factories can be provided which will be called to create any target +// types or formatters not built-in. +// +// To append log targets to an existing config, use `(*Logr).AddTarget` or +// `(*Logr).AddTargetFromConfig` instead. +func ConfigureTargets(lgr *logr.Logr, config map[string]TargetCfg, factories *Factories) error { + if err := lgr.RemoveTargets(context.Background(), removeAll); err != nil { + return fmt.Errorf("error removing existing log targets: %w", err) + } + + if factories == nil { + factories = &Factories{nil, nil} + } + + for name, tcfg := range config { + target, err := newTarget(tcfg.Type, tcfg.Options, factories.targetFactory) + if err != nil { + return fmt.Errorf("error creating log target %s: %w", name, err) + } + + if target == nil { + continue + } + + formatter, err := newFormatter(tcfg.Format, tcfg.FormatOptions, factories.formatterFactory) + if err != nil { + return fmt.Errorf("error creating formatter for log target %s: %w", name, err) + } + + filter := newFilter(tcfg.Levels) + qSize := tcfg.MaxQueueSize + if qSize == 0 { + qSize = logr.DefaultMaxQueueSize + } + + if err = lgr.AddTarget(target, name, filter, formatter, qSize); err != nil { + return fmt.Errorf("error adding log target %s: %w", name, err) + } + } + return nil +} + +func newFilter(levels []logr.Level) logr.Filter { + filter := &logr.CustomFilter{} + for _, lvl := range levels { + filter.Add(lvl) + } + return filter +} + +func newTarget(targetType string, options json.RawMessage, factory TargetFactory) (logr.Target, error) { + switch strings.ToLower(targetType) { + case "console": + c := ConsoleOptions{} + if len(options) != 0 { + if err := json.Unmarshal(options, &c); err != nil { + return nil, fmt.Errorf("error decoding console target options: %w", err) + } + } + var w io.Writer + switch c.Out { + case "stderr": + w = os.Stderr + case "stdout", "": + w = os.Stdout + default: + return nil, fmt.Errorf("invalid console target option '%s'", c.Out) + } + return targets.NewWriterTarget(w), nil + case "file": + fo := targets.FileOptions{} + if len(options) == 0 { + return nil, errors.New("missing file target options") + } + if err := json.Unmarshal(options, &fo); err != nil { + return nil, fmt.Errorf("error decoding file target options: %w", err) + } + if err := fo.CheckValid(); err != nil { + return nil, fmt.Errorf("invalid file target options: %w", err) + } + return targets.NewFileTarget(fo), nil + case "tcp": + to := targets.TcpOptions{} + if len(options) == 0 { + return nil, errors.New("missing TCP target options") + } + if err := json.Unmarshal(options, &to); err != nil { + return nil, fmt.Errorf("error decoding TCP target options: %w", err) + } + if err := to.CheckValid(); err != nil { + return nil, fmt.Errorf("invalid TCP target options: %w", err) + } + return targets.NewTcpTarget(&to), nil + case "syslog": + so := targets.SyslogOptions{} + if len(options) == 0 { + return nil, errors.New("missing SysLog target options") + } + if err := json.Unmarshal(options, &so); err != nil { + return nil, fmt.Errorf("error decoding Syslog target options: %w", err) + } + if err := so.CheckValid(); err != nil { + return nil, fmt.Errorf("invalid SysLog target options: %w", err) + } + return targets.NewSyslogTarget(&so) + case "none": + return nil, nil + default: + if factory != nil { + t, err := factory(targetType, options) + if err != nil || t == nil { + return nil, fmt.Errorf("error from target factory: %w", err) + } + return t, nil + } + } + return nil, fmt.Errorf("target type '%s' is unrecogized", targetType) +} + +func newFormatter(format string, options json.RawMessage, factory FormatterFactory) (logr.Formatter, error) { + switch strings.ToLower(format) { + case "json": + j := formatters.JSON{} + if len(options) != 0 { + if err := json.Unmarshal(options, &j); err != nil { + return nil, fmt.Errorf("error decoding JSON formatter options: %w", err) + } + if err := j.CheckValid(); err != nil { + return nil, fmt.Errorf("invalid JSON formatter options: %w", err) + } + } + return &j, nil + case "plain": + p := formatters.Plain{} + if len(options) != 0 { + if err := json.Unmarshal(options, &p); err != nil { + return nil, fmt.Errorf("error decoding Plain formatter options: %w", err) + } + if err := p.CheckValid(); err != nil { + return nil, fmt.Errorf("invalid plain formatter options: %w", err) + } + } + return &p, nil + case "gelf": + g := formatters.Gelf{} + if len(options) != 0 { + if err := json.Unmarshal(options, &g); err != nil { + return nil, fmt.Errorf("error decoding Gelf formatter options: %w", err) + } + if err := g.CheckValid(); err != nil { + return nil, fmt.Errorf("invalid GELF formatter options: %w", err) + } + } + return &g, nil + + default: + if factory != nil { + f, err := factory(format, options) + if err != nil || f == nil { + return nil, fmt.Errorf("error from formatter factory: %w", err) + } + return f, nil + } + } + return nil, fmt.Errorf("format '%s' is unrecogized", format) +} |