logan

package
v3.8.1+incompatible Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2022 License: MIT Imports: 6 Imported by: 73

README

Still alpha, some backward compatibility demages can happen.

Logan wraps logrus and adds:

  • Custom error with map for storing fields
  • WithStack to log stack of an error
  • WithRecover to log recover objects and retrieve stack from errors passed into panic

##Synopsis

####Log

    rootLog := logan.New().Level(loganLogLevel).WithField("application", "appName")
    childLog := rootLog.WithField("service", "serviceName") // contains `application`
    clildLog.WithField("key", "value").WithError(err).WithStack(err).Error("Error happened.")

####Errors

    plainError := errors.New("Error message.")
    
    wrapped := errors.Wrap(plainError, "Wrapping message")
    wrappedWithFields := errors.Wrap(plainError, "Wrapping message", logan.Field("key", "value").Add("key2", "value"))
    
    newErrorWithFields := errors.From(errors.New("Error message."), logan.Field("key", "value").Add("key2", "value"))

###Fielded error usage example:

package main

import (
	"gitlab.com/distributed_lab/logan/v3"
	"gitlab.com/distributed_lab/logan/v3/errors"
)

func main() {
	err := driveCar("Bob")
	if err != nil {
		log := logan.New()
		// Logan will log `car_color` here
		log.WithField("service", "car_manager").WithError(err).Error("Failed to start car.")
	}
}

func driveCar(driver string) error {
	var carColor string
	switch driver {
	case "John":
		// Only John drives blue car
		carColor = "BLUE"
	default:
		carColor = "RED"
	}

	err := startEngine(carColor)
	if err != nil {
	    // Mention `carColor` here, it is unknown from above.
		// Instead of logging the `carColor` here, put it into `err` as a field.
		return errors.Wrap(err, "Failed to start engine.", logan.F{"car_color": carColor})
	}

	return nil
}

// startEngine just returns simple error, if `carColor` is "RED".
func startEngine(carColor string) error {
	if carColor == "RED" {
	    // Do not add `carColor` into error here, it is known from above.
		return errors.New("Engine exploded.")
	}

	return nil
}

###To migrate from logan v1 to v3 do replaces:

Imports

"gitlab.com/distributed_lab/logan" --> "gitlab.com/distributed_lab/logan/v3"\n\t"gitlab.com/distributed_lab/logan/v3/errors" (do with regex) (Caution: this will also modify Gopkg files)

Wrap

logan.Wrap( --> errors.Wrap(

Wrap With fields

errors.Wrap\((.+)\)\.[\n\t ]*WithFields\((.+)\) --> errors.Wrap($1, $2) (do with regex)

Wrap With field

errors.Wrap\(([a-zA-Z]+, *".+")\)\.[\n\t ]*WithField\((.+)\)((\.[\n\t ]*WithField\(.+\))*) --> errors.Wrap($1, logan.Field($2)$3) (do with regex)

New With field

errors.New\((".+")\)\.[\n\t ]*WithField\((.+)\)((\.[\n\t ]*WithField\(.+\))*) --> errors.From(errors.New($1), logan.Field($2)$3) (do with regex)

For chained WithField calls - do multiple times logan.Field\((.+)\)\.[\n\t ]*WithField\((.+)\) --> logan.Field($1).Add($2) (do with regex)

Remove errors import, where logan/v3/errors import exists

\n\s"errors"((\n.*)*)"gitlab.com\/distributed_lab\/logan\/v3\/errors" --> $1"gitlab.com\/distributed_lab\/logan\/v3\/errors"

\n\s"github.com/go-errors/errors"((\n.*)*)"gitlab.com\/distributed_lab\/logan\/v3\/errors" --> $1"gitlab.com\/distributed_lab\/logan\/v3\/errors"

\n\s"github.com/pkg/errors"((\n.*)*)"gitlab.com\/distributed_lab\/logan\/v3\/errors" --> $1"gitlab.com\/distributed_lab\/logan\/v3\/errors"

Will then need to remove manually "gitlab.com/distributed_lab/logan/v3/errors" in some places (unused import)

If having some go errors imports - will also need to resolve manually.

###To replace deprecated logan.Field(), fields.Add() and fields.AddFields():

logan.Field\((\".+\"),[ ]*([^)]+)\) --> logan.F{$1: $2} (regexp)

\.AddFields\(([^)]+)\) --> .Merge($1) (regexp)

\.Add\((\"[^.]+\"),[ ]*([^)]+)\) --> [$1] = $2 (regexp) Fix the appeared compilation errors.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrorKey = logrus.ErrorKey
	StackKey = "stack"
)

Functions

This section is empty.

Types

type Entry

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

func New

func New() *Entry

func (*Entry) AddHook

func (e *Entry) AddHook(hook Hook)

func (*Entry) AddLogrusHook

func (e *Entry) AddLogrusHook(hook logrus.Hook)

func (*Entry) Debug

func (e *Entry) Debug(args ...interface{})

Debug logs a message at the debug severity.

func (*Entry) Debugf

func (e *Entry) Debugf(format string, args ...interface{})

Debugf logs a message at the debug severity.

func (*Entry) Error

func (e *Entry) Error(args ...interface{})

Error logs a message at the Error severity.

func (*Entry) Errorf

func (e *Entry) Errorf(format string, args ...interface{})

Errorf logs a message at the Error severity.

func (*Entry) Fatal

func (e *Entry) Fatal(args ...interface{})

Fatal logs a message at the Error severity.

func (*Entry) Fatalf

func (e *Entry) Fatalf(format string, args ...interface{})

Fatalf logs a message at the Error severity.

func (*Entry) Formatter

func (e *Entry) Formatter(formatter Formatter) *Entry

func (*Entry) Info

func (e *Entry) Info(args ...interface{})

Info logs a message at the Info severity.

func (*Entry) Infof

func (e *Entry) Infof(format string, args ...interface{})

Infof logs a message at the Info severity.

func (*Entry) Level

func (e *Entry) Level(level Level) *Entry

func (*Entry) Log

func (e *Entry) Log(level uint32, fields map[string]interface{}, err error, withStack bool, args ...interface{})

Log logs message with the provided severity(level), fields and error.

This Method is basically implemented to abstract packages which need logging with fields and errors from logan, so that users without logan could use such packages providing some other arbitrary implementation of Log method.

func (*Entry) Out

func (e *Entry) Out(writer io.Writer) *Entry

func (*Entry) Panic

func (e *Entry) Panic(args ...interface{})

Panic logs a message at the Panic severity.

func (*Entry) Panicf

func (e *Entry) Panicf(format string, args ...interface{})

Panicf logs a message at the Panic severity.

func (*Entry) Warn

func (e *Entry) Warn(args ...interface{})

Warn logs a message at the Warn severity.

func (*Entry) Warnf

func (e *Entry) Warnf(format string, args ...interface{})

Warnf logs a message at the Warn severity.

func (*Entry) WithError

func (e *Entry) WithError(err error) *Entry

func (*Entry) WithField

func (e *Entry) WithField(key string, value interface{}) *Entry

func (*Entry) WithFields

func (e *Entry) WithFields(f F) *Entry

func (*Entry) WithRecover

func (e *Entry) WithRecover(recoverData interface{}) *Entry

WithRecover creates error from the `recoverData` if it isn't actually an error already and returns Entry with this error and its stack.

func (*Entry) WithStack

func (e *Entry) WithStack(err error) *Entry

type F

type F map[string]interface{}

F type is for fields, connected to `withFields` error.

func Field

func Field(key string, value interface{}) F

WithField creates new `F` fields map and add provided key-value pair into it using Add method.

DEPRECATED: Use F{key: value} directly instead. Fields expanding is now happening on adding to log Entry.

func (F) Add

func (f F) Add(key string, value interface{}) F

Add tries to extract fields from `value`, if `value` implements fields.Provider interface:

type Provider interface {
	GetLoganFields() map[string]interface{}
}

And adds these fields using AddFields. If `value` does not implement Provider - a single key-value pair is added.

Add doesn't change any of maps - only creates a new one.

DEPRECATED: Use `fields[key] = value` instead. Fields expanding is now happening on adding to log Entry.

func (F) AddFields

func (f F) AddFields(newF F) F

AddFields returns `F` map, which contains key-values from both maps. If both maps has some key - the value from the `newF` will be used.

AddFields doesn't change any of maps - only creates a new one.

DEPRECATED: Use Merge method instead (it's same, but more obvious that it doesn't mutate the instance).

func (F) Merge

func (f F) Merge(newF F) F

Merge returns `F` map, which contains key-values from both maps. If both maps has some key - the value from the `newF` will be used.

Merge doesn't change any of maps - only creates a new one.

type Formatter

type Formatter interface {
	Format(*logrus.Entry) ([]byte, error)
}

The Formatter interface is used to implement a custom Formatter. It takes an Entry. It exposes all the fields, including the default ones:

* `entry.Data["msg"]`. The message passed from Info, Warn, Error .. * `entry.Data["time"]`. The timestamp. * `entry.Data["level"]. The level the entry was logged at.

Any additional fields added with `WithField` or `WithFields` are also in `entry.Data`. Format is expected to return an array of bytes which are then logged to `logger.Out`.

var JSONFormatter Formatter = &logrus.JSONFormatter{}

type Hook

type Hook interface {
	Levels() []Level
	Fire(*Entry) error
}

type Level

type Level logrus.Level
const (
	PanicLevel Level = iota
	FatalLevel
	ErrorLevel
	WarnLevel
	InfoLevel
	DebugLevel
)

func ParseLevel

func ParseLevel(level string) (Level, error)

Directories

Path Synopsis
hook

Jump to

Keyboard shortcuts

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