1
0
mirror of https://github.com/golang/go synced 2024-11-05 23:26:18 -07:00
go/internal/telemetry/event/event.go
Ian Cottrell bd061c738e internal/telemetry: expose the TagOf* and Unpack* methods
These allow tags to be constructed and used from outside
the event package.
This makes it easy for users of these APIs to write their own
implementations of Key.

Change-Id: Ic3320a80f297bbe1d4cd6d9beafbe13ebbace398
Reviewed-on: https://go-review.googlesource.com/c/tools/+/228232
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
2020-04-16 04:05:21 +00:00

114 lines
3.0 KiB
Go

// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package event provides support for event based telemetry.
package event
import (
"fmt"
"time"
)
type eventType uint8
const (
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
)
// 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
// 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
}
// eventTagMap implements TagMap for a the tags of an Event.
type eventTagMap struct {
event Event
}
func (ev Event) IsLog() bool { return ev.typ == LogType }
func (ev Event) IsEndSpan() bool { return ev.typ == EndSpanType }
func (ev Event) IsStartSpan() bool { return ev.typ == StartSpanType }
func (ev Event) IsLabel() bool { return ev.typ == LabelType }
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 := TagMap(ev)
if !ev.At.IsZero() {
fmt.Fprint(f, ev.At.Format("2006/01/02 15:04:05 "))
}
msg := Msg.Get(tagMap)
err := Err.Get(tagMap)
fmt.Fprint(f, msg)
if err != nil {
if f.Flag('+') {
fmt.Fprintf(f, ": %+v", err)
} else {
fmt.Fprintf(f, ": %v", err)
}
}
for index := 0; ev.Valid(index); index++ {
tag := ev.Tag(index)
// msg and err were both already printed above, so we skip them to avoid
// double printing
if !tag.Valid() || tag.Key() == Msg || tag.Key() == Err {
continue
}
fmt.Fprintf(f, "\n\t%v", tag)
}
}
func (ev Event) Valid(index int) bool {
return index >= 0 && index < len(ev.static)+len(ev.dynamic)
}
func (ev Event) Tag(index int) Tag {
if index < len(ev.static) {
return ev.static[index]
}
return ev.dynamic[index-len(ev.static)]
}
func (ev Event) Find(key Key) Tag {
for _, tag := range ev.static {
if tag.Key() == key {
return tag
}
}
for _, tag := range ev.dynamic {
if tag.Key() == key {
return tag
}
}
return Tag{}
}
func makeEvent(typ eventType, static sTags, tags []Tag) Event {
return Event{
typ: typ,
static: static,
dynamic: tags,
}
}