Skip to content

Commit

Permalink
Merge pull request #270 from airbrake/feature/zerolog
Browse files Browse the repository at this point in the history
add in zerolog integration
  • Loading branch information
Penthious authored May 4, 2022
2 parents 34b2d09 + ffa6681 commit bf4655e
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ We support two major logging frameworks:
original glog's functionality and adds the ability to send errors/logs to
[Airbrake.io][airbrake.io].
* [apex/log][apexlog], to check how to integrate gobrake with apex/log, see [example](examples/apexlog).
* [zerolog/log][zerolog], to check how to integrate gobrake with zerolog/log, see [example](examples/zerolog).

## Supported Go versions

Expand Down Expand Up @@ -177,3 +178,4 @@ The project uses the MIT License. See [LICENSE.md](https://github.com/airbrake/g
[twitter]: https://twitter.com/airbrake
[glog]: https://github.com/airbrake/glog
[apexlog]: https://github.com/apex/log
[zerolog]: https://github.com/rs/zerolog
6 changes: 3 additions & 3 deletions examples/apexlog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import (
"github.com/apex/log"
)

var ProjectId int64 = 999999 // Insert your Project Id here
var ProjectID int64 = 999999 // Insert your Project ID here
var ProjectKey string = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // Insert your Project Key here

func main() {
airbrake := gobrake.NewNotifierWithOptions(&gobrake.NotifierOptions{
ProjectId: ProjectId,
ProjectId: ProjectID,
ProjectKey: ProjectKey,
Environment: "production",
})
Expand All @@ -38,7 +38,7 @@ func main() {
"user": "tobi",
})

fmt.Printf("Check your Airbrake dashboard at https://airbrake.io/projects/%v to see these log messages\n", ProjectId)
fmt.Printf("Check your Airbrake dashboard at https://YOUR_SUBDOMAIN.airbrake.io/projects/%v to see these error occurrences\n", ProjectID)

ctx.Info("upload")
ctx.Info("upload complete")
Expand Down
60 changes: 60 additions & 0 deletions examples/zerolog/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"errors"
"fmt"
"io"
"os"

"github.com/airbrake/gobrake/v5"
zerobrake "github.com/airbrake/gobrake/v5/zerolog" // Named import so that we don't conflict with rs/zerolog
"github.com/rs/zerolog"
)

var ProjectID int64 = 999999 // Insert your Project ID here
var ProjectKey string = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // Insert your Project Key here

func main() {
airbrake := gobrake.NewNotifierWithOptions(&gobrake.NotifierOptions{
ProjectId: ProjectID,
ProjectKey: ProjectKey,
Environment: "production",
})

defer airbrake.Close()

// Note: This writer only accepts errors logs, all others will be ignored.
// You can still send logs to stdout or another writer via io.MultiWriter
w, err := zerobrake.New(airbrake)
if err != nil {
// The only way this error would be returned is if airbrake was not set up and passed in as a nil value
// Either stop the execution of the code or ignore it, as w is set to an empty writer that wont write to
// airbrake if a pointer to airbrake notifier is not provided.
panic("airbrake was not setup correctly")
}

// Insert the newly created writer (w) into zerolog
log := zerolog.New(io.MultiWriter(os.Stdout, w))
zerolog.SetGlobalLevel(zerolog.DebugLevel)

// Creates a sub logger that has additional ctx
loggerWithData := log.With().
Dict("ctx",
zerolog.Dict().
Str("BUILD", "gitsha").
Str("VERSION", "").
Str("TIME", ""),
).
Str("file", "something.png").
Str("type", "image/png").
Str("user", "tobi").
Logger()

fmt.Printf("Check your Airbrake dashboard at https://YOUR_SUBDOMAIN.airbrake.io/projects/%v to see these error occurrences\n", ProjectID)

loggerWithData.Info().Msg("upload") // Sends only to stdout because log level is Info
loggerWithData.Warn().Msg("upload retry") // Sends only to stdout because log level is Warn.

// This error is sent to Airbrake and stdout because the log level is Error
loggerWithData.Error().Err(errors.New("unauthorized")).Msg("upload failed")
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/apex/log v1.9.0
github.com/beego/beego/v2 v2.0.2
github.com/buger/jsonparser v1.1.1
github.com/caio/go-tdigest v3.1.0+incompatible
github.com/gin-gonic/gin v1.7.7
github.com/gobuffalo/buffalo v0.18.5
Expand All @@ -21,6 +22,7 @@ require (
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.19.0
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.26.1
github.com/smartystreets/goconvey v1.7.2 // indirect
github.com/urfave/negroni v1.0.0
github.com/valyala/fasthttp v1.35.0
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=
Expand Down Expand Up @@ -705,8 +707,11 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down Expand Up @@ -882,6 +887,7 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down
78 changes: 78 additions & 0 deletions zerolog/zerolog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package zerolog

import (
"encoding/json"
"errors"
"fmt"
"io"

"github.com/airbrake/gobrake/v5"
"github.com/buger/jsonparser"
"github.com/rs/zerolog"
)

type WriteCloser struct {
Gobrake *gobrake.Notifier
}

// Validates the WriteCloser matches the io.WriteCloser interface
var _ io.WriteCloser = (*WriteCloser)(nil)

// New creates a new WriteCloser
func New(notifier *gobrake.Notifier) (io.WriteCloser, error) {
if notifier == nil {
return &WriteCloser{}, errors.New("airbrake notifier not provided")
}
return &WriteCloser{Gobrake: notifier}, nil
}

// Write parses the log data and sends off error notices to airbrake
func (w *WriteCloser) Write(data []byte) (int, error) {
lvl, err := jsonparser.GetUnsafeString(data, zerolog.LevelFieldName)
if err != nil {
return 0, fmt.Errorf("error getting zerolog level: %w", err)
}

if lvl != zerolog.ErrorLevel.String() {
return len(data), nil
}

var logEntryData interface{}
err = json.Unmarshal(data, &logEntryData)
if err != nil {
return 0, fmt.Errorf("error unmarshalling logs: %w", err)
}
type zeroError struct {
message string
error string
}
var ze zeroError
_ = jsonparser.ObjectEach(data, func(key, value []byte, vt jsonparser.ValueType, offset int) error {
switch string(key) {
case zerolog.MessageFieldName:
ze.message = string(value)
case zerolog.ErrorFieldName:
ze.error = string(value)
}

return nil
})

// If gobrake was not setup but the writer was still used, ignore gobrake.
if w.Gobrake == nil {
return len(data), nil
}

notice := gobrake.NewNotice(ze.message, nil, 6)
notice.Context["severity"] = lvl
notice.Params["logEntryData"] = logEntryData
notice.Error = errors.New(ze.error)
w.Gobrake.SendNoticeAsync(notice)
return len(data), nil
}

// Close flushes any remaining notices left in gobrake queue
func (w *WriteCloser) Close() error {
w.Gobrake.Flush()
return nil
}

0 comments on commit bf4655e

Please sign in to comment.