func main() {
	logger := logrus.New()
	logger.SetOutput(os.Stdout)
	logger.SetFormatter(&logrus.JSONFormatter{})
	reqs := []request{
		{
			ID: "",  
		},
		{
			ID: "res1",  
		},
		{
			ID: "res2",  
		},
		{
			ID: "res3",  
		},
	}
	for _, req := range reqs {
		res, err := processResource(req)
		if req.ID != "res1" {
			logRequest(logger, logReq{
				Method: "ProcessResource",
				Req:    req,
				Res:    res,
				Err:    err,
			})
		} else {
			fmt.Printf("%+v\n", err)
		}
	}
}
This example demonstrates how to integrate eris with a JSON logger (e.g. logrus). It's broken
into several methods to show the formatted output for wrapped errors, and it includes three
failing cases to demonstrate how your error logs should look in different scenarios.
package main
import (
	"fmt"
	"os"
	"path/filepath"
	"github.com/pkg/errors"
	"github.com/rotisserie/eris"
	"github.com/sirupsen/logrus"
)
var (
	errInternalServer = eris.New("error internal server")
	errNotFound = errors.New("error not found")
)
type request struct {
	ID string
}
func (req *request) validate() error {
	if req.ID == "" {
		err := eris.New("error bad request")
		return eris.Wrap(err, "received a request with no ID")
	}
	return nil
}
type resource struct {
	ID      string
	AbsPath string
}
func getResource(req request) (*resource, error) {
	if req.ID == "res2" {
		return &resource{
			ID:      req.ID,
			AbsPath: "./some/malformed/absolute/path/data.json",  
		}, nil
	} else if req.ID == "res3" {
		return &resource{
			ID:      req.ID,
			AbsPath: "/some/correct/path/data.json",
		}, nil
	}
	return nil, errors.Wrapf(errNotFound, "failed to get resource '%v'", req.ID)
}
func getRelPath(base string, path string) (string, error) {
	relPath, err := filepath.Rel(base, path)
	if err != nil {
		return "", eris.Wrap(errInternalServer, err.Error())
	}
	return relPath, nil
}
type response struct {
	RelPath string
}
func processResource(req request) (*response, error) {
	if err := req.validate(); err != nil {
		return nil, err
	}
	resource, err := getResource(req)
	if err != nil {
		return nil, err
	}
	relPath, err := getRelPath("/Users/roti/", resource.AbsPath)
	if err != nil {
		return nil, eris.Wrapf(err, "failed to get relative path for resource '%v'", resource.ID)
	}
	return &response{
		RelPath: relPath,
	}, nil
}
type logReq struct {
	Method string
	Req    request
	Res    *response
	Err    error
}
func logRequest(logger *logrus.Logger, logReq logReq) {
	fields := logrus.Fields{
		"method": logReq.Method,
	}
	if logReq.Err != nil {
		fields["error"] = eris.ToJSON(logReq.Err, true)
		logger.WithFields(fields).Error("method completed with error")
	} else {
		fields["response"] = *logReq.Res
		logger.WithFields(fields).Info("method completed successfully")
	}
}