github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/conf/logger/span_exporters.go (about) 1 package logger 2 3 import ( 4 "context" 5 "log/slog" 6 "strings" 7 8 "go.opentelemetry.io/otel/codes" 9 "go.opentelemetry.io/otel/sdk/trace" 10 11 "github.com/machinefi/w3bstream/pkg/depends/kit/metax" 12 ) 13 14 func ErrIgnoreExporter() trace.SpanExporter { 15 return &errIgnoreExporter{} 16 } 17 18 type errIgnoreExporter struct { 19 trace.SpanExporter 20 } 21 22 func (e *errIgnoreExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { 23 _ = e.SpanExporter.ExportSpans(ctx, spans) 24 return nil 25 } 26 27 func (e *errIgnoreExporter) Shutdown(_ context.Context) error { return nil } 28 29 func StdoutSpanExporter() trace.SpanExporter { 30 return &stdoutSpanExporter{} 31 } 32 33 type stdoutSpanExporter struct{} 34 35 var _ trace.SpanExporter = (*stdoutSpanExporter)(nil) 36 37 func (e *stdoutSpanExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { 38 for i := range spans { 39 data := spans[i] 40 41 for _, event := range data.Events() { 42 if event.Name == "" || event.Name[0] != '@' { 43 continue 44 } 45 lv := slog.Level(0) 46 if err := lv.UnmarshalText([]byte(strings.TrimPrefix(event.Name, "@"))); err != nil { 47 continue 48 } 49 attr := make([]slog.Attr, 0) 50 51 spanID := data.Name() 52 if data.SpanContext().HasSpanID() { 53 spanID = data.SpanContext().SpanID().String() 54 } 55 attr = append(attr, slog.String("span_id", spanID)) 56 attr = append(attr, slog.String("trace_id", data.SpanContext().TraceID().String())) 57 if p := data.Parent(); p.IsValid() && p.HasSpanID() { 58 attr = append(attr, slog.String("parent", p.SpanID().String())) 59 } 60 61 for _, kv := range event.Attributes { 62 switch k := string(kv.Key); k { 63 case "@msg": 64 attr = append(attr, slog.String("@msg", kv.Value.AsString())) 65 case "@stack": 66 continue // too long 67 case "": 68 continue 69 default: 70 attr = append(attr, slog.Any(k, kv.Value.AsInterface())) 71 } 72 } 73 for _, kv := range data.Attributes() { 74 k := string(kv.Key) 75 if k == "meta" { 76 meta := metax.ParseMeta(kv.Value.AsString()) 77 for key := range meta { 78 if key == "_id" { 79 continue 80 } 81 attr = append(attr, slog.Any(k, meta[k])) 82 } 83 continue 84 } 85 if kv.Valid() { 86 attr = append(attr, slog.Any(k, kv.Value.AsInterface())) 87 } 88 } 89 90 gStdLogger.LogAttrs(ctx, lv, "", attr...) 91 } 92 } 93 return nil 94 } 95 96 func (*stdoutSpanExporter) Shutdown(ctx context.Context) error { return nil } 97 98 func SpanMapExporter() trace.SpanExporter { 99 return &spanMapExporter{} 100 } 101 102 type SpanMapper func(trace.ReadOnlySpan) trace.ReadOnlySpan 103 104 type spanMapExporter struct { 105 mappers []SpanMapper 106 trace.SpanExporter 107 } 108 109 var _ trace.SpanExporter = (*spanMapExporter)(nil) 110 111 func (e *spanMapExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error { 112 snapshots := make([]trace.ReadOnlySpan, 0) 113 for i := range spans { 114 data := spans[i] 115 for _, m := range e.mappers { 116 data = m(data) 117 } 118 if data == nil { 119 continue 120 } 121 snapshots = append(snapshots, data) 122 } 123 if len(snapshots) == 0 { 124 return nil 125 } 126 return e.SpanExporter.ExportSpans(ctx, snapshots) 127 } 128 129 func OutputFilter() SpanMapper { 130 return func(span trace.ReadOnlySpan) trace.ReadOnlySpan { 131 if gOutput == OUTPUT_TYPE__NEVER { 132 return nil 133 } 134 code := span.Status().Code 135 if gOutput == OUTPUT_TYPE__ON_FAILURE && code != codes.Error { 136 return nil 137 } 138 return span 139 } 140 } 141 142 func WithSpanMapExporter(mappers ...SpanMapper) func(trace.SpanExporter) trace.SpanExporter { 143 return func(exporter trace.SpanExporter) trace.SpanExporter { 144 return &spanMapExporter{ 145 mappers: mappers, 146 SpanExporter: exporter, 147 } 148 } 149 } 150 151 func WithErrIgnoreExporter() func(trace.SpanExporter) trace.SpanExporter { 152 return func(exporter trace.SpanExporter) trace.SpanExporter { 153 return &errIgnoreExporter{ 154 SpanExporter: exporter, 155 } 156 } 157 }