errlog

package module
v0.0.0-...-0045885 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2019 License: MIT Imports: 10 Imported by: 0

README

Errlog: reduce debugging time while programming Go Report Card Awesome Documentation GitHub issues license

Example

Introduction

Use errlog to improve error logging and speed up debugging while you create amazing code :

  • Highlight source code
  • Detect and point out which func call is causing the fail
  • Pretty stack trace
  • No-op mode for production
  • Easy implementation, adaptable logger
  • Plug to any current project without changing you or your teammates habits
  • Plug to your current logging system
Go to
Get started
Documentation
Examples
Tweaking
Feedbacks
Contributions
License
Contributors

Get started

Install
go get github.com/snwfdhmp/errlog
Usage

Replace your if err != nil with if errlog.Debug(err) to add debugging informations.

func someFunc() {
    //...
    if errlog.Debug(err) { // will debug & pass if err != nil, will ignore if err == nil
        return
    }
}

In production, call errlog.Disable(true) to enable no-op (equivalent to if err != nil)

Tweak as you need

You can configure your own logger with the following options :

type Config struct {
    PrintFunc          func(format string, data ...interface{}) //Printer func (eg: fmt.Printf)
    LinesBefore        int  //How many lines to print *before* the error line when printing source code
    LinesAfter         int  //How many lines to print *after* the error line when printing source code
    PrintStack         bool //Shall we print stack trace ? yes/no
    PrintSource        bool //Shall we print source code along ? yes/no
    PrintError         bool //Shall we print the error of Debug(err) ? yes/no
    ExitOnDebugSuccess bool //Shall we os.Exit(1) after Debug has finished logging everything ? (doesn't happen when err is nil). Will soon be replaced by ExitFunc to enable panic-ing the current goroutine. (if you need this quick, please open an issue)
}

As we don't yet update automatically this README immediately when we add new features, this definition may be outdated. (Last update: 2019/08/07) See the struct definition in godoc.org for the up to date definition

Example

Try yourself
Name and link  Description 
Basic standard usage, quick setup
Custom guided configuration for fulfilling your needs
Disabled how to disable the logging & debugging (eg: for production use)
Failing line far away example of finding the func call that caused the error while it is lines away from the errlog.Debug call
Pretty stack trace pretty stack trace printing instead of debugging.
Just read
Basic example

Note that in the example, you will see some unuseful func. Those are made to generate additional stack trace levels for the sake of example

We're going to use this sample program :

func main() {
    fmt.Println("Program start")

    wrapingFunc() //call to our important function

    fmt.Println("Program end")
}

func wrapingFunc() {
    someBigFunction() // call some func 
}

func someBigFunction() {
    someDumbFunction() // just random calls
    someSmallFunction() // just random calls
    someDumbFunction() // just random calls

    // Here it can fail, so instead of `if err  != nil` we use `errlog.Debug(err)`
    if err := someNastyFunction(); errlog.Debug(err) {
        return
    }

    someSmallFunction() // just random calls
    someDumbFunction() // just random calls
}

func someSmallFunction() {
    _ = fmt.Sprintf("I do things !")
}

func someNastyFunction() error {
    return errors.New("I'm failing for some reason") // simulate an error
}

func someDumbFunction() bool {
    return false // just random things
}
Output

Console Output examples/basic.go

We are able to detect and point out which line is causing the error.

Custom Configuration Example

Let's see what we can do with a custom configuration.

debug := errlog.NewLogger(&errlog.Config{
    // PrintFunc is of type `func (format string, data ...interface{})`
    // so you can easily implement your own logger func.
    // In this example, logrus is used, but any other logger can be used.
    // Beware that you should add '\n' at the end of format string when printing.
    PrintFunc:          logrus.Printf,
    PrintSource:        true, //Print the failing source code
    LinesBefore:        2, //Print 2 lines before failing line
    LinesAfter:         1, //Print 1 line after failing line
    PrintError:         true, //Print the error
    PrintStack:         false, //Don't print the stack trace
    ExitOnDebugSuccess: true, //Exit if err
})

Please note: This definition may be outdated. (Last update: 2019/08/07) See the struct definition in godoc.org for the up to date definition

Output

Console Output examples/custom.go

When the failing func call is a few lines away

Even when the func call is a few lines away, there is no problem for finding it.

Output

Documentation

Documentation can be found here : Documentation

Feedbacks

Feel free to open an issue for any feedback or suggestion.

I fix process issues quickly.

Contributions

We are happy to collaborate with you :

When submitting a PR, please apply Effective Go best practices. For more information: https://golang.org/doc/effective_go.html

License information

Click the following badge to open LICENSE information.

license

Contributors

Major
Minor fixes

Documentation

Overview

Package errlog provides a simple object to enhance Go source code debugging

Example result:

$ go run myfailingapp.go
Program starting
error in main.main: something failed here
line 13 of /Users/snwfdhmp/go/src/github.com/snwfdhmp/sandbox/testerr.go
9: func main() {
10:     fmt.Println("Program starting")
11:     err := errors.New("something failed here")
12:
13:     errlog.Debug(err)
14:
15:     fmt.Println("End of the program")
16: }
exit status 1

You can configure your own logger with these options :

type Config struct {
	LinesBefore        int
	LinesAfter         int
	PrintStack         bool
	PrintSource        bool
	PrintError         bool
	ExitOnDebugSuccess bool
}

Example :

debug := errlog.NewLogger(&errlog.Config{
	LinesBefore:        2,
	LinesAfter:         1,
	PrintError:         true,
	PrintSource:        true,
	PrintStack:         false,
	ExitOnDebugSuccess: true,
})

// ...
if err != nil {
	debug.Debug(err)
	return
}

Outputs :

Error in main.someBigFunction(): I'm failing for no reason
line 41 of /Users/snwfdhmp/go/src/github.com/snwfdhmp/sandbox/testerr.go:41
33: func someBigFunction() {
...
40:     if err := someNastyFunction(); err != nil {
41:             debug.Debug(err)
42:             return
43:     }
exit status 1

Index

Constants

View Source
const (
	// ModeDisabled represents the disabled mode (NO-OP)
	ModeDisabled = iota + 1
	// ModeEnabled represents the enabled mode (Print)
	ModeEnabled
)

Variables

View Source
var (
	//DefaultLoggerPrintFunc is log.Printf without return values
	DefaultLoggerPrintFunc = func(format string, data ...interface{}) {
		log.Printf(format+"\n", data...)
	}

	//DefaultLoggerPrintFunc is log.Printf without return values
	DefaultLoggerPrintlnFunc = func(data ...interface{}) {
		log.Println(data...)
	}

	//DefaultLogger logger implements default configuration for a logger
	DefaultLogger = &logger{
		config: &Config{
			PrintFunc:          DefaultLoggerPrintFunc,
			PrintlnFunc:        DefaultLoggerPrintlnFunc,
			LinesBefore:        4,
			LinesAfter:         2,
			PrintStack:         false,
			PrintSource:        true,
			PrintError:         true,
			ExitOnDebugSuccess: false,
		},
	}
)

Functions

func Debug

func Debug(uErr error) bool

Debug is a shortcut for DefaultLogger.Debug.

func Debugx

func Debugx(uErr error, args ...interface{}) bool

Debugx is a shortcut for DefaultLogger.Debug.

func PrintRawStack

func PrintRawStack()

PrintRawStack prints the current stack trace unparsed

func PrintStack

func PrintStack()

PrintStack pretty prints the current stack trace

func PrintStackMinus

func PrintStackMinus(depthToRemove int)

PrintStackMinus prints the current stack trace minus the amount of depth in parameter

func SetDebugMode

func SetDebugMode(toggle bool)

SetDebugMode sets debug mode to On if toggle==true or Off if toggle==false. It changes log level an so displays more logs about whats happening. Useful for debugging.

Types

type Config

type Config struct {
	PrintFunc               func(format string, data ...interface{}) //Printer func (eg: fmt.Printf)
	PrintlnFunc             func(data ...interface{})                //Printer func (eg: fmt.Printf)
	LinesBefore             int                                      //How many lines to print *before* the error line when printing source code
	LinesAfter              int                                      //How many lines to print *after* the error line when printing source code
	PrintStack              bool                                     //Shall we print stack trace ? yes/no
	PrintSource             bool                                     //Shall we print source code along ? yes/no
	PrintError              bool                                     //Shall we print the error of Debug(err) ? yes/no
	ExitOnDebugSuccess      bool                                     //Shall we os.Exit(1) after Debug has finished logging everything ? (doesn't happen when err is nil)
	DisableStackIndentation bool                                     //Shall we print stack vertically instead of indented
	Mode                    int
}

Config holds the configuration for a logger

type Logger

type Logger interface {
	// Debug wraps up Logger debugging funcs related to an error
	// If the given error is nil, it returns immediately
	// It relies on Logger.Config to determine what will be printed or executed
	// It returns whether err != nil
	Debug(err error) bool
	//PrintSource prints lines based on given opts (see PrintSourceOptions type definition)
	PrintSource(lines []string, opts PrintSourceOptions)
	//DebugSource debugs a source file
	DebugSource(filename string, lineNumber int)
	//SetConfig replaces current config with the given one
	SetConfig(cfg *Config)
	//Config returns current config
	Config() *Config
	//Disable is used to disable Logger (every call to this Logger will perform NO-OP (no operation)) and return instantly
	//Use Disable(true) to disable and Disable(false) to enable again
	Disable(bool)
}

Logger interface allows to log an error, or to print source code lines. Check out NewLogger function to learn more about Logger objects and Config.

func NewLogger

func NewLogger(cfg *Config) Logger

NewLogger creates a new logger struct with given config

type PrintSourceOptions

type PrintSourceOptions struct {
	FuncLine    int
	StartLine   int
	EndLine     int
	Highlighted map[int][]int //map[lineIndex][columnstart, columnEnd] of chars to highlight
}

PrintSourceOptions represents config for (*logger).PrintSource func

type StackTraceItem

type StackTraceItem struct {
	CallingObject string
	Args          []string
	SourcePathRef string
	SourceLineRef int
	MysteryNumber int64
}

StackTraceItem represents parsed information of a stack trace item

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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