Skip to content

Instantly share code, notes, and snippets.

@Bak-Jin-Hyeong
Last active April 23, 2019 07:14
Show Gist options
  • Save Bak-Jin-Hyeong/f4769f53edcc966c6d8b8b04c873d643 to your computer and use it in GitHub Desktop.
Save Bak-Jin-Hyeong/f4769f53edcc966c6d8b8b04c873d643 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/aws/awserr"
"github.com/pkg/errors"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"runtime"
)
func newLogger() (*zap.Logger, error) {
encoderCfg := zap.NewProductionEncoderConfig()
encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
cfg := zap.NewProductionConfig()
cfg.EncoderConfig = encoderCfg
return cfg.Build()
}
func stackTrace(e error) errors.StackTrace {
type stackTracer interface {
StackTrace() errors.StackTrace
}
if s, ok := e.(stackTracer); ok {
return s.StackTrace()
}
return nil
}
type Error struct {
E error
}
type StackTrace errors.StackTrace
func (st StackTrace) MarshalLogArray(enc zapcore.ArrayEncoder) error {
for i := range st {
pc := uintptr(st[i] - 1)
fn := runtime.FuncForPC(pc)
if fn == nil {
continue
}
name := fn.Name()
file, line := fn.FileLine(pc)
enc.AppendString(name)
enc.AppendString(fmt.Sprintf("%s:%d", file, line))
}
return nil
}
func (receiver Error) MarshalLogObject(enc zapcore.ObjectEncoder) error {
enc.AddString("e", receiver.E.Error())
if st := stackTrace(receiver.E); st != nil {
if err := enc.AddArray("st", StackTrace(st)); err != nil {
return err
}
}
type causer interface {
Cause() error
}
cause := receiver.E
for cause != nil {
c, ok := cause.(causer)
if !ok {
break
}
cause = c.Cause()
if err := enc.AddObject("cause", Error{cause}); err != nil {
return err
}
}
return nil
}
func makeErr() error {
return errors.New("what the fuck")
}
func makeErrWrap() error {
return errors.WithMessage(makeErr(), "shit")
}
func makeAwsErr() error {
orig := awserr.New("fake-code", "fake-msg", fmt.Errorf("fake-orig"))
return errors.WithStack(awserr.NewRequestFailure(orig, 500, "fake-request-id"))
}
func main() {
logger, _ := newLogger()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
defer sugar.Info("term")
sugar.Info("init")
logger.Info("err")
logger.Info("custom", zap.Object("error", Error{makeErrWrap()}))
logger.Info("custom", zap.Object("error", Error{makeErr()}))
logger.Info("custom", zap.Object("error", Error{makeAwsErr()}))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment