mirror of
https://github.com/golang/go
synced 2024-09-30 18:18:32 -06:00
c81623a0cb
Also moves core.Key to label.Key, but leaves the implementations behind for now. After using for a while, the word Tag conveys slightly the wrong concept, tagging implies the entire set of information, label maps better to a single named piece of information. A label is just a named key/value pair, it is not really tied to the event package, separating it makes it much easier to understand the public symbols of the event and core packages, and allows us to also move the key implementations somewhere else, which otherwise dominate the API. Change-Id: I46275d531cec91e28af6ab1e74a2713505d52533 Reviewed-on: https://go-review.googlesource.com/c/tools/+/229239 Run-TryBot: Ian Cottrell <iancottrell@google.com> Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
115 lines
3.0 KiB
Go
115 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 core provides support for event based telemetry.
|
|
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"golang.org/x/tools/internal/event/label"
|
|
)
|
|
|
|
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
|
|
)
|
|
|
|
// Event holds the information about an event of note that ocurred.
|
|
type Event struct {
|
|
At time.Time
|
|
|
|
typ eventType
|
|
|
|
// As events are often on the stack, storing the first few labels directly
|
|
// in the event can avoid 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 labels (one for each value and
|
|
// one for the message itself).
|
|
|
|
static [3]label.Label // inline storage for the first few labels
|
|
dynamic []label.Label // dynamically sized storage for remaining labels
|
|
}
|
|
|
|
// eventLabelMap implements label.Map for a the labels of an Event.
|
|
type eventLabelMap 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) {
|
|
lm := label.Map(ev)
|
|
if !ev.At.IsZero() {
|
|
fmt.Fprint(f, ev.At.Format("2006/01/02 15:04:05 "))
|
|
}
|
|
msg := Msg.Get(lm)
|
|
err := Err.Get(lm)
|
|
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++ {
|
|
l := ev.Label(index)
|
|
// msg and err were both already printed above, so we skip them to avoid
|
|
// double printing
|
|
if !l.Valid() || l.Key() == Msg || l.Key() == Err {
|
|
continue
|
|
}
|
|
fmt.Fprintf(f, "\n\t%v", l)
|
|
}
|
|
}
|
|
|
|
func (ev Event) Valid(index int) bool {
|
|
return index >= 0 && index < len(ev.static)+len(ev.dynamic)
|
|
}
|
|
|
|
func (ev Event) Label(index int) label.Label {
|
|
if index < len(ev.static) {
|
|
return ev.static[index]
|
|
}
|
|
return ev.dynamic[index-len(ev.static)]
|
|
}
|
|
|
|
func (ev Event) Find(key label.Key) label.Label {
|
|
for _, l := range ev.static {
|
|
if l.Key() == key {
|
|
return l
|
|
}
|
|
}
|
|
for _, l := range ev.dynamic {
|
|
if l.Key() == key {
|
|
return l
|
|
}
|
|
}
|
|
return label.Label{}
|
|
}
|
|
|
|
func MakeEvent(typ eventType, static [3]label.Label, labels []label.Label) Event {
|
|
return Event{
|
|
typ: typ,
|
|
static: static,
|
|
dynamic: labels,
|
|
}
|
|
}
|