log

package module
v0.11.1 Latest Latest
Warning

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

Go to latest
Published: Mar 7, 2024 License: Apache-2.0 Imports: 11 Imported by: 102

README

rockbears/log

Log with context values as fields.

Compatible with zap, logrus, std logger and testing.T logger.

It supports pkg/errors to add a stack_trace field if the handled error error implements StackTracerinterface.

It offers a convenient way to keep your logs when you are running unit tests.

Install

    go get github.com/rockbears/log

How to use

Global logger

By default, it is initialized to wrap logrus package. You can override log.Factory to use the logger library you want.

First register fields

const myField = log.Field("component")

func init() {
    log.RegisterField(myField)
}

Then add fields as values to you current context.

ctx = context.WithValue(ctx, myField, "myComponent")

Finally log as usual.

log.Info(ctx, "this is a log")
Logger instance

You can opt to use a logger instance instead of the global state:

logger := log.NewWithFactory(log.NewLogrusWrapper(logrus.New()))

// Registration is scoped to the logger instance
logger.RegisterField(myField)

logger.Info(ctx, "this is a log")

A typical use case may be to instanciate a logger at app startup and storing it in a struct for use in other methods.

Examples

    const myField = log.Field("component")

    func init() {
        log.RegisterField(myField)
    }

    func foo(ctx context.Context) {
        ctx = context.WithValue(ctx, myField, "myComponent")
        log.Info(ctx, "this is a log")
    }

Preserve your log in unit tests.

    func TestFoo(t *testing.T) {
        log.Factory = log.NewTestingWrapper(t)
        foo(context.TODO())
    }

Log errors easily.

    import "github.com/pkg/errors"

    func foo() {
        ctx := context.Background()
        err := errors.New("this is an error") // from package "github.com/pkg/errors"
        log.ErrorWithStackTrace(ctx, err) // will produce a nice stack_trace field 
    )

Documentation

Index

Examples

Constants

View Source
const (
	FieldSourceFile = Field("source_file")
	FieldSourceLine = Field("source_line")
	FieldCaller     = Field("caller")
	FieldStackTrace = Field("stack_trace")
)

Variables

This section is empty.

Functions

func ContextWithStackTrace added in v0.4.0

func ContextWithStackTrace(ctx context.Context, err error) context.Context

func Debug

func Debug(ctx context.Context, format string, args ...interface{})

func Error

func Error(ctx context.Context, format string, args ...interface{})

func ErrorWithStackTrace added in v0.4.0

func ErrorWithStackTrace(ctx context.Context, err error)

func Fatal

func Fatal(ctx context.Context, format string, args ...interface{})

func FieldValues added in v0.6.0

func FieldValues(ctx context.Context) map[Field]interface{}

func GetFramesToSkip added in v0.11.0

func GetFramesToSkip() int

func Info

func Info(ctx context.Context, format string, args ...interface{})

func Panic added in v0.8.0

func Panic(ctx context.Context, format string, args ...interface{})

func RegisterDefaultFields added in v0.9.0

func RegisterDefaultFields()

func RegisterField

func RegisterField(fields ...Field)

func SetFramesToSkip added in v0.11.0

func SetFramesToSkip(s int)

func Skip added in v0.7.0

func Skip(field Field, value interface{})

func UnregisterField added in v0.2.0

func UnregisterField(fields ...Field)

func Warn

func Warn(ctx context.Context, format string, args ...interface{})

Types

type ExcludeRule added in v0.10.1

type ExcludeRule struct {
	Field Field
	Value any
}

type Field

type Field string

func GetRegisteredFields added in v0.9.0

func GetRegisteredFields() []Field
Example
package main

import (
	"fmt"

	"github.com/rockbears/log"
)

const (
	fieldComponent = log.Field("component")
	fieldAsset     = log.Field("asset")
)

func registerDefaultFields() {
	log.RegisterField(fieldComponent, fieldAsset)
}

func main() {
	log.RegisterDefaultFields()
	registerDefaultFields()
	fmt.Println(log.GetRegisteredFields())
}
Output:

[asset caller component source_file source_line stack_trace]

type Level added in v0.3.0

type Level int
const (
	LevelDebug Level = iota
	LevelInfo
	LevelWarn
	LevelError
	LevelFatal
	LevelPanic
)

type Logger added in v0.10.0

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

func New added in v0.10.0

func New() *Logger

func NewWithFactory added in v0.10.0

func NewWithFactory(factory WrapperFactoryFunc) *Logger
Example
package main

import (
	"context"
	"os"

	"github.com/rockbears/log"
	"github.com/sirupsen/logrus"
)

const (
	fieldComponent = log.Field("component")
	fieldAsset     = log.Field("asset")
)

func main() {
	// Init the wrapper
	lrus := logrus.New()
	logger := log.NewWithFactory(log.NewLogrusWrapper(lrus))
	logger.RegisterField(fieldComponent, fieldAsset)
	logger.UnregisterField(log.FieldSourceLine, log.FieldSourceFile)

	// Init the logrus logger
	lrus.SetLevel(logrus.InfoLevel)
	lrus.SetFormatter(&logrus.TextFormatter{
		DisableColors:    true,
		DisableTimestamp: true,
	})
	lrus.Out = os.Stdout

	// Init the context
	ctx := context.Background()
	ctx = context.WithValue(ctx, fieldComponent, "rockbears/log")
	ctx = context.WithValue(ctx, fieldAsset, "ExampleWithLogrus")
	logger.Debug(ctx, "this log should not be displayed")
	logger.Info(ctx, "this is %q", "info")
	logger.Warn(ctx, "this is warn")
	logger.Error(ctx, "this is error")

}
Output:

level=info msg="this is \"info\"" asset=ExampleWithLogrus caller=github.com/rockbears/log_test.ExampleNewWithFactory component=rockbears/log
level=warning msg="this is warn" asset=ExampleWithLogrus caller=github.com/rockbears/log_test.ExampleNewWithFactory component=rockbears/log
level=error msg="this is error" asset=ExampleWithLogrus caller=github.com/rockbears/log_test.ExampleNewWithFactory component=rockbears/log

func (*Logger) Debug added in v0.10.0

func (l *Logger) Debug(ctx context.Context, format string, args ...interface{})

func (*Logger) Error added in v0.10.0

func (l *Logger) Error(ctx context.Context, format string, args ...interface{})

func (*Logger) ErrorWithStackTrace added in v0.10.0

func (l *Logger) ErrorWithStackTrace(ctx context.Context, err error)

func (*Logger) Fatal added in v0.10.0

func (l *Logger) Fatal(ctx context.Context, format string, args ...interface{})

func (*Logger) FieldValues added in v0.10.0

func (l *Logger) FieldValues(ctx context.Context) map[Field]interface{}

func (*Logger) GetExcludeRules added in v0.10.1

func (l *Logger) GetExcludeRules() []ExcludeRule

func (*Logger) GetFramesToSkip added in v0.11.0

func (l *Logger) GetFramesToSkip() int

func (*Logger) GetRegisteredFields added in v0.10.0

func (l *Logger) GetRegisteredFields() []Field

func (*Logger) Info added in v0.10.0

func (l *Logger) Info(ctx context.Context, format string, args ...interface{})

func (*Logger) Panic added in v0.10.0

func (l *Logger) Panic(ctx context.Context, format string, args ...interface{})

func (*Logger) RegisterDefaultFields added in v0.10.0

func (l *Logger) RegisterDefaultFields()

func (*Logger) RegisterField added in v0.10.0

func (l *Logger) RegisterField(fields ...Field)

func (*Logger) SetFramesToSkip added in v0.11.0

func (l *Logger) SetFramesToSkip(s int)

func (*Logger) Skip added in v0.10.0

func (l *Logger) Skip(field Field, value interface{})

func (*Logger) UnregisterField added in v0.10.0

func (l *Logger) UnregisterField(fields ...Field)

func (*Logger) Warn added in v0.10.0

func (l *Logger) Warn(ctx context.Context, format string, args ...interface{})

type LogrusWrapper

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

func (*LogrusWrapper) Debugf

func (l *LogrusWrapper) Debugf(format string, args ...interface{})

func (*LogrusWrapper) Errorf

func (l *LogrusWrapper) Errorf(format string, args ...interface{})

func (*LogrusWrapper) Fatalf

func (l *LogrusWrapper) Fatalf(format string, args ...interface{})

func (*LogrusWrapper) GetLevel added in v0.3.0

func (l *LogrusWrapper) GetLevel() Level

func (*LogrusWrapper) Infof

func (l *LogrusWrapper) Infof(format string, args ...interface{})

func (*LogrusWrapper) Panicf added in v0.3.0

func (l *LogrusWrapper) Panicf(format string, args ...interface{})

func (*LogrusWrapper) Warnf

func (l *LogrusWrapper) Warnf(format string, args ...interface{})

func (*LogrusWrapper) WithField

func (l *LogrusWrapper) WithField(key string, value interface{})

type StackTracer added in v0.4.0

type StackTracer interface {
	StackTrace() errors.StackTrace
}

type StdWrapper

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

func (*StdWrapper) Debugf

func (l *StdWrapper) Debugf(format string, args ...interface{})

func (*StdWrapper) Errorf

func (l *StdWrapper) Errorf(format string, args ...interface{})

func (*StdWrapper) Fatalf

func (l *StdWrapper) Fatalf(format string, args ...interface{})

func (*StdWrapper) GetLevel added in v0.3.0

func (l *StdWrapper) GetLevel() Level

func (*StdWrapper) Infof

func (l *StdWrapper) Infof(format string, args ...interface{})

func (*StdWrapper) Panicf added in v0.3.0

func (l *StdWrapper) Panicf(format string, args ...interface{})

func (*StdWrapper) Print added in v0.3.0

func (l *StdWrapper) Print(s string)

func (*StdWrapper) Warnf

func (l *StdWrapper) Warnf(format string, args ...interface{})

func (*StdWrapper) WithField

func (l *StdWrapper) WithField(key string, value interface{})

type StdWrapperOptions added in v0.3.0

type StdWrapperOptions struct {
	Level            Level
	DisableTimestamp bool
}

type TestingWrapper

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

func (*TestingWrapper) Debugf

func (l *TestingWrapper) Debugf(format string, args ...interface{})

func (*TestingWrapper) Errorf

func (l *TestingWrapper) Errorf(format string, args ...interface{})

func (*TestingWrapper) Fatalf

func (l *TestingWrapper) Fatalf(format string, args ...interface{})

func (*TestingWrapper) GetLevel added in v0.3.0

func (l *TestingWrapper) GetLevel() Level

func (*TestingWrapper) Infof

func (l *TestingWrapper) Infof(format string, args ...interface{})

func (*TestingWrapper) Panicf added in v0.3.0

func (l *TestingWrapper) Panicf(format string, args ...interface{})

func (*TestingWrapper) Warnf

func (l *TestingWrapper) Warnf(format string, args ...interface{})

func (*TestingWrapper) WithField

func (l *TestingWrapper) WithField(key string, value interface{})

type Wrapper

type Wrapper interface {
	GetLevel() Level
	WithField(key string, value interface{})
	Debugf(format string, args ...interface{})
	Infof(format string, args ...interface{})
	Warnf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
	Panicf(format string, args ...interface{})
}

type WrapperFactoryFunc

type WrapperFactoryFunc func() Wrapper

func NewLogrusWrapper

func NewLogrusWrapper(logger *logrus.Logger) WrapperFactoryFunc
Example
package main

import (
	"context"
	"os"

	"github.com/rockbears/log"
	"github.com/sirupsen/logrus"
)

const (
	fieldComponent = log.Field("component")
	fieldAsset     = log.Field("asset")
)

func main() {
	// Init the wrapper
	log.Factory = log.NewLogrusWrapper(logrus.StandardLogger())
	log.UnregisterField(log.FieldSourceLine, log.FieldSourceFile)

	// Init the logrus logger
	logrus.StandardLogger().SetLevel(logrus.InfoLevel)
	logrus.StandardLogger().SetFormatter(&logrus.TextFormatter{
		DisableColors:    true,
		DisableTimestamp: true,
	})
	logrus.StandardLogger().Out = os.Stdout

	// Init the context
	ctx := context.Background()
	ctx = context.WithValue(ctx, fieldComponent, "rockbears/log")
	ctx = context.WithValue(ctx, fieldAsset, "ExampleWithLogrus")
	log.Debug(ctx, "this log should not be displayed")
	log.Info(ctx, "this is %q", "info")
	log.Warn(ctx, "this is warn")
	log.Error(ctx, "this is error")

}
Output:

level=info msg="this is \"info\"" asset=ExampleWithLogrus caller=github.com/rockbears/log_test.ExampleNewLogrusWrapper component=rockbears/log
level=warning msg="this is warn" asset=ExampleWithLogrus caller=github.com/rockbears/log_test.ExampleNewLogrusWrapper component=rockbears/log
level=error msg="this is error" asset=ExampleWithLogrus caller=github.com/rockbears/log_test.ExampleNewLogrusWrapper component=rockbears/log

func NewStdWrapper

func NewStdWrapper(opts StdWrapperOptions) WrapperFactoryFunc
Example
package main

import (
	"context"

	"github.com/rockbears/log"
)

const (
	fieldComponent = log.Field("component")
	fieldAsset     = log.Field("asset")
)

func main() {
	// Init the wrapper
	log.Factory = log.NewStdWrapper(log.StdWrapperOptions{Level: log.LevelInfo, DisableTimestamp: true})
	log.UnregisterField(log.FieldSourceLine, log.FieldSourceFile)
	// Init the context
	ctx := context.Background()
	ctx = context.WithValue(ctx, fieldComponent, "rockbears/log")
	ctx = context.WithValue(ctx, fieldAsset, "ExampleNewStdWrapper")
	log.Debug(ctx, "this log should not be displayed")
	log.Info(ctx, "this is %q", "info")
	log.Warn(ctx, "this is warn")
	log.Error(ctx, "this is error")
}
Output:

[INFO] [asset=ExampleNewStdWrapper][caller=github.com/rockbears/log_test.ExampleNewStdWrapper][component=rockbears/log] this is "info"
[WARN] [asset=ExampleNewStdWrapper][caller=github.com/rockbears/log_test.ExampleNewStdWrapper][component=rockbears/log] this is warn
[ERROR] [asset=ExampleNewStdWrapper][caller=github.com/rockbears/log_test.ExampleNewStdWrapper][component=rockbears/log] this is error

func NewTestingWrapper

func NewTestingWrapper(t testing.TB) WrapperFactoryFunc

func NewZapWrapper added in v0.3.0

func NewZapWrapper(logger *zap.Logger) WrapperFactoryFunc
Example
package main

import (
	"context"
	"os"

	"github.com/rockbears/log"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

const (
	fieldComponent = log.Field("component")
	fieldAsset     = log.Field("asset")
)

func main() {
	// Init the wrapper
	encoderCfg := zapcore.EncoderConfig{
		MessageKey:     "msg",
		LevelKey:       "level",
		NameKey:        "logger",
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeTime:     zapcore.ISO8601TimeEncoder,
		EncodeDuration: zapcore.StringDurationEncoder,
	}
	core := zapcore.NewCore(zapcore.NewJSONEncoder(encoderCfg), os.Stdout, zap.InfoLevel)
	log.Factory = log.NewZapWrapper(zap.New(core))
	log.UnregisterField(log.FieldSourceLine, log.FieldSourceFile)
	// Init the context
	ctx := context.Background()
	ctx = context.WithValue(ctx, fieldComponent, "rockbears/log")
	ctx = context.WithValue(ctx, fieldAsset, "ExampleNewZapWrapper")
	log.Debug(ctx, "this log should not be displayed")
	log.Info(ctx, "this is %q", "info")
	log.Warn(ctx, "this is warn")
	log.Error(ctx, "this is error")
}
Output:

{"level":"info","msg":"this is \"info\"","asset":"ExampleNewZapWrapper","caller":"github.com/rockbears/log_test.ExampleNewZapWrapper","component":"rockbears/log"}
{"level":"warn","msg":"this is warn","asset":"ExampleNewZapWrapper","caller":"github.com/rockbears/log_test.ExampleNewZapWrapper","component":"rockbears/log"}
{"level":"error","msg":"this is error","asset":"ExampleNewZapWrapper","caller":"github.com/rockbears/log_test.ExampleNewZapWrapper","component":"rockbears/log"}

type ZapWrapper added in v0.3.0

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

func (*ZapWrapper) Debugf added in v0.3.0

func (l *ZapWrapper) Debugf(format string, args ...interface{})

func (*ZapWrapper) Errorf added in v0.3.0

func (l *ZapWrapper) Errorf(format string, args ...interface{})

func (*ZapWrapper) Fatalf added in v0.3.0

func (l *ZapWrapper) Fatalf(format string, args ...interface{})

func (*ZapWrapper) GetLevel added in v0.3.0

func (l *ZapWrapper) GetLevel() Level

func (*ZapWrapper) Infof added in v0.3.0

func (l *ZapWrapper) Infof(format string, args ...interface{})

func (*ZapWrapper) Panicf added in v0.3.0

func (l *ZapWrapper) Panicf(format string, args ...interface{})

func (*ZapWrapper) Warnf added in v0.3.0

func (l *ZapWrapper) Warnf(format string, args ...interface{})

func (*ZapWrapper) WithField added in v0.3.0

func (l *ZapWrapper) WithField(key string, value interface{})

Jump to

Keyboard shortcuts

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