1
0
mirror of https://github.com/golang/go synced 2024-11-18 10:54:40 -07:00

internal/telemetry: use tags instead of special event fields.

Change-Id: I0e6a26c62bd1f6eaa07c38a06152cb7a0f2eedc2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/225579
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Ian Cottrell 2020-03-20 12:00:56 -04:00
parent f8bbb56955
commit f61d083d3b
11 changed files with 80 additions and 71 deletions

View File

@ -543,7 +543,7 @@ func (i *Instance) writeMemoryDebug(threshold uint64) error {
func makeGlobalExporter(stderr io.Writer) event.Exporter {
return func(ctx context.Context, ev event.Event, tags event.TagMap) context.Context {
i := GetInstance(ctx)
if ev.IsLog() && (ev.Error != nil || i == nil) {
if ev.IsLog() && (event.Err.Get(ev.Map()) != nil || i == nil) {
fmt.Fprintf(stderr, "%v\n", ev)
}
ctx = protocol.LogEvent(ctx, ev, tags)

View File

@ -27,7 +27,7 @@ func LogEvent(ctx context.Context, ev event.Event, tags event.TagMap) context.Co
return ctx
}
msg := &LogMessageParams{Type: Info, Message: fmt.Sprint(ev)}
if ev.Error != nil {
if event.Err.Get(tags) != nil {
msg.Type = Error
}
go client.LogMessage(xcontext.Detach(ctx), msg)

View File

@ -13,21 +13,32 @@ import (
type eventType uint8
const (
LogType = eventType(iota)
StartSpanType
EndSpanType
LabelType
DetachType
RecordType
invalidType = eventType(iota)
LogType // an event that should be recorded in a log
StartSpanType // the start of a span of time
EndSpanType // the end of a span of time
LabelType // some values that should be noted for later events
DetachType // an event that causes a context to detach
RecordType // a value that should be tracked
)
type Event struct {
typ eventType
At time.Time
Message string
Error error
// sTags is used to hold a small number of tags inside an event whichout
// requiring a separate allocation.
// As tags are often on the stack, this avoids an allocation at all for
// the very common cases of simple events.
// The length needs to be large enough to cope with the majority of events
// but no so large as to cause undue stack pressure.
// A log message with two values will use 3 tags (one for each value and
// one for the message itself).
type sTags [3]Tag
tags []Tag
// Event holds the information about an event of note that ocurred.
type Event struct {
At time.Time
typ eventType
static sTags // inline storage for the first few tags
dynamic []Tag // dynamically sized storage for remaining tags
}
func (ev Event) IsLog() bool { return ev.typ == LogType }
@ -38,15 +49,18 @@ func (ev Event) IsDetach() bool { return ev.typ == DetachType }
func (ev Event) IsRecord() bool { return ev.typ == RecordType }
func (ev Event) Format(f fmt.State, r rune) {
tagMap := ev.Map()
if !ev.At.IsZero() {
fmt.Fprint(f, ev.At.Format("2006/01/02 15:04:05 "))
}
fmt.Fprint(f, ev.Message)
if ev.Error != nil {
msg := Msg.Get(tagMap)
err := Err.Get(tagMap)
fmt.Fprint(f, msg)
if err != nil {
if f.Flag('+') {
fmt.Fprintf(f, ": %+v", ev.Error)
fmt.Fprintf(f, ": %+v", err)
} else {
fmt.Fprintf(f, ": %v", ev.Error)
fmt.Fprintf(f, ": %v", err)
}
}
for it := ev.Tags(); it.Valid(); it.Advance() {
@ -56,12 +70,21 @@ func (ev Event) Format(f fmt.State, r rune) {
}
func (ev Event) Tags() TagIterator {
if len(ev.tags) == 0 {
return TagIterator{}
}
return NewTagIterator(ev.tags...)
return ChainTagIterators(
NewTagIterator(ev.static[:]...),
NewTagIterator(ev.dynamic...))
}
func (ev Event) Map() TagMap {
return NewTagMap(ev.tags...)
return MergeTagMaps(
NewTagMap(ev.static[:]...),
NewTagMap(ev.dynamic...))
}
func makeEvent(typ eventType, static sTags, tags []Tag) Event {
return Event{
typ: typ,
static: static,
dynamic: tags,
}
}

View File

@ -4,11 +4,17 @@
package event
import "math"
import (
"math"
)
var (
// Msg is a key used to add message strings to tag lists.
Msg = NewStringKey("message", "a readable message")
// Name is used for things like traces that have a name.
Name = NewStringKey("name", "an entity name")
// Err is a key used to add error values to tag lists.
Err = NewErrorKey("error", "")
Err = NewErrorKey("error", "an error that occurred")
)
// Key is the interface shared by all key implementations.
@ -487,4 +493,7 @@ func (k *ErrorKey) Get(tags TagMap) error {
}
// From can be used to get a value from a Tag.
func (k *ErrorKey) From(t Tag) error { return t.untyped.(error) }
func (k *ErrorKey) From(t Tag) error {
err, _ := t.untyped.(error)
return err
}

View File

@ -10,8 +10,5 @@ import (
// Label sends a label event to the exporter with the supplied tags.
func Label(ctx context.Context, tags ...Tag) context.Context {
return dispatch(ctx, Event{
typ: LabelType,
tags: tags,
})
return dispatch(ctx, makeEvent(LabelType, sTags{}, tags))
}

View File

@ -11,20 +11,13 @@ import (
// Log sends a log event with the supplied tag list to the exporter.
func Log(ctx context.Context, tags ...Tag) {
dispatch(ctx, Event{
typ: LogType,
tags: tags,
})
dispatch(ctx, makeEvent(LogType, sTags{}, tags))
}
// Print takes a message and a tag list and combines them into a single event
// before delivering them to the exporter.
func Print(ctx context.Context, message string, tags ...Tag) {
dispatch(ctx, Event{
typ: LogType,
Message: message,
tags: tags,
})
dispatch(ctx, makeEvent(LogType, sTags{Msg.Of(message)}, tags))
}
// Error takes a message and a tag list and combines them into a single event
@ -35,10 +28,5 @@ func Error(ctx context.Context, message string, err error, tags ...Tag) {
err = errors.New(message)
message = ""
}
dispatch(ctx, Event{
typ: LogType,
Message: message,
Error: err,
tags: tags,
})
dispatch(ctx, makeEvent(LogType, sTags{Msg.Of(message), Err.Of(err)}, tags))
}

View File

@ -9,8 +9,5 @@ import (
)
func Record(ctx context.Context, tags ...Tag) {
dispatch(ctx, Event{
typ: RecordType,
tags: tags,
})
dispatch(ctx, makeEvent(RecordType, sTags{}, tags))
}

View File

@ -9,18 +9,12 @@ import (
)
func StartSpan(ctx context.Context, name string, tags ...Tag) (context.Context, func()) {
ctx = dispatch(ctx, Event{
typ: StartSpanType,
Message: name,
tags: tags,
})
return ctx, func() {
dispatch(ctx, Event{typ: EndSpanType})
}
ctx = dispatch(ctx, makeEvent(StartSpanType, sTags{Name.Of(name)}, tags))
return ctx, func() { dispatch(ctx, makeEvent(EndSpanType, sTags{}, nil)) }
}
// Detach returns a context without an associated span.
// This allows the creation of spans that are not children of the current span.
func Detach(ctx context.Context) context.Context {
return dispatch(ctx, Event{typ: DetachType})
return dispatch(ctx, makeEvent(DetachType, sTags{}, nil))
}

View File

@ -29,7 +29,7 @@ type logWriter struct {
func (w *logWriter) ProcessEvent(ctx context.Context, ev event.Event, tagMap event.TagMap) context.Context {
switch {
case ev.IsLog():
if w.onlyErrors && ev.Error == nil {
if w.onlyErrors && event.Err.Get(tagMap) == nil {
return ctx
}
fmt.Fprintf(w.writer, "%v\n", ev)

View File

@ -200,7 +200,7 @@ func convertSpan(span *export.Span) *wire.Span {
Kind: wire.UnspecifiedSpanKind,
StartTime: convertTimestamp(span.Start.At),
EndTime: convertTimestamp(span.Finish.At),
Attributes: convertAttributes(span.Start.Tags()),
Attributes: convertAttributes(event.Filter(span.Start.Tags(), event.Name)),
TimeEvents: convertEvents(span.Events),
SameProcessAsParentSpan: true,
//TODO: StackTrace?
@ -295,19 +295,20 @@ func convertEvent(ev event.Event) wire.TimeEvent {
}
func convertAnnotation(ev event.Event) *wire.Annotation {
description := ev.Message
if description == "" && ev.Error != nil {
description = ev.Error.Error()
ev.Error = nil
}
tags := ev.Tags()
if ev.Error != nil {
extra := event.NewTagIterator(event.Err.Of(ev.Error))
tags = event.ChainTagIterators(extra, tags)
}
if description == "" && !tags.Valid() {
if !tags.Valid() {
return nil
}
tagMap := ev.Map()
description := event.Msg.Get(tagMap)
tags = event.Filter(tags, event.Msg)
if description == "" {
err := event.Err.Get(tagMap)
tags = event.Filter(tags, event.Err)
if err != nil {
description = err.Error()
}
}
return &wire.Annotation{
Description: toTruncatableString(description),
Attributes: convertAttributes(tags),

View File

@ -54,7 +54,7 @@ func Spans(output event.Exporter) event.Exporter {
}
case ev.IsStartSpan():
span := &Span{
Name: ev.Message,
Name: event.Name.Get(tagMap),
Start: ev,
}
if parent := GetSpan(ctx); parent != nil {