errorhandler.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. // Package errorhandler provides the global error handler for OpenTelemetry.
  4. //
  5. // This package has no OTel dependencies, allowing it to be imported by any
  6. // package in the module without creating import cycles.
  7. package errorhandler // import "go.opentelemetry.io/otel/internal/errorhandler"
  8. import (
  9. "errors"
  10. "log"
  11. "sync"
  12. "sync/atomic"
  13. )
  14. // ErrorHandler handles irremediable events.
  15. type ErrorHandler interface {
  16. // Handle handles any error deemed irremediable by an OpenTelemetry
  17. // component.
  18. Handle(error)
  19. }
  20. type ErrDelegator struct {
  21. delegate atomic.Pointer[ErrorHandler]
  22. }
  23. // Compile-time check that delegator implements ErrorHandler.
  24. var _ ErrorHandler = (*ErrDelegator)(nil)
  25. func (d *ErrDelegator) Handle(err error) {
  26. if eh := d.delegate.Load(); eh != nil {
  27. (*eh).Handle(err)
  28. return
  29. }
  30. log.Print(err)
  31. }
  32. // setDelegate sets the ErrorHandler delegate.
  33. func (d *ErrDelegator) setDelegate(eh ErrorHandler) {
  34. d.delegate.Store(&eh)
  35. }
  36. type errorHandlerHolder struct {
  37. eh ErrorHandler
  38. }
  39. var (
  40. globalErrorHandler = defaultErrorHandler()
  41. delegateErrorHandlerOnce sync.Once
  42. )
  43. // GetErrorHandler returns the global ErrorHandler instance.
  44. //
  45. // The default ErrorHandler instance returned will log all errors to STDERR
  46. // until an override ErrorHandler is set with SetErrorHandler. All
  47. // ErrorHandler returned prior to this will automatically forward errors to
  48. // the set instance instead of logging.
  49. //
  50. // Subsequent calls to SetErrorHandler after the first will not forward errors
  51. // to the new ErrorHandler for prior returned instances.
  52. func GetErrorHandler() ErrorHandler {
  53. return globalErrorHandler.Load().(errorHandlerHolder).eh
  54. }
  55. // SetErrorHandler sets the global ErrorHandler to h.
  56. //
  57. // The first time this is called all ErrorHandler previously returned from
  58. // GetErrorHandler will send errors to h instead of the default logging
  59. // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
  60. // delegate errors to h.
  61. func SetErrorHandler(h ErrorHandler) {
  62. current := GetErrorHandler()
  63. if _, cOk := current.(*ErrDelegator); cOk {
  64. if _, ehOk := h.(*ErrDelegator); ehOk && current == h {
  65. // Do not assign to the delegate of the default ErrDelegator to be
  66. // itself.
  67. log.Print(errors.New("no ErrorHandler delegate configured"), " ErrorHandler remains its current value.")
  68. return
  69. }
  70. }
  71. delegateErrorHandlerOnce.Do(func() {
  72. if def, ok := current.(*ErrDelegator); ok {
  73. def.setDelegate(h)
  74. }
  75. })
  76. globalErrorHandler.Store(errorHandlerHolder{eh: h})
  77. }
  78. func defaultErrorHandler() *atomic.Value {
  79. v := &atomic.Value{}
  80. v.Store(errorHandlerHolder{eh: &ErrDelegator{}})
  81. return v
  82. }