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 15package otel // import "go.opentelemetry.io/otel" 16 17import ( 18 "log" 19 "os" 20 "sync" 21 "sync/atomic" 22) 23 24var ( 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 = &loggingErrorHandler{ 30 l: log.New(os.Stderr, "", log.LstdFlags), 31 } 32 33 // delegateErrorHandlerOnce ensures that a user provided ErrorHandler is 34 // only ever registered once. 35 delegateErrorHandlerOnce sync.Once 36 37 // Comiple time check that loggingErrorHandler implements ErrorHandler. 38 _ ErrorHandler = (*loggingErrorHandler)(nil) 39) 40 41// loggingErrorHandler logs all errors to STDERR. 42type loggingErrorHandler struct { 43 delegate atomic.Value 44 45 l *log.Logger 46} 47 48// setDelegate sets the ErrorHandler delegate if one is not already set. 49func (h *loggingErrorHandler) setDelegate(d ErrorHandler) { 50 if h.delegate.Load() != nil { 51 // Delegate already registered 52 return 53 } 54 h.delegate.Store(d) 55} 56 57// Handle implements ErrorHandler. 58func (h *loggingErrorHandler) Handle(err error) { 59 if d := h.delegate.Load(); d != nil { 60 d.(ErrorHandler).Handle(err) 61 return 62 } 63 h.l.Print(err) 64} 65 66// GetErrorHandler returns the global ErrorHandler instance. If no ErrorHandler 67// instance has been set (`SetErrorHandler`), the default ErrorHandler which 68// logs errors to STDERR is returned. 69func GetErrorHandler() ErrorHandler { 70 return globalErrorHandler 71} 72 73// SetErrorHandler sets the global ErrorHandler to be h. 74func SetErrorHandler(h ErrorHandler) { 75 delegateErrorHandlerOnce.Do(func() { 76 current := GetErrorHandler() 77 if current == h { 78 return 79 } 80 if internalHandler, ok := current.(*loggingErrorHandler); ok { 81 internalHandler.setDelegate(h) 82 } 83 }) 84} 85 86// Handle is a convience function for ErrorHandler().Handle(err) 87func Handle(err error) { 88 GetErrorHandler().Handle(err) 89} 90