observer/pkg/exporters/console_exporter/multiline_formatter.go

118 lines
3.0 KiB
Go
Raw Permalink Normal View History

package console_exporter
import (
"fmt"
"slices"
"git.ma-al.com/maal-libraries/observer/pkg/console_fmt"
"git.ma-al.com/maal-libraries/observer/pkg/level"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/trace"
)
func NewPrettyMultilineFormatter() TraceFormatter {
return &PrettyMultilineFormatter{}
}
// A formatter that will print only events using a multiline format with colors.
// It uses attributes from the [attr] and [semconv] packages.
type PrettyMultilineFormatter struct{}
func AttrValueToString(val attribute.Value) string {
switch val.Type() {
case attribute.STRING:
return val.AsString()
case attribute.BOOL:
if val.AsBool() {
return "true"
} else {
return "false"
}
case attribute.BOOLSLICE, attribute.INT64SLICE, attribute.FLOAT64SLICE, attribute.STRINGSLICE:
json, _ := val.MarshalJSON()
return string(json)
case attribute.FLOAT64:
fmt.Sprintf("%f", val.AsFloat64())
case attribute.INT64:
return fmt.Sprintf("%d", val.AsInt64())
default:
json, _ := val.MarshalJSON()
return string(json)
}
return ""
}
func (f *PrettyMultilineFormatter) FormatSpanStart(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
attrs := ""
slices.SortFunc(selectedAttrs, func(a, b attribute.KeyValue) int {
if a.Key > b.Key {
return 1
} else {
return -1
}
})
for _, kv := range selectedAttrs {
if len(kv.Key) > 0 {
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), AttrValueToString(kv.Value))
}
}
formattedSpanString := fmt.Sprintf(
"%s\n%s",
console_fmt.Bold(console_fmt.SeverityLevelToColor(lvl)+fmt.Sprintf("[%s][SpanStart] ", lvl.String())+span.Name()),
attrs,
)
return formattedSpanString, nil
}
func (f *PrettyMultilineFormatter) FormatSpanEnd(span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
attrs := ""
slices.SortFunc(selectedAttrs, func(a, b attribute.KeyValue) int {
if a.Key > b.Key {
return 1
} else {
return -1
}
})
for _, kv := range selectedAttrs {
if len(kv.Key) > 0 {
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), AttrValueToString(kv.Value))
}
}
formattedSpanString := fmt.Sprintf(
"%s\n%s",
console_fmt.Bold(console_fmt.SeverityLevelToColor(lvl)+fmt.Sprintf("[%s][SpanEnd] ", lvl.String())+span.Name()),
attrs,
)
return formattedSpanString, nil
}
func (f *PrettyMultilineFormatter) FormatEvent(event trace.Event, span trace.ReadOnlySpan, selectedAttrs []attribute.KeyValue, lvl level.SeverityLevel) (string, error) {
attrs := ""
slices.SortFunc(selectedAttrs, func(a, b attribute.KeyValue) int {
if a.Key > b.Key {
return 1
} else {
return -1
}
})
for _, kv := range selectedAttrs {
if len(kv.Key) > 0 {
attrs += fmt.Sprintf("\t%s = %s\n", string(kv.Key), AttrValueToString(kv.Value))
}
}
formattedSpanString := fmt.Sprintf(
"%s\n%s",
console_fmt.Bold(console_fmt.SeverityLevelToColor(lvl)+fmt.Sprintf("[%s][Event] ", lvl.String())+event.Name),
attrs,
)
return formattedSpanString, nil
}