handler.go (3256B)
1 // Copyright The OpenTelemetry Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package global // import "go.opentelemetry.io/otel/internal/global" 16 17 import ( 18 "log" 19 "os" 20 "sync/atomic" 21 "unsafe" 22 ) 23 24 var ( 25 // GlobalErrorHandler provides an ErrorHandler that can be used 26 // throughout an OpenTelemetry instrumented project. When a user 27 // specified ErrorHandler is registered (`SetErrorHandler`) all calls to 28 // `Handle` and will be delegated to the registered ErrorHandler. 29 GlobalErrorHandler = defaultErrorHandler() 30 31 // Compile-time check that delegator implements ErrorHandler. 32 _ ErrorHandler = (*ErrDelegator)(nil) 33 // Compile-time check that errLogger implements ErrorHandler. 34 _ ErrorHandler = (*ErrLogger)(nil) 35 ) 36 37 // ErrorHandler handles irremediable events. 38 type ErrorHandler interface { 39 // Handle handles any error deemed irremediable by an OpenTelemetry 40 // component. 41 Handle(error) 42 } 43 44 type ErrDelegator struct { 45 delegate unsafe.Pointer 46 } 47 48 func (d *ErrDelegator) Handle(err error) { 49 d.getDelegate().Handle(err) 50 } 51 52 func (d *ErrDelegator) getDelegate() ErrorHandler { 53 return *(*ErrorHandler)(atomic.LoadPointer(&d.delegate)) 54 } 55 56 // setDelegate sets the ErrorHandler delegate. 57 func (d *ErrDelegator) setDelegate(eh ErrorHandler) { 58 atomic.StorePointer(&d.delegate, unsafe.Pointer(&eh)) 59 } 60 61 func defaultErrorHandler() *ErrDelegator { 62 d := &ErrDelegator{} 63 d.setDelegate(&ErrLogger{l: log.New(os.Stderr, "", log.LstdFlags)}) 64 return d 65 } 66 67 // ErrLogger logs errors if no delegate is set, otherwise they are delegated. 68 type ErrLogger struct { 69 l *log.Logger 70 } 71 72 // Handle logs err if no delegate is set, otherwise it is delegated. 73 func (h *ErrLogger) Handle(err error) { 74 h.l.Print(err) 75 } 76 77 // GetErrorHandler returns the global ErrorHandler instance. 78 // 79 // The default ErrorHandler instance returned will log all errors to STDERR 80 // until an override ErrorHandler is set with SetErrorHandler. All 81 // ErrorHandler returned prior to this will automatically forward errors to 82 // the set instance instead of logging. 83 // 84 // Subsequent calls to SetErrorHandler after the first will not forward errors 85 // to the new ErrorHandler for prior returned instances. 86 func GetErrorHandler() ErrorHandler { 87 return GlobalErrorHandler 88 } 89 90 // SetErrorHandler sets the global ErrorHandler to h. 91 // 92 // The first time this is called all ErrorHandler previously returned from 93 // GetErrorHandler will send errors to h instead of the default logging 94 // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not 95 // delegate errors to h. 96 func SetErrorHandler(h ErrorHandler) { 97 GlobalErrorHandler.setDelegate(h) 98 } 99 100 // Handle is a convenience function for ErrorHandler().Handle(err). 101 func Handle(err error) { 102 GetErrorHandler().Handle(err) 103 }