Skip to content

Commit

Permalink
plugin/klogr: support for go-logr
Browse files Browse the repository at this point in the history
Closes #237.
  • Loading branch information
Luke-Vear authored and twmb committed Feb 25, 2023
1 parent 3322f31 commit d8230ca
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 0 deletions.
14 changes: 14 additions & 0 deletions plugin/klogr/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/twmb/franz-go/plugin/klogr

go 1.18

require (
github.com/go-logr/logr v1.2.3
github.com/twmb/franz-go v1.12.1
)

require (
github.com/klauspost/compress v1.15.15 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/twmb/franz-go/pkg/kmsg v1.4.0 // indirect
)
20 changes: 20 additions & 0 deletions plugin/klogr/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/twmb/franz-go v1.12.1 h1:8lWT8q0spL40Nfw6eonJ8OoPGLvF9arvadRRmcSiu9Y=
github.com/twmb/franz-go v1.12.1/go.mod h1:Ofc5tSSUJKLmpRNUYSejUsAZKYAHDHywTS322KWdChQ=
github.com/twmb/franz-go/pkg/kmsg v1.4.0 h1:tbp9hxU6m8qZhQTlpGiaIJOm4BXix5lsuEZ7K00dF0s=
github.com/twmb/franz-go/pkg/kmsg v1.4.0/go.mod h1:SxG/xJKhgPu25SamAq0rrucfp7lbzCpEXOC+vH/ELrY=
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
81 changes: 81 additions & 0 deletions plugin/klogr/klogr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Package klogr is a wrapper around logr.Logger.
package klogr

import (
"github.com/go-logr/logr"
"github.com/twmb/franz-go/pkg/kgo"
)

var _ kgo.Logger = (*Logger)(nil)

// Opt applies options to the logger.
type Opt interface{ apply(*Logger) }

type opt struct{ fn func(*Logger) }

func (o opt) apply(l *Logger) { o.fn(l) }

// LevelToV returns the logr V level that corresponds to the given
// kgo.LogLevel.
//
// By default, the kgo.LogLevel is just doubled -- error is 2, warn is 4, info
// is 6, and debug is 8.
func LevelToV(fn func(kgo.LogLevel) int) Opt {
return opt{func(l *Logger) { l.levelMap = fn }}
}

// Logger that wraps the logr.Logger.
type Logger struct {
logr logr.Logger
levelMap func(kgo.LogLevel) int
}

// New returns a new Logger.
func New(logr logr.Logger, opts ...Opt) *Logger {
l := &Logger{
logr: logr,
levelMap: func(level kgo.LogLevel) int { return int(level) * 2 },
}
for _, opt := range opts {
opt.apply(l)
}
return l
}

// Level returns the log level to log at.
func (l *Logger) Level() kgo.LogLevel {
// The kgo library really only checks the level ahead of time for debug
// logs currently.
for _, level := range []kgo.LogLevel{
kgo.LogLevelDebug,
kgo.LogLevelInfo,
kgo.LogLevelWarn,
kgo.LogLevelError,
} {
if l.logr.GetSink().Enabled(l.levelMap(level)) {
return level
}
}
return kgo.LogLevelNone
}

// Log using the underlying logr.Logger. If kgo.LogLevelError is set, keyvals
// will be type checked for an error, and the first one found will be used.
func (l *Logger) Log(level kgo.LogLevel, msg string, keyvals ...interface{}) {
switch level {
case kgo.LogLevelNone:
case kgo.LogLevelError:
var err error
for _, kv := range keyvals {
kverr, ok := kv.(error)
if ok {
err = kverr
break
}
}
l.logr.Error(err, msg, keyvals...)

default:
l.logr.V(l.levelMap(level)).Info(msg, keyvals...)
}
}
67 changes: 67 additions & 0 deletions plugin/klogr/klogr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package klogr

import (
"fmt"
"testing"

"github.com/go-logr/logr/funcr"
"github.com/twmb/franz-go/pkg/kgo"
)

func TestLogger_Log(t *testing.T) {
for _, test := range []struct {
level kgo.LogLevel
expectOutput bool
}{
{level: kgo.LogLevelInfo, expectOutput: true},
{level: kgo.LogLevelError, expectOutput: true},
{level: kgo.LogLevelNone, expectOutput: false},
} {
t.Run(fmt.Sprintf("logging level %s", test.level), func(t *testing.T) {
l, hasOutput := loggerOutput()
l.Log(test.level, msg, keyvals...)

if *hasOutput != test.expectOutput {
t.Errorf("expect output: %v, has output: %t", test.expectOutput, *hasOutput)
}
})
}
}

func BenchmarkLogError(b *testing.B) {
benchLogger(b, kgo.LogLevelError)
}

func BenchmarkLogInfo(b *testing.B) {
benchLogger(b, kgo.LogLevelInfo)
}

func BenchmarkLogNone(b *testing.B) {
benchLogger(b, kgo.LogLevelNone)
}

var (
msg = "message"
keyvals = []interface{}{
"bool", true,
"string", "str",
"int", 42,
"float", 3.14,
"struct", struct{ A, B int }{13, 37},
"err", fmt.Errorf("error"),
}
)

func loggerOutput() (*Logger, *bool) {
var hasOutput bool
write := func(prefix, args string) { hasOutput = true }
lr := funcr.New(write, funcr.Options{Verbosity: 42})
return New(lr), &hasOutput
}

func benchLogger(b *testing.B, level kgo.LogLevel) {
l, _ := loggerOutput()
for i := 0; i < b.N; i++ {
l.Log(level, msg, keyvals...)
}
}

0 comments on commit d8230ca

Please sign in to comment.