github.com/facebookincubator/go-belt@v0.0.0-20230703220935-39cd348f1a38/tool/experimental/errmon/README.md (about) 1 # Disclaimer 2 3 This API is experimental and has no stability guarantees. 4 5 # Example 6 ```go 7 package errmon_test 8 9 import ( 10 "context" 11 12 sentryupstream "github.com/getsentry/sentry-go" 13 14 "github.com/facebookincubator/go-belt" 15 "github.com/facebookincubator/go-belt/beltctx" 16 "github.com/facebookincubator/go-belt/tool/experimental/errmon" 17 "github.com/facebookincubator/go-belt/tool/experimental/errmon/implementation/logger" 18 "github.com/facebookincubator/go-belt/tool/experimental/errmon/implementation/sentry" 19 ) 20 21 func Example() { 22 // easy to use: 23 m := logger.Default() 24 someFunction(1, m) 25 26 // implementation agnostic: 27 sentryClient, err := sentryupstream.NewClient(sentryupstream.ClientOptions{}) 28 if err != nil { 29 panic(err) 30 } 31 m = sentry.New(sentryClient) 32 someFunction(2, m) 33 34 // one may still reuse all the features of the emitter ErrorMonitor: 35 _ = m.Emitter().(*sentry.Emitter).SentryClient.Options() 36 37 // use go-belt to manage the ErrorMonitor 38 obs := belt.New() 39 obs = errmon.BeltWithErrorMonitor(obs, m) 40 someBeltyFunction(3, obs) 41 42 // use context to manage the ErrorMonitor 43 ctx := context.Background() 44 ctx = errmon.CtxWithErrorMonitor(ctx, m) 45 someContextyFunction(ctx, 4) 46 47 // use a singletony ErrorMonitor: 48 errmon.Default = func() errmon.ErrorMonitor { 49 return m 50 } 51 yetOneMoreFunction(5) 52 } 53 54 func someFunction(arg int, m errmon.ErrorMonitor) { 55 // experience close to logrus/zap: 56 m = errmon.WithField(m, "arg", arg) 57 anotherFunction(m) 58 } 59 60 func anotherFunction(m errmon.ErrorMonitor) { 61 defer func() { m.ObserveRecover(nil, recover()) }() 62 // ..do something here.. 63 } 64 65 func someBeltyFunction(arg int, obs *belt.Belt) { 66 obs = obs.WithField("arg", arg) 67 anotherBeltyFunction(obs) 68 } 69 70 func anotherBeltyFunction(obs *belt.Belt) { 71 defer func() { errmon.ObserveRecoverBelt(obs, recover()) }() 72 // ..do something here.. 73 } 74 75 func someContextyFunction(ctx context.Context, arg int) { 76 ctx = beltctx.WithField(ctx, "arg", arg) 77 anotherContextyFunction(ctx) 78 } 79 80 func anotherContextyFunction(ctx context.Context) { 81 defer func() { errmon.ObserveRecoverCtx(ctx, recover()) }() 82 // ..do something here.. 83 } 84 85 func yetOneMoreFunction(arg int) { 86 m := errmon.Default() 87 m = errmon.WithField(m, "arg", arg) 88 defer func() { m.ObserveRecover(nil, recover()) }() 89 // ..do something here.. 90 } 91 ``` 92 93 # Interface 94 ```go 95 // ErrorMonitor is an observability Tool (belt.Tool) which allows 96 // to report about any exceptions which happen for debugging. It 97 // collects any useful information it can. 98 // 99 // An ErrorMonitor implementation is not supposed to be fast, but 100 // it supposed to provide verbose reports (sufficient enough to 101 // debug found problems). 102 type ErrorMonitor interface { 103 belt.Tool 104 105 // Emitter returns the Emitter. 106 // 107 // A read-only value, do not change it. 108 Emitter() Emitter 109 110 // ObserveError issues an error event if `err` is not an untyped nil. Additional 111 // data (left by various observability tooling) is extracted from `belt`. 112 // 113 // Returns an Event only if one was issued (and for example was not sampled out by a Sampler Hook). 114 ObserveError(*belt.Belt, error) *Event 115 116 // ObserveRecover issues a panic event if `recoverResult` is not an untyped nil. 117 // Additional data (left by various observability tooling) is extracted from `belt`. 118 // 119 // Is supposed to be used in constructions like: 120 // 121 // defer func() { errmon.ObserveRecover(ctx, recover()) }() 122 // 123 // See also: https://go.dev/ref/spec#Handling_panics 124 // 125 // Returns an Event only if one was issued (and for example was not sampled out by a Sampler Hook). 126 ObserveRecover(_ *belt.Belt, recoverResult any) *Event 127 128 // WithPreHooks returns a ErrorMonitor derivative which also includes/appends pre-hooks from the arguments. 129 // 130 // Special case: to reset hooks use `WithHooks()` (without any arguments). 131 WithPreHooks(...PreHook) ErrorMonitor 132 133 // WithHooks returns a ErrorMonitor derivative which also includes/appends hooks from the arguments. 134 // 135 // Special case: to reset hooks use `WithHooks()` (without any arguments). 136 WithHooks(...Hook) ErrorMonitor 137 } 138 ``` 139