zerolog icon indicating copy to clipboard operation
zerolog copied to clipboard

Not getting the stack in an error

Open conor-tread opened this issue 2 years ago • 7 comments

Im using the package in an AWS serverless codebase and when I force an error Im not seeing the stack trace in the logs. In the init() function I have zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack.

I can see my error message in the log that gets printed its just not printing the stack

conor-tread avatar Aug 16 '22 19:08 conor-tread

+1

Mehrdad-Dadkhah avatar Sep 02 '22 03:09 Mehrdad-Dadkhah

You need to use WithStack() from pkg/errors.

The documentation lists pkg/errors as a requirement: https://github.com/rs/zerolog#error-logging-with-stacktrace

Not sure if there are any downsides to the below approach, but you can just wrap the MarshalStack reference in a closure, so you don't need to pollute the entire codebase with pkg/errors imports, and only use this reference when you add the .Stack() call to the logger context chain:

import (
	"github.com/pkg/errors"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/pkgerrors"
)
...
	zerolog.ErrorStackMarshaler = func(err error) interface{} {
		return pkgerrors.MarshalStack(errors.WithStack(err))
	}

skormos avatar Sep 04 '22 17:09 skormos

I created another issue requesting pkg/errors be removed as a dependency since that library is now in maintenance mode.

skormos avatar Sep 04 '22 18:09 skormos

You need to use WithStack() from pkg/errors.

The documentation lists pkg/errors as a requirement: https://github.com/rs/zerolog#error-logging-with-stacktrace

Not sure if there are any downsides to the below approach, but you can just wrap the MarshalStack reference in a closure, so you don't need to pollute the entire codebase with pkg/errors imports, and only use this reference when you add the .Stack() call to the logger context chain:

import (
	"github.com/pkg/errors"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/pkgerrors"
)
...
	zerolog.ErrorStackMarshaler = func(err error) interface{} {
		return pkgerrors.MarshalStack(errors.WithStack(err))
	}

could you explain why we need this? your code just works fine, but why its not in the official code? i couldnt get it to work with the example out of the readme. should we create a PR to add your fix?

xsteadfastx avatar Jan 27 '23 13:01 xsteadfastx

also this doesnt show a full stack of the wrapped errors. it just show the stack trace from defining the zerolog.ErrorStackMarshaler to the goexit. im my case i have a few wrapped errors and get this output:

{"level":"error","devEui":"000","deviceName":"IOT-ELCMI-0001","applictionName":"Testlab","applicationId":954,"tags":{"productive":"false","usecase":"zaehler","vendor":"landis+gyr"},"pusher":"db","stack":[{"func":"init.0.func1","line":"87","source":"integration_test.go"},{"func":"(*Event).Err","line":"381","source":"event.go"},{"func":"Push.func1.1","line":"55","source":"event.go"},{"func":"goexit","line":"1594","source":"asm_amd64.s"}],"error":"could not push db entry: failed to read sql asset: open sqls/insert-recordings-without-location.sql: file does not exist","time":"2023-01-27T13:32:46Z","message":"error on push"}

xsteadfastx avatar Jan 27 '23 13:01 xsteadfastx

@xsteadfastx, if you use the pkgerrors.MarshalStack, it can only print stack traces for errors that are from github.com/pkg/errors. That is, it won't print stack traces to any arbitrary error you encounter. In order to add the stack traces to "external errors", wrap them with errors.Wrap(...) when you first encounter them.

Example from here: https://pkg.go.dev/github.com/pkg/errors#hdr-Adding_context_to_an_error

_, err := ioutil.ReadAll(r)
if err != nil {
        return errors.Wrap(err, "read failed")
}

For example in my tests

import (
	"fmt"

	"github.com/pkg/errors"
	"github.com/rs/zerolog"
	zl "github.com/rs/zerolog/log"
	"github.com/rs/zerolog/pkgerrors"

	"testing"
)

func TestZl(t *testing.T) {
	zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack

	zl.Info().Stack().Err(wrapperError()).Msg("with stack trace")
	zl.Info().Stack().Err(fmtError()).Msg("without stack trace")
}

func fmtError() error {
	return fmt.Errorf("fmt error")
}

func wrapperError() error {
	return errors.Wrap(fmtError(), "wrapped")
}

tpokki avatar Feb 04 '23 17:02 tpokki

thank you alot for explaining. it helped me alot to understand it!

On Sa, 04. Feb 09:18, Toni Pokki wrote:

@xsteadfastx, if you use the pkgerrors.MarshalStack, it can only print stack traces for errors that are from github.com/pkg/errors. That is, it won't print stack traces to any arbitrary error you encounter. In order to add the stack traces to "external errors", wrap them with errors.Wrap(...) when you first encounter them.

Example from here: https://pkg.go.dev/github.com/pkg/errors#hdr-Adding_context_to_an_error

_, err := ioutil.ReadAll(r)
if err != nil {
        return errors.Wrap(err, "read failed")
}

For example in my tests

import (
	"fmt"

	"github.com/pkg/errors"
	"github.com/rs/zerolog"
	zl "github.com/rs/zerolog/log"
	"github.com/rs/zerolog/pkgerrors"

	"testing"
)

func TestZl(t *testing.T) {
	zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack

	zl.Info().Stack().Err(wrapperError()).Msg("with stack trace")
	zl.Info().Stack().Err(fmtError()).Msg("without stack trace")
}

func fmtError() error {
	return fmt.Errorf("fmt error")
}

func wrapperError() error {
	return errors.Wrap(fmtError(), "wrapped")
}

-- Reply to this email directly or view it on GitHub: https://github.com/rs/zerolog/issues/462#issuecomment-1416804371 You are receiving this because you were mentioned.

Message ID: @.***>

xsteadfastx avatar Feb 06 '23 11:02 xsteadfastx