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 ) 22 23 var ( 24 // GlobalErrorHandler provides an ErrorHandler that can be used 25 // throughout an OpenTelemetry instrumented project. When a user 26 // specified ErrorHandler is registered (`SetErrorHandler`) all calls to 27 // `Handle` and will be delegated to the registered ErrorHandler. 28 GlobalErrorHandler = defaultErrorHandler() 29 30 // Compile-time check that delegator implements ErrorHandler. 31 _ ErrorHandler = (*ErrDelegator)(nil) 32 // Compile-time check that errLogger implements ErrorHandler. 33 _ ErrorHandler = (*ErrLogger)(nil) 34 ) 35 36 // ErrorHandler handles irremediable events. 37 type ErrorHandler interface { 38 // Handle handles any error deemed irremediable by an OpenTelemetry 39 // component. 40 Handle(error) 41 } 42 43 type ErrDelegator struct { 44 delegate atomic.Pointer[ErrorHandler] 45 } 46 47 func (d *ErrDelegator) Handle(err error) { 48 d.getDelegate().Handle(err) 49 } 50 51 func (d *ErrDelegator) getDelegate() ErrorHandler { 52 return *d.delegate.Load() 53 } 54 55 // setDelegate sets the ErrorHandler delegate. 56 func (d *ErrDelegator) setDelegate(eh ErrorHandler) { 57 d.delegate.Store(&eh) 58 } 59 60 func defaultErrorHandler() *ErrDelegator { 61 d := &ErrDelegator{} 62 d.setDelegate(&ErrLogger{l: log.New(os.Stderr, "", log.LstdFlags)}) 63 return d 64 } 65 66 // ErrLogger logs errors if no delegate is set, otherwise they are delegated. 67 type ErrLogger struct { 68 l *log.Logger 69 } 70 71 // Handle logs err if no delegate is set, otherwise it is delegated. 72 func (h *ErrLogger) Handle(err error) { 73 h.l.Print(err) 74 } 75 76 // GetErrorHandler returns the global ErrorHandler instance. 77 // 78 // The default ErrorHandler instance returned will log all errors to STDERR 79 // until an override ErrorHandler is set with SetErrorHandler. All 80 // ErrorHandler returned prior to this will automatically forward errors to 81 // the set instance instead of logging. 82 // 83 // Subsequent calls to SetErrorHandler after the first will not forward errors 84 // to the new ErrorHandler for prior returned instances. 85 func GetErrorHandler() ErrorHandler { 86 return GlobalErrorHandler 87 } 88 89 // SetErrorHandler sets the global ErrorHandler to h. 90 // 91 // The first time this is called all ErrorHandler previously returned from 92 // GetErrorHandler will send errors to h instead of the default logging 93 // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not 94 // delegate errors to h. 95 func SetErrorHandler(h ErrorHandler) { 96 GlobalErrorHandler.setDelegate(h) 97 } 98 99 // Handle is a convenience function for ErrorHandler().Handle(err). 100 func Handle(err error) { 101 GetErrorHandler().Handle(err) 102 } 103