Files
opencloud/extensions/glauth/pkg/mlogr/mlogr.go
Christian Richter d4442941a1 refactor glauth
Signed-off-by: Christian Richter <crichter@owncloud.com>
2022-04-13 17:04:37 +02:00

131 lines
2.9 KiB
Go

package mlogr
import (
"errors"
"github.com/go-logr/logr"
plog "github.com/owncloud/ocis/ocis-pkg/log"
"github.com/rs/zerolog"
)
const debugVerbosity = 6
const traceVerbosity = 8
// New returns a logr.Logger which is implemented by the log.
func New(l *plog.Logger) logr.Logger {
sink := logSink{
l: l,
verbosity: 0,
prefix: "glauth",
values: nil,
}
return logr.New(sink)
}
func (l logSink) Init(info logr.RuntimeInfo) {
}
// logSink is a logr.LogSink that uses the ocis-pkg log.
type logSink struct {
l *plog.Logger
verbosity int
prefix string
values []interface{}
}
func (l logSink) clone() logSink {
out := l
out.values = copySlice(l.values)
return out
}
func copySlice(in []interface{}) []interface{} {
out := make([]interface{}, len(in))
copy(out, in)
return out
}
// add converts a bunch of arbitrary key-value pairs into zerolog fields.
func add(e *zerolog.Event, keysAndVals []interface{}) {
// make sure we got an even number of arguments
if len(keysAndVals)%2 != 0 {
e.Interface("args", keysAndVals).
AnErr("zerologr-err", errors.New("odd number of arguments passed as key-value pairs for logging")).
Stack()
return
}
for i := 0; i < len(keysAndVals); {
// process a key-value pair,
// ensuring that the key is a string
key, val := keysAndVals[i], keysAndVals[i+1]
keyStr, isString := key.(string)
if !isString {
// if the key isn't a string, log additional error
e.Interface("invalid key", key).
AnErr("zerologr-err", errors.New("non-string key argument passed to logging, ignoring all later arguments")).
Stack()
return
}
e.Interface(keyStr, val)
i += 2
}
}
func (l logSink) Info(level int, msg string, kvList ...interface{}) {
if l.Enabled(level) {
var e *zerolog.Event
if l.verbosity < debugVerbosity {
e = l.l.Info()
} else if l.verbosity < traceVerbosity {
e = l.l.Debug()
} else {
e = l.l.Trace()
}
e.Int("verbosity", l.verbosity)
if l.prefix != "" {
e.Str("name", l.prefix)
}
add(e, l.values)
add(e, kvList)
e.Msg(msg)
}
}
func (l logSink) Enabled(level int) bool {
return true
}
func (l logSink) Error(err error, msg string, keysAndVals ...interface{}) {
e := l.l.Error().Err(err)
if l.prefix != "" {
e.Str("name", l.prefix)
}
add(e, l.values)
add(e, keysAndVals)
e.Msg(msg)
}
// WithName returns a new logr.LogSink with the specified name appended. zerologr
// uses '/' characters to separate name elements. Callers should not pass '/'
// in the provided name string, but this library does not actually enforce that.
func (l logSink) WithName(name string) logr.LogSink {
nl := l.clone()
if len(l.prefix) > 0 {
nl.prefix = l.prefix + "/"
}
nl.prefix += name
return nl
}
func (l logSink) WithValues(kvList ...interface{}) logr.LogSink {
nl := l.clone()
nl.values = append(nl.values, kvList...)
return nl
}
var _ logr.LogSink = logSink{}