From 92ff96233d9fb305bae5fa26bfc0370cb4facf38 Mon Sep 17 00:00:00 2001 From: David Muir Sharnoff Date: Sun, 10 Jul 2022 17:30:49 -0700 Subject: [PATCH] remove Prefill, add logging of spanID in test logger --- POTENTIAL-FEATURES.md | 27 +++++++++++ TODO | 34 ++++++++++++++ internal/multibase/group.go | 22 --------- logger.go | 6 --- xopbase/base.go | 6 --- xopbase/testlogger/testlogger.go | 79 +++++++++++++++++++------------- 6 files changed, 109 insertions(+), 65 deletions(-) create mode 100644 POTENTIAL-FEATURES.md create mode 100644 TODO diff --git a/POTENTIAL-FEATURES.md b/POTENTIAL-FEATURES.md new file mode 100644 index 00000000..867a999a --- /dev/null +++ b/POTENTIAL-FEATURES.md @@ -0,0 +1,27 @@ +# Things not built, but considered + +These are things that could be built if there is sufficient interest. + +## Per-line prefill + +Add per-line data for all lines in a span. Allow the set of data to +change. + +In the base loggers: + +```go +type Span interface { + ... other stuff + + // On a per-Span basis, there will only ever be one outstanding Prefill + // in progress at a time and it will not overlap Flush() + Prefill() Prefilling + + type Prefilling interface { + ObjectParts + Replace() // replaces per-line prefill + AddTo() // adds to per-line prefill + } +} +``` + diff --git a/TODO b/TODO new file mode 100644 index 00000000..acdac968 --- /dev/null +++ b/TODO @@ -0,0 +1,34 @@ + +Replace HexBytes with arrays etc can be used as map keys + +Adhere to go spec: Id -> ID + +Replace SpanType & AddData + + Each registered type should be bound to a + specific data type. Replace Span.AddData & span.SetType + something better. + + RegisterSpanType(interface{}) + + Hmmm. AddData(SpanData) + type interface {} + struct tags: + "unique" - map-key-types only, smashes duplicates in an array + "index" - these values should be indexed + "keep-first" - when given duplicates, keep only the first + +Can chaining be done with generics? + + type bot interface{ + Int(string, int64) + Bool(string, bool) + New() bot + } + + type top interface{ + + type Builder[T:any, B:bot] struct { + T + } + func (b Builder[T]) Int8(k string, v int8) Builder[T] diff --git a/internal/multibase/group.go b/internal/multibase/group.go index 83f8a6f7..bc7b5934 100644 --- a/internal/multibase/group.go +++ b/internal/multibase/group.go @@ -88,28 +88,6 @@ func (s Spans) SpanInfo(st xopconst.SpanType, things []xop.Thing) { } } -func (s Requests) AddPrefill(things []xop.Thing) { - for _, span := range s { - span.AddPrefill(things) - } -} -func (s Spans) AddPrefill(things []xop.Thing) { - for _, span := range s { - span.AddPrefill(things) - } -} - -func (s Requests) ResetLinePrefill() { - for _, span := range s { - span.ResetLinePrefill() - } -} -func (s Spans) ResetLinePrefill() { - for _, span := range s { - span.ResetLinePrefill() - } -} - func (s Requests) Line(level xopconst.Level, t time.Time) xopbase.Line { lines := make(Lines, len(s)) for i, span := range s { diff --git a/logger.go b/logger.go index 8ec7b289..e951dc57 100644 --- a/logger.go +++ b/logger.go @@ -313,12 +313,6 @@ func (ll *LogLine) Any(k string, v interface{}) *LogLine { // TODO: func (l *Log) AdjustCounter(name string, value float64, ) // TODO: func (l *Log) Event -func (s *Span) CurrentPrefill() []xop.Thing { - c := make([]xop.Thing, len(s.seed.prefill)) - copy(c, s.seed.prefill) - return c -} - func copyMap(o map[string]interface{}) map[string]interface{} { n := make(map[string]interface{}) for k, v := range o { diff --git a/xopbase/base.go b/xopbase/base.go index 5a5750b8..e12c6657 100644 --- a/xopbase/base.go +++ b/xopbase/base.go @@ -35,12 +35,6 @@ type Span interface { // SpanInfo calls are only made while holding the Flush() lock SpanInfo(xopconst.SpanType, []xop.Thing) - // AddPrefill adds to what has already been provided for this span. - // Calls to AddPrefill will not overlap other calls to AddPrefil or - // to ResetLinePrefil. - AddPrefill([]xop.Thing) - ResetLinePrefill() - // Line starts another line of log output. Span implementations // can expect multiple calls simultaneously and even during a call // to SpanInfo() or Flush(). diff --git a/xopbase/testlogger/testlogger.go b/xopbase/testlogger/testlogger.go index bbdfa96b..4ec6c364 100644 --- a/xopbase/testlogger/testlogger.go +++ b/xopbase/testlogger/testlogger.go @@ -2,6 +2,7 @@ package testlogger import ( "encoding/json" + "fmt" "strconv" "sync" "time" @@ -25,16 +26,47 @@ var _ xopbase.Line = &Line{} func New(t testingT) *TestLogger { return &TestLogger{ - t: t, + t: t, + traceMap: make(map[string]*traceInfo), } } type TestLogger struct { - lock sync.Mutex - t testingT - Requests []*Span - Spans []*Span - Lines []*Line + lock sync.Mutex + t testingT + Requests []*Span + Spans []*Span + Lines []*Line + traceCount int + traceMap map[string]*traceInfo +} + +type traceInfo struct { + spanCount int + traceNum int + spans map[string]int +} + +func (l *TestLogger) setShort(span trace.Bundle) string { + ts := span.Trace.GetTraceId().String() + if ti, ok := l.traceMap[ts]; ok { + ti.spanCount++ + ti.spans[span.Trace.GetSpanId().String()] = ti.spanCount + short := fmt.Sprintf("T%d.%d", ti.traceNum, ti.spanCount) + l.t.Log("Start span " + short + "=" + span.Trace.HeaderString()) + return short + } + l.traceCount++ + l.traceMap[ts] = &traceInfo{ + spanCount: 1, + traceNum: l.traceCount, + spans: map[string]int{ + span.Trace.GetSpanId().String(): 1, + }, + } + short := fmt.Sprintf("T%d.%d", l.traceCount, 1) + l.t.Log("Start span " + short + "=" + span.Trace.HeaderString()) + return short } type Span struct { @@ -48,8 +80,7 @@ type Span struct { Lines []*Line Data []xop.Thing SpanType xopconst.SpanType - SpanPrefill []xop.Thing - LinePrefill []xop.Thing + short string } type Line struct { @@ -66,11 +97,14 @@ func (l *TestLogger) WithMe() xoplog.SeedModifier { func (l *TestLogger) Close() {} func (l *TestLogger) ReferencesKept() bool { return true } -func (l *TestLogger) Request(bundle trace.Bundle) xopbase.Request { +func (l *TestLogger) Request(span trace.Bundle) xopbase.Request { + l.lock.Lock() + defer l.lock.Unlock() return &Span{ testLogger: l, IsRequest: true, - Trace: bundle, + Trace: span, + short: l.setShort(span), } } @@ -83,6 +117,8 @@ func (s *Span) Span(span trace.Bundle) xopbase.Span { defer s.lock.Unlock() n := &Span{ testLogger: s.testLogger, + Trace: span, + short: s.testLogger.setShort(span), } s.Spans = append(s.Spans, n) s.testLogger.Spans = append(s.testLogger.Spans, n) @@ -94,24 +130,6 @@ func (s *Span) SpanInfo(spanType xopconst.SpanType, data []xop.Thing) { s.Data = data } -func (s *Span) AddPrefill(data []xop.Thing) { - s.lock.Lock() - defer s.lock.Unlock() - s.LinePrefill = append(s.LinePrefill, data...) -} - -func (s *Span) ResetLinePrefill() { - s.lock.Lock() - defer s.lock.Unlock() - s.LinePrefill = nil -} - -func (s *Span) ResetPrefil(data []xop.Thing) { - s.lock.Lock() - defer s.lock.Unlock() - s.LinePrefill = nil -} - func (s *Span) Line(level xopconst.Level, t time.Time) xopbase.Line { line := &Line{ Level: level, @@ -137,7 +155,7 @@ func (l *Line) Recycle(level xopconst.Level, t time.Time) { func (l Line) Msg(m string) { l.Message = m - text := m + text := l.Span.short + ": " + m // TODO: replace with higher performance version // TODO: move encoding somewhere else for _, thing := range l.Things.Things { @@ -150,8 +168,7 @@ func (l Line) Msg(m string) { case xop.BoolType: text += strconv.FormatBool(thing.Any.(bool)) case xop.StringType: - enc, _ := json.Marshal(thing.String) - text += string(enc) + text += strconv.Quote(thing.String) case xop.TimeType: text += thing.Any.(time.Time).Format(time.RFC3339) case xop.AnyType: