zrepl/cmd/config_logging.go
2017-09-23 12:58:13 +02:00

139 lines
3.0 KiB
Go

package cmd
import (
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"os"
"time"
)
type LoggingConfig struct {
Stdout struct {
Level logrus.Level
Format LogFormat
}
TCP *TCPLoggingConfig
}
type TCPLoggingConfig struct {
Level logrus.Level
Format LogFormat
Net string
Address string
RetryInterval time.Duration
}
func parseLogging(i interface{}) (c *LoggingConfig, err error) {
c = &LoggingConfig{}
c.Stdout.Level = logrus.WarnLevel
c.Stdout.Format = LogFormatHuman
if i == nil {
return c, nil
}
var asMap struct {
Stdout struct {
Level string
Format string
}
TCP struct {
Level string
Format string
Net string
Address string
RetryInterval string `mapstructure:"retry_interval"`
}
}
if err = mapstructure.Decode(i, &asMap); err != nil {
return nil, errors.Wrap(err, "mapstructure error")
}
if asMap.Stdout.Level != "" {
lvl, err := logrus.ParseLevel(asMap.Stdout.Level)
if err != nil {
return nil, errors.Wrap(err, "cannot parse stdout log level")
}
c.Stdout.Level = lvl
}
if asMap.Stdout.Format != "" {
format, err := parseLogFormat(asMap.Stdout.Format)
if err != nil {
return nil, errors.Wrap(err, "cannot parse log format")
}
c.Stdout.Format = format
}
if asMap.TCP.Address != "" {
c.TCP = &TCPLoggingConfig{}
c.TCP.Format, err = parseLogFormat(asMap.TCP.Format)
if err != nil {
return nil, errors.Wrap(err, "cannot parse log format")
}
c.TCP.Level, err = logrus.ParseLevel(asMap.TCP.Level)
if err != nil {
return nil, errors.Wrap(err, "cannot parse level")
}
c.TCP.RetryInterval, err = time.ParseDuration(asMap.TCP.RetryInterval)
c.TCP.Net, c.TCP.Address = asMap.TCP.Net, asMap.TCP.Address
}
return c, nil
}
type LogFormat string
const (
LogFormatHuman LogFormat = "human"
LogFormatLogfmt LogFormat = "logfmt"
LogFormatJSON LogFormat = "json"
)
func (f LogFormat) Formatter() logrus.Formatter {
switch f {
case LogFormatHuman:
return HumanFormatter{}
case LogFormatLogfmt:
return &logrus.TextFormatter{}
case LogFormatJSON:
return &logrus.JSONFormatter{}
default:
panic("incomplete implementation")
}
}
var LogFormats []LogFormat = []LogFormat{LogFormatHuman, LogFormatLogfmt, LogFormatJSON}
func parseLogFormat(i interface{}) (f LogFormat, err error) {
var is string
switch j := i.(type) {
case string:
is = j
default:
return "", errors.Errorf("invalid log format: wrong type: %T", i)
}
for _, f := range LogFormats {
if string(f) == is {
return f, nil
}
}
return "", errors.Errorf("invalid log format: '%s'", is)
}
func (c *LoggingConfig) MakeLogrus() (l logrus.FieldLogger) {
log := logrus.New()
log.Out = os.Stdout
log.Level = logrus.DebugLevel // FIXTHIS IN LOGRUS
log.Formatter = c.Stdout.Format.Formatter()
th := &TCPHook{Formatter: JSONFormatter{}, MinLevel: c.TCP.Level, Net: c.TCP.Net, Address: c.TCP.Address, RetryInterval: c.TCP.RetryInterval}
log.Hooks.Add(th)
return log
}