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}