mirror of
https://github.com/zrepl/zrepl.git
synced 2024-12-23 07:28:57 +01:00
139 lines
3.0 KiB
Go
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
|
|
|
|
}
|