2024-05-17 16:21:09 +00:00
|
|
|
package event
|
|
|
|
|
|
|
|
import (
|
2024-05-20 06:20:13 +00:00
|
|
|
"git.ma-al.com/maal-libraries/observer/pkg/attr"
|
|
|
|
"git.ma-al.com/maal-libraries/observer/pkg/level"
|
2024-05-17 16:21:09 +00:00
|
|
|
"go.opentelemetry.io/otel/attribute"
|
2024-05-20 11:55:53 +00:00
|
|
|
"go.opentelemetry.io/otel/codes"
|
2024-05-17 16:21:09 +00:00
|
|
|
"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()...)
|
|
|
|
}
|
|
|
|
|
2024-05-20 11:39:55 +00:00
|
|
|
func (e Event) SkipMoreInCallStack(skip int) Event {
|
|
|
|
e.extraSkipInStack += skip
|
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
2024-05-17 16:21:09 +00:00
|
|
|
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()...)
|
|
|
|
}
|
|
|
|
|
2024-05-20 11:39:55 +00:00
|
|
|
func (e Error) SkipMoreInCallStack(skip int) Error {
|
|
|
|
e.extraSkipInStack += skip
|
|
|
|
return e
|
|
|
|
}
|
|
|
|
|
2024-05-17 16:21:09 +00:00
|
|
|
func NewErrInSpan[E IntoErrorEvent](err E, span trace.Span) E {
|
|
|
|
er := err.IntoErrorEvent()
|
|
|
|
er.extraSkipInStack += 1
|
|
|
|
span.RecordError(er.Err, er.AsOpts())
|
2024-05-20 11:55:53 +00:00
|
|
|
if er.Level <= level.ERR {
|
|
|
|
span.SetStatus(codes.Error, er.Error())
|
|
|
|
}
|
2024-05-17 16:21:09 +00:00
|
|
|
return err
|
|
|
|
}
|