golog

package module
v1.14.1 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2023 License: MIT Imports: 12 Imported by: 0

README

GOLOG

codecov

Golog is an opinionated Go logger with simple APIs and configurable behavior.

Why another logger?

Golog is designed to address mainly two issues:

Reduce the amount of PII (personally identifiable information) data in logs

Golog exposes APIs which does not allow to simply introduce a struct or a map as part of the log fields.

This design pushes the consumers of this library to care about PII data and aim to reduce as much as possible the amount of data which can be logged.

It is possible to extend the logger behavior for handling complex data type by implementing an interface as shown in the "Custom field type" section.

Add tracing and other extra data into the logging behavior

Golog expects to have a context passed down to the logging API.

The context.Context in Go is usually the holder for tracing information and embedding one of the decorators available to the logger plugs this behavior for free in all the places where the logger is used.

Who uses Golog?

  • Pento - Used in multiple production services.

Examples

Based on your needs, you can find some presets available.

The ones highly recommended are the one that adds tracing metadata in your logs.

If you use opentelemetry, the code snippet will look like this:

package main

import (
	"context"

	"github.com/damianopetrungaro/golog"
	"github.com/damianopetrungaro/golog/opentelemetry"
)

func main() {
	logger, flusher := NewLogger(golog.DEBUG) // min level
	defer flusher.Flush()
	// ....
	logger.Info(context.Background(), "Hello world")
}

func NewLogger(lvl golog.Level) (golog.StdLogger, golog.Flusher) {
	return opentelemetry.NewProductionLogger(lvl)
}

If you use opencensus, the code snippet will look like this:

package main

import (
	"context"

	"github.com/damianopetrungaro/golog"
	"github.com/damianopetrungaro/golog/opencensus"
)

func main() {
	logger, flusher := NewLogger(golog.DEBUG) // min level
	defer flusher.Flush()
	// ....
	logger.Info(context.Background(), "Hello world")
}

func NewLogger(lvl golog.Level) (golog.StdLogger, golog.Flusher) {
	return opencensus.NewProductionLogger(lvl)
}

There is also a method for development purposes, wo use that use the factory function NewDevelopemntLogger.

For more extensive and customized implementations, plesse continue reading the documentation!

Logger

The Logger interface is implemented by the StdLogger type. It allows you to write log messages.

An example of its usage may look like this:

w := golog.NewBufWriter(
   golog.NewJsonEncoder(golog.DefaultJsonConfig()),
   bufio.NewWriter(os.Stdout),
   golog.DefaultErrorHandler(),
   golog.INFO,
)
defer w.Flush()

logger := golog.New(w, golog.NewTimestampDecoratorOption("timestamp", time.RFC3339))
golog.SetLogger(logger)

golog.With(
   golog.Bool("key name", true),
   golog.Strings("another key name", []string{"one", "two"}),
).Error(ctx, "log message here")

which will print

{"level":"ERROR","message":"log message here","key name":true,"another key name":["one","two"],"timestamp":"2022-05-20T16:16:29+02:00"}
CheckLogger

The CheckLogger interface is implemented by the StdLogger type. It allows you to write log messages allowing to set fields only if the log message will be written.

For example if the min log level set is higher than the one which will be logged, as shown in this example, there will be no extra data allocation as well as having a huge performance improvement::

w := golog.NewBufWriter(
    golog.NewJsonEncoder(golog.DefaultJsonConfig()),
    bufio.NewWriter(os.Stdout),
    golog.DefaultErrorHandler(),
    golog.INFO,
)
defer w.Flush()

logger := golog.New(w, golog.NewTimestampDecoratorOption("timestamp", time.RFC3339))
golog.SetCheckLogger(logger)

if checked, ok := golog.CheckDebug(ctx, "This is a message"); ok {
    checked.Log(
        golog.Bool("key name", true),
        golog.Strings("another key name", []string{"one", "two"}),
    )
}
{"level":"DEBUG","message":"This is a message","timestamp":"2022-05-20T16:28:15+02:00","key name":true,"another key name":["one","two"]}
Standard Library support

Golog Writer can be used by the go log package as well as output

w := &BufWriter{
    Encoder:         enc,
    Writer:          bufio.NewWriter(buf),
    ErrHandler:      errHandler.Handle,
    DefaultLogLevel: DEBUG, //! This will be the log level used for all the logs by the stdlib logger
}

log.SetOutput(w)
log.Println("your log message here...")

Customization

Golog provides multiple ways to customize behaviors

Decorators

A decorator is a function that gets executed before a log message gets written, allowing to inject only once a recurring logging behavior to modify the log message.

An example may be adding a trace and span ids to the log:

var customTraceDecorator golog.DecoratorFunc = func(e golog.Entry) golog.Entry {
    span := trace.FromContext(e.Context()).SpanContext()

    return e.With(
        golog.String("span_id", span.SpanID.String()),
        golog.String("trace_id", span.TraceID.String()),
    )
}

var logger golog.Logger = golog.New(
    // other arguments here
    golog.OptionFunc(func(l golog.StdLogger) golog.StdLogger {
        return l.WithDecorator(customTraceDecorator)
    }),
)

Out of the box are provided some decorators for tracing purposes in the opencensus and opentelemetry packages, PRs are welcome to add more behavior.

Checkers

A checker is a function that gets executed before a log message gets decorated, allowing to skip the decoration and the writing of a log entry due to custom logic.

An example may be skipping a log if the context doesn't have a value:

var customCtxValueChecker golog.Checker = golog.CheckerFunc(func(e golog.Entry) bool {
    if _, ok := e.Context().Value("key").(string); !ok {
        return false
    }

    return true
})

var logger golog.Logger = golog.New(
    // other arguments here
    golog.OptionFunc(func(l golog.StdLogger) golog.StdLogger {
        return l.WithChecker(customCtxValueChecker)
    }),
)

Out of the box are provided some checkers:

Min level checker

This checker will skip logging all the entry with level lower than an expected one.

Example usage:

var logger golog.Logger = golog.New(
    // other arguments here
    golog.NewLevelCheckerOption(golog.INFO),
)

Custom field type

Logging complex data structure is not intentionally supported out of the box, Golog expects you to implement a FieldMapper interface.

An example may be something like this:

// The complex data structure to log
type User struct {
	ID              string
	Email           string
	Password        string
	ReferenceCode   string
}

// The FieldMapper interface method to create fields out of the complex data structure
func (u User) ToFields() golog.Fields {
    return golog.Fields{
        golog.String("user_id", u.ID),
        golog.String("reference_code", u.ReferenceCode),
    }
}

//...

var u User{...} 
golog.With(golog.Mapper("user", u)).Debug(ctx, "...")

Writers

Based on your need you may want to use different entry writers.

Golog provide you those implementations:

BufWriter

It is the standard implementation, and it can be created in this way:

w := golog.NewBufWriter(
    golog.NewJsonEncoder(golog.DefaultJsonConfig()),
    bufio.NewWriter(os.Stdout),
    golog.DefaultErrorHandler(),
    golog.INFO,
)
LeveledWriter

This implementation provides you a way to use a different writer based on the log level, with a default writer used in case there is not an override defined for a log level

var stdOutWriter golog.Writer 
var stdErrWriter golog.Writer 

w := NewLeveledWriter(
    stdOutWriter,
    golog.DefaultMuxWriterOptionFunc(golog.ERROR, stdErrWriter),
    golog.DefaultMuxWriterOptionFunc(golog.FATAL, stdErrWriter),
)
MultiWriter

This implementation simply writes an across multiple writers concurrently

var w1 golog.Writer
var w2 golog.Writer
var w3 golog.Writer
w := golog.NewMultiWriter(w1, w2, w3)
DeduplicatorWriter

This implementation will deduplicate keys with the same values.

The logger is slower when using this writer, so make sure you actually need it.

w := golog.NewBufWriter(
    golog.NewJsonEncoder(golog.DefaultJsonConfig()),
    bufio.NewWriter(os.Stdout),
    golog.DefaultErrorHandler(),
    golog.DEBUG,
)
defer w.Flush()

w = golog.NewDeduplicatorWriter(w)
golog.SetLogger(golog.New(w, golog.NewLevelCheckerOption(golog.DEBUG)))

golog.With(golog.String("hello", "world"), golog.String("hello", "another world")).Error(ctx, "an error message")

This will print

{"level":"ERROR","message":"an error message","hello":"world","hello_1":"another world"}

Testing utilities

The golog/test package provides a mock generated using gomock for helping developers to test the logger.

The golog/test package provides a null logger as well, useful when the logger need to be passed as dependency but there the test don't care about the logging logic.

HTTP utilities

The golog/http utility package provide a simple and customizable API for adding some logging behavior on an HTTP server.

// ...
import (
    "net/http"
    
	"github.com/damianopetrungaro/golog"
    httplog "github.com/damianopetrungaro/golog/http"
)

// ...
var h http.Handler // the handler you want to decorate
var logger golog.Logger // your logger
httplog.NewHandler(h, logger, httplog.DefaultLogHandle()) // returns your decorated handler

Presets

Golog provides configurations and encoders utilities for several log consumers

Datadog (DD)
import (
    "github.com/damianopetrungaro/golog/datadog"
)

logger := golog.New(
    golog.NewBufWriter(
        datadog.NewJsonEncoder(),
        bufio.NewWriter(os.Stdout),
        golog.DefaultErrorHandler(),
        golog.DEBUG,
    ),
    golog.NewLevelCheckerOption(golog.WARN),
    // any other option you may want to pass
)

Performances

Golog is a really fast logging solution, with a low number of allocations as well as crazy performances.

Benchmarks comparing it to logrus and zap

goos: darwin
goarch: amd64
pkg: github.com/damianopetrungaro/golog/benchmarks/logger
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkLogger/logrus-12				322524			3544 ns/op		6162 B/op	70 allocs/op
BenchmarkLogger/golog-12				1314696			878.1 ns/op		2841 B/op	27 allocs/op
BenchmarkLogger/golog.deduplicator-12	811656			1318 ns/op		4370 B/op	34 allocs/op
BenchmarkLogger/zap-12					1292510			1093 ns/op		2836 B/op	20 allocs/op
BenchmarkLogger/golog.Check-12			69898831		18.23 ns/op		64 B/op 	1 allocs/op
BenchmarkLogger/zap.Check-12			1000000000		0.8543 ns/op	0 B/op 		0 allocs/op
PASS
ok      github.com/damianopetrungaro/golog/benchmarks/logger    9.179s

Considering the nature of the logger and the design it has, the performances are really high.

In the future there may be a support for an even faster and zero allocations version of the logger, but the APIs exposed won't be matching the current one and there will be a different interface provided for that purpose.

More updated benchmarks can be found on this page

Note

Golog doesn't hande key deduplication by default.

Meaning that

golog.With(
    golog.String("hello", "world"),
    golog.String("hello", "another world"),
).Info(ctx, "no deduplication")

will print

{"level": "INFO","message":"no deduplication","hello":"world","hello":"another world"}

If you need deduplicated keys, please check the DeduplicatorWriter section.

Documentation

Index

Examples

Constants

View Source
const (
	COLOUR_RESET  = "\033[0m"
	COLOUR_RED    = "\033[31m"
	COLOUR_REDBG  = "\033[41m"
	COLOUR_GREEN  = "\033[32m"
	COLOUR_YELLOW = "\033[33m"
	COLOUR_BLUE   = "\033[34m"
	COLOUR_WHITE  = "\033[97m"
)

Variables

View Source
var (
	ErrEntriesNotFlushed = errors.New("golog: could not flush entries")
	ErrEntryNotWritten   = errors.New("golog: could not write entry")
)
View Source
var ErrLevelNotParsed = errors.New("golog: could not parse level")

ErrLevelNotParsed is an error returned when a given string can't be parsed as a log Level

Functions

func Debug

func Debug(ctx context.Context, msg string)

Debug calls the base Logger's Debug method

func Error

func Error(ctx context.Context, msg string)

Error calls the base Logger's Error method

func Fatal

func Fatal(ctx context.Context, msg string)

Fatal calls the base Logger's Fatal method

func Info

func Info(ctx context.Context, msg string)

Info calls the base Logger's Info method

func NewDevelopmentLogger added in v1.12.0

func NewDevelopmentLogger(lvl Level) (StdLogger, Flusher)

NewDevelopmentLogger returns a pre-configured logger for development environment

func NewProductionLogger added in v1.12.0

func NewProductionLogger(lvl Level) (StdLogger, Flusher)

NewProductionLogger returns a pre-configured logger for production environment

func NewWithEncoder added in v1.12.0

func NewWithEncoder(lvl Level, enc Encoder) (StdLogger, Flusher)

NewWithEncoder returns a preset logger with a customer Encoder

func SetCheckLogger

func SetCheckLogger(l CheckLogger)

SetCheckLogger overrides the base CheckLogger

func SetLogger

func SetLogger(l Logger)

SetLogger overrides the base Logger

func Warning

func Warning(ctx context.Context, msg string)

Warning calls the base Logger's Warning method

Types

type BufWriter

type BufWriter struct {
	Encoder         Encoder
	Writer          *bufio.Writer
	ErrHandler      ErrorHandler
	DefaultLogLevel Level
	// contains filtered or unexported fields
}

BufWriter is a Writer which holds a buffer behind the scene to reduce sys calls

func NewBufWriter

func NewBufWriter(
	enc Encoder,
	w *bufio.Writer,
	errHandler ErrorHandler,
	defaultLogLevel Level,
) *BufWriter

NewBufWriter returns a BufWriter

func (*BufWriter) Flush

func (w *BufWriter) Flush() error

Flush forces the data in the buffer to be written

func (*BufWriter) Write

func (w *BufWriter) Write(msg []byte) (int, error)

Write writes an Entry to the buffer This method is implemented to add provide support the std library log package

func (*BufWriter) WriteEntry added in v0.1.0

func (w *BufWriter) WriteEntry(e Entry)

WriteEntry writes an Entry to the buffer

type CheckLogger

type CheckLogger interface {
	CheckDebug(context.Context, Message) (CheckedLogger, bool)
	CheckInfo(context.Context, Message) (CheckedLogger, bool)
	CheckWarn(context.Context, Message) (CheckedLogger, bool)
	CheckError(context.Context, Message) (CheckedLogger, bool)
	CheckFatal(context.Context, Message) (CheckedLogger, bool)
}

CheckLogger is a logger able to check if a message should be written

type CheckedLogger

type CheckedLogger interface {
	Log(...Field)
}

CheckedLogger logs an already checked log

func CheckDebug

func CheckDebug(ctx context.Context, msg string) (CheckedLogger, bool)

CheckDebug calls the base Logger's CheckDebug method

func CheckError

func CheckError(ctx context.Context, msg string) (CheckedLogger, bool)

CheckError calls the base Logger's CheckError method

func CheckFatal

func CheckFatal(ctx context.Context, msg string) (CheckedLogger, bool)

CheckFatal calls the base Logger's CheckFatal method

func CheckInfo

func CheckInfo(ctx context.Context, msg string) (CheckedLogger, bool)

CheckInfo calls the base Logger's CheckInfo method

func CheckWarning

func CheckWarning(ctx context.Context, msg string) (CheckedLogger, bool)

CheckWarning calls the base Logger's CheckWarning method

type Checker

type Checker interface {
	Check(Entry) bool
}

Checker modifies an entry before it get written

type CheckerFunc

type CheckerFunc func(Entry) bool

CheckerFunc is a handy function which implements Checker

func (CheckerFunc) Check

func (fn CheckerFunc) Check(e Entry) bool

Check checks if an entry should proceed to be written when using a CheckLogger

type Checkers

type Checkers []Checker

Checkers is a slice of Checker

type Decorator

type Decorator interface {
	Decorate(Entry) Entry
}

Decorator modifies an entry before it get written

type DecoratorFunc

type DecoratorFunc func(Entry) Entry

DecoratorFunc is a handy function which implements Decorator

func (DecoratorFunc) Decorate

func (fn DecoratorFunc) Decorate(e Entry) Entry

Decorate changes the entry with custom logic and return the new modified one

type Decorators

type Decorators []Decorator

Decorators is a slice of Decorator

type DeduplicatorWriter added in v1.8.0

type DeduplicatorWriter struct {
	Default Writer
}

DeduplicatorWriter is a Writer which deduplicate fields with the same name

func NewDeduplicatorWriter added in v1.8.0

func NewDeduplicatorWriter(
	defaultWriter Writer,
) *DeduplicatorWriter

NewDeduplicatorWriter returns a DeduplicatorWriter

func (*DeduplicatorWriter) Flush added in v1.14.1

func (m *DeduplicatorWriter) Flush() error

Flush flushes the data

func (*DeduplicatorWriter) Write added in v1.8.0

func (m *DeduplicatorWriter) Write(msg []byte) (int, error)

Write calls the Default Write method

func (*DeduplicatorWriter) WriteEntry added in v1.8.0

func (m *DeduplicatorWriter) WriteEntry(e Entry)

WriteEntry writes an Entry to the related Writer If not found, then fallback on the Default

type Encoder

type Encoder interface {
	Encode(Entry) (io.WriterTo, error)
}

Encoder transforms an entry into io.WriterTo which holds the encoded content

type Entry

type Entry interface {
	Level() Level
	Message() Message
	Fields() Fields
	Context() context.Context
	With(...Field) Entry
}

Entry is a log entry

type ErrorHandler

type ErrorHandler func(error)

ErrorHandler is a function which handle logging error in order to avoid returning it

func DefaultErrorHandler

func DefaultErrorHandler() ErrorHandler

DefaultErrorHandler returns the default error handler

type Field

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

Field is a key value pair representing a log entry metadata field

func Bool

func Bool(k string, v bool) Field

Bool creates a field containing a value of type "bool"

func Bools

func Bools(k string, v []bool) Field

Bools creates a field containing a value of type "[]bool"

func Byte added in v1.4.0

func Byte(k string, v byte) Field

Byte creates a field containing a value of type "byte"

func Bytes added in v1.4.0

func Bytes(k string, v []byte) Field

Bytes creates a field containing a value of type "[]byte"

func Err

func Err(err error) Field

Err creates a field containing a value of type ") Fi"

func Errs

func Errs(errs []error) Field

Errs creates a field containing a value of type "or"

func Float32

func Float32(k string, v float32) Field

Float32 creates a field containing a value of type "float32"

func Float32s

func Float32s(k string, v []float32) Field

Float32s creates a field containing a value of type "[]float32"

func Float64

func Float64(k string, v float64) Field

Float64 creates a field containing a value of type "float64"

func Float64s

func Float64s(k string, v []float64) Field

Float64s creates a field containing a value of type "[]float64"

func Int

func Int(k string, v int) Field

Int creates a field containing a value of type "int"

func Int16 added in v0.6.0

func Int16(k string, v int16) Field

Int16 creates a field containing a value of type "int16"

func Int16s added in v0.6.0

func Int16s(k string, v []int16) Field

Int16s creates a field containing a value of type "[]int16"

func Int32 added in v0.6.0

func Int32(k string, v int32) Field

Int32 creates a field containing a value of type "int32"

func Int32s added in v0.6.0

func Int32s(k string, v []int32) Field

Int32s creates a field containing a value of type "[]int32"

func Int64 added in v0.6.0

func Int64(k string, v int64) Field

Int64 creates a field containing a value of type "int64"

func Int64s added in v0.6.0

func Int64s(k string, v []int64) Field

Int64s creates a field containing a value of type "[]int64"

func Int8 added in v0.6.0

func Int8(k string, v int8) Field

Int8 creates a field containing a value of type "int8"

func Int8s added in v0.6.0

func Int8s(k string, v []int8) Field

Int8s creates a field containing a value of type "[]int8"

func Ints

func Ints(k string, v []int) Field

Ints creates a field containing a value of type "[]int"

func Mapper added in v1.5.0

func Mapper(k string, v FieldMapper) Field

Mapper creates a field containing a value of type "Fields"

func Mappers added in v1.13.0

func Mappers(k string, v []FieldMapper) Field

Mappers creates a field containing a value of type "Fields"

func String

func String(k string, v string) Field

String creates a field containing a value of type "string"

func Strings

func Strings(k string, v []string) Field

Strings creates a field containing a value of type "[]string"

func Time added in v0.6.0

func Time(k string, v time.Time) Field

Time creates a field containing a value of type "time.Time"

func Times added in v0.6.0

func Times(k string, v []time.Time) Field

Times creates a field containing a value of type "[]time.Time"

func Uint

func Uint(k string, v uint) Field

Uint creates a field containing a value of type "uint"

func Uint16 added in v0.6.0

func Uint16(k string, v uint16) Field

Uint16 creates a field containing a value of type "uint16"

func Uint16s added in v0.6.0

func Uint16s(k string, v []uint16) Field

Uint16s creates a field containing a value of type "[]uint16"

func Uint32 added in v0.6.0

func Uint32(k string, v uint32) Field

Uint32 creates a field containing a value of type "uint32"

func Uint32s added in v0.6.0

func Uint32s(k string, v []uint32) Field

Uint32s creates a field containing a value of type "[]uint32"

func Uint64 added in v0.6.0

func Uint64(k string, v uint64) Field

Uint64 creates a field containing a value of type "uint64"

func Uint64s added in v0.6.0

func Uint64s(k string, v []uint64) Field

Uint64s creates a field containing a value of type "[]uint64"

func Uint8 added in v0.6.0

func Uint8(k string, v uint8) Field

Uint8 creates a field containing a value of type "uint8"

func Uint8s added in v0.6.0

func Uint8s(k string, v []uint8) Field

Uint8s creates a field containing a value of type "[]uint8"

func Uints

func Uints(k string, v []uint) Field

Uints creates a field containing a value of type "[]uint"

func (Field) Key

func (f Field) Key() string

Key returns the key of the Field

func (Field) Value

func (f Field) Value() any

Value returns the value of the Field

type FieldMapper added in v1.5.0

type FieldMapper interface {
	ToFields() Fields
}

FieldMapper an interface which returns Fields to add to an Entry

type Fields

type Fields []Field

Fields is a slice of Field

type Flusher

type Flusher interface {
	Flush() error
}

Flusher ensure that the data that a Writer may hold is written

type JsonConfig

type JsonConfig struct {
	LevelKeyName   string
	MessageKeyName string
	TimeLayout     string
}

JsonConfig is a configuration for JsonEncoder

func DefaultJsonConfig

func DefaultJsonConfig() JsonConfig

DefaultJsonConfig returns a default JsonConfig

type JsonEncoder

type JsonEncoder struct {
	Config JsonConfig
}

JsonEncoder is an encoder for json

func NewJsonEncoder

func NewJsonEncoder(cfg JsonConfig) JsonEncoder

NewJsonEncoder returns a JsonEncoder

func (JsonEncoder) Encode

func (j JsonEncoder) Encode(e Entry) (io.WriterTo, error)

Encode encodes an entry into a json content holds into an io.WriterTo

type Level

type Level int

Level is a log severity level

const (
	DEBUG Level
	INFO
	WARN
	ERROR
	FATAL
)

func ParseLevel

func ParseLevel(s string) (Level, error)

ParseLevel returns a Level given a string, returns an error in case the string is not a recognized one

func (Level) String

func (l Level) String() string

String returns a string format of a log Level

type LevelChecker

type LevelChecker struct {
	MinSeverity MinSeverity
}

LevelChecker is a Checker which ensure the log has an expected Level

func NewLevelChecker

func NewLevelChecker(minSev MinSeverity) LevelChecker

NewLevelChecker returns a LevelChecker with the given MinSeverity

func (LevelChecker) Check

func (lc LevelChecker) Check(e Entry) bool

Check returns true if the Entry's Level is at least the one configured

type LevelFormatter added in v1.11.0

type LevelFormatter func(Level) string

func ColoredLevelFormatter added in v1.12.0

func ColoredLevelFormatter() LevelFormatter

ColoredLevelFormatter returns a colored LevelFormatter

func DefaultLevelFormatter added in v1.12.0

func DefaultLevelFormatter() LevelFormatter

DefaultLevelFormatter returns a default LevelFormatter

type LeveledWriter added in v1.2.0

type LeveledWriter struct {
	Default     Writer
	LevelWriter map[Level]Writer
}

LeveledWriter is a Writer which based on the log level will write to a writer It also uses a Default one for the Write method as well as supporting the case when the Writer is not found in the Level map

func NewLeveledWriter added in v1.2.0

func NewLeveledWriter(
	defaultWriter Writer,
	fns ...LeveledWriterOptionFunc,
) *LeveledWriter

NewLeveledWriter returns a LeveledWriter

func (*LeveledWriter) Flush added in v1.14.1

func (m *LeveledWriter) Flush() error

Flush flushes the data

func (*LeveledWriter) Write added in v1.2.0

func (m *LeveledWriter) Write(msg []byte) (int, error)

Write calls the Default Write method

func (*LeveledWriter) WriteEntry added in v1.2.0

func (m *LeveledWriter) WriteEntry(e Entry)

WriteEntry writes an Entry to the related Writer If not found, then fallback on the Default

type LeveledWriterOptionFunc added in v1.2.0

type LeveledWriterOptionFunc func(*LeveledWriter)

LeveledWriterOptionFunc is a handy function which implements attach a Writer for a given Level in a LeveledWriter

func DefaultLeveledWriterOptionFunc added in v1.2.0

func DefaultLeveledWriterOptionFunc(lvl Level, w Writer) LeveledWriterOptionFunc

DefaultLeveledWriterOptionFunc implements LeveledWriterOptionFunc

type Logger

type Logger interface {
	Debug(context.Context, Message)
	Info(context.Context, Message)
	Warn(context.Context, Message)
	Error(context.Context, Message)
	Fatal(context.Context, Message)
	With(...Field) Logger
}

Logger is a logger able to write custom log Message with Fields

Example
ctx := context.Background()
t, err := time.Parse("2006", "2021")
if err != nil {
	fmt.Println(err)
	return
}

w := golog.NewBufWriter(
	golog.NewJsonEncoder(golog.DefaultJsonConfig()),
	bufio.NewWriter(os.Stdout),
	golog.DefaultErrorHandler(),
	golog.DEBUG,
)
defer w.Flush()

golog.SetLogger(golog.New(w, golog.NewLevelCheckerOption(golog.DEBUG)))

logger := golog.With(golog.String("hello", "world"))
logger.Error(ctx, "an error message")
logger.Error(ctx, `another error 
message`)
loggerWithErr := logger.With(golog.Err(fmt.Errorf("error: ops!")))
logger.Info(ctx, "an info 	message")
loggerWithErr.Warn(ctx, "a warning message")
loggerWithErr.With(golog.Mapper("user", user{ID: "uuid", Reference: 123, Birthdate: t})).Error(ctx, "a warning message")
Output:

{"level":"ERROR","message":"an error message","hello":"world"}
{"level":"ERROR","message":"another error \nmessage","hello":"world"}
{"level":"INFO","message":"an info \tmessage","hello":"world"}
{"level":"WARN","message":"a warning message","hello":"world","error":"error: ops!"}
{"level":"ERROR","message":"a warning message","hello":"world","error":"error: ops!","user":{"id":"uuid","ref":123,"birthdate":"2021-01-01T00:00:00Z"}}

func With

func With(fields ...Field) Logger

With calls the base Logger's With method

type Message

type Message = string

Message is a log entry message

type MinSeverity

type MinSeverity = Level

MinSeverity is the min log Level which can be written

type MultiWriter added in v1.2.0

type MultiWriter struct {
	Writers []Writer
}

MultiWriter is a Writer which based on the log level will write to a writer It also uses a Default one for the Write method as well as supporting the case when the Writer is not found in the Level map

func NewMultiWriter added in v1.2.0

func NewMultiWriter(
	ws ...Writer,
) *MultiWriter

NewMultiWriter returns a MultiWriter

func (*MultiWriter) Flush added in v1.14.0

func (m *MultiWriter) Flush() error

Flush flushes the data to the related Writer

func (*MultiWriter) Write added in v1.2.0

func (m *MultiWriter) Write(msg []byte) (int, error)

Write calls the Default Write method

func (*MultiWriter) WriteEntry added in v1.2.0

func (m *MultiWriter) WriteEntry(e Entry)

WriteEntry writes an Entry to the related Writer If not found, then fallback on the Default

type NoopCheckedLogger

type NoopCheckedLogger struct{}

NoopCheckedLogger is a nil-like CheckedLogger

func (NoopCheckedLogger) Log

func (n NoopCheckedLogger) Log(_ ...Field)

Log does nothing

type Option

type Option interface {
	Apply(StdLogger) StdLogger
}

Option modifies a StdLogger and returns the modified one

func NewLevelCheckerOption

func NewLevelCheckerOption(minSev MinSeverity) Option

NewLevelCheckerOption returns an Option which applies a LevelChecker with the given MinSeverity

func NewStackTraceDecoratorOption

func NewStackTraceDecoratorOption(n string, depth int) Option

NewStackTraceDecoratorOption returns an Option which applies a StackTraceDecorator with the given field name

func NewTimestampDecoratorOption added in v0.2.0

func NewTimestampDecoratorOption(name, layout string) Option

NewTimestampDecoratorOption returns an Option which applies a TimestampDecorator with the given field name

type OptionFunc

type OptionFunc func(StdLogger) StdLogger

OptionFunc is a handy function which implements Option

func (OptionFunc) Apply

func (fn OptionFunc) Apply(l StdLogger) StdLogger

Apply change a StdLogger with custom logic and return the new modified one

type StackTraceDecorator

type StackTraceDecorator struct {
	StacktraceFieldName string
	Depth               int
}

StackTraceDecorator is a Decorator which add the log stacktrace

func NewStackTraceDecorator

func NewStackTraceDecorator(n string, depth int) StackTraceDecorator

NewStackTraceDecorator returns a StackTraceDecorator with the given field name

func (StackTraceDecorator) Decorate

func (sd StackTraceDecorator) Decorate(e Entry) Entry

Decorate adds the stacktrace to the entry

type StdCheckedLogger

type StdCheckedLogger struct {
	Writer Writer
	Entry  Entry
}

StdCheckedLogger is a CheckedLogger which will write when called

func (StdCheckedLogger) Log

func (l StdCheckedLogger) Log(flds ...Field)

Log writes a log with the given Fields Log panics with the message if the Level is FATAL

type StdEntry

type StdEntry struct {
	Ctx  context.Context
	Lvl  Level
	Msg  Message
	Flds Fields
}

StdEntry is a representation of the standard log Entry

func NewStdEntry

func NewStdEntry(
	ctx context.Context,
	lvl Level,
	msg string,
	flds Fields,
) StdEntry

NewStdEntry returns a StdEntry

func (StdEntry) Context

func (e StdEntry) Context() context.Context

Context returns an entry assigned to the entry This could be used to enrich the entry after it get created for the first time

func (StdEntry) Fields

func (e StdEntry) Fields() Fields

Fields returns the fields assigned to a log entry

func (StdEntry) Level

func (e StdEntry) Level() Level

Level returns the entry Level

func (StdEntry) Message

func (e StdEntry) Message() Message

Message returns the entry Message

func (StdEntry) With

func (e StdEntry) With(flds ...Field) Entry

With returns a new StdEntry appending the given extra Fields

type StdLogger

type StdLogger struct {
	Writer     Writer
	Fields     Fields
	Decorators Decorators
	Checkers   Checkers
}

StdLogger is a representation of the standard Logger

func New

func New(w Writer, options ...Option) StdLogger

New returns a StdLogger which writes starting from the given Level to the given Writer

func (StdLogger) CheckDebug

func (l StdLogger) CheckDebug(ctx context.Context, msg Message) (CheckedLogger, bool)

CheckDebug returns a CheckedLogger and a guard When the guard is true and the CheckDebug is called a log with the DEBUG Level is written

func (StdLogger) CheckError

func (l StdLogger) CheckError(ctx context.Context, msg Message) (CheckedLogger, bool)

CheckError returns a CheckedLogger and a guard When the guard is true and the CheckError is called a log with the ERROR Level is written

func (StdLogger) CheckFatal

func (l StdLogger) CheckFatal(ctx context.Context, msg Message) (CheckedLogger, bool)

CheckFatal returns a CheckedLogger and a guard When the guard is true and the with is called a log with the FATAL Level is written CheckFatal will also panic with the given message

func (StdLogger) CheckInfo

func (l StdLogger) CheckInfo(ctx context.Context, msg Message) (CheckedLogger, bool)

CheckInfo returns a CheckedLogger and a guard When the guard is true and the CheckInfo is called a log with the INFO Level is written

func (StdLogger) CheckWarn added in v1.0.0

func (l StdLogger) CheckWarn(ctx context.Context, msg Message) (CheckedLogger, bool)

CheckWarn returns a CheckedLogger and a guard When the guard is true and the CheckWarn is called a log with the WARN Level is written

func (StdLogger) Debug

func (l StdLogger) Debug(ctx context.Context, msg Message)

Debug writes a log with the DEBUG Level

func (StdLogger) Error

func (l StdLogger) Error(ctx context.Context, msg Message)

Error writes a log with the ERROR Level

func (StdLogger) Fatal

func (l StdLogger) Fatal(ctx context.Context, msg Message)

Fatal writes a log with the FATAL Level Fatal also panic with the given message

func (StdLogger) Info

func (l StdLogger) Info(ctx context.Context, msg Message)

Info writes a log with the INFO Level

func (StdLogger) Warn added in v1.0.0

func (l StdLogger) Warn(ctx context.Context, msg Message)

Warn writes a log with the WARN Level

func (StdLogger) With

func (l StdLogger) With(fields ...Field) Logger

With returns a new Logger appending the given extra Fields

func (StdLogger) WithCheckers

func (l StdLogger) WithCheckers(cs ...Checker) StdLogger

WithCheckers returns a new StdLogger appending the given extra Checkers

func (StdLogger) WithDecorator

func (l StdLogger) WithDecorator(ds ...Decorator) StdLogger

WithDecorator returns a new StdLogger appending the given extra Decorators

type TextConfig added in v0.2.2

type TextConfig struct {
	LevelKeyName   string
	MessageKeyName string
	TimeLayout     string
	LevelFormatter LevelFormatter
}

TextConfig is a configuration for TextEncoder

func DefaultTextConfig added in v0.2.2

func DefaultTextConfig() TextConfig

DefaultTextConfig returns a default TextConfig

type TextEncoder added in v0.2.2

type TextEncoder struct {
	Config TextConfig
}

TextEncoder is an encoder for text

func NewTextEncoder added in v0.2.2

func NewTextEncoder(cfg TextConfig) TextEncoder

NewTextEncoder returns a TextEncoder

func (TextEncoder) Encode added in v0.2.2

func (t TextEncoder) Encode(e Entry) (io.WriterTo, error)

Encode encodes an entry into a text content holds into an io.WriterTo

type TickFlusher

type TickFlusher struct {
	Flusher
	Ticker *time.Ticker
}

TickFlusher is a Flusher triggered by a time.Ticker

func NewTickFlusher

func NewTickFlusher(f Flusher, d time.Duration) *TickFlusher

NewTickFlusher returns a TickFlusher

func (*TickFlusher) Close

func (f *TickFlusher) Close() error

Close stops the time.Ticker and flushes the data

func (*TickFlusher) Flush

func (f *TickFlusher) Flush() error

Flush forces the data in the inner Flusher to be written

type TimestampDecorator added in v0.2.0

type TimestampDecorator struct {
	TimestampLayout    string
	TimestampFieldName string
}

TimestampDecorator is a Decorator which add the log timestamp

func NewTimestampDecorator added in v0.2.0

func NewTimestampDecorator(name, layout string) TimestampDecorator

NewTimestampDecorator returns a TimestampDecorator with the given field name and layout

func (TimestampDecorator) Decorate added in v0.2.0

func (td TimestampDecorator) Decorate(e Entry) Entry

Decorate adds the timestamp to the entry

type Writer

type Writer interface {
	WriteEntry(Entry)
	Flusher
	io.Writer
}

Writer is an Entry writer

Directories

Path Synopsis
Package test is a generated GoMock package.
Package test is a generated GoMock package.

Jump to

Keyboard shortcuts

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