Cut trace_id, span_id and parent_id from one hex string, added by emit rather than a wrapping handler, and carry the ids in the context only for the OTLP log handler, which keeps parent_id as an attribute.
- commit
- de03a0c642cf9a778613fb2715dce7d7690f3ae7
- parent
- 8a7c5a48163e0b1920242a70a008062497ec28d3
- author
- Dami <dami.etoile@gmail.com>
| M | internal/ | 16 | +++++++++----- |
| M | internal/ | 13 | +++++++---- |
| M | internal/ | 35 | +++++++++++++++--------------- |
@@ -7,8 +7,8 @@ import (
77 "time"88 )99 10-// spanKey carries a span's ids (spanIDs) from emit to the log handlers,11-// so the log record of an operation links to its span.10+// spanKey carries a span's ids (spanIDs) from emit to the OTLP log11+// handler, so the log record of an operation links to its span.1212 type spanKey struct{}1313 1414 // otlpHandler is a slog.Handler that queues OTLP log records.@@ -32,13 +32,17 @@ func (h *otlpHandler) Handle(ctx context.Context, r slog.Record) error {
3232 Body: str(r.Message),3333 Attributes: slices.Clip(h.attrs),3434 }35+ ids, span := ctx.Value(spanKey{}).(spanIDs)36+ if span {37+ rec.TraceID, rec.SpanID = ids.trace, ids.span38+ }3539 r.Attrs(func(a slog.Attr) bool {36- rec.Attributes = appendAttr(rec.Attributes, h.prefix, a)40+ // The record's own trace and span ids say these; parent_id stays.41+ if !span || (a.Key != "trace_id" && a.Key != "span_id") {42+ rec.Attributes = appendAttr(rec.Attributes, h.prefix, a)43+ }3744 return true3845 })39- if ids, ok := ctx.Value(spanKey{}).(spanIDs); ok {40- rec.TraceID, rec.SpanID = ids.trace, ids.span41- }4246 h.e.log(rec)4347 return nil4448 }@@ -91,8 +91,8 @@ func start(w io.Writer, e *exporter, c Config) {
9191 var hs []slog.Handler9292 if w != nil {9393 // OTLP carries the service in its resource instead.94- hs = append(hs, idsHandler{slog.NewJSONHandler(w, &slog.HandlerOptions{Level: c.Level}).95- WithAttrs([]slog.Attr{slog.String("service", "012")})})94+ hs = append(hs, slog.NewJSONHandler(w, &slog.HandlerOptions{Level: c.Level}).95+ WithAttrs([]slog.Attr{slog.String("service", "012")}))9696 }9797 if e != nil && e.urls.logs != "" {9898 hs = append(hs, &otlpHandler{e: e, level: c.Level})@@ -187,11 +187,14 @@ func emit(level slog.Level, name string, d time.Duration, attrs []slog.Attr, ids
187187 if !l.Enabled(ctx, level) {188188 return189189 }190+ all := make([]slog.Attr, 0, len(attrs)+5)191+ all = append(all, slog.String("event", name), slog.Float64("dur_ms", ms(d)))190192 if span {191- ctx = context.WithValue(ctx, spanKey{}, ids)193+ all = idAttrs(all, ids)194+ if e != nil && e.urls.logs != "" { // the OTLP log handler's195+ ctx = context.WithValue(ctx, spanKey{}, ids)196+ }192197 }193- all := make([]slog.Attr, 0, len(attrs)+2)194- all = append(all, slog.String("event", name), slog.Float64("dur_ms", ms(d)))195198 l.LogAttrs(ctx, level, name, append(all, attrs...)...)196199 }197200 @@ -259,23 +259,22 @@ func ParentFrom(ctx context.Context) Parent {
259259 return p260260 }261261 262-// idsHandler adds a span's ids to its record in the JSON log, as263-// trace_id, span_id and, below a root, parent_id, so the file log holds264-// the same tree as the traces.265-type idsHandler struct{ slog.Handler }266-267-func (h idsHandler) Handle(ctx context.Context, r slog.Record) error {268- if ids, ok := ctx.Value(spanKey{}).(spanIDs); ok {269- r = r.Clone()270- r.AddAttrs(slog.String("trace_id", hex.EncodeToString(ids.trace[:])), slog.String("span_id", hex.EncodeToString(ids.span[:])))271- if !ids.parent.IsZero() {272- r.AddAttrs(slog.String("parent_id", hex.EncodeToString(ids.parent[:])))273- }262+// idAttrs appends a span's ids to attrs as trace_id, span_id and, below263+// a root, parent_id, so the JSON log holds the same tree as the traces.264+// The three are cut from one string, one allocation.265+func idAttrs(attrs []slog.Attr, ids spanIDs) []slog.Attr {266+ var b [64]byte267+ hex.Encode(b[:32], ids.trace[:])268+ hex.Encode(b[32:48], ids.span[:])269+ n := 48270+ if !ids.parent.IsZero() {271+ hex.Encode(b[48:], ids.parent[:])272+ n = 64274273 }275- return h.Handler.Handle(ctx, r)276-}277-278-func (h idsHandler) WithAttrs(as []slog.Attr) slog.Handler {279- return idsHandler{h.Handler.WithAttrs(as)}274+ s := string(b[:n])275+ attrs = append(attrs, slog.String("trace_id", s[:32]), slog.String("span_id", s[32:48]))276+ if n == 64 {277+ attrs = append(attrs, slog.String("parent_id", s[48:]))278+ }279+ return attrs280280 }281-func (h idsHandler) WithGroup(name string) slog.Handler { return idsHandler{h.Handler.WithGroup(name)} }