package funcr
import "github.com/go-logr/logr/funcr"
Package funcr implements formatting of structured log messages and optionally captures the call site. This will not call String or Error methods on values.
The simplest way to use it is via its implementation of a github.com/go-logr/logr.LogSink with output through an arbitrary "write" function. Alternatively, funcr can also be embedded inside a custom LogSink implementation. This is useful when the LogSink needs to implement additional methods.
Index ¶
- func New(fn func(prefix, args string), opts Options) logr.Logger
- type Formatter
- func NewFormatter(opts Options) Formatter
- func (f *Formatter) AddCallDepth(depth int)
- func (f *Formatter) AddName(name string)
- func (f *Formatter) AddValues(kvList []interface{})
- func (f Formatter) Enabled(level int) bool
- func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string)
- func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string)
- func (f *Formatter) Init(info logr.RuntimeInfo)
- type MessageClass
- type Options
- type Underlier
Examples ¶
Functions ¶
func New ¶
New returns a logr.Logger which is implemented by an arbitrary function.
Types ¶
type Formatter ¶
type Formatter struct {
// contains filtered or unexported fields
}
Formatter is an opaque struct which can be embedded in a LogSink
implementation. It should be constructed with NewFormatter. Some of
its methods directly implement logr.LogSink.
Code:play
Output:Example¶
package main
import (
"fmt"
"strings"
"github.com/go-logr/logr"
"github.com/go-logr/logr/funcr"
)
// NewStdoutLogger returns a logr.Logger that prints to stdout.
// It demonstrates how to implement a custom With* function which
// controls whether INFO or ERROR are printed in front of the log
// message.
func NewStdoutLogger() logr.Logger {
l := &stdoutlogger{
Formatter: funcr.NewFormatter(funcr.Options{}),
}
return logr.New(l)
}
type stdoutlogger struct {
funcr.Formatter
logMsgType bool
}
func (l stdoutlogger) WithName(name string) logr.LogSink {
l.Formatter.AddName(name)
return &l
}
func (l stdoutlogger) WithValues(kvList ...interface{}) logr.LogSink {
l.Formatter.AddValues(kvList)
return &l
}
func (l stdoutlogger) WithCallDepth(depth int) logr.LogSink {
l.Formatter.AddCallDepth(depth)
return &l
}
func (l stdoutlogger) Info(level int, msg string, kvList ...interface{}) {
prefix, args := l.FormatInfo(level, msg, kvList)
l.write("INFO", prefix, args)
}
func (l stdoutlogger) Error(err error, msg string, kvList ...interface{}) {
prefix, args := l.FormatError(err, msg, kvList)
l.write("ERROR", prefix, args)
}
func (l stdoutlogger) write(msgType, prefix, args string) {
var parts []string
if l.logMsgType {
parts = append(parts, msgType)
}
if prefix != "" {
parts = append(parts, prefix)
}
parts = append(parts, args)
fmt.Println(strings.Join(parts, ": "))
}
// WithLogMsgType returns a copy of the logger with new settings for
// logging the message type. It returns the original logger if the
// underlying LogSink is not a stdoutlogger.
func WithLogMsgType(log logr.Logger, logMsgType bool) logr.Logger {
if l, ok := log.GetSink().(*stdoutlogger); ok {
clone := *l
clone.logMsgType = logMsgType
log = log.WithSink(&clone)
}
return log
}
func main() {
l := NewStdoutLogger()
l.Info("no message type")
WithLogMsgType(l, true).Info("with message type")
}
"level"=0 "msg"="no message type"
INFO: "level"=0 "msg"="with message type"
func NewFormatter ¶
NewFormatter constructs a Formatter.
func (*Formatter) AddCallDepth ¶
AddCallDepth increases the number of stack-frames to skip when attributing the log line to a file and line.
func (*Formatter) AddName ¶
AddName appends the specified name. funcr uses '/' characters to separate name elements. Callers should not pass '/' in the provided name string, but this library does not actually enforce that.
func (*Formatter) AddValues ¶
func (f *Formatter) AddValues(kvList []interface{})
AddValues adds key-value pairs to the set of saved values to be logged with each log line.
func (Formatter) Enabled ¶
Enabled checks whether an info message at the given level should be logged.
func (Formatter) FormatError ¶
func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string)
FormatError flattens an Error log message into strings. The prefix will be empty when no names were set.
func (Formatter) FormatInfo ¶
FormatInfo flattens an Info log message into strings. The prefix will be empty when no names were set.
func (*Formatter) Init ¶
func (f *Formatter) Init(info logr.RuntimeInfo)
Init configures this Formatter from runtime info, such as the call depth imposed by logr itself. Note that this receiver is a pointer, so depth can be saved.
type MessageClass ¶
type MessageClass int
MessageClass indicates which category or categories of messages to consider.
const ( // None ignores all message classes. None MessageClass = iota // All considers all message classes. All // Info only considers info messages. Info // Error only considers error messages. Error )
type Options ¶
type Options struct { // LogCaller tells funcr to add a "caller" key to some or all log lines. // This has some overhead, so some users might not want it. LogCaller MessageClass // LogTimestamp tells funcr to add a "ts" key to log lines. This has some // overhead, so some users might not want it. LogTimestamp bool // Verbosity tells funcr which V logs to be write. Higher values enable // more logs. Verbosity int }
Options carries parameters which influence the way logs are generated.
type Underlier ¶
type Underlier interface { GetUnderlying() func(prefix, args string) }
Underlier exposes access to the underlying logging function. Since
callers only have a logr.Logger, they have to know which
implementation is in use, so this interface is less of an
abstraction and more of a way to test type conversion.
Code:play
Output:Example¶
package main
import (
"fmt"
"github.com/go-logr/logr"
"github.com/go-logr/logr/funcr"
)
func main() {
var log logr.Logger = funcr.New(func(prefix, args string) {
fmt.Println(prefix, args)
}, funcr.Options{})
if underlier, ok := log.GetSink().(funcr.Underlier); ok {
fn := underlier.GetUnderlying()
fn("hello", "world")
}
}
hello world
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
funcr/example |
- Version
- v1.1.0-rc1
- Published
- Aug 20, 2021
- Platform
- linux/amd64
- Imports
- 9 packages
- Last checked
- 2 hours ago –
Tools for package owners.