package console_exporter import ( "fmt" "slices" "git.ma-al.com/gora_filip/pkg/attr" "git.ma-al.com/gora_filip/pkg/code_location" "git.ma-al.com/gora_filip/pkg/console_fmt" "git.ma-al.com/gora_filip/pkg/level" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/sdk/trace/tracetest" "go.opentelemetry.io/otel/semconv/v1.25.0" ) // A formatter that will print only events using a multiline format with colors. // It uses attributes from the [attr] and [semconv] packages. type EventsOnlyFormatter struct{} func (f *EventsOnlyFormatter) FormatSpans(spans []trace.ReadOnlySpan, removeFields []attribute.Key, verbosityLevel level.SeverityLevel, addTraceId bool, onlyOnError bool) (string, error) { stubs := tracetest.SpanStubsFromReadOnlySpans(spans) var formattedSpanString string for i := range stubs { stub := &stubs[i] for j := range stub.Events { var attributes map[attribute.Key]string = make(map[attribute.Key]string, 0) var msg string var lvl level.SeverityLevel var isErr bool var location code_location.CodeLocation for _, attrKV := range stub.Attributes { if _, exists := attributes[attrKV.Key]; !exists { attributes[attrKV.Key] = attrKV.Value.AsString() } } for _, attrKV := range stub.Events[j].Attributes { switch attrKV.Key { case attr.LogMessageLongKey: msg = attrKV.Value.AsString() case attr.LogMessageShortKey: if len(msg) == 0 { msg = attrKV.Value.AsString() } case attr.SeverityLevelKey: lvl = level.FromString(attrKV.Value.AsString()) case semconv.CodeFilepathKey: location.FilePath = attrKV.Value.AsString() case semconv.CodeLineNumberKey: location.LineNumber = int(attrKV.Value.AsInt64()) case semconv.CodeColumnKey: location.ColumnNumber = int(attrKV.Value.AsInt64()) case semconv.ExceptionMessageKey: attributes[attrKV.Key] = attrKV.Value.AsString() isErr = true default: if !slices.Contains(removeFields, attrKV.Key) && len(attrKV.Key) > 0 { attributes[attrKV.Key] = attrKV.Value.AsString() } } } if len(msg) == 0 { msg = stub.Name } if addTraceId { attributes[attribute.Key("trace_id")] = stub.SpanContext.TraceID().String() } if len(location.FilePath) > 0 { attributes["code.location"] = fmt.Sprintf("%s:%d:%d", location.FilePath, location.LineNumber, location.ColumnNumber) } if !(!isErr && onlyOnError) && lvl <= verbosityLevel { attrs := "" for k, v := range attributes { attrs += fmt.Sprintf("\t%s%s%s = %s\n", console_fmt.ColorBold, k, console_fmt.ColorReset, v) } formattedSpanString += fmt.Sprintf( "%s %s\n%s", fmt.Sprintf("%s[%s]", console_fmt.SeverityLevelToColor(lvl), lvl.String()), fmt.Sprintf("%s%s", msg, console_fmt.ColorReset), attrs, ) } } } return formattedSpanString, nil }