Parent directory

config.go

4085 bytes
  1package config
  2
  3import (
  4	"fmt"
  5	"strings"
  6
  7	"github.com/fatih/color"
  8	"github.com/jessevdk/go-flags"
  9)
 10
 11const (
 12	Trace = iota
 13	Debug
 14	Info
 15	Warning
 16	Error
 17	Fatal
 18)
 19
 20type Config struct {
 21	// LogLevel is the level filter for the log output
 22	LogLevel int
 23	// OutputFields is a list of fields to include on the log output
 24	OutputFields []string
 25	// ExcludeFields is a list of fields to exclude from the log output
 26	ExcludeFields []string
 27	// Filter is a map of fields and values which are used to filter the log output
 28	Filter map[string]string
 29	// NoTime disables the time output
 30	NoTime bool
 31	// Keep lines with no fields
 32	KeepEmpty bool
 33	// Only values
 34	Raw bool
 35	// All after output in record order (causes output to become order)
 36	All bool
 37	// How long can a line be?
 38	BufferSize int
 39}
 40
 41type rawConfig struct {
 42	LogLevel      string `long:"level" short:"l" description:"Log level filter. One of TRACE, DEBUG, INFO, WARN, ERROR, FATAL" default:"INFO"` // nolint:lll
 43	OutputFields  string `long:"output" short:"o" description:"Output field selector (comma separated)"`
 44	ExcludeFields string `long:"exclude" short:"e" description:"Exclude field selector (comma separated)"`
 45	Filter        string `long:"filter" short:"f" description:"Filter fields (key=value comma separated)"`
 46	NoColor       bool   `long:"no-color" short:"n" description:"Disable color output"`
 47	ForceColor    bool   `long:"force-color" short:"c" description:"Force color output, even when outputting to a pipe"`
 48	NoTime        bool   `long:"no-time" short:"t" description:"Disable time output"`
 49	KeepEmpty     bool   `long:"keep-empty" short:"k" description:"Keep lines with no field present selected by output or with all excluded"` // nolint:lll
 50	Raw           bool   `long:"raw" short:"r" description:"Output only selected fields values (comma separated) lcut like"`                  // nolint:lll
 51	All           bool   `long:"all" short:"A" description:"Output all field after the output fields effectivly making it ordered"`           // nolint:lll
 52	BufferSize    int    `long:"buffer-size" short:"B" description:"How long should a line be expected to be?" default:"1048576"`             // nolint:lll
 53}
 54
 55func Parse() (*Config, error) {
 56	var raw rawConfig
 57
 58	parser := flags.NewParser(&raw, flags.HelpFlag|flags.PassDoubleDash)
 59	_, err := parser.Parse()
 60	if err != nil {
 61		return nil, err
 62	}
 63
 64	if raw.ExcludeFields != "" && raw.OutputFields != "" {
 65		return nil, fmt.Errorf("cannot use both --exclude and --output")
 66	}
 67
 68	cfg := Config{
 69		OutputFields:  parseFieldList(raw.OutputFields),
 70		ExcludeFields: parseFieldList(raw.ExcludeFields),
 71	}
 72	err = cfg.setFilter(raw.Filter)
 73	if err != nil {
 74		return nil, err
 75	}
 76	err = cfg.setLevel(raw.LogLevel)
 77	if err != nil {
 78		return nil, err
 79	}
 80	if raw.ForceColor && raw.NoColor {
 81		return nil, fmt.Errorf("cannot use both --force-color and --no-color")
 82	}
 83	if raw.ForceColor {
 84		color.NoColor = false
 85	}
 86	if raw.NoColor {
 87		color.NoColor = true
 88	}
 89	if raw.NoTime {
 90		cfg.NoTime = true
 91	}
 92	if raw.KeepEmpty {
 93		cfg.KeepEmpty = true
 94	}
 95	if raw.Raw {
 96		cfg.Raw = true
 97	}
 98	if raw.All {
 99		cfg.All = true
100	}
101	if raw.BufferSize != 0 {
102		cfg.BufferSize = raw.BufferSize
103	}
104	return &cfg, nil
105}
106
107func (c *Config) setLevel(level string) error {
108	switch level {
109	case "TRACE":
110		c.LogLevel = Trace
111	case "DEBUG":
112		c.LogLevel = Debug
113	case "INFO":
114		c.LogLevel = Info
115	case "WARN":
116		c.LogLevel = Warning
117	case "ERROR":
118		c.LogLevel = Error
119	case "FATAL":
120		c.LogLevel = Fatal
121	default:
122		return fmt.Errorf("invalid log level: %s", level)
123	}
124	return nil
125}
126
127func parseFieldList(fields string) []string {
128	fields = strings.Trim(fields, " ")
129	if fields == "" {
130		return nil
131	}
132	return strings.Split(fields, ",")
133}
134
135func (c *Config) setFilter(filter string) error {
136	if filter == "" {
137		return nil
138	}
139
140	filters := strings.Split(filter, ",")
141	c.Filter = make(map[string]string)
142	for _, f := range filters {
143		f = strings.Trim(f, " ")
144		parts := strings.Split(f, "=")
145		if len(parts) != 2 {
146			return fmt.Errorf("invalid filter: %s", f)
147		}
148		c.Filter[parts[0]] = parts[1]
149	}
150	return nil
151}