genericr

package module
v0.0.0-...-752ff2d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2022 License: Apache-2.0 Imports: 9 Imported by: 0

README

GoDoc

genericr

A generic logr implementation that makes it easy to write your own logging backend.

This package allows you to implement the logr interface by implementing a single callback function instead of the full interface.

Examples

Basic example

Basic example that directly writes to stderr:

log := genericr.New(func(e genericr.Entry) {
	fmt.Fprintln(os.Stderr, e.String())
})

log.WithName("some-component").WithValues("x", 123).V(1).Info("some event", "y", 42)

This outputs the default string representation which currently looks like this:

[1] some-component "some event" x=123 y=42

The genericr.Entry struct you receive in your handler contains the following fields that you can use to do your own formatting:

type Entry struct {
	Level     int           // level at which this was logged
	Name      string        // name parts joined with '.'
	NameParts []string      // individual name segments
	Message   string        // message as send to log call
	Error     error         // error if .Error() was called
	Fields    []interface{} // alternating key-value pairs

	// Caller information
	Caller      runtime.Frame // only available after .WithCaller(true)
	CallerDepth int           // caller depth from callback
}

Use e.FieldsMap() to retrieve the Fields as a map.

To enable caller information, use genericr.New(...).WithCaller(true).

To filter messages above a certain verbosity level, use genericr.New(...).WithVerbosity(1).

Usage in tests

This shows how you can redirect logs to the testing.T logger and keep a reference to the last log entry if you want to check that one:

func TestLogger_Table(t *testing.T) {
	var last genericr.Entry
	log := genericr.New(func(e genericr.Entry) {
		last = e
		t.Log(e.String())
	})
    // ...
}
Logrus example

More complicated example that implements a logrus adapter:

root := logrus.New()
root.SetLevel(logrus.TraceLevel)
root.SetFormatter(&logrus.TextFormatter{
	DisableColors:    true,
	DisableTimestamp: true,
})
root.Out = os.Stdout

var lf genericr.LogFunc = func(e genericr.Entry) {
	var l *logrus.Entry = root.WithField("component", e.Name)
	if e.Error != nil {
		l = l.WithError(e.Error)
	}
	if len(e.Fields) != 0 {
		l = l.WithFields(e.FieldsMap())
	}
	logrusLevel := logrus.Level(e.Level) + logrus.InfoLevel // 0 = info
	if logrusLevel < logrus.ErrorLevel {
		logrusLevel = logrus.ErrorLevel
	} else if logrusLevel > logrus.TraceLevel {
		logrusLevel = logrus.TraceLevel
	}
	l.Log(logrusLevel, e.Message)
}
log := genericr.New(lf)

Documentation

Overview

Package genericr implements github.com/go-logr/logr.LogSink in a generic way that allows easy implementation of other logging backends.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewForTesting

func NewForTesting(t TLogSink) logr.Logger

NewForTesting returns a LogSink for given testing.T or B. Note that the source line reference will be incorrect in all messages written by testing.T. There is nothing we can do about that, the call depth is hardcoded in there.

Types

type Entry

type Entry struct {
	Level     int           // level at which this was logged
	Name      string        // name parts joined with '.'
	NameParts []string      // individual name segments
	Message   string        // message as send to log call
	IsError   bool          // true if .Error() was called
	Error     error         // error if .Error() was called
	Fields    []interface{} // alternating key-value pairs

	// Caller information
	Caller      runtime.Frame // only available after .WithCaller(true)
	CallerDepth int           // caller depth from callback
}

Entry is a log entry that your adapter will receive for actual logging

func (Entry) CallerShort

func (e Entry) CallerShort() string

CallerShort returns a short caller location string ("somefile.go:123")

func (Entry) FieldsMap

func (e Entry) FieldsMap() map[string]interface{}

FieldsMap converts the fields to a map. This map is also compatible with logrus.Fields.

func (Entry) String

func (e Entry) String() string

String converts the entry to a string. The output format is subject to change! Implement your own conversion if you need to parse these logs later! TODO: Neater way to log values with newlines?

type LogFunc

type LogFunc func(e Entry)

LogFunc is your custom log backend

type LogSink

type LogSink struct {
	// contains filtered or unexported fields
}

LogSink is a generic logger that implements the logr.LogSink interface and calls a function of type LogFunc for every log message received.

func New

func New(f LogFunc) LogSink

New returns a logr.LogSink which is implemented by your custom LogFunc.

func (LogSink) Enabled

func (l LogSink) Enabled(level int) bool

func (LogSink) Error

func (l LogSink) Error(err error, msg string, kvList ...interface{})

func (LogSink) Info

func (l LogSink) Info(level int, msg string, kvList ...interface{})

func (LogSink) Init

func (l LogSink) Init(info logr.RuntimeInfo)

func (LogSink) WithCallDepth

func (l LogSink) WithCallDepth(depth int) logr.LogSink

WithCallDepth implements logr.CallDepthLogSink.

func (LogSink) WithCaller

func (l LogSink) WithCaller(enabled bool) LogSink

WithCaller enables or disables caller lookup for Entry.Caller. It is disabled by default. Local benchmarks show close to 1µs and 2 allocs extra overhead from enabling this, without actually using this extra information. This is not part of the logr interface, so you can only use this on the root object.

func (LogSink) WithName

func (l LogSink) WithName(name string) logr.LogSink

func (LogSink) WithValues

func (l LogSink) WithValues(kvList ...interface{}) logr.LogSink

func (LogSink) WithVerbosity

func (l LogSink) WithVerbosity(level int) LogSink

WithVerbosity returns a new instance with given max verbosity level. This is not part of the logr interface, so you can only use this on the root object.

type TLogSink

type TLogSink interface {
	Log(args ...interface{})
}

TLogSink is the subset of the testing.TB interface we need to log with it

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL