Newer
Older
package orusapi
import (
"io"
"github.com/rs/zerolog"
"golang.org/x/term"
// NewLoggingOptions creates a LoggingOptions.
func NewLoggingOptions(output io.Writer) *LoggingOptions {
o.Setup(output)
// DefaultLogger ...
func DefaultLogger(output io.Writer) zerolog.Logger {
return zerolog.
New(output).
With().
Timestamp().
Logger().
Level(zerolog.WarnLevel)
}
// LoggingOptions holds the logging options.
type LoggingOptions struct {
Level string `long:"level" env:"LEVEL" ini-name:"level" choice:"trace" choice:"debug" choice:"info" choice:"warn" choice:"error" choice:"fatal" choice:"panic" choice:"auto" default:"auto" description:"log level. 'auto' selects 'info' when stdout is a tty, 'error' otherwise."` //nolint:lll
Format string `long:"format" env:"FORMAT" ini-name:"format" choice:"json" choice:"pretty" choice:"auto" default:"auto" description:"Logs format. 'auto' selects 'pretty' if stdout is a tty."` //nolint:lll
Verbose func() `short:"v" long:"verbose" no-ini:"t" description:"Increase log verbosity. Can be repeated"`
logOutput io.Writer `no-flag:"t"`
logFinalOutput io.Writer `no-flag:"t"`
wrappedOutput io.Writer `no-flag:"t"`
logWrappers []func(io.Writer) io.Writer `no-flag:"t"`
log *zerolog.Logger `no-flag:"t"`
minLevel zerolog.Level
verboseCount int `no-flag:"t"`
lockedVerbose bool
lockedLevel string
lockedFormat string
}
func (o *LoggingOptions) Lock(lockLevel, lockFormat bool) {
o.lockedVerbose = true
if lockLevel {
o.lockedLevel = o.Level
}
if lockFormat {
o.lockedFormat = o.Format
}
// Logger returns the latest configured logger.
func (o *LoggingOptions) Logger() *zerolog.Logger {
if o.log == nil {
o.BuildLogger()
}
return o.log
func (o *LoggingOptions) Output() io.Writer {
return o.wrappedOutput
}
// AddLogWrapper adds a log wrapper to the stack.
func (o *LoggingOptions) AddLogWrapper(wrapper func(io.Writer) io.Writer) {
o.logWrappers = append(o.logWrappers, wrapper)
}
// SetMinLoggingLevel makes sure the logging level is not under a given value.
func (o *LoggingOptions) SetMinLoggingLevel(level zerolog.Level) {
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
o.minLevel = level
}
func parseOutputFormat(format string, finalOutput io.Writer) io.Writer {
switch format {
case "pretty":
return ConsoleWriter{Out: finalOutput}
case "json":
return finalOutput
default:
panic("unknown 'log-format' value: " + format)
}
}
func parseLogLevel(value string, finalOutput io.Writer) zerolog.Level {
if value == "auto" || value == "" {
if outputFile, hasFd := finalOutput.(interface{ Fd() uintptr }); hasFd &&
term.IsTerminal(int(outputFile.Fd())) {
value = zerolog.LevelInfoValue
} else {
value = zerolog.LevelWarnValue
}
}
level, err := zerolog.ParseLevel(value)
if err != nil {
panic(err)
}
return level
}
func (o LoggingOptions) buildOutput() io.Writer {
format := o.GetFormat()
if format == "auto" || format == "" {
if outputFile, hasFd := o.logFinalOutput.(interface{ Fd() uintptr }); hasFd &&
term.IsTerminal(int(outputFile.Fd())) {
format = "pretty"
} else {
format = "json"
}
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
out := parseOutputFormat(format, o.logFinalOutput)
for _, wrapper := range o.logWrappers {
out = wrapper(out)
}
return out
}
func (o LoggingOptions) GetLevel() string {
if o.lockedLevel != "" {
return o.lockedLevel
}
return o.Level
}
func (o LoggingOptions) GetFormat() string {
if o.lockedFormat != "" {
return o.lockedFormat
}
return o.Format
}
// BuildLogger rebuild the logger even if already initialized
func (o *LoggingOptions) BuildLogger() {
out := o.buildOutput()
o.wrappedOutput = out
level := parseLogLevel(o.GetLevel(), o.logFinalOutput)
level -= zerolog.Level(o.verboseCount)
log := zerolog.
New(out).
With().
Timestamp().
Logger().
Level(level)
o.log = &log
func (o *LoggingOptions) Setup(output io.Writer) {
o.logFinalOutput = output
o.Verbose = func() {
if !o.lockedVerbose {
o.verboseCount++