mirror of
https://github.com/golang/go
synced 2024-11-05 23:26:18 -07:00
bd061c738e
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>
114 lines
3.0 KiB
Go
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,
|
|
}
|
|
}
|