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
|
|||
|
}
|