98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
package lightstep
|
||
|
||
import (
|
||
"log"
|
||
"sync"
|
||
"sync/atomic"
|
||
)
|
||
|
||
func init() {
|
||
SetGlobalEventHandler(NewEventLogOneError())
|
||
}
|
||
|
||
var eventHandler atomic.Value
|
||
|
||
// An EventHandler can be registered with SetGlobalEventHandler to
|
||
type EventHandler func(Event)
|
||
|
||
// emitEvent is a thread-safe function for emiting tracer events.
|
||
func emitEvent(event Event) {
|
||
handler := eventHandler.Load().(EventHandler)
|
||
handler(event)
|
||
}
|
||
|
||
// SetGlobalEventHandler sets a global handler to receive tracer events as they occur. Events
|
||
// may be emitted by the tracer, or by calls to static functions in this package.
|
||
// It is suggested that you set your EventHandler before starting your tracer,
|
||
// but it is safe to set a new handler at any time. Setting a new handler removes
|
||
// the previous one.
|
||
//
|
||
// The EventHandler is called synchronously – do not block in your handler as it
|
||
// may interfere with the tracer. If no EventHandler handler is set, a
|
||
// LogOnceOnError handler is set by default.
|
||
//
|
||
// NOTE: Event handling is for reporting purposes only. It is not intended as a
|
||
// mechanism for controling or restarting the tracer. Connection issues, retry
|
||
// logic, and other transient errors are handled internally by the tracer.
|
||
func SetGlobalEventHandler(handler EventHandler) {
|
||
eventHandler.Store(handler)
|
||
}
|
||
|
||
/*
|
||
SetGlobalEventHandler Handlers
|
||
*/
|
||
|
||
// NewEventLogger logs events using the standard go logger.
|
||
func NewEventLogger() EventHandler {
|
||
return logOnEvent
|
||
}
|
||
|
||
func logOnEvent(event Event) {
|
||
switch event := event.(type) {
|
||
case ErrorEvent:
|
||
log.Println("LS Tracer error: ", event)
|
||
default:
|
||
log.Println("LS Tracer event: ", event)
|
||
}
|
||
}
|
||
|
||
// NewEventLogOneError logs the first error event that occurs.
|
||
func NewEventLogOneError() EventHandler {
|
||
logger := logOneError{}
|
||
return logger.OnEvent
|
||
}
|
||
|
||
type logOneError struct {
|
||
sync.Once
|
||
}
|
||
|
||
func (l *logOneError) OnEvent(event Event) {
|
||
switch event := event.(type) {
|
||
case ErrorEvent:
|
||
l.Once.Do(func() {
|
||
log.Printf("LS Tracer error: (%s). NOTE: Set the SetGlobalEventHandler handler to log events.\n", event.Error())
|
||
})
|
||
}
|
||
}
|
||
|
||
// NewEventChannel returns an SetGlobalEventHandler callback handler, and a channel that
|
||
// produces the errors. When the channel buffer is full, subsequent errors will
|
||
// be dropped. A buffer size of less than one is incorrect, and will be adjusted
|
||
// to a buffer size of one.
|
||
func NewEventChannel(buffer int) (EventHandler, <-chan Event) {
|
||
if buffer < 1 {
|
||
buffer = 1
|
||
}
|
||
|
||
eventChan := make(chan Event, buffer)
|
||
|
||
handler := func(event Event) {
|
||
select {
|
||
case eventChan <- event:
|
||
default:
|
||
}
|
||
}
|
||
|
||
return handler, eventChan
|
||
}
|