observer/pkg/event/event.go

116 lines
2.8 KiB
Go

package event
import (
"git.ma-al.com/maal-libraries/observer/pkg/attr"
"git.ma-al.com/maal-libraries/observer/pkg/level"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)
// An event that maps well to a log message
type Event struct {
FullMessage string
ShortMessage string
Attributes []attribute.KeyValue
// Defaults to INFO when converted into attributes and unset
Level level.SeverityLevel
extraSkipInStack int
}
type IntoEvent interface {
IntoEvent() Event
}
func (e Event) IntoEvent() Event {
return e
}
func (e Event) IntoTraceAttributes() []attribute.KeyValue {
attrs := make([]attribute.KeyValue, 0)
attrs = append(attrs, attr.SourceCodeLocation(1+e.extraSkipInStack)...)
attrs = append(attrs, e.Attributes...)
if len(e.FullMessage) > 0 {
attrs = append(attrs, attr.LogMessageLong(e.FullMessage))
}
if len(e.ShortMessage) > 0 {
attrs = append(attrs, attr.LogMessageShort(e.ShortMessage))
}
if e.Level == 0 {
e.Level = level.INFO
}
attrs = append(attrs, attr.SeverityLevel(e.Level))
return attrs
}
func (e Event) AsOpts() trace.EventOption {
e.extraSkipInStack += 1
return trace.WithAttributes(e.IntoTraceAttributes()...)
}
func (e Event) SkipMoreInCallStack(skip int) Event {
e.extraSkipInStack += skip
return e
}
func NewInSpan[E IntoEvent](ev E, span trace.Span) {
event := ev.IntoEvent()
event.extraSkipInStack += 1
span.AddEvent(event.ShortMessage, trace.WithAttributes(event.IntoTraceAttributes()...))
}
type Error struct {
Err error
ExtendedMessage string
// Defaults to ALERT when converted into attributes and unset
Level level.SeverityLevel
Attributes []attribute.KeyValue
extraSkipInStack int
}
type IntoErrorEvent interface {
IntoErrorEvent() Error
}
func (e Error) Error() string {
return e.Err.Error()
}
func (e Error) IntoErrorEvent() Error {
return e
}
func (e Error) IntoTraceAttributes() []attribute.KeyValue {
attrs := make([]attribute.KeyValue, 0)
attrs = append(attrs, e.Attributes...)
if len(e.ExtendedMessage) > 0 {
attrs = append(attrs, attr.LogMessageLong(e.ExtendedMessage))
}
if e.Level == 0 {
e.Level = level.ALERT
}
attrs = append(attrs, attr.SeverityLevel(e.Level), attr.LogMessageShort(e.Err.Error()))
attrs = append(attrs, attr.SourceCodeLocation(1+e.extraSkipInStack)...)
return attrs
}
func (e Error) AsOpts() trace.EventOption {
e.extraSkipInStack += 1
return trace.WithAttributes(e.IntoTraceAttributes()...)
}
func (e Error) SkipMoreInCallStack(skip int) Error {
e.extraSkipInStack += skip
return e
}
func NewErrInSpan[E IntoErrorEvent](err E, span trace.Span) E {
er := err.IntoErrorEvent()
er.extraSkipInStack += 1
span.RecordError(er.Err, er.AsOpts())
if er.Level <= level.ERR {
span.SetStatus(codes.Error, er.Error())
}
return err
}