From d8ca164052f9c85de365727bbe527be44cf15cf8 Mon Sep 17 00:00:00 2001 From: itzaname Date: Sat, 16 Jul 2022 15:49:44 -0400 Subject: [PATCH] first commit --- errors/errors.go | 40 +++++++++++++++++++++++++++++++ go.mod | 9 +++++++ go.sum | 18 ++++++++++++++ logger/logger.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 errors/errors.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 logger/logger.go diff --git a/errors/errors.go b/errors/errors.go new file mode 100644 index 0000000..97c9320 --- /dev/null +++ b/errors/errors.go @@ -0,0 +1,40 @@ +package errors + +import ( + "encoding/json" + "fmt" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +type internalError struct { + data interface{} +} + +func (e *internalError) Error() string { + data, err := json.Marshal(&e.data) + if err != nil { + return err.Error() + } + + return string(data) +} + +func newError(msg, cor string, code int) error { + return &internalError{data: map[string]interface{}{ + "correlation": cor, + "message": msg, + "code": code, + }} +} + +func WithCorrelationLog(message string, err error, code int) error { + id := uuid.New().String() + log.WithField("correlation", id).WithField("error", err.Error()).Error(message) + return newError(fmt.Sprintf("%s: %s", id, message), id, code) +} + +func WithCorrelation(message string, code int) (string, error) { + id := uuid.New().String() + return id, newError(fmt.Sprintf("%s: %s", id, message), id, code) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a304555 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module git.itzana.me/strafesnet/utils + +go 1.16 + +require ( + github.com/google/uuid v1.3.0 + github.com/sirupsen/logrus v1.8.1 + gorm.io/gorm v1.21.11 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..754ccf2 --- /dev/null +++ b/go.sum @@ -0,0 +1,18 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gorm.io/gorm v1.21.11 h1:CxkXW6Cc+VIBlL8yJEHq+Co4RYXdSLiMKNvgoZPjLK4= +gorm.io/gorm v1.21.11/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..8ccd841 --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,61 @@ +package logger + +import ( + "context" + "errors" + "time" + + log "github.com/sirupsen/logrus" + "gorm.io/gorm" + gormlogger "gorm.io/gorm/logger" + "gorm.io/gorm/utils" +) + +type logger struct { + SlowThreshold time.Duration + SourceField string + SkipErrRecordNotFound bool +} + +func New() *logger { + return &logger{ + SkipErrRecordNotFound: true, + } +} + +func (l *logger) LogMode(gormlogger.LogLevel) gormlogger.Interface { + return l +} + +func (l *logger) Info(ctx context.Context, s string, args ...interface{}) { + log.WithContext(ctx).Infof(s, args) +} + +func (l *logger) Warn(ctx context.Context, s string, args ...interface{}) { + log.WithContext(ctx).Warnf(s, args) +} + +func (l *logger) Error(ctx context.Context, s string, args ...interface{}) { + log.WithContext(ctx).Errorf(s, args) +} + +func (l *logger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { + elapsed := time.Since(begin) + sql, _ := fc() + fields := log.Fields{} + if l.SourceField != "" { + fields[l.SourceField] = utils.FileWithLineNum() + } + if err != nil && !(errors.Is(err, gorm.ErrRecordNotFound) && l.SkipErrRecordNotFound) { + fields[log.ErrorKey] = err + log.WithContext(ctx).WithFields(fields).Errorf("%s [%s]", sql, elapsed) + return + } + + if l.SlowThreshold != 0 && elapsed > l.SlowThreshold { + log.WithContext(ctx).WithFields(fields).Warnf("%s [%s]", sql, elapsed) + return + } + + log.WithContext(ctx).WithFields(fields).Debugf("%s [%s]", sql, elapsed) +}